private static void Define(Evaluator eval, StackFrame frame) { var(sym, value, context) = StructureUtils.Split3(frame.args); if (sym.type != AtomType.Symbol) { throw new ArgumentException("Definition name must be symbol!"); } if (eval.HaveReturn()) { string name = (string)sym.value; Atom result = eval.TakeReturn(); Context ctx = context?.value as Context ?? frame.context.value as Context; if (result?.value is Closure function) { function.Name = name; } //Console.WriteLine($"DEFINE: '{name}' = '{result}' at -internal-state-{ctx}"); ContextUtils.Define(ctx, result, name); eval.Return(result); return; } eval.CreateFrame("-eval-", value, frame.context); frame.state = Atoms.INTERNAL_STATE; }
private static void Undefine(Evaluator eval, StackFrame frame) { var args = frame.args; Atom sym = (Atom)args?.value; if (sym.type != AtomType.Symbol) { throw new ArgumentException("Undefining name must be symbol!"); } var ctx = frame.context.value as Context; var result = ContextUtils.Undefine(ctx, (string)sym.value); eval.Return(result); }
private static void TableImportAll(Evaluator eval, StackFrame frame) { var(src, dst) = StructureUtils.Split2(frame.args); if (dst == null || dst.IsPair) { dst = frame.context.atom; } var srcCtx = GetDictionary(src); var dstCtx = GetDictionary(dst); ContextUtils.ImportAllSymbols(srcCtx, dstCtx); eval.Return(null); }
private static void TableImport(Evaluator eval, StackFrame frame) { var(src, dst, names) = StructureUtils.Split3(frame.args); if (names == null && dst.IsPair) { names = dst; dst = frame.context.atom; } var srcCtx = GetDictionary(src); var dstCtx = GetDictionary(dst); string[] nameList = StructureUtils.ListToStringArray(names, "TABLE"); ContextUtils.ImportSymbols(srcCtx, dstCtx, nameList); eval.Return(null); }
private static void SetFirst(Evaluator eval, StackFrame frame) { var args = frame.args; Atom sym = (Atom)args?.value; if (sym.type != AtomType.Symbol) { throw new ArgumentException("Variable name must be symbol!"); } if (eval.HaveReturn()) { var result = eval.TakeReturn(); var ctx = frame.context.value as Context; ContextUtils.Set(ctx, result, (string)sym.value); eval.Return(result); return; } eval.CreateFrame("-eval-", args.next?.atom, frame.context); frame.state = Atoms.INTERNAL_STATE; }
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); }