namespace KumiScript.Interpreter { public class ProperListExpression : ListExpression { readonly List _values; public ProperListExpression(List expressions) { _values = expressions; } public override Expression Eval(Environment env) { ProcedureExpression? rator = Car().Eval(env) as ProcedureExpression; if (rator is null) throw new InterpreterInvalidInvocationException(); ListExpression rand = Cdr(); return rator.Apply(rand, env); } public override List EvalMembers(Environment env) { List result = new List(); for (int i = 0; i < _values.Count; i++) result.Add(_values[i].Eval(env)); return result; } public override List GetMembers() { return _values; } public override string ToString() { return String.Concat("(", String.Join(' ', (object[]) _values.ToArray()), ")"); } public override Expression Car() { if (_values.Count == 0) return this; return _values.First(); } public override ListExpression Cdr() { if (_values.Count == 0) return this; List rest = new List(_values); rest.RemoveAt(0); return ListFactory.MakeList(rest); } public override ProperListExpression Cons(Expression expr) { List consd = new List(_values); consd.Insert(0, expr); return new ProperListExpression(consd); } public override bool Equals(Expression expr) { ProperListExpression? lexpr = expr as ProperListExpression; if (lexpr is null) return false; return lexpr.GetMembers().SequenceEqual(_values); } } }