Пример #1
0
        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);
        }
Пример #2
0
        public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData)
        {
            this.Operand.GenerateCode(codeGenerator, generatorData);

            codeGenerator.GenerateFunctionCall(
                "unary" + this.op,
                this,
                generatorData);
        }
Пример #3
0
        public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData)
        {
            foreach (var currentArg in arguments)
            {
                currentArg.GenerateCode(codeGenerator, generatorData);
            }

            codeGenerator.GenerateFunctionCall(
                this.funcName,
                this,
                generatorData);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
		/// <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);
			}
		}
Пример #8
0
        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);
            }
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
		/// <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);
Пример #11
0
		public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData)
		{
			this.Operand.GenerateCode(codeGenerator, generatorData);

			codeGenerator.GenerateFunctionCall(
				"unary" + this.op,
				this,
				generatorData);
		}
Пример #12
0
 public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData)
 {
     generatorData.ILGenerator.Emit(OpCodes.Ldc_R8, this.Value);
 }
Пример #13
0
		public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData)
		{
			foreach (var currentArg in arguments)
			{
				currentArg.GenerateCode(codeGenerator, generatorData);
			}

			codeGenerator.GenerateFunctionCall(
				this.funcName,
				this,
				generatorData);
		}
Пример #14
0
 public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData)
 {
 }
Пример #15
0
		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);
			}
		}
Пример #16
0
		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);
			}
		}
Пример #17
0
 /// <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);
Пример #18
0
		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);
			}
		}
Пример #19
0
        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);
        }        
Пример #20
0
		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);
		}
Пример #21
0
        /// <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);
            }
        }
Пример #22
0
		public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData)
		{

		}
Пример #23
0
		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);
			}
		}
Пример #24
0
		public override void GenerateCode(CodeGenerator codeGenerator, SyntaxTreeGeneratorData generatorData)
		{
			generatorData.ILGenerator.Emit(OpCodes.Ldc_R8, this.Value);
		}