public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { LocalBuilder loopVar = generatorData.ILGenerator.DeclareLocal(typeof(double)); this.Start.GenerateCode(codeGenerator, generatorData); generatorData.ILGenerator.Emit(OpCodes.Stloc, loopVar); //Add the loop variable generatorData = generatorData.WithSymbol(this.VariableName, new LocalVariableSymbol(loopVar)); Label loopStart = generatorData.ILGenerator.DefineLabel(); Label end = generatorData.ILGenerator.DefineLabel(); //Emit the loop condition generatorData.ILGenerator.MarkLabel(loopStart); this.End.GenerateCode(codeGenerator, generatorData); generatorData.ILGenerator.Emit(OpCodes.Ldc_R8, 0.0); generatorData.ILGenerator.Emit(OpCodes.Beq, end); //The body this.Body.GenerateCode(codeGenerator, generatorData); //Pop any value returned from the body generatorData.ILGenerator.Emit(OpCodes.Pop); //The step generatorData.ILGenerator.Emit(OpCodes.Ldloc, loopVar); this.Step.GenerateCode(codeGenerator, generatorData); generatorData.ILGenerator.Emit(OpCodes.Add); generatorData.ILGenerator.Emit(OpCodes.Stloc, loopVar); generatorData.ILGenerator.Emit(OpCodes.Br, loopStart); generatorData.ILGenerator.MarkLabel(end); generatorData.ILGenerator.Emit(OpCodes.Ldc_R8, 0.0); }
public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { this.Operand.GenerateCode(codeGenerator, generatorData); codeGenerator.GenerateFunctionCall( "unary" + this.op, this, generatorData); }
public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { foreach (var currentArg in arguments) { currentArg.GenerateCode(codeGenerator, generatorData); } codeGenerator.GenerateFunctionCall( this.funcName, this, generatorData); }
public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { Type[] argumentTypes = new Type[this.Prototype.Arguments.Count]; for (int i = 0; i < argumentTypes.Length; i++) { argumentTypes[i] = typeof(double); } //Create the function string funcName = this.Prototype.Name; Type returnType = typeof(double); if (funcName == "") { funcName = "main"; } var function = new DynamicMethod(funcName, returnType, argumentTypes); var generator = function.GetILGenerator(); var symbolTable = ImmutableDictionary.Create <string, Symbol>(); for (int i = 0; i < this.Prototype.Arguments.Count; i++) { string currentArg = this.Prototype.Arguments[i]; symbolTable = symbolTable.Add(currentArg, new FunctionArgumentSymbol(i)); } if (!codeGenerator.Methods.ContainsKey(funcName)) { codeGenerator.Methods.Add(funcName, function); //Emit the method this.Body.GenerateCode( codeGenerator, new SyntaxTreeGeneratorData(generator, symbolTable)); generator.Emit(OpCodes.Ret); //If a binary operator, add it to the operator table if (this.Prototype.IsBinaryOperator) { codeGenerator.Session.DefineBinaryOperator( this.Prototype.OperatorName.Value, this.Prototype.Precedence); } } else { throw new CodeGeneratorException("Function '" + funcName + "' is already defined.", this); } }
public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { Label endLabel = generatorData.ILGenerator.DefineLabel(); Label elseLabel = generatorData.ILGenerator.DefineLabel(); this.Condition.GenerateCode(codeGenerator, generatorData); generatorData.ILGenerator.Emit(OpCodes.Ldc_R8, 0.0); generatorData.ILGenerator.Emit(OpCodes.Beq, elseLabel); this.ThenBody.GenerateCode(codeGenerator, generatorData); generatorData.ILGenerator.Emit(OpCodes.Br, endLabel); generatorData.ILGenerator.MarkLabel(elseLabel); this.ElseBody.GenerateCode(codeGenerator, generatorData); generatorData.ILGenerator.MarkLabel(endLabel); }
public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { this.LeftHandSide.GenerateCode(codeGenerator, generatorData); this.RightHandSide.GenerateCode(codeGenerator, generatorData); bool isBuiltinOperator = true; switch (this.Operator) { case '+': generatorData.ILGenerator.Emit(OpCodes.Add); break; case '-': generatorData.ILGenerator.Emit(OpCodes.Sub); break; case '*': generatorData.ILGenerator.Emit(OpCodes.Mul); break; case '<': Label endLabel = generatorData.ILGenerator.DefineLabel(); Label trueLabel = generatorData.ILGenerator.DefineLabel(); generatorData.ILGenerator.Emit(OpCodes.Blt, trueLabel); generatorData.ILGenerator.Emit(OpCodes.Ldc_R8, 0.0); generatorData.ILGenerator.Emit(OpCodes.Br, endLabel); generatorData.ILGenerator.MarkLabel(trueLabel); generatorData.ILGenerator.Emit(OpCodes.Ldc_R8, 1.0); generatorData.ILGenerator.MarkLabel(endLabel); break; default: isBuiltinOperator = false; break; } //If not a builtin operator, generate a function call if (!isBuiltinOperator) { codeGenerator.GenerateFunctionCall( "binary" + this.op, this, generatorData); } }
/// <summary> /// Generates a function call /// </summary> /// <param name="functionName">The name of the function to call</param> /// <param name="syntaxTree">The syntax tree</param> /// <param name="generatorData">The generator data for the syntax tree</param> public void GenerateFunctionCall(string functionName, SyntaxTrees syntaxTree, SyntaxTreeGeneratorData generatorData) { if (this.Methods.ContainsKey(functionName)) { MethodInfo calledMethod = this.Methods[functionName]; generatorData.ILGenerator.EmitCall(OpCodes.Call, calledMethod, null); //Because the language is expression based, when we call functions that return void we return 0 if (calledMethod.ReturnType == typeof(void)) { generatorData.ILGenerator.Emit(OpCodes.Ldc_R8, 0.0); } } else { throw new CodeGeneratorException("Function '" + functionName + "' not found.", syntaxTree); } }
public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { if (generatorData.SymbolTable.ContainsKey(this.Name)) { FunctionArgumentSymbol argSymbol = generatorData.SymbolTable[this.Name] as FunctionArgumentSymbol; LocalVariableSymbol varSymbol = generatorData.SymbolTable[this.Name] as LocalVariableSymbol; if (argSymbol != null) { generatorData.ILGenerator.Emit(OpCodes.Ldarg, argSymbol.ArgumentIndex); } if (varSymbol != null) { generatorData.ILGenerator.Emit(OpCodes.Ldloc, varSymbol.LocalVariable); } } else { throw new CodeGeneratorException("Variable '" + this.Name + "' not found.", this); } }
public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { //Find the .NET class and method reference string[] splitedFuncRef = this.FuncReference.Split('.'); string funcClassName = string.Join(".", splitedFuncRef.Take(splitedFuncRef.Length - 1)); string funcName = splitedFuncRef.Last(); Type[] typeArgs = this.Prototype.Arguments.Select(_ => typeof(double)).ToArray(); Type funcClass = Type.GetType(funcClassName); if (funcClass == null) { throw new CodeGeneratorException("Could not find class '" + funcClassName + "'.", this); } MethodInfo func = funcClass.GetMethod(funcName, typeArgs); if (func == null) { throw new CodeGeneratorException("Could not find method '" + funcName + "' in class '" + funcClassName + "'.", this); } if (func.ReturnType == typeof(double) || func.ReturnType == typeof(void)) { if (!codeGenerator.Methods.ContainsKey(this.Prototype.Name)) { codeGenerator.Methods[this.Prototype.Name] = func; } else { throw new CodeGeneratorException("The function '" + this.Prototype.Name + "' is already defined.", this); } } else { throw new CodeGeneratorException("External function must return type of double or void. Return type: " + func.ReturnType.Name, this); } }
/// <summary> /// Generates code for the current syntax tree /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="ilGenerator">The generator data</param> public abstract void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData);
public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { generatorData.ILGenerator.Emit(OpCodes.Ldc_R8, this.Value); }
public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { }
public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData) { Type[] argumentTypes = new Type[this.Prototype.Arguments.Count]; for (int i = 0; i < argumentTypes.Length; i++) { argumentTypes[i] = typeof(double); } //Create the function string funcName = this.Prototype.Name; Type returnType = typeof(double); if (funcName == "") { funcName = "main"; } var function = new DynamicMethod(funcName, returnType, argumentTypes); var generator = function.GetILGenerator(); var symbolTable = ImmutableDictionary.Create<string, Symbol>(); for (int i = 0; i < this.Prototype.Arguments.Count; i++) { string currentArg = this.Prototype.Arguments[i]; symbolTable = symbolTable.Add(currentArg, new FunctionArgumentSymbol(i)); } if (!codeGenerator.Methods.ContainsKey(funcName)) { codeGenerator.Methods.Add(funcName, function); //Emit the method this.Body.GenerateCode( codeGenerator, new SyntaxTreeGeneratorData(generator, symbolTable)); generator.Emit(OpCodes.Ret); //If a binary operator, add it to the operator table if (this.Prototype.IsBinaryOperator) { codeGenerator.Session.DefineBinaryOperator( this.Prototype.OperatorName.Value, this.Prototype.Precedence); } } else { throw new CodeGeneratorException("Function '" + funcName + "' is already defined.", this); } }