public override void Write(char value) { if (value == CoreNewLine[CoreNewLine.Length - 1]) { _lineSoFar.Append(value); _listener.Error(_lineSoFar.ToString()); _lineSoFar.Length = 0; } else { _lineSoFar.Append(value); } }
public VM.CompiledScript Compile(ICharStream input) { try { LSLTreeAdaptor lslAdaptor = new LSLTreeAdaptor(); // // Initial parse and AST creation // LSLLexer lex = new LSLLexer(input); CommonTokenStream tokens = new CommonTokenStream(lex); LSLParser p = new LSLParser(tokens); p.TreeAdaptor = lslAdaptor; p.TraceDestination = _traceRedirect; lex.TraceDestination = _traceRedirect; LSLParser.prog_return r = p.prog(); if (p.NumberOfSyntaxErrors > 0) { _listener.Error(Convert.ToString(p.NumberOfSyntaxErrors) + " syntax error(s)"); return(null); } // // Definitions // CommonTree t = (CommonTree)r.Tree; CommonTreeNodeStream nodes = new CommonTreeNodeStream(lslAdaptor, t); nodes.TokenStream = tokens; SymbolTable symtab = new SymbolTable(tokens, Defaults.SystemMethods.Values, DefaultConstants.Constants.Values); symtab.StatusListener = _listener; Def def = new Def(nodes, symtab); def.TraceDestination = _traceRedirect; def.Downup(t); nodes.Reset(); if (_listener.HasErrors() || def.NumberOfSyntaxErrors > 0) { return(null); } // // Type and more semantic checks // Compiler.Types types = new Compiler.Types(nodes, symtab); types.TraceDestination = _traceRedirect; types.Downup(t); nodes.Reset(); if (_listener.HasErrors() || types.NumberOfSyntaxErrors > 0) { return(null); } StringTemplateGroup templates; using (TextReader fr = new StreamReader(Path.Combine(_templatePath, "ByteCode.stg"))) { templates = new StringTemplateGroup(fr); fr.Close(); } if (_outputAstGraph) { DotTreeGenerator dotgen = new DotTreeGenerator(); string dot = dotgen.ToDot(t); TextWriter tw = new StreamWriter("ast.txt"); tw.WriteLine(dot); tw.Close(); } Analyze analyze = new Analyze(nodes, symtab); analyze.TraceDestination = _traceRedirect; analyze.Downup(t); nodes.Reset(); foreach (Compiler.BranchAnalyze.FunctionBranch b in analyze.FunctionBranches.Where(pred => pred.Type != null)) { if (!b.AllCodePathsReturn()) { if (_listener != null) { _listener.Error("line: " + b.Node.Line + ":" + b.Node.CharPositionInLine + " " + b.Node.Text + "(): Not all control paths return a value"); } } } if (_listener.HasErrors() || analyze.NumberOfSyntaxErrors > 0) { return(null); } // // Bytecode generation // Gen g = new Gen(nodes, symtab); g.TemplateGroup = templates; g.TraceDestination = _traceRedirect; Gen.script_return ret = g.script(); if (_listener.HasErrors() || g.NumberOfSyntaxErrors > 0) { return(null); } if (ret.Template == null) { return(null); } StringTemplate template = ret.Template; if (_byteCodeDebugging) { _byteCode = template.ToString(); } // // Bytecode compilation // AssemblerLexer alex = new AssemblerLexer(new ANTLRStringStream(template.ToString())); CommonTokenStream atokens = new CommonTokenStream(alex); AssemblerParser ap = new AssemblerParser(atokens); BytecodeGenerator bcgen = new BytecodeGenerator(Defaults.SystemMethods.Values); ap.SetGenerator(bcgen); ap.TraceDestination = _traceRedirect; try { ap.program(); if (_listener.HasErrors() || p.NumberOfSyntaxErrors > 0) { _listener.Error(Convert.ToString(ap.NumberOfSyntaxErrors) + " bytecode generation error(s)"); return(null); } return(bcgen.Result); } catch (GenerationException e) { _listener.Error(e.Message); } return(null); } catch (TooManyErrorsException e) { _listener.Error(String.Format("Too many errors {0}", e.InnerException.Message)); } catch (RecognitionException e) { _listener.Error("line: " + e.Line.ToString() + ":" + e.CharPositionInLine.ToString() + " " + e.Message); } catch (Exception e) { string message = e.Message; while ((e = e.InnerException) != null) { message += "\n" + e.Message; } _listener.Error(message); } return(null); }
public string Compile(ICharStream input) { try { LSLTreeAdaptor lslAdaptor = new LSLTreeAdaptor(); LSLLexer lex = new LSLLexer(input); CommonTokenStream tokens = new CommonTokenStream(lex); LSLParser p = new LSLParser(tokens); p.TreeAdaptor = lslAdaptor; p.TraceDestination = _traceDestination; lex.TraceDestination = _traceDestination; LSLParser.prog_return r = p.prog(); if (p.NumberOfSyntaxErrors > 0) { if (_listener != null) { _listener.Error(Convert.ToString(p.NumberOfSyntaxErrors) + " syntax error(s)"); } return(null); } CommonTree t = (CommonTree)r.Tree; CommonTreeNodeStream nodes = new CommonTreeNodeStream(lslAdaptor, t); nodes.TokenStream = tokens; SymbolTable symtab = new SymbolTable(tokens, Defaults.SystemMethods.Values, DefaultConstants.Constants.Values); if (this.Listener != null) { symtab.StatusListener = this.Listener; } Def def = new Def(nodes, symtab); def.TraceDestination = _traceDestination; def.Downup(t); CommonTreeNodeStream nodes2 = new CommonTreeNodeStream(lslAdaptor, t); nodes2.TokenStream = tokens; Types types = new Types(nodes2, symtab); types.TraceDestination = _traceDestination; types.Downup(t); if (_listener != null) { if (_listener.HasErrors()) { return(null); } } CommonTreeNodeStream nodes4 = new CommonTreeNodeStream(lslAdaptor, t); nodes4.TokenStream = tokens; CommonTreeNodeStream nodes3 = new CommonTreeNodeStream(lslAdaptor, t); nodes3.TokenStream = tokens; TextReader fr = new StreamReader("ByteCode.stg"); StringTemplateGroup templates = new StringTemplateGroup(fr); fr.Close(); DotTreeGenerator dotgen = new DotTreeGenerator(); string dot = dotgen.ToDot(t); TextWriter tw = new StreamWriter("ast.txt"); tw.WriteLine(dot); tw.Close(); Analyze analyze = new Analyze(nodes4, symtab); types.TraceDestination = _traceDestination; analyze.Downup(t); foreach (FunctionBranch b in analyze.FunctionBranches.Where(pred => pred.Type != null)) { if (!b.AllCodePathsReturn()) { if (_listener != null) { _listener.Error("line: " + b.Node.Line + ":" + b.Node.CharPositionInLine + " " + b.Node.Text + "(): Not all control paths return a value"); } } } Gen g = new Gen(nodes3, symtab); g.TemplateGroup = templates; g.TraceDestination = _traceDestination; StringTemplate template = g.script().Template; if (template != null) { string bcOut = template.ToString(); Console.WriteLine("** byte code **\n" + bcOut); return(bcOut); } } catch (TooManyErrorsException e) { if (_listener != null) { _listener.Error(String.Format("Too many errors {0}", e.InnerException.Message)); } } catch (RecognitionException e) { if (_listener != null) { _listener.Error("line: " + e.Line.ToString() + ":" + e.CharPositionInLine.ToString() + " " + e.Message); } } catch (Exception e) { if (_listener != null) { _listener.Error(e.Message); } } return(null); }
public Symbol EnsureResolve(LSLAst node, IScope scope, string symName) { Symbol sym = scope.Resolve(symName); if (sym == null) { _listener.Error("line " + node.Token.Line + ":" + node.Token.CharPositionInLine + " Undefined symbol '" + symName + "'"); return(null); } //globals are always ok to ref, so skip the rest of the checks if this is a global if (sym.Scope == Globals) { return(sym); } //consts are always ok to ref if (sym is ConstantSymbol) { return(sym); } if (sym.Def == null) { _listener.Error(String.Format("INTERNAL COMPILER ERROR: Symbol definition not set: {0}", sym)); return(sym); } //if the symbol is local, it cant be used before it's defined if (sym.Def.TokenStartIndex > node.TokenStartIndex) { //if we are in a local scope, check if there is a version of this symbol in the function (parameter) scope //then check if there is a version of this symbol on the global scope Symbol methodSymbol = FindSymbolInMethodScope(sym, scope); Symbol globalSymbol = Globals.Resolve(symName); if (methodSymbol == null && globalSymbol == null) { //there is no global by this name, it's only defined locally and it's defined after //its use _listener.Error("line " + node.Token.Line + ":" + node.Token.CharPositionInLine + " Symbol '" + symName + "' can not be used before it is defined"); } if (methodSymbol != null) { sym = methodSymbol; } else { sym = globalSymbol; } } //also if this symbol is local, it can not be defined in the root of the expression from which it is being used else if (IsChildNodeOf((LSLAst)sym.Def.GetAncestor(LSLParser.VAR_DECL), node)) { //the symbol we found is a parent of the declaration and is therefore not valid for use //check parent scopes for a valid symbol Symbol methodSymbol = FindSymbolInMethodScope(sym, scope); Symbol globalSymbol = Globals.Resolve(symName); if (methodSymbol == null && globalSymbol == null) { //there is no global by this name, it's only defined locally and it's defined after //its use _listener.Error("line " + node.Token.Line + ":" + node.Token.CharPositionInLine + " Symbol '" + symName + "' can not be used before it is defined"); } if (methodSymbol != null) { sym = methodSymbol; } else { sym = globalSymbol; } } return(sym); }