/// <summary> /// Generates intermediate language code /// </summary> /// <param name="output"></param> public static void GenerateIL(PModule output) { var codegen = new CodeGenerator(output); codegen.Initialize(); LLVM.DumpModule(module); }
private CodeGenerator(PModule output) { this.source = output; // module = LLVM.ModuleCreateWithName(output.Name); builder = LLVM.CreateBuilder(); moduleInitializerFunction = LLVM.AddFunction(module, "module.init", LLVM.FunctionType(LLVM.VoidType(), new LLVMTypeRef[0], false)); moduleInitializerBlock = LLVM.AppendBasicBlock(moduleInitializerFunction, "entry"); }
public static Symbol AddExtern(this Intermediate.Module mod, string name, BuiltinFunction value) { var sym = new Symbol(value.Type, name) { IsConst = true, IsExported = false, Kind = SymbolKind.Extern, Initializer = new Intermediate.FunctionLiteral(value), }; mod.Symbols.Add(sym); return(sym); }
public static Symbol AddBuiltin(this Intermediate.Module mod, FunctionType type, string name) { var sym = new Symbol(type, name) { IsConst = true, IsExported = false, Kind = SymbolKind.Builtin, Initializer = new Intermediate.FunctionLiteral(new BuiltinFunction(type)), }; mod.Symbols.Add(sym); return(sym); }
private static Intermediate.Module CreateStd() { var std = new Intermediate.Module(null, "std"); std.AddType("bool", BuiltinType.Boolean, true); std.AddType("byte", BuiltinType.Byte, true); std.AddType("int", BuiltinType.Integer, true); std.AddType("uint", BuiltinType.UnsignedInteger, true); std.AddType("char", BuiltinType.Character, true); std.AddType("real", BuiltinType.Real, true); std.AddType("string", BuiltinType.String, true); std.AddConst("true", BuiltinType.Boolean, new BoolLiteral(true), true); std.AddConst("false", BuiltinType.Boolean, new BoolLiteral(false), true); var compiler = new Intermediate.Module(std, "compiler"); compiler.AddType("type", Type.MetaType, true); compiler.AddType("void", Type.VoidType, true); compiler.AddType("module", Type.ModuleType, true); std.AddModule("compiler", compiler); var math = new Intermediate.Module(std, "math"); math.AddConst("pi", BuiltinType.Real, new RealLiteral(3.14159265358979323846), true); math.AddConst("e", BuiltinType.Real, new RealLiteral(2.71828182845904523536), true); std.AddModule("math", math); /* * var typelist = new Type[] { * BuiltinType.Character, * BuiltinType.String, * BuiltinType.Real, * BuiltinType.UnsignedInteger, * BuiltinType.Byte, * BuiltinType.Boolean, * BuiltinType.Integer * }; * foreach (var type in typelist) * io.AddExtern(new FunctionType(Type.VoidType, type), "print"); */ { // Input/Output Module var io = new Intermediate.Module(std, "io"); var mod = CodeGenerator.module; var putchar = LLVM.AddFunction(mod, "putchar", LLVM.FunctionType(LLVM.VoidType(), new[] { LLVM.Int32Type() }, false)); LLVM.SetLinkage(putchar, LLVMLinkage.LLVMExternalLinkage); var printfun = LLVM.AddFunction(mod, "print(byte)", LLVM.FunctionType(LLVM.VoidType(), new[] { LLVM.Int8Type() }, false)); LLVM.SetLinkage(printfun, LLVMLinkage.LLVMExternalLinkage); var builder = LLVM.CreateBuilder(); // Create a new basic block to start insertion into. LLVM.PositionBuilderAtEnd(builder, LLVM.AppendBasicBlock(printfun, "entry")); var arg = LLVM.BuildZExt(builder, LLVM.GetParam(printfun, 0), LLVM.Int32Type(), "c"); LLVM.BuildCall(builder, putchar, new[] { arg }, ""); // Finish off the function with a default return value LLVM.BuildRetVoid(builder); LLVM.DisposeBuilder(builder); // Validate the generated code, checking for consistency. LLVM.VerifyFunction(printfun, LLVMVerifierFailureAction.LLVMPrintMessageAction); io.AddExtern("print", new BuiltinFunction(new FunctionType(Type.VoidType, BuiltinType.Byte), printfun)); std.AddModule("io", io); } return(std); }