/// <summary> /// Lists the environment (and optionally parent environment) as key value pairs /// (A Q-expr of Q-exprs) /// </summary> internal static Value ListEnv(Env environment, Value arguments) { SExprValue sexprValue = arguments.As <SExprValue>(); Debug.Assert(sexprValue != null, "Non s-expr"); // Check Error Conditions var check = ArgumentsExactCount(sexprValue, 1, "printenv"); if (check != null) { return(check); } var result = new QExprValue(); foreach (var k in environment.Keys(true)) { var kvp = new QExprValue(); kvp.Cell.Add(new SymbolValue(k)); kvp.Cell.Add(environment.Get(k)); result.Cell.Add(kvp); } return(result); }
/// <summary> /// Joins multiple q-expressions together /// </summary> /// <returns>The join.</returns> internal static Value Join(Env environment, Value arguments) { SExprValue sexprValue = arguments.As <SExprValue>(); Debug.Assert(sexprValue != null, "Non s-expr"); var check = ArgumentsAllOfType(sexprValue, QExprValue.TYPE, "join"); if (check != null) { return(check); } QExprValue x = sexprValue.Cell[0].As <QExprValue>(); sexprValue.Cell.RemoveAt(0); while (sexprValue.Cell.Count > 0) { QExprValue y = sexprValue.Cell[0].As <QExprValue>(); sexprValue.Cell.RemoveAt(0); x = Join(environment, x, y); } return(x); }
/// <summary> /// Joins two q-expressions by copying all chilren of y into x /// </summary> /// <returns>The isp value join.</returns> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> static QExprValue Join(Env environment, QExprValue x, QExprValue y) { // For each child in 'y' add it to 'x' while (y.Cell.Count > 0) { var z = y.Cell[0]; y.Cell.RemoveAt(0); x.Cell.Add(z); } return(x); }
/// <summary> /// Variable put and def. /// </summary> static Value Var(Env environment, Value arguments, string func) { SExprValue sexprValue = arguments.As <SExprValue>(); Debug.Assert(sexprValue != null, "Non s-expr"); var check = ArgumentsIOfType(sexprValue, 0, QExprValue.TYPE, func); if (check != null) { return(check); } QExprValue syms = sexprValue.Cell[0].As <QExprValue>(); for (int i = 0; i < syms.Cell.Count; i++) { if (!(syms.Cell[i] is SymbolValue)) { return(new ErrorValue($"Function '{func}' cannot define non-symbol. Got {syms.Cell[i].Type}. Expected {SymbolValue.TYPE}")); } } if (syms.Cell.Count != sexprValue.Cell.Count - 1) { return(new ErrorValue($"Function '{func}' passed wrong number of arguments. Got {syms.Cell.Count} symbols and {sexprValue.Cell.Count - 1} arguments.")); } for (int i = 0; i < syms.Cell.Count; i++) { // If 'def' define in globally. If 'put' define in locally if (func == "def") { environment.Def(syms.Cell[i].As <SymbolValue>().Value, sexprValue.Cell[i + 1]); } if (func == "=") { environment.Put(syms.Cell[i].As <SymbolValue>().Value, sexprValue.Cell[i + 1]); } } return(new SExprValue()); }
/// <summary> /// Creates a lambda function consisting of two q-expressions /// representing the formal parameters (all must be symbols) and the body. /// </summary> internal static Value Lambda(Env environment, Value arguments) { SExprValue sexprValue = arguments.As <SExprValue>(); Debug.Assert(sexprValue != null, "Non s-expr"); // Check Error Conditions var check = ArgumentsExactCount(sexprValue, 2, "lambda"); if (check != null) { return(check); } check = ArgumentsIOfType(sexprValue, 0, QExprValue.TYPE, "lambda (formals)"); if (check != null) { return(check); } check = ArgumentsIOfType(sexprValue, 1, QExprValue.TYPE, "lambda (body)"); if (check != null) { return(check); } // Check first Q-Expression contains only Symbols QExprValue formals = sexprValue.Cell[0].As <QExprValue>(); for (int i = 0; i < formals.Cell.Count; i++) { if (!(formals.Cell[i] is SymbolValue)) { return(new ErrorValue($"Cannot define non-symbol. Got {formals.Cell[i].Type} Expected {SymbolValue.TYPE}.")); } } Value body = sexprValue.Cell[1]; return(new LambdaFuncValue(formals, body)); }
/// <summary> /// Evaluates the q-expression contained as first child of this s-expr /// </summary> /// <returns>The eval.</returns> internal static Value Eval(Env environment, Value arguments) { SExprValue sexprValue = arguments.As <SExprValue>(); Debug.Assert(sexprValue != null, "Non s-expr"); var check = ArgumentsExactCount(sexprValue, 1, "eval"); if (check != null) { return(check); } check = ArgumentsIOfType(sexprValue, 0, QExprValue.TYPE, "eval"); if (check != null) { return(check); } QExprValue x = sexprValue.Cell[0].As <QExprValue>(); return(environment.Evaluate(x.CreateSExpression())); }