public void GenerateBitcode(List <Stmt> statements) { foreach (var funcdecl in statements) { Stmt.FunctionDeclaration func = (Stmt.FunctionDeclaration)funcdecl; FunctionPrototype(func); } foreach (var funcdecl in statements) { Visit(funcdecl); } LLVM.VerifyModule(_module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out string error); if (error != null) { Console.WriteLine(error); } //LLVM.LinkInMCJIT(); LLVM.WriteBitcodeToFile(_module, "test.bc"); LLVM.DumpModule(_module); LLVM.DisposeBuilder(_builder); }
public void ExecuteTypeCheck() { foreach (var functionDeclaration in Declarations) { Stmt.FunctionDeclaration func = (Stmt.FunctionDeclaration)functionDeclaration; if (FunctionTable.ContainsKey(func.Identifier.Source)) { Console.WriteLine($"There already exists a '{func.Identifier.Source}' function declaration"); } else { FunctionTable.Add(func.Identifier.Source, new FunctionSymbol { ReturnType = func.ReturnType, Parameters = func.Parameters }); } } foreach (var statement in Declarations) { var success = Examine(statement); if (!success) { Failed = true; } } }
public bool VisitFunctionDeclaration(Stmt.FunctionDeclaration statement) { LocalTypes.Clear(); foreach (var parameter in statement.Parameters) { LocalTypes.Add(parameter.Identifier, parameter.Type); } CurrentFunction = FunctionTable[statement.Identifier.Source]; return(Examine(statement.FunctionBody)); }
public void FunctionPrototype(Stmt.FunctionDeclaration func) { uint argc = (uint)func.Parameters.Count; var argv = new LLVMTypeRef[argc]; var function = LLVM.GetNamedFunction(_module, func.Identifier.Source); if (function.Pointer != IntPtr.Zero) { if (LLVM.CountBasicBlocks(function) != 0) { throw new Exception("redefinition of function."); } if (LLVM.CountParams(function) != argc) { throw new Exception("redefinition of function with different # args"); } } else { for (int i = 0; i < argc; i++) { argv[i] = GetParameterType(func.Parameters[i].Type); } function = LLVM.AddFunction(_module, func.Identifier.Source, LLVM.FunctionType(GetParameterType(func.ReturnType), argv, false)); LLVM.SetLinkage(function, LLVMLinkage.LLVMExternalLinkage); } for (int i = 0; i < argc; i++) { string argName = func.Parameters[i].Identifier; LLVMValueRef param = LLVM.GetParam(function, (uint)i); LLVM.SetValueName(param, argName); //_namedValues[argName] = new LLVMSymbol { Binding = null, IsFunction = false, KtsType = stmt.Parameters[i].Type, Value = param }; } _functions.Add(func.Identifier.Source, new FunctionSymbol { ReturnType = func.ReturnType, Parameters = func.Parameters }); }
public Stmt VisitFunctionDeclaration(Stmt.FunctionDeclaration stmt) { currentFunction = new FunctionSymbol { Parameters = stmt.Parameters, ReturnType = stmt.ReturnType }; uint argc = (uint)stmt.Parameters.Count; //var argv = new LLVMTypeRef[argc]; var function = LLVM.GetNamedFunction(_module, stmt.Identifier.Source); if (function.Pointer != IntPtr.Zero) { if (LLVM.CountBasicBlocks(function) != 0) { throw new Exception("redefinition of function."); } if (LLVM.CountParams(function) != argc) { throw new Exception("redefinition of function with different # args"); } } #region FunctionBody _namedValues.Clear(); LLVM.PositionBuilderAtEnd(_builder, LLVM.AppendBasicBlock(function, "entry")); var args = LLVM.GetParams(function); for (int i = 0; i < args.Length; i++) { var name = stmt.Parameters[i].Identifier; var type = stmt.Parameters[i].Type; var alloca = EntryAllocation(function, type, name); LLVM.BuildStore(_builder, args[i], alloca); bool decayed = false; if (type.Dimensions != 0) { decayed = true; } _namedValues.Add(name, new LLVMSymbol { Binding = null, IsDecayed = decayed, KtsType = type, Value = alloca }); } try { Visit(stmt.FunctionBody); if (stmt.ReturnType.Type == TypeEnum.VOID) { Stmt.BlockStatement block = (Stmt.BlockStatement)stmt.FunctionBody; var length = block.Statements.Count; if (block.Statements[length - 1] is not Stmt.Return) { LLVM.BuildRetVoid(_builder); } } } catch { LLVM.DeleteFunction(function); throw; } LLVM.VerifyFunction(function, LLVMVerifierFailureAction.LLVMPrintMessageAction); _valueStack.Push(function); #endregion return(stmt); }