Example #1
0
        public void Traverse(CParser.Node Node)
        {
            if (TraverseHook == null)
            {
                TraverseHook = delegate(Action _Action, CParser.Node _ParentNode, CParser.Node _Node) { _Action(); }
            }
            ;

            TraverseHook(() =>
            {
                Scopable.RefScope(ref ParentNode, Node, () =>
                {
                    if (Node != null)
                    {
                        var NodeType = Node.GetType();
                        if (Map.ContainsKey(NodeType))
                        {
                            Map[NodeType].Invoke(TargetObject, new object[] { Node });
                        }
                        else
                        {
                            throw (new NotImplementedException(String.Format("Not implemented {0}", Node.GetType())));
                        }
                    }
                });
            }, ParentNode, Node);
        }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="BaseWhileStatement"></param>
        /// <param name="ExecuteAtLeastOnce"></param>
        private void BaseWhileStatement(CParser.BaseWhileStatement BaseWhileStatement, bool ExecuteAtLeastOnce)
        {
            PutDebugLine(BaseWhileStatement);

            var IterationLabel          = SafeILGenerator.DefineLabel("IterationLabel");
            var BreakLabel              = SafeILGenerator.DefineLabel("BreakLabel");
            var ContinueLabel           = SafeILGenerator.DefineLabel("ContinueLabel");
            var LoopCheckConditionLabel = SafeILGenerator.DefineLabel("LoopCheckConditionLabel");

            if (!ExecuteAtLeastOnce)
            {
                SafeILGenerator.BranchAlways(LoopCheckConditionLabel);
            }

            IterationLabel.Mark();

            Scopable.RefScope(ref BreakableContext, new LabelContext(BreakLabel), () =>
            {
                Scopable.RefScope(ref ContinuableContext, new LabelContext(ContinueLabel), () =>
                {
                    Traverse(BaseWhileStatement.LoopStatements);
                });
            });

            ContinueLabel.Mark();
            LoopCheckConditionLabel.Mark();
            Traverse(BaseWhileStatement.Condition);
            SafeILGenerator.BranchIfTrue(IterationLabel);

            BreakLabel.Mark();
        }
 public void SetText(string FileName, string NewText, Action Action)
 {
     Scopable.RefScope(ref this.Text, NewText, () =>
     {
         Scopable.RefScope(ref this.FileName, FileName, () =>
         {
             Action();
         });
     });
 }
Example #4
0
        public void SwitchStatement(CParser.SwitchStatement SwitchStatement)
        {
            PutDebugLine(SwitchStatement);

            SafeILGenerator.SaveRestoreTypeStack(() =>
            {
                // TODO: improve speed with tables and proper switch instead of lot of "if" checks.
                var MapLabels    = new Dictionary <int, SafeLabel>();
                var DefaultLabel = SafeILGenerator.DefineLabel("SwitchDefault");
                var EndLabel     = SafeILGenerator.DefineLabel("SwitchEnd");

                //var SwitchExpressionLocal = SafeILGenerator.DeclareLocal<long>("SwitchReference");
                //SafeILGenerator.LoadLocal(SwitchExpressionLocal);

                //foreach (var SwitchCaseStatement in SwitchStatement.Statements.Statements.Where(Item => Item is CParser.SwitchCaseStatement).Cast<CParser.SwitchCaseStatement>())
                foreach (var Statement in SwitchStatement.Statements.Statements)
                {
                    var SwitchCaseStatement    = Statement as CParser.SwitchCaseStatement;
                    var SwitchDefaultStatement = Statement as CParser.SwitchDefaultStatement;

                    if (SwitchCaseStatement != null)
                    {
                        var Value               = SwitchCaseStatement.Value.GetConstantValue <int>(null);
                        var CaseLabel           = SafeILGenerator.DefineLabel("SwitchCase");
                        SwitchCaseStatement.Tag = CaseLabel;
                        //Console.WriteLine("Value: {0}", Value);
                        MapLabels.Add(Value, CaseLabel);
                    }
                    else if (SwitchDefaultStatement != null)
                    {
                        SwitchDefaultStatement.Tag = DefaultLabel;
                    }
                }

                Traverse(SwitchStatement.ReferenceExpression);
                SafeILGenerator.Switch(MapLabels, DefaultLabel);

                Scopable.RefScope(ref BreakableContext, new LabelContext(EndLabel), () =>
                {
                    Traverse(SwitchStatement.Statements);
                });

                if (!DefaultLabel.Marked)
                {
                    DefaultLabel.Mark();
                }

                EndLabel.Mark();
            });
        }
Example #5
0
        public void ForStatement(CParser.ForStatement ForStatement)
        {
            PutDebugLine(ForStatement);

            if (ForStatement.Init != null)
            {
                Traverse(ForStatement.Init);
                SafeILGenerator.PopLeft();
            }

            var IterationLabel          = SafeILGenerator.DefineLabel("IterationLabel");
            var BreakLabel              = SafeILGenerator.DefineLabel("BreakLabel");
            var ContinueLabel           = SafeILGenerator.DefineLabel("ContinueLabel");
            var LoopCheckConditionLabel = SafeILGenerator.DefineLabel("LoopCheckConditionLabel");
            {
                SafeILGenerator.BranchAlways(LoopCheckConditionLabel);

                IterationLabel.Mark();
                Scopable.RefScope(ref BreakableContext, new LabelContext(BreakLabel), () =>
                {
                    Scopable.RefScope(ref ContinuableContext, new LabelContext(ContinueLabel), () =>
                    {
                        Traverse(ForStatement.LoopStatements);
                    });
                });

                ContinueLabel.Mark();

                if (ForStatement.PostOperation != null)
                {
                    Traverse(ForStatement.PostOperation);
                    SafeILGenerator.PopLeft();
                }

                LoopCheckConditionLabel.Mark();
                if (ForStatement.Condition != null)
                {
                    Traverse(ForStatement.Condition);
                }
                else
                {
                    SafeILGenerator.Push(1);
                }
                SafeILGenerator.BranchIfTrue(IterationLabel);
                BreakLabel.Mark();
            }
        }
Example #6
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="Set"></param>
 /// <param name="Action"></param>
 private void DoGenerateAddress(bool Set, Action Action)
 {
     Scopable.RefScope(ref this.GenerateAddress, Set, Action);
 }
Example #7
0
        public void FunctionDeclaration(CParser.FunctionDeclaration FunctionDeclaration)
        {
            PutDebugLine(FunctionDeclaration);

            var FunctionName      = FunctionDeclaration.CFunctionType.Name;
            var ReturnType        = ConvertCTypeToType(FunctionDeclaration.CFunctionType.Return);
            var ParameterTypes    = FunctionDeclaration.CFunctionType.Parameters.Select(Item => ConvertCTypeToType(Item.CType)).ToArray();
            var ParameterCSymbols = FunctionDeclaration.CFunctionType.Parameters;

            if (ParameterTypes.Length == 1 && ParameterTypes[0] == typeof(void))
            {
                ParameterTypes = new Type[0];
            }
            var FunctionReference = FunctionScope.Find(FunctionName);

            if (FunctionReference == null)
            {
                var CurrentMethodLazy = new Lazy <MethodInfo>(() =>
                {
                    var MethodBuilder = CurrentClass.DefineMethod(
                        FunctionName,
                        MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard,
                        ReturnType,
                        ParameterTypes
                        );

                    for (int n = 0; n < ParameterCSymbols.Length; n++)
                    {
                        MethodBuilder.DefineParameter(n, ParameterAttributes.None, ParameterCSymbols[n].Name);
                    }

                    return(MethodBuilder);
                });

                FunctionReference = new FunctionReference(this, FunctionName, CurrentMethodLazy, new SafeMethodTypeInfo()
                {
                    IsStatic   = true,
                    ReturnType = ReturnType,
                    Parameters = ParameterTypes,
                })
                {
                    BodyFinalized = false,
                };

                FunctionScope.Push(FunctionName, FunctionReference);
            }

            // Just declaration
            if (FunctionDeclaration.FunctionBody == null)
            {
            }
            // Has function body.
            else
            {
                var CurrentMethod = (FunctionReference.MethodInfo as MethodBuilder);

                if (FunctionName == "main")
                {
                    //HasEntryPoint = true;

                    var StartupMethod = CurrentClass.DefineMethod(
                        "__startup",
                        MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard,
                        typeof(int),
                        new Type[] { typeof(string[]) }
                        );

                    var StartupSafeILGenerator = new SafeILGenerator(StartupMethod.GetILGenerator(), CheckTypes: true, DoDebug: false, DoLog: false);
                    var ArgsArgument           = StartupSafeILGenerator.DeclareArgument(typeof(string[]), 0);

                    StartupSafeILGenerator.Push(CurrentClass);
                    StartupSafeILGenerator.Call((Func <RuntimeTypeHandle, Type>)Type.GetTypeFromHandle);
                    StartupSafeILGenerator.LoadArgument(ArgsArgument);
                    StartupSafeILGenerator.Call((Func <Type, string[], int>)CLibUtils.RunTypeMain);
                    //StartupSafeILGenerator.Call((Func<Type, string[], int>)CLibUtils.RunTypeMain);
                    StartupSafeILGenerator.Return(typeof(int));

                    EntryPoint = StartupMethod;
                    //EntryPoint = CurrentMethod;
                }

                var ILGenerator            = CurrentMethod.GetILGenerator();
                var CurrentSafeILGenerator = new SafeILGenerator(ILGenerator, CheckTypes: false, DoDebug: false, DoLog: true);

                AScope <VariableReference> .NewScope(ref this.VariableScope, () =>
                {
                    Scopable.RefScope(ref this.GotoContext, new LabelsContext(CurrentSafeILGenerator), () =>
                    {
                        Scopable.RefScope(ref this.CurrentMethod, CurrentMethod, () =>
                        {
                            Scopable.RefScope(ref this.SafeILGenerator, CurrentSafeILGenerator, () =>
                            {
                                // Set argument variables
                                ushort ArgumentIndex = 0;
                                foreach (var Parameter in FunctionDeclaration.CFunctionType.Parameters)
                                {
                                    var Argument = SafeILGenerator.DeclareArgument(ConvertCTypeToType(Parameter.CType), ArgumentIndex);
                                    this.VariableScope.Push(Parameter.Name, new VariableReference(Parameter.Name, Parameter.CType, Argument));
                                    ArgumentIndex++;
                                }

                                Traverse(FunctionDeclaration.FunctionBody);


                                if (FunctionDeclaration.FunctionBody.Statements.Length == 0 || !(FunctionDeclaration.FunctionBody.Statements.Last() is CParser.ReturnStatement))
                                //if (true)
                                {
                                    if (CurrentMethod.ReturnType != typeof(void))
                                    {
                                        SafeILGenerator.Push((int)0);
                                    }
                                    SafeILGenerator.Return(CurrentMethod.ReturnType);
                                }
                            });
#if SHOW_INSTRUCTIONS
                            Console.WriteLine("Code for '{0}':", FunctionName);
                            foreach (var Instruction in CurrentSafeILGenerator.GetEmittedInstructions())
                            {
                                Console.WriteLine("  {0}", Instruction);
                            }
#endif
                        });
                    });
                });

                FunctionReference.BodyFinalized = true;
            }
        }
Example #8
0
        public void VariableDeclaration(CParser.VariableDeclaration VariableDeclaration)
        {
            PutDebugLine(VariableDeclaration);

            var VariableName  = VariableDeclaration.Symbol.Name;
            var VariableCType = VariableDeclaration.Symbol.CType;

            //Console.WriteLine(VariableCType);

            // ??
            if (VariableCType == null)
            {
                Console.Error.WriteLine("Warning: Global variable '{0}' doesn't have type!!", VariableName);
                return;
            }

            var VariableType = ConvertCTypeToType(VariableCType);

            var IsExternVariable = (VariableCType.GetCSimpleType().Storage == CTypeStorage.Extern);
            var IsAlreadyDefined = (VariableScope.Find(VariableName) != null);


            if (IsAlreadyDefined)
            {
                if (!IsExternVariable)
                {
                    Console.Error.WriteLine("Warning: Global variable '{0}' already defined but not defined as external", VariableName);
                }
                return;
            }

            if (VariableName == null || VariableName.Length == 0)
            {
                Console.Error.WriteLine("Variable doesn't have name!");
                return;
            }
            if (VariableCType is CFunctionType)
            {
                Console.Error.WriteLine("Variable is not a function!");
                return;
            }
            if (VariableType == typeof(void))
            {
                Console.Error.WriteLine("Variable has void type!");
                return;
            }

            VariableReference Variable;
            bool GlobalScope;

            // Global Scope
            if (this.SafeILGenerator == null)
            {
                GlobalScope = true;

                var Field = CurrentClass.DefineField(VariableName, VariableType, FieldAttributes.Static | FieldAttributes.Public);
                Variable = new VariableReference(VariableDeclaration.Symbol.Name, VariableDeclaration.Symbol.CType, Field);
            }
            // Local Scope
            else
            {
                GlobalScope = false;

                var Local = this.SafeILGenerator.DeclareLocal(VariableType, VariableName);
                Variable = new VariableReference(VariableDeclaration.Symbol.Name, VariableDeclaration.Symbol.CType, Local);
            }

            this.VariableScope.Push(VariableName, Variable);

            Action Initialize = () =>
            {
                Variable.LoadAddress(SafeILGenerator);
                SafeILGenerator.InitObject(VariableType);

                Traverse(VariableDeclaration.InitialValue);
                SafeILGenerator.PopLeft();
            };

            if (GlobalScope)
            {
                Scopable.RefScope(ref SafeILGenerator, StaticInitializerSafeILGenerator, () =>
                {
                    Initialize();
                });
            }
            else
            {
                Initialize();
            }
        }
Example #9
0
        public void TranslationUnit(CParser.TranslationUnit TranslationUnit)
        {
#if false
            try
            {
#endif
            PutDebugLine(TranslationUnit);

            try { File.Delete(OutFolder + "\\" + OutputName); }
            catch { }
            var ClassName = Path.GetFileNameWithoutExtension(OutputName);
            this.AssemblyBuilder = SafeAssemblyUtils.CreateAssemblyBuilder(ClassName, OutFolder);
            this.ModuleBuilder   = this.AssemblyBuilder.CreateModuleBuilder(OutputName);
            this.RootTypeBuilder = this.ModuleBuilder.DefineType(ClassName, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit);
            PendingTypesToCreate.Add(this.RootTypeBuilder);
            var InitializerBuilder = this.RootTypeBuilder.DefineTypeInitializer();
            var CurrentStaticInitializerSafeILGenerator = new SafeILGenerator(InitializerBuilder.GetILGenerator(), CheckTypes: false, DoDebug: false, DoLog: false);

            Scopable.RefScope(ref this.StaticInitializerSafeILGenerator, CurrentStaticInitializerSafeILGenerator, () =>
            {
                Scopable.RefScope(ref this.CurrentClass, this.RootTypeBuilder, () =>
                {
                    AScope <VariableReference> .NewScope(ref this.VariableScope, () =>
                    {
                        Traverse(TranslationUnit.Declarations);
                        this.StaticInitializerSafeILGenerator.Return(typeof(void));
                        //RootTypeBuilder.CreateType();

                        foreach (var FunctionReference in FunctionScope.GetAll())
                        {
                            if (!FunctionReference.BodyFinalized && FunctionReference.HasStartedBody)
                            {
                                Console.WriteLine("Function {0} without body", FunctionReference.Name);
                                var FakeSafeILGenerator = new SafeILGenerator((FunctionReference.MethodInfo as MethodBuilder).GetILGenerator(), CheckTypes: true, DoDebug: true, DoLog: false);
                                FakeSafeILGenerator.Push(String.Format("Not implemented '{0}'", FunctionReference.Name));
                                FakeSafeILGenerator.NewObject(typeof(NotImplementedException).GetConstructor(new Type[] { typeof(string) }));
                                FakeSafeILGenerator.Throw();
                            }
                        }

                        foreach (var TypeToCreate in PendingTypesToCreate)
                        {
                            TypeToCreate.CreateType();
                        }

                        if (EntryPoint != null)
                        {
                            this.AssemblyBuilder.SetEntryPoint(EntryPoint);
                        }
                        if (SaveAssembly)
                        {
                            // Copy the runtime.
                            var RuntimePath = typeof(CModuleAttribute).Assembly.Location;
                            try
                            {
                                File.Copy(RuntimePath, OutFolder + "\\" + Path.GetFileName(RuntimePath), overwrite: true);
                            }
                            catch
                            {
                            }

                            /*
                             * if (EntryPoint != null)
                             * {
                             *      OutputName = Path.GetFileNameWithoutExtension(OutputName) + ".exe";
                             * }
                             * else
                             * {
                             *      OutputName = Path.GetFileNameWithoutExtension(OutputName) + ".dll";
                             * }
                             */

#if false
                            Console.WriteLine("Writting to {0}", OutputName);
#endif
                            //this.AssemblyBuilder.Save(OutputName, PortableExecutableKinds.Required32Bit, ImageFileMachine.I386);
                            this.AssemblyBuilder.Save(OutputName, PortableExecutableKinds.ILOnly, ImageFileMachine.I386);
                        }
                    });
                });
            });
#if false
        }

        catch (Exception Exception)
        {
            if (ThrowException)
            {
                throw (Exception);
            }

            while (Exception.InnerException != null)
            {
                Exception = Exception.InnerException;
            }
            Console.Error.WriteLine("");
            Console.Error.WriteLine("LastPosition: {0}", LastPositionInfo);
            Console.Error.WriteLine("{0} : '{1}'", Exception.TargetSite, Exception.Message);
            if (Exception.StackTrace != null)
            {
                Console.Error.WriteLine("{0}", String.Join("\n", Exception.StackTrace.Split('\n').Take(4)));
                Console.Error.WriteLine("   ...");
            }
        }
#endif
        }