// 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; } }
public static Atom Handle(List <Token> tokens) { Atom list = null; int offset = 0; int length = tokens.Count; while (offset < length) { Atom node = ReadNode(tokens, ref offset, true); list = StructureUtils.BuildListContainer(list, node); } return(list?.atom); }
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; } }
public Atom Evaluate(Atom atom, Context current_context, string startState = null) { _retValue = null; _haveReturn = false; Stack.CreateFrame(startState ?? "-eval-", atom, current_context); Console.WriteLine("Start evaluation"); while (Stack.stack.Count > 0) { if (ErrorMessage != null) { Console.WriteLine($"[ERROR] {ErrorMessage}"); ErrorMessage = null; return(null); } // Console.WriteLine($"RetValue: {_retValue}"); // Stack.Dump(1); //Thread.Sleep(50); Function func; StackFrame frame = Stack.TopFrame; switch (frame.state.value) { case "-eval-": if (frame.expression.IsPair) { frame.state = new Atom("-eval-sexp-head-"); continue; } if (frame.expression.IsSymbol) { var name = (string)frame.expression.value; try { SetReturn(ContextUtils.Get((Context)frame.context.value, name)); } catch (BombardoException e) { Console.WriteLine($"[ERROR] {e}"); return(null); } CloseFrame(); continue; } SetReturn(frame.expression); CloseFrame(); continue; case "-eval-each-": if (HaveReturn()) { frame.temp1 = StructureUtils.BuildListContainer(frame.temp1, TakeReturn()); } if (frame.expression != null) { var subExpression = frame.expression.atom; frame.expression = frame.expression.next; Stack.CreateFrame("-eval-", subExpression, frame.context); continue; } SetReturn(frame.temp1.atom); // frame.temp1 = null; CloseFrame(); continue; case "-eval-block-": if (HaveReturn()) { frame.temp1 = TakeReturn(); } if (frame.expression != null) { var subExpression = frame.expression.atom; frame.expression = frame.expression.next; Stack.CreateFrame("-eval-", subExpression, frame.context); continue; } SetReturn(frame.temp1); // frame.temp1 = null; CloseFrame(); continue; case "-eval-sexp-head-": if (!HaveReturn()) { var head = frame.expression.atom; Stack.CreateFrame("-eval-", head, frame.context); continue; } frame.function = TakeReturn(); if (!frame.function.IsFunction) { Console.WriteLine($"[ERROR] Head is not function: {frame.function}"); return(null); } frame.state = new Atom("-eval-sexp-args-"); continue; case "-eval-sexp-args-": if (!HaveReturn()) { func = (Function)frame.function.value; if (func.EvalArgs && frame.expression.next != null) { Stack.CreateFrame("-eval-each-", frame.expression.next, frame.context); continue; } frame.args = frame.expression.next; frame.state = new Atom("-eval-sexp-body-"); continue; } frame.args = TakeReturn(); frame.state = new Atom("-eval-sexp-body-"); continue; case "-eval-sexp-body-": func = (Function)frame.function.value; if (!HaveReturn()) { func.Apply(this, frame); continue; } if (func.EvalResult) { frame.state = new Atom("-eval-sexp-result-"); frame.temp1 = TakeReturn(); continue; } CloseFrame(); continue; case "-eval-sexp-result-": if (!HaveReturn()) { Stack.CreateFrame("-eval-", frame.temp1, frame.context); continue; } SetReturn(frame.temp1); frame.temp1 = null; CloseFrame(); continue; } // Ни один из указанных стейтов, значит: // Либо это стейты функции и тогда её надо вызывать if (frame.function != null) { func = (Function)frame.function.value; func.Apply(this, frame); continue; } // Либо если нет функции - то это ошибка интерпретации SetError($"Wrong evaluation state: {frame.state.value}"); } if (HaveReturn()) { return(TakeReturn()); } return(null); }