private static void List(Evaluator eval, StackFrame frame) { var args = frame.args; if (args == null) { eval.SetReturn(null); return; } if (args.IsEmpty) { eval.SetReturn(new Atom()); return; } Atom head, tail; head = tail = new Atom(); head.value = args.value; for (Atom iter = args.next; iter != null; iter = iter.next) { tail = tail.next = new Atom(); tail.value = iter.value; } eval.Return(head); }
// TODO: Осознать, что тут происходит private static void TableEach(Evaluator eval, StackFrame frame) { var args = frame.args; var(dict, func) = StructureUtils.Split2(args); Context dictionary = GetDictionary(dict); Function proc = func?.value as Function; if (dictionary == null) { throw new ArgumentException("First argument must be table!"); } if (proc == null) { throw new ArgumentException("Second argument must be procedure!"); } switch (frame.state.value) { case "-eval-sexp-body-": var list = dictionary .Select(pair => StructureUtils.List(new Atom(AtomType.String, pair.Key), pair.Value)) .ToArray(); frame.temp1 = StructureUtils.List(list); frame.state = new Atom("-built-in-table-each-"); break; case "-built-in-table-each-": if (eval.HaveReturn()) { frame.temp2 = StructureUtils.BuildListContainer(frame.temp2, eval.TakeReturn()); } if (frame.temp1 != null) { var pair = frame.temp1.atom; frame.temp1 = frame.temp1.next; var newFrame = eval.CreateFrame( "-eval-sexp-args-", new Atom(func, pair), frame.context); newFrame.function = func; newFrame.args = frame.temp1.atom; } else { eval.SetReturn(null); frame.state = new Atom("-eval-sexp-body-"); } break; } }
private static void Filter(Evaluator eval, StackFrame frame) { (var list, var proc, var skip) = StructureUtils.Split3(frame.args); bool skipNull = (bool?)skip?.value ?? false; switch (frame.state.value) { case "-eval-sexp-body-": frame.temp1 = list; frame.state = new Atom("-built-in-map-"); break; case "-built-in-map-": if (eval.HaveReturn()) { var pred = eval.TakeReturn(); bool add = (bool?)pred?.value ?? false; if (add) { frame.temp2 = StructureUtils.BuildListContainer(frame.temp2, frame.temp3); } } if (frame.temp1 != null) { while (skipNull && frame.temp1.atom == null) { frame.temp1 = frame.temp1.next; } var subExpression = frame.temp1.atom; frame.temp3 = subExpression; frame.temp1 = frame.temp1.next; subExpression = new Atom(subExpression, null); frame.temp1 = frame.temp1.next; var newFrame = eval.CreateFrame( "-eval-sexp-args-", new Atom(proc, subExpression), frame.context); newFrame.function = proc; newFrame.args = subExpression; } else { eval.SetReturn(frame.temp2.atom); frame.state = new Atom("-eval-sexp-body-"); } break; } }
private static void TablePred(Evaluator eval, StackFrame frame) { var atom = frame.args.atom; var result = atom != null && atom.type == AtomType.Native; if (!result) { eval.SetReturn(Atoms.FALSE); } else { var table = atom.value as Context; eval.Return(table != null ? Atoms.TRUE : Atoms.FALSE); } }
private static void Each(Evaluator eval, StackFrame frame) { (var list, var proc, var skip) = StructureUtils.Split3(frame.args); bool skipNull = (bool?)skip?.value ?? false; switch (frame.state.value) { case "-eval-sexp-body-": frame.temp1 = list; frame.state = new Atom("-built-in-each-"); break; case "-built-in-each-": if (eval.HaveReturn()) { frame.temp2 = StructureUtils.BuildListContainer(frame.temp2, eval.TakeReturn()); } if (frame.temp1 != null) { while (skipNull && frame.temp1.atom == null) { frame.temp1 = frame.temp1.next; } var subExpression = new Atom(frame.temp1.atom, null); var newFrame = eval.CreateFrame( "-eval-sexp-body-", StructureUtils.List(proc, frame.temp1.atom), frame.context); newFrame.function = proc; newFrame.args = subExpression; frame.temp1 = frame.temp1.next; } else { eval.SetReturn(null); frame.state = new Atom("-eval-sexp-body-"); } break; } }