// two arguments primitive. // more that two arguments will be raped to list of primitives // (foo 1 2) public static AST Expand(Syntax stx, Environment env) { var list = stx.AsLinkedList <Value>(); var argc = GetArgsCount(list); AssertArgsMinimum("primitive2", "arity mismatch", 2, argc, list, stx); var set_kwd = list[0].AsSyntax(); var arguments = AstBuilder.ExpandListElements(list, 1, env); if (argc == 2) { return(new AstPrimitive(stx, set_kwd, arguments)); } else { // for expression (+ 1 2 3 4) var args = arguments.DuplicateReverse(0, -1); //< (+ 4 3 2 1) var rightarg = args[0]; //< 4 var skip = 1; foreach (var leftarg in args) //< 3, 2, 1, { if (skip-- > 0) { continue; } var values = ValueLinkedList.FromArguments(leftarg, rightarg); var prim = new AstPrimitive(stx, set_kwd, values); rightarg.Set(prim); } return(rightarg.AsAST()); } }
public void LinkedListTest() { string expect = "(1 2 3.1)"; LinkedList <Value> x1 = ValueLinkedList.FromArguments(1, 2, 3.1); Value a1 = new Value(x1); Assert.AreEqual(expect, x1.ToString()); Assert.AreEqual(expect, a1.ToString()); }
public void LinkedListTest() { LinkedList <Value> x1 = ValueLinkedList.FromArguments(1, 2, 3); LinkedList <Value> x2 = ValueLinkedList.FromArguments(4, 5, 6); Value a1 = new Value(x1); Value a2 = new Value(x2); Value b1 = new Value(x1); Value b2 = new Value(x2); Assert.AreEqual(x1, (LinkedList <Value>)a1); Assert.AreEqual(x2, (LinkedList <Value>)a2); Assert.AreEqual(a1, b1); Assert.AreEqual(a2, b2); Assert.AreNotEqual(a1, a2); Assert.AreNotEqual(b1, b2); Assert.AreNotEqual(x1, (LinkedList <Value>)a2); Assert.AreNotEqual(x2, (LinkedList <Value>)a1); }
// (cond () ...) public static AST Expand(Syntax stx, Environment env) { var list = stx.AsLinkedList <Value>(); //< list of syntax objects var argc = GetArgsCount(list); var keyword = list[0].AsSyntax(); LinkedList <Value> allcases = null; LinkedList <Value> elsecase = null; var curent = list.GetNodeAtIndex(1); while (curent != null) { var conditional_stx = curent.Value.AsSyntax(); if (elsecase != null) { throw SchemeError.SyntaxError("cond", "unexpected expression after condition's else clause", conditional_stx); } if (conditional_stx.IsExpression) { // Get single conditional expression var conditional_list = conditional_stx.AsLinkedList <Value>(); // Check arguments count, should be 2 for each condition var size = conditional_list.Count; if (size != 2) { throw SchemeError.ArityError("cond", "arity mismatch", 2, size, conditional_list, conditional_stx); } // Now get condition and it's expression var var = conditional_list[0].AsSyntax(); var val = conditional_list[1].AsSyntax(); if (var.IsIdentifier && var.AsIdentifier() == Symbol.ELSE) { var ast = AstBuilder.ExpandInternal(val, env); elsecase = ValueLinkedList.FromArguments(new Value(var), new Value(ast)); } else { var cond_ = AstBuilder.ExpandInternal(var, env); var then_ = AstBuilder.ExpandInternal(val, env); var single_cond = ValueLinkedList.FromArguments(cond_, then_); if (allcases == null) { allcases = new LinkedList <Value>(); } allcases.AddLast(new Value(single_cond)); } } else { throw SchemeError.SyntaxError("cond", "Expected condition's expression list", conditional_stx); } curent = curent.Next; } return(new AstCondition(stx, keyword, allcases, elsecase)); }