public static void DefineBuiltinFunctions(Scope scope, out FunctionDecNode printFunct, out FunctionDecNode printiFunct, out FunctionDecNode printlineFunct, out FunctionDecNode getCharFunct, out FunctionDecNode getlineFunct, out FunctionDecNode chrFunct, out FunctionDecNode sizeFunct, out FunctionDecNode substringFunct, out FunctionDecNode concatFunct, out FunctionDecNode notFunct, out FunctionDecNode exitFunct, out FunctionDecNode flushFunct, out FunctionDecNode ordFunct) { // print() Function printFunct = new FunctionDecNode(); printFunct.Name = "print"; printFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "text" } }; printFunct.RelatedType = VoidType.VoidInstance; scope.AddFunVar("print", printFunct); // printline() Function printlineFunct = new FunctionDecNode(); printlineFunct.Name = "printline"; printlineFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "text" } }; printlineFunct.RelatedType = VoidType.VoidInstance; scope.AddFunVar("printline", printlineFunct); // printi() Function printiFunct = new FunctionDecNode(); printiFunct.Name = "printi"; printiFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "number" } }; printiFunct.RelatedType = VoidType.VoidInstance; scope.AddFunVar("printi", printiFunct); //getchar():string Function getCharFunct = new FunctionDecNode(); getCharFunct.Name = "getchar"; getCharFunct.Arguments = new List<FunctionVariableDecNode>(); getCharFunct.RelatedType = StringType.StringInstance; scope.AddFunVar("getchar", getCharFunct); //getcharln():string Function getlineFunct = new FunctionDecNode(); getlineFunct.Name = "getline"; getlineFunct.Arguments = new List<FunctionVariableDecNode>(); getlineFunct.RelatedType = StringType.StringInstance; scope.AddFunVar("getline", getlineFunct); //chr(i:int):string Function chrFunct = new FunctionDecNode(); chrFunct.Name = "chr"; chrFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "number" } }; chrFunct.RelatedType = StringType.StringInstance; scope.AddFunVar("chr", chrFunct); //size(s:string): int Function sizeFunct = new FunctionDecNode(); sizeFunct.Name = "size"; sizeFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "strg" } }; sizeFunct.RelatedType = IntType.IntInstance; scope.AddFunVar("size", sizeFunct); //substring(s:string , first:int, n:int): int Function substringFunct = new FunctionDecNode(); substringFunct.Name = "substring"; substringFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "s" }, new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "first" }, new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "n" } }; substringFunct.RelatedType = StringType.StringInstance; scope.AddFunVar("substring", substringFunct); //concat(s1:string ,s1:string ):string Function concatFunct = new FunctionDecNode(); concatFunct.Name = "concat"; concatFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "s1" }, new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "s2" } }; concatFunct.RelatedType = StringType.StringInstance; scope.AddFunVar("concat", concatFunct); //not(i:int ):int Function notFunct = new FunctionDecNode(); notFunct.Name = "not"; notFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "i" } }; notFunct.RelatedType = IntType.IntInstance; scope.AddFunVar("not", notFunct); //exit(i:int ):int Function exitFunct = new FunctionDecNode(); exitFunct.Name = "exit"; exitFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = IntType.IntInstance, VariableName = "exitcode" } }; exitFunct.RelatedType = VoidType.VoidInstance; scope.AddFunVar("exit", exitFunct); //flush () Function flushFunct = new FunctionDecNode(); flushFunct.Name = "flush"; flushFunct.Arguments = new List<FunctionVariableDecNode>(); flushFunct.RelatedType = VoidType.VoidInstance; scope.AddFunVar("flush", flushFunct); //ord(s:string): int Function ordFunct = new FunctionDecNode(); ordFunct.Name = "ord"; ordFunct.Arguments = new List<FunctionVariableDecNode>() { new FunctionVariableDecNode() { RelatedType = StringType.StringInstance, VariableName = "str" } }; ordFunct.RelatedType = IntType.IntInstance; scope.AddFunVar("ord", ordFunct); }
public static void GenerateBuiltinCode(FunctionDecNode printFunct, FunctionDecNode printiFunct, FunctionDecNode printlineFunct, FunctionDecNode getCharFunct, FunctionDecNode getlineFunct, FunctionDecNode chrFunct, FunctionDecNode sizeFunct, FunctionDecNode substringFunct, FunctionDecNode concatFunct, FunctionDecNode notFunct, FunctionDecNode exitFunct, FunctionDecNode flushFunct, FunctionDecNode ordFunct, TypeBuilder typeBuilder) { MethodBuilder methodBuilder; ILGenerator ilGen; // print(s:string) ---------------------------------------------------------- if (UsedFunctions.Contains("print")) { methodBuilder = typeBuilder.DefineMethod("print", MethodAttributes.Public | MethodAttributes.Static, typeof (void), new Type[] {typeof (string)}); ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Call, typeof (Console).GetMethod("Write", new Type[] {typeof (string)})); ilGen.Emit(OpCodes.Ret); printFunct.MethodBuilder = methodBuilder; } // printline(s:string) ---------------------------------------------------------- if (UsedFunctions.Contains("printline")) { methodBuilder = typeBuilder.DefineMethod("printline", MethodAttributes.Public | MethodAttributes.Static, typeof (void), new Type[] {typeof (string)}); ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Call, typeof (Console).GetMethod("WriteLine", new Type[] {typeof (string)})); ilGen.Emit(OpCodes.Ret); printlineFunct.MethodBuilder = methodBuilder; } // printi(i:int) ------------------------------------------------------------ if (UsedFunctions.Contains("printi")) { methodBuilder = typeBuilder.DefineMethod("printi", MethodAttributes.Public | MethodAttributes.Static, typeof (void), new Type[] {typeof (int)}); ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Call, typeof (Console).GetMethod("Write", new Type[] {typeof (int)})); ilGen.Emit(OpCodes.Ret); printiFunct.MethodBuilder = methodBuilder; } // getchar():string ---------------------------------------------------------- if (UsedFunctions.Contains("getchar")) { methodBuilder = typeBuilder.DefineMethod("getchar", MethodAttributes.Public | MethodAttributes.Static, typeof (string), new Type[] {}); ilGen = methodBuilder.GetILGenerator(); Label ok = ilGen.DefineLabel(); ilGen.Emit(OpCodes.Call, typeof (Console).GetMethod("Read", new Type[] {})); ilGen.Emit(OpCodes.Dup); ilGen.Emit(OpCodes.Ldc_I4, 10); ilGen.Emit(OpCodes.Bne_Un, ok); ilGen.Emit(OpCodes.Pop); // sacar el 10 ilGen.Emit(OpCodes.Call, typeof (Console).GetMethod("Read", new Type[] {})); ilGen.Emit(OpCodes.Pop); // sacar el 13 ilGen.Emit(OpCodes.Ldstr, ""); ilGen.Emit(OpCodes.Ret); ilGen.MarkLabel(ok); ilGen.Emit(OpCodes.Conv_U2); ilGen.Emit(OpCodes.Call, typeof (Char).GetMethod("ToString", new Type[] {typeof (char)})); ilGen.Emit(OpCodes.Ret); getCharFunct.MethodBuilder = methodBuilder; } // getline():string ---------------------------------------------------------- if (UsedFunctions.Contains("getline")) { methodBuilder = typeBuilder.DefineMethod("getline", MethodAttributes.Public | MethodAttributes.Static, typeof(string), new Type[] { }); ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine", new Type[] { })); ilGen.Emit(OpCodes.Ret); getlineFunct.MethodBuilder = methodBuilder; } // chr(i:int):string -------------------------------------------------------- if (UsedFunctions.Contains("chr")) { methodBuilder = typeBuilder.DefineMethod("chr", MethodAttributes.Public | MethodAttributes.Static, typeof (string), new Type[] {typeof (int)}); ilGen = methodBuilder.GetILGenerator(); Label error = ilGen.DefineLabel(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Dup); ilGen.Emit(OpCodes.Ldc_I4_0); ilGen.Emit(OpCodes.Blt, error); ilGen.Emit(OpCodes.Dup); ilGen.Emit(OpCodes.Ldc_I4, 256); ilGen.Emit(OpCodes.Bge, error); ilGen.Emit(OpCodes.Conv_U2); ilGen.Emit(OpCodes.Call, typeof (Char).GetMethod("ToString", new Type[] {typeof (char)})); ilGen.Emit(OpCodes.Ret); ilGen.MarkLabel(error); ilGen.ThrowException(typeof (ArgumentException)); chrFunct.MethodBuilder = methodBuilder; } // size(s:string):int ------------------------------------------------------ if (UsedFunctions.Contains("size")) { methodBuilder = typeBuilder.DefineMethod("size", MethodAttributes.Public | MethodAttributes.Static, typeof (int), new Type[] {typeof (string)}); ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Call, typeof (String).GetMethod("get_Length", Type.EmptyTypes)); ilGen.Emit(OpCodes.Ret); sizeFunct.MethodBuilder = methodBuilder; } // substring(s:string , first:int, n:int): int ------------------------------ if (UsedFunctions.Contains("substring")) { methodBuilder = typeBuilder.DefineMethod("substring", MethodAttributes.Public | MethodAttributes.Static, typeof (string), new Type[] {typeof (string), typeof (int), typeof (int)}); ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Ldarg_2); ilGen.Emit(OpCodes.Call, typeof (String).GetMethod("Substring", new Type[] {typeof (int), typeof (int)})); ilGen.Emit(OpCodes.Ret); substringFunct.MethodBuilder = methodBuilder; } // concat(s1 : string ,s2 : string) : string -------------------------------- if (UsedFunctions.Contains("concat")) { methodBuilder = typeBuilder.DefineMethod("concat", MethodAttributes.Public | MethodAttributes.Static, typeof (string), new Type[] {typeof (string), typeof (string)}); ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Call, typeof (String).GetMethod("Concat", new Type[] {typeof (string), typeof (string)})); ilGen.Emit(OpCodes.Ret); concatFunct.MethodBuilder = methodBuilder; } // not(i:int):int ----------------------------------------------------------- if (UsedFunctions.Contains("not")) { methodBuilder = typeBuilder.DefineMethod("not", MethodAttributes.Public | MethodAttributes.Static, typeof (int), new Type[] {typeof (int)}); ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldc_I4_0); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ceq); ilGen.Emit(OpCodes.Ret); notFunct.MethodBuilder = methodBuilder; } // exit(i:int):int ---------------------------------------------------------- if (UsedFunctions.Contains("exit")) { methodBuilder = typeBuilder.DefineMethod("exit", MethodAttributes.Public | MethodAttributes.Static, typeof (void), new Type[] {typeof (int)}); ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Call, typeof (System.Environment).GetMethod("Exit", new Type[] {typeof (int)})); ilGen.Emit(OpCodes.Ret); exitFunct.MethodBuilder = methodBuilder; } // flush() ------------------------------------------------------------------ if (UsedFunctions.Contains("flush")) { methodBuilder = typeBuilder.DefineMethod("flush", MethodAttributes.Public | MethodAttributes.Static, typeof (void), Type.EmptyTypes); ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Call, typeof (Console).GetMethod("get_Out", Type.EmptyTypes)); ilGen.Emit(OpCodes.Call, typeof (TextWriter).GetMethod("Flush", Type.EmptyTypes)); ilGen.Emit(OpCodes.Ret); flushFunct.MethodBuilder = methodBuilder; } // ord(string):int ---------------------------------------------------------- if (UsedFunctions.Contains("ord")) { methodBuilder = typeBuilder.DefineMethod("ord", MethodAttributes.Public | MethodAttributes.Static, typeof (int), new Type[] {typeof (string)}); ilGen = methodBuilder.GetILGenerator(); Label emptyStr = ilGen.DefineLabel(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Dup); ilGen.Emit(OpCodes.Call, typeof (String).GetMethod("get_Length", Type.EmptyTypes)); ilGen.Emit(OpCodes.Brfalse, emptyStr); ilGen.Emit(OpCodes.Ldc_I4_0); ilGen.Emit(OpCodes.Call, typeof (String).GetMethod("get_Chars", new Type[] {typeof (int)})); ilGen.Emit(OpCodes.Ret); ilGen.MarkLabel(emptyStr); ilGen.Emit(OpCodes.Pop); ilGen.Emit(OpCodes.Ldc_I4, -1); ilGen.Emit(OpCodes.Ret); ordFunct.MethodBuilder = methodBuilder; } }