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; } }
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(); } }