private static Expression addExpr(ListNode tree, Expression env) { if (tree.values.Count != 3) { return createRuntimeException("wrong number of arguments passed to add procedure"); } //unboxing from type object Expression lhs = unboxValue(matchExpression(tree.values[1], env), typeof(RacketNum)); Expression rhs = unboxValue(matchExpression(tree.values[2], env), typeof(RacketNum)); Expression result = Expression.Call(lhs, typeof(RacketNum).GetMethod("Plus"), new Expression[] { rhs }); // we do not need to wrap this in an obj box because this is done in logic already //return wrapInObjBox(result, type); return result; }
/** match all top level forms in the form of: * * topLevelForms ::= (<def> | <using>)* * * each define will become a method that a c# code can call * returns a list of using statments and a list of defines **/ static Tuple<List<Expression>, List<ExposedFunction>> matchTopLevelDll(ListNode tree, Expression env) { List<Expression> usingList = new List<Expression>(); List<ExposedFunction> defineList = new List<ExposedFunction>(); foreach (Node n in tree.values) { if (n.isList()) { ListNode list = (ListNode)n; if (list.values[0].isLeaf()) { Expression name = Expression.Constant(list.values[0].getValue(), typeof(String)); if (list.values[0].isLeaf() && list.values[0].getValue() == "define") { defineList.Add(dllDefineExpr(list, env)); } else if (list.values[0].isLeaf() && list.values[0].getValue() == "using") { usingList.Add(netImportStmt(list, env)); } } } else { throw new Exception("Illegal expression encountered at the top level of a DLL. Expression: " + tree.getValue()); } } if (defineList.Count == 0) { throw new Exception("Dll being compiled with no top level defines?"); } return new Tuple<List<Expression>, List<ExposedFunction>>(usingList, defineList); }
// create a new lambda expression and store it into the environment private static Expression lambdaExpr(ListNode tree, Expression env) { if (tree.values.Count < 3 || !tree.values[1].isList()) { return createRuntimeException("too few arguments passed to lambda procedure or first argument was not parameter list"); } //make new environment var makeEnv = Expression.New( typeof(CompilerLib.Environment).GetConstructor(new Type[] { typeof(CompilerLib.Environment) }), env); var new_env = Expression.Variable(typeof(CompilerLib.Environment)); var assign = Expression.Assign(new_env, makeEnv); //Add the environment to the start of the body of the lambda List<Expression> body = new List<Expression>(); body.Add(new_env); body.Add(assign); //make our parameter list List<ParameterExpression> paramList = new List<ParameterExpression>(); foreach (Node n in tree.values[1].getList()) { if (!n.isLeaf()) { return createRuntimeException("list embeded in the parameter list of labmda expression"); } ParameterExpression var = Expression.Variable(typeof(Object), n.getValue()); paramList.Add(var); // we also need to add a statement to put each of our parameters into our new environment (for scoping reasons) var name = Expression.Constant(n.getValue()); Expression addToEnv = Expression.Call( new_env, typeof(CompilerLib.Environment).GetMethod("add"), name, Expression.Convert(var, typeof(ObjBox))); body.Add(addToEnv); } List<Node> values = new List<Node>(); for (int i = 2; i < tree.values.Count; i++) { body.Add(matchTopLevel(tree.values[i], new_env)); } var lambda = Expression.Lambda(Expression.Block(new ParameterExpression[] { new_env }, body), paramList); //Now we want to box this expression in a FunctionHolder Expression func = Expression.New( typeof(FunctionHolder).GetConstructor(new Type[] { typeof(Delegate), typeof(int)}), lambda, Expression.Constant(paramList.Count, typeof(int))); //Now lets box this into a objBox return Expression.New( typeof(ObjBox).GetConstructor(new Type[] {typeof(Object), typeof(Type)}), Expression.Convert(func, typeof(Object)), Expression.Call(null, typeof(TypeUtils).GetMethod("funcType"))); }
private static Expression ifExpr(ListNode list, Expression env) { if (list.values.Count != 4) { return createRuntimeException("wrong number of arguments passed to if procedure"); } // this will get assigned the result of the if statement ParameterExpression objBox = Expression.Parameter(typeof(ObjBox)); //one expression tree for each branch of the if statment Expression t = matchExpression(list.values[2], env); Expression f = matchExpression(list.values[3], env); ParameterExpression tTemp = Expression.Parameter(typeof(ObjBox)); ParameterExpression fTemp = Expression.Parameter(typeof(ObjBox)); //asign whichever branch we take to our return value, objBox Expression ifTrue = Expression.Assign(objBox, Expression.Convert(t, typeof(ObjBox))); Expression ifFalse = Expression.Assign(objBox, Expression.Convert(f, typeof(ObjBox))); Expression ifThenElse = Expression.IfThenElse( unboxValue(matchExpression(list.values[1], env), typeof(Boolean)), ifTrue, ifFalse); return Expression.Block( new ParameterExpression[] {objBox, }, new Expression[] { ifThenElse, objBox }); }
private static Expression filterExpr(ListNode list, Expression env) { if (list.values.Count != 3) throw new ParsingException("The expected number of arguments does not match the given number"); Node function = list.values[1]; Expression fun; List<Expression> body = new List<Expression>(); if (function.isList()) { ListNode l = (ListNode)function; fun = unboxValue(matchExpression(l, env), typeof(FunctionHolder)); } return null; }
private static Expression defineExpr(ListNode tree, Expression env) { List<Expression> block = new List<Expression>(); //TODO check variable names are a legal scheme variable name if (tree.values.Count != 3 || tree.values[1].isList() || tree.values[1].getValue().GetType() != typeof(String)) { return createRuntimeException("define procedure failed"); } var rhs = matchExpression(tree.values[2], env); var name = Expression.Constant(tree.values[1].getValue()); Expression add = Expression.Call( env, typeof(CompilerLib.Environment).GetMethod("add"), name, Expression.Convert(rhs, typeof(ObjBox))); block.Add(add); block.Add(voidSingleton); return Expression.Block(block); }
private static Expression divExpr(ListNode tree, Expression env) { if (tree.values.Count != 3) { return createRuntimeException("wrong number of arguments passed to divide procedure"); } //unboxing from type object Expression lhs = unboxValue(matchExpression(tree.values[1], env), typeof(RacketNum)); Expression rhs = unboxValue(matchExpression(tree.values[2], env), typeof(RacketNum)); Expression result = Expression.Call(lhs, typeof(RacketNum).GetMethod("Div"), new Expression[] { rhs }); return result; }
//DEPRECIATED (I think) private static Expression autoInvokeLambda(ListNode list, Expression env) { //first expression must be a lambda Expression lambBox = lambdaExpr((ListNode)list.values[0], env); //lets get the function wrapper out of the obj box Expression lamb = unboxValue(lambBox, typeof(FunctionHolder)); List<Expression> invokeLamb = new List<Expression>(); //Statement to make a List (it will hold the arguments) Expression newObjList = Expression.New(typeof(List<Object>).GetConstructor(new Type[] { })); ParameterExpression objList = Expression.Variable(typeof(List<Object>), "argList"); Expression assignExpr = Expression.Assign(objList, newObjList); invokeLamb.Add(objList); invokeLamb.Add(assignExpr); // add each matched argument into our list of arguments for (int i = 1; i < list.values.Count; i++) { invokeLamb.Add(Expression.Call( objList, typeof(List<Object>).GetMethod("Add", new Type[] { typeof(Object) }), Expression.Convert(matchExpression(list.values[i], env), typeof(Object)))); } var invoke = Expression.Call( lamb, typeof(FunctionHolder).GetMethod("invoke"), objList); invokeLamb.Add(invoke); return Expression.Block(new ParameterExpression[] { objList }, invokeLamb); }
private static Expression reverseExpr(ListNode list, Expression env) { if (list.values.Count != 2) return createRuntimeException("reverse only takes one list"); Expression l = unboxValue(matchExpression(list.values[1], env), typeof(RacketPair)); return Expression.Call(null, typeof(FunctionLib).GetMethod("Reverse"), l); }
private static Expression notExpr(ListNode list, Expression env) { if (list.values.Count != 2) { return createRuntimeException("wrong number of arguments passed to not procedure"); } Expression not = Expression.Not(unboxValue(matchExpression(list.values[1], env), typeof(Boolean))); return wrapInObjBox( not, Expression.Call(null, typeof(TypeUtils).GetMethod("boolType"))); }
private static Expression nullCheckExpr(ListNode list, Expression env) { if (list.values.Count != 2) { return createRuntimeException("wrong number of arguments passed to null? procedure"); } // the object we are testing is null Expression obj = matchExpression(list.values[1], env); //the result that we will assign the result too ParameterExpression result = Expression.Variable(typeof(Boolean)); //what our ifThenElse expression will branch on Expression getType = Expression.Call(obj, typeof(ObjBox).GetMethod("getType")); Expression test = Expression.Call(getType, typeof(Type).GetMethod("Equals", new Type[] { typeof(Type) }), Expression.Constant(typeof(RacketPair), typeof(Type))); Expression isNullCall = Expression.Call(unboxValue(obj, typeof(RacketPair)), typeof(RacketPair).GetMethod("isNull", new Type[] { })); Expression trueBranch = Expression.Assign(result, isNullCall); Expression falseBranch = Expression.Assign(result, Expression.Constant(false)); Expression ifExpr = Expression.IfThenElse(test, trueBranch, falseBranch); Expression boolType = Expression.Call(null, typeof(TypeUtils).GetMethod("boolType")); Expression wrapResult = wrapInObjBox(result, boolType); return Expression.Block(new ParameterExpression[] { result }, new Expression[] { ifExpr, wrapResult }); }
private static Expression newTypeList(ListNode list, Expression env) { List<Expression> body = new List<Expression>(); Expression cons = Expression.New(typeof(typeListWrapper).GetConstructor(new Type[] { })); ParameterExpression var = Expression.Parameter(typeof(typeListWrapper)); Expression assign = Expression.Assign(var, cons); body.Add(assign); for (int i = 1; i < list.values.Count; i++) { body.Add( Expression.Call(var, typeof(typeListWrapper).GetMethod("add"), unboxValue(aliasOrLiteralName(list.values[i], env), typeof(String)))); } body.Add(var); Expression block = Expression.Block(new ParameterExpression[] { var }, body); return wrapInObjBox(block, Expression.Call(null, typeof(TypeUtils).GetMethod("typeListType"))); }
private static Expression newNetObj(ListNode list, Expression env) { List<Expression> block = new List<Expression>(); if (list.values.Count < 2) { return createRuntimeException("wrong number of arguments passed to new procedure"); } ParameterExpression arr = Expression.Parameter(typeof(List<ObjBox>)); Expression argArray = Expression.New(typeof(List<ObjBox>).GetConstructor(new Type[] { })); Expression assign = Expression.Assign(arr, argArray); block.Add(assign); for(int i = 2; i < list.values.Count; i++) { block.Add( Expression.Call( arr, typeof(List<ObjBox>).GetMethod("Add", new Type[] { typeof(ObjBox) }), matchExpression(list.values[i], env))); } Expression type = unboxValue(aliasOrLiteralName(list.values[1], env), typeof(String)); block.Add(Expression.Call(null, typeof(NetIneractLib).GetMethod("callConstruct"), type, Expression.Call(arr, typeof(List<ObjBox>).GetMethod("ToArray")))); return Expression.Block(new ParameterExpression[] { arr }, block); }
private static Expression netImportStmt(ListNode list, Expression env) { if(list.values.Count == 2) { Expression importStr = unboxValue(aliasOrLiteralName(list.values[1], env), typeof(String)); return Expression.Block( new ParameterExpression[] { }, new Expression[] { Expression.Call(null, typeof(typeResolver).GetMethod("import", new Type[] { typeof(String) }), importStr), voidSingleton }); } else if (list.values.Count == 3) { Expression filename = unboxValue(aliasOrLiteralName(list.values[1], env), typeof(String)); Expression importStr = unboxValue(aliasOrLiteralName(list.values[2], env), typeof(String)); return Expression.Block( new ParameterExpression[] { }, new Expression[] { Expression.Call(null, typeof(typeResolver).GetMethod("import", new Type[] { typeof(String), typeof(String) }), filename, importStr), voidSingleton }); } else { return createRuntimeException("wrong number of arguments passed to using procedure: " + list.values.Count); } }
static void createDll(ListNode parseTree, String outputName) { // these expressions will initalize the top level environment var makeEnv = Expression.New(typeof(CompilerLib.Environment)); var env = Expression.Variable(typeof(CompilerLib.Environment), "env"); var assign = Expression.Assign(env, makeEnv); //set up a single instance of type void voidSingleton = Expression.Variable(typeof(ObjBox), "void"); Expression voidType = Expression.Call(null, typeof(TypeUtils).GetMethod("voidType")); Expression initVoidObjBox = Expression.New( typeof(ObjBox).GetConstructor(new Type[] { typeof(Object), typeof(Type) }), new Expression[] { Expression.Convert(Expression.New(typeof(voidObj).GetConstructor(new Type[] { })), typeof(Object)), voidType }); Expression assignVoid = Expression.Assign(voidSingleton, initVoidObjBox); // create the code for each top level form independantly Tuple<List<Expression>, List<ExposedFunction>> dllTopLevels = matchTopLevelDll(parseTree, env); List<Expression> buildFunctions = new List<Expression>(); //Add the environment set up to the very start of the program buildFunctions.Add(env); buildFunctions.Add(assign); buildFunctions.Add(assignVoid); //Add all the using statments buildFunctions.AddRange(dllTopLevels.Item1); //Add the list of program definitions foreach (ExposedFunction ef in dllTopLevels.Item2) { buildFunctions.Add(ef.expTree); } buildFunctions.Add(env); //turn our program body into a expression block Expression init = Expression.Block(new ParameterExpression[] { env, voidSingleton }, buildFunctions); var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(outputName), System.Reflection.Emit.AssemblyBuilderAccess.Save); var module = asm.DefineDynamicModule(outputName, outputName + ".dll"); var type = module.DefineType(outputName, TypeAttributes.Public); //make an init (ideally this would be in a static constructor for our type but currently I don't know how to do this) //this must be called manually or any other calls will fail var method = type.DefineMethod("init", MethodAttributes.Public | MethodAttributes.Static); Expression methodBody = init; Expression.Lambda<Func<CompilerLib.Environment>>(methodBody).CompileToMethod(method); //make an method to invoke each function createDllMethods(type, dllTopLevels.Item2, env); type.CreateType(); asm.Save(outputName + ".dll"); }
private static Expression setBangExpr(ListNode list, Expression env) { List<Expression> block = new List<Expression>(); //TODO check variable names are a legal scheme variable name if (list.values.Count != 3 || list.values[1].isList() || list.values[1].getValue().GetType() != typeof(String)) { return createRuntimeException("wrong number of arguments passed to set! procedure"); } var name = Expression.Constant(list.values[1].getValue()); var rhs = matchExpression(list.values[2], env); Expression set = Expression.Call( env, typeof(CompilerLib.Environment).GetMethod("set"), name, Expression.Convert(rhs, typeof(ObjBox))); block.Add(set); block.Add(voidSingleton); return Expression.Block(block); }
static void createExe(ListNode parseTree, Boolean run, String outputName) { //Body of the program List<Expression> program = new List<Expression>(); // these expressions will initalize the top level environment var makeEnv = Expression.New(typeof(CompilerLib.Environment)); var env = Expression.Variable(typeof(CompilerLib.Environment), "env"); var assign = Expression.Assign(env, makeEnv); //set up a single instance of type void voidSingleton = Expression.Variable(typeof(ObjBox), "void"); Expression voidType = Expression.Call(null, typeof(TypeUtils).GetMethod("voidType")); Expression initVoidObjBox = Expression.New( typeof(ObjBox).GetConstructor(new Type[] { typeof(Object), typeof(Type) }), new Expression[] { Expression.Convert(Expression.New(typeof(voidObj).GetConstructor(new Type[] { })), typeof(Object)), voidType }); Expression assignVoid = Expression.Assign(voidSingleton, initVoidObjBox); //Add the environment set up to the very start of the program program.Add(env); program.Add(assign); program.Add(assignVoid); // add all the top level forms into the program foreach(Node n in parseTree.values) { program.Add(matchTopLevel(n, env)); } //Print whatever the program returns /* program.Add( Expression.Call( null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }), Expression.Call(result, typeof(Object).GetMethod("ToString")))); * */ //program.Add(Expression.Empty()); //turn our program body into a expression block Expression code = Expression.Block(new ParameterExpression[] { env, voidSingleton}, program); //create and output an assembly var asmName = new AssemblyName(outputName); var asmBuilder = AssemblyBuilder.DefineDynamicAssembly (asmName, AssemblyBuilderAccess.RunAndSave); var moduleBuilder = asmBuilder.DefineDynamicModule(outputName + "Module", outputName + ".exe"); var typeBuilder = moduleBuilder.DefineType("Program", TypeAttributes.Public); var methodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Static, typeof(void), new[] { typeof(string) }); Expression.Lambda<Action>(code).CompileToMethod(methodBuilder); typeBuilder.CreateType(); asmBuilder.SetEntryPoint(methodBuilder); asmBuilder.Save(outputName + ".exe"); if(run) { ProcessStartInfo comp = new ProcessStartInfo(outputName + ".exe"); comp.UseShellExecute = false; comp.CreateNoWindow = false; Process Compile = Process.Start(comp); Compile.WaitForExit(); Compile.Close(); } }
private static Expression whileExpr(ListNode list, Expression env) { if (list.values.Count != 3) { return createRuntimeException("wrong number of arguments passed to while procedure"); } LabelTarget done = Expression.Label(typeof(ObjBox)); Expression test = unboxValue(matchExpression(list.values[1], env), typeof(Boolean)); Expression body = matchExpression(list.values[2], env); Expression fi = Expression.IfThenElse(test, body, Expression.Break(done, voidSingleton)); return Expression.Block(new ParameterExpression[] { }, Expression.Loop(fi, done)); }
private static Expression displayExpr(ListNode list, Expression env) { List<Expression> block = new List<Expression>(); if (list.values.Count != 2) { return createRuntimeException("wrong number of arguments passed to displayln procedure"); } Expression print = unboxValue(matchExpression(list.values[1], env), typeof(Object)); Expression toStr = Expression.Call(print, typeof(Object).GetMethod("ToString")); Expression println = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }), toStr); block.Add(println); block.Add(voidSingleton); return Expression.Block( block ); }
private static Expression begin0Expr(ListNode list, Expression env) { if (list.values.Count < 2) { return createRuntimeException("wrong number of arguments passed to begin procedure"); } List<Node> values = new List<Node>(); return null; }
private static ExposedFunction dllDefineExpr(ListNode tree, Expression env) { List<Expression> block = new List<Expression>(); //TODO check variable names are a legal scheme variable name if (tree.values.Count != 3 || tree.values[1].isList() || tree.values[1].getValue().GetType() != typeof(String) || tree.values[2].isLeaf()) { throw new Exception("define procedure failed"); } ListNode lam = (ListNode) tree.values[2]; if (lam.values[0].getValue() != "lambda" || lam.values[1].isLeaf()) { throw new Exception("define procedure of dll failed: third argument was not a lambda"); } int paramCount = ((ListNode)lam.values[1]).values.Count; var func = matchExpression(lam, env); String funcName = tree.values[1].getValue(); var name = Expression.Constant(funcName); Expression add = Expression.Call( env, typeof(CompilerLib.Environment).GetMethod("add"), name, Expression.Convert(func, typeof(ObjBox))); block.Add(add); block.Add(voidSingleton); return new ExposedFunction(Expression.Block(new ParameterExpression[] { }, block), funcName, paramCount); }
private static Expression beginExpr(ListNode list, Expression env) { List<Expression> body = new List<Expression>(); for (int i = 1; i < list.values.Count; i++) { body.Add(matchExpression(list.values[i], env)); } if (body.Count == 0) { body.Add(voidSingleton); } return Expression.Block(new ParameterExpression[] { }, body); }
private static Expression equalExpr(ListNode tree, Expression env) { if (tree.values.Count != 3) { return createRuntimeException("wrong number of arguments passed to equal? procedure"); } Expression lhs = unboxValue(matchExpression(tree.values[1], env), typeof(Object)); Expression rhs = unboxValue(matchExpression(tree.values[2], env), typeof(Object)); Expression equal = Expression.Call(lhs, typeof(Object).GetMethod("Equals", new Type[] { typeof(Object) }), rhs); return Expression.New( typeof(ObjBox).GetConstructor(new Type[] { typeof(Object), typeof(Type) }), new Expression[] { Expression.Convert(equal, typeof(Object)), Expression.Call(null, typeof(TypeUtils).GetMethod("boolType")) }); }
private static Expression callNetExpr(ListNode list, Expression env) { List<Expression> block = new List<Expression>(); if (list.values.Count < 3) { return createRuntimeException("wrong number of arguments passed to call procedure"); } ParameterExpression arr = Expression.Parameter(typeof(List<ObjBox>)); Expression argArray = Expression.New(typeof(List<ObjBox>).GetConstructor(new Type[] { })); Expression assign = Expression.Assign(arr, argArray); block.Add(assign); if (list.values.Count > 3) { Expression arg; if (list.values[3].isLeaf() && list.values[3].getValue() == "set") { arg = wrapInObjBox(Expression.Constant("set"), Expression.Call(null, typeof(TypeUtils).GetMethod("strType"))); } else { arg = matchExpression(list.values[3], env); } block.Add( Expression.Call( arr, typeof(List<ObjBox>).GetMethod("Add", new Type[] { typeof(ObjBox) }), arg)); } for (int i = 4; i < list.values.Count; i++) { Expression arg = matchExpression(list.values[i], env); block.Add( Expression.Call( arr, typeof(List<ObjBox>).GetMethod("Add", new Type[] { typeof(ObjBox) }), arg)); } Expression instance = matchExpression(list.values[1], env); Expression name = aliasOrLiteralName(list.values[2], env); Expression callStr = unboxValue(name, typeof(String)); block.Add(Expression.Call(null, typeof(NetIneractLib).GetMethod("call"), Expression.Convert(instance, typeof(ObjBox)), callStr, Expression.Call(arr, typeof(List<ObjBox>).GetMethod("ToArray")))); return Expression.Block(new ParameterExpression[] { arr }, block); }
private static Expression foldlExpr(ListNode list, Expression env) { int foldCount = list.values.Count; if (foldCount < 4) { return createRuntimeException("wrong number of arguments passed to foldl procedure"); } // 1. function is user defined // 2. function is built in // 3. function is a lambda Node function = list.values[1]; Expression fun; List<Expression> body = new List<Expression>(); // init lists for map ParameterExpression listArrs = Expression.Parameter(typeof(List<RacketPair>)); Expression argArray = Expression.New(typeof(List<RacketPair>).GetConstructor(new Type[] { })); Expression assign = Expression.Assign(listArrs, argArray); body.Add(assign); // must add parameter for init arg if (function.isList()) // lambda case or could be another function call that returns a function, fuckckckckckck { ListNode l = (ListNode)function; // fun = matchExpression(l, env); fun = unboxValue(matchExpression(l, env), typeof(FunctionHolder)); } else { fun = unboxValue(lookup(Expression.Constant(function.getValue()), env), typeof(FunctionHolder)); } Expression init = matchExpression(list.values[2], env); // is this correct? for (int h = 3; h < foldCount; h++) // lists start at 3, 2 is init parameter { Expression l_ = unboxValue(matchExpression(list.values[h], env), typeof(RacketPair)); body.Add( Expression.Call( listArrs, typeof(List<RacketPair>).GetMethod("Add", new Type[] { typeof(RacketPair) }), l_)); } body.Add(Expression.Call(null, typeof(FunctionLib).GetMethod("Foldl"), fun, init, listArrs)); return Expression.Block(new ParameterExpression[] { listArrs }, body); }
private static Expression cdrExpr(ListNode list, Expression env) { if(list.values.Count != 2) { return createRuntimeException("wrong number of arguments passed to cdr procedure"); } Expression pair = unboxValue(matchExpression(list.values[1], env), typeof(RacketPair)); return Expression.Call(pair, typeof(RacketPair).GetMethod("cdr")); }
private static Expression invokeLambda(ListNode tree, Expression env) { List<Expression> invokeLamb = new List<Expression>(); //Statement to make a List Expression newObjList = Expression.New(typeof(List<Object>).GetConstructor(new Type[] {})); ParameterExpression objList = Expression.Variable(typeof(List<Object>), "argList"); Expression assignExpr = Expression.Assign(objList, newObjList); invokeLamb.Add(objList); invokeLamb.Add(assignExpr); // add each matched argument into our list of arguments for (int i = 1; i < tree.values.Count; i++) { invokeLamb.Add(Expression.Call( objList, typeof(List<Object>).GetMethod("Add", new Type[] { typeof(Object) }), Expression.Convert(matchExpression(tree.values[i], env), typeof(Object)))); } Expression getFunction = unboxValue(matchExpression(tree.values[0], env), typeof(FunctionHolder)); var invoke = Expression.Call( getFunction, typeof(FunctionHolder).GetMethod("invoke"), objList); invokeLamb.Add(invoke); return Expression.Block(new ParameterExpression[] {objList}, invokeLamb); }
private static Expression consExpr(ListNode list, Expression env) { if (list.values.Count != 3) { return createRuntimeException("wrong number of arguments passed to cons procedure"); } Expression first = matchExpression(list.values[1], env); Expression rest = matchExpression(list.values[2], env); Expression cons = Expression.New( typeof(RacketPair).GetConstructor( new Type[] { typeof(ObjBox), typeof(ObjBox) }), first, rest); Expression type = Expression.Call(null, typeof(TypeUtils).GetMethod("pairType")); return wrapInObjBox(cons, type); }
private static Expression lessThanEqualExpr(ListNode tree, Expression env) { if (tree.values.Count != 3) { return createRuntimeException("wrong number of arguments passed to less-than-equal procedure"); } Expression lhs = unboxValue(matchExpression(tree.values[1], env), typeof(RacketNum)); Expression rhs = unboxValue(matchExpression(tree.values[2], env), typeof(RacketNum)); Expression type = Expression.Call(null, typeof(TypeUtils).GetMethod("boolType")); Expression result = Expression.Call(lhs, typeof(RacketNum).GetMethod("lessThanEqual"), rhs); return wrapInObjBox(result, type); }
static Expression matchLiteralList(ListNode tree, Expression env) { if (tree.values.Count == 0) { Expression cons_ = Expression.New(typeof(RacketPair).GetConstructor(new Type[] {})); Expression type_ = Expression.Call(null, typeof(TypeUtils).GetMethod("pairType")); return wrapInObjBox(cons_, type_); } Expression first; Expression rest; Node n = tree.values[0]; first = matchLiteral(n, env); tree.values.RemoveAt(0); rest = matchLiteral(tree, env); Expression cons = Expression.New( typeof(RacketPair).GetConstructor( new Type[] { typeof(ObjBox), typeof(ObjBox) }), first, rest); Expression type = Expression.Call(null, typeof(TypeUtils).GetMethod("pairType")); return wrapInObjBox(cons, type); }