Ejemplo n.º 1
0
        public static void EmitVariableDefinition(VariableSymbol vSymbol, SymbolTable table, ILGenerator ilGen)
        {
            Type localType = GetTypeForCompilerType(vSymbol.VariableType);

            LocalBuilder localBuilder = ilGen.DeclareLocal(localType);
            if (vSymbol.InitExpression != null)
            {
                if (vSymbol.InitExpression.ResultType.TypeEnum == VariableTypeEnum.NULL)
                {
                    Type arrayType = GetTypeForCompilerType(vSymbol.VariableType);
                    ilGen.Emit(OpCodes.Call, GetArrayNullGetter(arrayType));
                }
                else
                {
                    EmitExpression(vSymbol.InitExpression, table, ilGen);
                }
            }
            else
            {
                if (vSymbol.VariableType.TypeEnum == VariableTypeEnum.Array)
                {
                    MethodInfo mi = GetArrayNullGetter(localType);
                    ilGen.Emit(OpCodes.Call, mi);
                }
                else
                {
                    ilGen.Emit(OpCodes.Ldc_I4_0);
                }
            }
            ilGen.Emit(OpCodes.Stloc, localBuilder);

            table.AddSymbol(vSymbol.Name, localType, localBuilder);
        }
Ejemplo n.º 2
0
        public static AssemblyBuilder GenerateAssembly(string name, L1Program program)
        {
            AssemblyName assemblyName = new AssemblyName(name);
            AssemblyBuilder assemblyBuilder
                = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.ToString(), assemblyName + ".exe");

            //Main method

            TypeBuilder mainTypeBuilder = moduleBuilder.DefineType("L1ProgramMain", TypeAttributes.Class | TypeAttributes.Public);
            MethodBuilder mainMethodBuilder = mainTypeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static);
            mainMethodBuilder.SetParameters(typeof(string[]));
            ILGenerator mainIlGenerator = mainMethodBuilder.GetILGenerator();

            mainIlGenerator.Emit(OpCodes.Ldarg_0);
            mainIlGenerator.Emit(OpCodes.Call, f_mainRuntimeMethod);
            mainIlGenerator.Emit(OpCodes.Ret);

            //Program methods

            TypeBuilder functionsTypeBuilder = moduleBuilder.DefineType("L1ProgramFunctions", TypeAttributes.Class | TypeAttributes.Public);
            List<MethodBuilder> functionBuilders = new List<MethodBuilder>();

            foreach (FunctionDefinition fDef in program.Functions)
            {
                if (fDef.IsEmbedded)
                    continue;

                MethodBuilder functionBuilder = functionsTypeBuilder.DefineMethod(fDef.Header.FunctionName, MethodAttributes.Public | MethodAttributes.Static);
                if (fDef.Header.ReturnType != null)
                {
                    Type t = GetTypeForCompilerType(fDef.Header.ReturnType);
                    functionBuilder.SetReturnType(t);
                }
                else
                {
                    functionBuilder.SetReturnType(typeof(void));
                }
                List<Type> paramTypes = new List<Type>();
                foreach (FunctionParameter parameter in fDef.Header.Parameters)
                {
                    Type t = GetTypeForCompilerType(parameter.Type);
                    paramTypes.Add(t);
                }
                functionBuilder.SetParameters(paramTypes.ToArray());

                f_functions.Add(fDef.Header, functionBuilder);
            }

            foreach (FunctionDefinition fDef in program.Functions)
            {
                if (fDef.IsEmbedded)
                    continue;
                MethodBuilder functionBuilder = (MethodBuilder)f_functions[fDef.Header];
                ILGenerator ilGen = functionBuilder.GetILGenerator();
                SymbolTable table = new SymbolTable();
                int i = 0;
                foreach (FunctionParameter parameter in fDef.Header.Parameters)
                {
                    Type t = GetTypeForCompilerType(parameter.Type);
                    table.AddSymbol(parameter.Name, t, i++);
                }

                EmitFunction(fDef, table, ilGen);
            }

            //Завершение процесса генерации

            Type tMain = mainTypeBuilder.CreateType();
            Type tFunctions = functionsTypeBuilder.CreateType();

            moduleBuilder.CreateGlobalFunctions();
            assemblyBuilder.SetEntryPoint(mainMethodBuilder, PEFileKinds.ConsoleApplication);

            return assemblyBuilder;
        }
Ejemplo n.º 3
0
        public static void EmitStatementList(StatementList statements, SymbolTable table, ILGenerator ilGen)
        {
            foreach (Statement statement in statements)
            {

                #region MarkLabel

                if (!String.IsNullOrEmpty(statement.Label))
                {
                    ilGen.MarkLabel(f_contextLabels[statement.Label]);
                }

                #endregion

                #region GoTo

                if (statement is GotoStatement)
                {
                    ilGen.Emit(OpCodes.Br, f_contextLabels[(statement as GotoStatement).GoTo]);
                }

                #endregion

                #region Expression

                if (statement is Expression)
                {
                    Expression expr = (Expression)statement;

                    EmitExpression(expr, table, ilGen);

                    if (!wasVoidFuncCalled)
                    {
                        ilGen.Emit(OpCodes.Pop);
                    }
                    wasVoidFuncCalled = false;
                }

                #endregion

                #region VariableDefinitionList

                if (statement is VariableDefinitionList)
                {
                    VariableDefinitionList vdList = (VariableDefinitionList)statement;

                    foreach (VariableSymbol vSymbol in vdList.Definitions)
                    {
                        EmitVariableDefinition(vSymbol, table, ilGen);
                    }
                }

                #endregion

                #region Return

                if (statement is ReturnStatement)
                {
                    ReturnStatement returnStatement = (ReturnStatement)statement;

                    EmitReturn(returnStatement, table, ilGen);
                }

                #endregion

                #region Assert

                if (statement is AssertStatement)
                {
                    AssertStatement assertStatement = (AssertStatement)statement;

                    EmitExpression(assertStatement.Expression, table, ilGen);
                    ilGen.Emit(OpCodes.Ldc_I4, assertStatement.Expression.Location.eLin);
                    ilGen.Emit(OpCodes.Call, GetAssert());
                }

                #endregion

                #region WhileDo

                if (statement is WhileDoStatement)
                {
                    WhileDoStatement wds = (WhileDoStatement)statement;
                    SymbolTable newTable = new SymbolTable(table);
                    Label condition = ilGen.DefineLabel();
                    Label endLoop = ilGen.DefineLabel();

                    ilGen.MarkLabel(condition);
                    EmitExpression(wds.Condition, table, ilGen);
                    ilGen.Emit(OpCodes.Brfalse, endLoop);
                    EmitStatementList(wds.Statements, newTable, ilGen);
                    ilGen.Emit(OpCodes.Br, condition);
                    ilGen.MarkLabel(endLoop);
                }

                #endregion

                #region DoWhile

                if (statement is DoWhileStatement)
                {
                    DoWhileStatement dws = (DoWhileStatement)statement;
                    SymbolTable newTable = new SymbolTable(table);
                    Label begin = ilGen.DefineLabel();

                    ilGen.MarkLabel(begin);
                    EmitStatementList(dws.Statements, newTable, ilGen);
                    EmitExpression(dws.Condition, table, ilGen);
                    ilGen.Emit(OpCodes.Brtrue, begin);
                }

                #endregion

                #region If

                if (statement is IfStatement)
                {
                    IfStatement ifStatement = (IfStatement)statement;
                    Label end = ilGen.DefineLabel();
                    Label elseLabel = ilGen.DefineLabel();
                    List<Label> labels = new List<Label>();
                    labels.Add(new Label());
                    for (int i = 1; i < ifStatement.Clauses.Count; ++i)
                    {
                        labels.Add(ilGen.DefineLabel());
                    }
                    labels.Add(elseLabel);

                    for (int i = 0; i < ifStatement.Clauses.Count; ++i)
                    {
                        SymbolTable newTable = new SymbolTable(table);
                        if (i != 0)
                            ilGen.MarkLabel(labels[i]);

                        EmitExpression(ifStatement.Clauses[i].Condition, table, ilGen);
                        ilGen.Emit(OpCodes.Brfalse, labels[i + 1]);
                        EmitStatementList(ifStatement.Clauses[i].Statements, newTable, ilGen);
                        ilGen.Emit(OpCodes.Br, end);
                    }
                    ilGen.MarkLabel(elseLabel);
                    if (ifStatement.AlternativeStatements != null)
                    {
                        SymbolTable newTable = new SymbolTable(table);
                        EmitStatementList(ifStatement.AlternativeStatements, newTable, ilGen);
                    }
                    ilGen.MarkLabel(end);
                }

                #endregion

                #region СycleFor

                if (statement is CycleStatement)
                {
                    CycleStatement cycle = (CycleStatement)statement;
                    SymbolTable newTable = new SymbolTable(table);

                    Symbol cycleIndex = null;

                    if (cycle.DeclareVariable != String.Empty)
                    {
                        Type localType = GetTypeForCompilerType(cycle.VariableType);
                        LocalBuilder indx = ilGen.DeclareLocal(localType);
                        newTable.AddSymbol(cycle.DeclareVariable, localType, indx);
                        cycleIndex = newTable.FindSymbol(cycle.DeclareVariable);
                    }
                    else
                    {
                        string indexName = cycle.Init.LeftNode.Value.ToString();
                        Symbol symbol = table.FindSymbol(indexName);
                        cycleIndex = symbol;
                    }

                    LocalBuilder end = ilGen.DeclareLocal(typeof(int));
                    LocalBuilder step = ilGen.DeclareLocal(typeof(int));

                    Label loopLabel = ilGen.DefineLabel();
                    Label endLabel = ilGen.DefineLabel();

                    //Save cycle step and end condition to local variables
                    EmitExpression(cycle.Step, table, ilGen);
                    ilGen.Emit(OpCodes.Stloc, step);
                    EmitExpression(cycle.EndValue, table, ilGen);
                    ilGen.Emit(OpCodes.Stloc, end);

                    //Init variable

                    if (cycle.DeclareVariable == String.Empty)
                    {
                        EmitExpression(cycle.Init, table, ilGen);
                        ilGen.Emit(OpCodes.Pop);
                    }
                    else
                    {
                        EmitExpression(cycle.Init, table, ilGen);
                        ilGen.Emit(OpCodes.Stloc, cycleIndex.LocalBuilder);
                    }

                    ilGen.MarkLabel(loopLabel);

                    //Check for cycle' condition

                    if (cycleIndex.IsParameter)
                        ilGen.Emit(OpCodes.Ldarg, cycleIndex.ParameterIndex);
                    else
                        ilGen.Emit(OpCodes.Ldloc, cycleIndex.LocalBuilder);
                    ilGen.Emit(OpCodes.Ldloc, end);
                    ilGen.Emit(OpCodes.Cgt);
                    ilGen.Emit(OpCodes.Brtrue, endLabel);

                    //Cycle body

                    EmitStatementList(cycle.Statements, newTable, ilGen);

                    //Increment

                    if (cycleIndex.IsParameter)
                        ilGen.Emit(OpCodes.Ldarg, cycleIndex.ParameterIndex);
                    else
                        ilGen.Emit(OpCodes.Ldloc, cycleIndex.LocalBuilder);
                    ilGen.Emit(OpCodes.Ldloc, step);
                    ilGen.Emit(OpCodes.Add);
                    if (cycleIndex.Type == typeof(char))
                        ilGen.Emit(OpCodes.Conv_U2);
                    if (cycleIndex.IsParameter)
                        ilGen.Emit(OpCodes.Starg, cycleIndex.ParameterIndex);
                    else
                        ilGen.Emit(OpCodes.Stloc, cycleIndex.LocalBuilder);

                    ilGen.Emit(OpCodes.Br, loopLabel);

                    ilGen.MarkLabel(endLabel);

                }

                #endregion

            }
        }