public void ExitPrintstatement(BASICParser.PrintstatementContext context) { if (currentPrintList.items.Count != currentPrintList.separators.Count + 1) { CompileException ex = new CompileException("Malformed print statement"); throw ex; } finishedLine = new Statement_Print(currentPrintList); }
public void ExitStringletstatement(BASICParser.StringletstatementContext context) { if (currentStringVariable.Count == 0 || currentStringExpression.Count == 0) { CompileException ex = new CompileException("Malformed LET statement"); ex.message = "Expected: LET <StringVariable> = <StringExpression>"; throw ex; } finishedLine = new Statement_Let_String(currentStringVariable.Pop(), currentStringExpression.Pop()); }
public override void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e) { // suppress this error if we're not in debug mode if (!Program.debug) { return; } string position = String.Format("{0}:{1}: ", Parser.currentLine, charPositionInLine); CompileException.printColour(position + msg, ConsoleColor.Cyan); }
public void ExitLine(BASICParser.LineContext context) { if (finishedLine == null) { // something has gone HORRIBLY wrong! CompileException ex = new CompileException("Syntax Error"); ex.message = "Expected statement"; throw ex; } if (thisLineNumber > -2) { finishedLine.lineNumber = thisLineNumber; finishedLine.hasLineNumber = true; Parser.variables.codeLineNumbers[Parser.currentLine] = thisLineNumber; } else { finishedLine.lineNumber = Parser.currentLine; finishedLine.hasLineNumber = false; } }
public static List <Statement> parseFile(string inputFile) { try { // setup global static variables i8 = LLVM.Type.GetInteger8Type(context); i8p = LLVM.Type.GetInteger8PointerType(context); i8pp = LLVM.PointerType.GetUnqualified(i8p); i32 = LLVM.Type.GetInteger32Type(context); dbl = LLVM.Type.GetDoubleType(context); dblp = LLVM.Type.GetDoublePointerType(context); vd = LLVM.Type.GetVoidType(context); zero = new Constant(context, 8, 0); zero32 = new Constant(context, 32, 0); zeroFP = ConstantFP.Get(context, new APFloat((double)0)); variables = new VariableStore(); currentLine = 0; string line; List <Statement> parsedLines = new List <Statement>(); // Read the file and parse it line by line StreamReader file = new System.IO.StreamReader(inputFile); while ((line = file.ReadLine()) != null) { // Do ANTLR stuff AntlrInputStream stream = new AntlrInputStream(line); ITokenSource lexer = new BASICLexer(stream); ITokenStream tokens = new CommonTokenStream(lexer); BASICParser parser = new BASICParser(tokens); parser.RemoveErrorListeners(); parser.AddErrorListener(new AntlrErrorListener()); Listener lis = new Listener(); parser.BuildParseTree = true; parser.AddParseListener(lis); try { RuleContext tree = parser.line(); } catch (CompileException ex) { ex.print("INNER PARSE ERROR"); file.Close(); return(null); } parsedLines.Add(lis.finishedLine); currentLine++; } file.Close(); currentLine = -1; if (!Statement_End.existsEnd) { CompileException ex = new CompileException("No END line"); ex.message = "An END line is required"; throw ex; } return(parsedLines); } catch (CompileException ex) { ex.print("OUTER PARSE ERROR"); return(null); } catch (Exception ex) { CompileException.printColour("UNHANDLED PARSE ERROR", ConsoleColor.Red); Console.WriteLine(ex.Message); return(null); } }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Usage: BASICLLVM <inputfile> <flags>"); Console.WriteLine("-debug enables compiler debugging output"); Console.WriteLine("-block blocks on finished compile"); Console.WriteLine("-o <outputfile> outputs to specified file"); Console.WriteLine("-output LL/S/EXE specifies desired output format"); Console.WriteLine("-output LL/S/EXE specifies desired output format"); return; } // Interpret arguments string inputFile = args[0]; string defaultOutputFile = inputFile.Substring(0, inputFile.LastIndexOf(".")); outputFile = defaultOutputFile; bool outNext = false; bool formatNext = false; foreach (string arg in args) { if (outNext) { outputFile = arg; outNext = false; } if (formatNext) { outputFormat = (arg == "EXE") ? outputFormats.EXE : ((arg == "S") ? outputFormats.S : outputFormats.LL); formatNext = false; } if (arg == "-debug") { debug = true; } if (arg == "-block") { block = true; } if (arg == "-o") { outNext = true; } if (arg == "-output") { formatNext = true; } } if (outputFile.Equals(defaultOutputFile)) { if (outputFormat == outputFormats.LL) { outputFile += ".ll"; } if (outputFormat == outputFormats.S) { outputFile += ".s"; } if (outputFormat == outputFormats.EXE) { outputFile += ".exe"; } } // Setup LLVM LLVMContext context = new LLVMContext(); Parser.context = context; /* * PARSE STAGE */ if (debug) { Console.WriteLine("---"); } if (debug) { Console.WriteLine(); } if (debug) { Console.WriteLine("1 - Parsing"); } List <Statement> lines = Parser.parseFile(inputFile); if (lines == null) { // parsing failed if (block) { Console.ReadLine(); } return; } if (debug) { Console.WriteLine("Done"); } if (debug) { Console.WriteLine(); } if (debug) { Console.WriteLine("---"); } if (debug) { Console.WriteLine(); } /* * COMPILE STAGE */ if (debug) { Console.WriteLine("2 - Compiling"); } // Setup LLVM module Module module = new Module(context, "SourceFile"); Parser.module = module; // Setup LLVM function LLVM.Type[] mainArgs = new LLVM.Type[] { Parser.i32, Parser.i8pp }; FunctionType mainType = new FunctionType(Parser.i32, mainArgs); Function mainFunction = new Function(module, "main", mainType); Parser.function = mainFunction; try { for (int i = 0; i < lines.Count; i++) { Parser.currentLine = i; // Compile Line lines[i].code(); if (lines[i].hasLineNumber) { // add code line number to dictionary if (!Parser.variables.lines.ContainsKey(lines[i].lineNumber)) { Parser.variables.lines.Add(lines[i].lineNumber, lines[i]); } else { CompileException ex = new CompileException("Duplicate line number"); ex.message = "Line numbers must be unique"; throw ex; } } } // add jumps between adjacent lines for (int i = 0; i < lines.Count - 1; i++) { lines[i].jumpToNext(lines[i + 1]); } // process control flow statements for (int i = 0; i < lines.Count; i++) { lines[i].processGoto(); } } catch (CompileException ex) { ex.print("COMPILE ERROR"); if (block) { Console.ReadLine(); } return; } if (debug) { Console.WriteLine("Done"); } if (debug) { Console.WriteLine(); Console.WriteLine("---"); Console.WriteLine(); // Compile is complete ConsoleColor prevColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Magenta; module.Dump(); // Dump LLVM IR for debug purposes Console.ForegroundColor = prevColor; Console.WriteLine(); Console.WriteLine("---"); Console.WriteLine(); Console.WriteLine("3 - Output"); } // Write out LLVM module to file try { module.WriteToFile("ll.tmp"); } catch (Exception e) { CompileException.printColour("Failed to write to output file", ConsoleColor.Red); Console.WriteLine(e.Message); } // Call llc and gcc as well if we were asked to do that switch (outputFormat) { case outputFormats.LL: File.Delete(outputFile); File.Move("ll.tmp", outputFile); break; case outputFormats.S: do_llc(); File.Delete(outputFile); File.Move("ll.tmp.s", outputFile); break; case outputFormats.EXE: do_llc(); do_gcc(); break; } if (debug) { Console.WriteLine("Compile complete"); } if (block) { Console.ReadLine(); } }