public List <Stmt> GenerateAST() { Block currentBlock = new Block(); var blockstack = new Stack <Block>(); Token tok = null; var tree = new List <Stmt>(); var running = true; while (running) { try { tok = CurrentToken; CurrentIndex++; if (tok == null) { break; } } catch { } if (currentBlock is IfBlock ifb) { if (IfEndsAtThisLine != -1 && tok.Line > IfEndsAtThisLine) { currentBlock.AddStmt(new EndIf()); Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } } switch (tok.TokenName) { case Lexer.Tokens.Call: currentBlock.AddStmt(ParseCall()); break; case Lexer.Tokens.Label: currentBlock.AddStmt(new Label(tok.TokenValue.TrimEnd(new[] { ':' }).ToLowerInvariant()) { Line = tok.Line }); CurrentIndex++; break; case Lexer.Tokens.Goto: { currentBlock.AddStmt(new Goto(CurrentToken.TokenValue.TrimEnd(new[] { ':' }).ToLowerInvariant()) { Line = tok.Line }); CurrentIndex++; Block block = currentBlock; /* if ( blockstack.Count > 0 && block is Func ) * { * currentBlock = blockstack.Pop(); * currentBlock.AddStmt( block ); * }*/ } break; case Lexer.Tokens.Event: currentBlock.AddStmt(ParseEvent()); break; case Lexer.Tokens.FindItem: currentBlock.AddStmt(ParseFindItem()); break; } if (tok.TokenName == Lexer.Tokens.Import) { // Program.imports.Add( ParseImport() ); } else if (tok.TokenName == Lexer.Tokens.Function) { Block block = currentBlock; if (blockstack.Count > 0 && block is Func) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } Func func = ParseFunc(); if (currentBlock != null) { blockstack.Push(currentBlock); currentBlock = func; } } else if (tok.TokenName == Lexer.Tokens.If) { IfBlock ifblock = ParseIf(); if (currentBlock != null) { blockstack.Push(currentBlock); currentBlock = ifblock; } } /* else if ( tok.TokenName == Lexer.Tokens.ElseIf ) * { * ElseIfBlock elseifblock = ParseElseIf(); * * if ( currentBlock != null ) * { * blockstack.Push( currentBlock ); * currentBlock = elseifblock; * } * }*/ else if (tok.TokenName == Lexer.Tokens.Else) { if (currentBlock != null) { blockstack.Push(currentBlock); currentBlock = new ElseBlock() { Line = tok.Line }; } } else if (tok.TokenName == Lexer.Tokens.Repeat) { if (currentBlock != null) { blockstack.Push(currentBlock); currentBlock = new RepeatBlock() { Line = tok.Line }; } } else if (tok.TokenName == Lexer.Tokens.Set) { Assign a = ParseAssign(); currentBlock.AddStmt(a); } /*else if ( tok.TokenName == Lexer.Tokens.Ident ) * { * if ( tokens.Peek().TokenName == Lexer.Tokens.Equal ) * { * tokens.pos--; * Assign a = ParseAssign(); * currentBlock.AddStmt( a ); * } * else if ( tokens.Peek().TokenName == Lexer.Tokens.LeftParan ) * { * tokens.pos--; * Call c = ParseCall(); * currentBlock.AddStmt( c ); * } * }*/ else if (tok.TokenName == Lexer.Tokens.Return) { Return r = ParseReturn(); currentBlock.AddStmt(r); Block block = currentBlock; if (blockstack.Count > 0 && block is Func) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } else if (tok.TokenName == Lexer.Tokens.RightBrace) { if (currentBlock is Func) { currentBlock.AddStmt(new Return(null)); //tree.Add( currentBlock ); //currentBlock = null; Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } else if (currentBlock is IfBlock || currentBlock is ElseIfBlock || currentBlock is ElseBlock) { currentBlock.AddStmt(new EndIf()); Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } else if (currentBlock is RepeatBlock) { Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } } else if (tok.TokenName == Lexer.Tokens.EOF) { if (currentBlock is Func) { currentBlock.AddStmt(new Return(null)); //tree.Add( currentBlock ); //currentBlock = null; Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } tree.Add(currentBlock); running = false; } } return(tree); }
public List <Stmt> GenerateAST() { Block currentBlock = new Block(); var blockstack = new Stack <Block>(); Token tok = null; var tree = new List <Stmt>(); var running = true; while (running) { try { tok = CurrentToken; CurrentIndex++; if (tok == null) { break; } } catch { } if (currentBlock is IfBlock ifb) { if (BlockEndsAtThisLine != -1 && tok.Line > BlockEndsAtThisLine) { // currentBlock.AddStmt( new EndIf() ); Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } BlockEndsAtThisLine = -1; } } if (currentBlock is ForBlock || currentBlock is WhileBlock) { if (BlockEndsAtThisLine != -1 && tok.Line > BlockEndsAtThisLine) { Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } BlockEndsAtThisLine = -1; } } switch (tok.TokenName) { case Lexer.Tokens.LeftBrace: case Lexer.Tokens.Comment: case Lexer.Tokens.NewLine: continue; case Lexer.Tokens.Call: currentBlock.AddStmt(ParseCall()); continue; case Lexer.Tokens.Tile: currentBlock.AddStmt(ParseTile()); continue; case Lexer.Tokens.Scanjournal: currentBlock.AddStmt(ParseScanJournal()); continue; case Lexer.Tokens.ExEvent: currentBlock.AddStmt(ParseExEvent()); continue; case Lexer.Tokens.Target: currentBlock.AddStmt(ParseTarget()); continue; case Lexer.Tokens.Msg: currentBlock.AddStmt(ParseMessage()); continue; case Lexer.Tokens.Move: currentBlock.AddStmt(ParseMove()); continue; case Lexer.Tokens.Menu: currentBlock.AddStmt(ParseMenu()); continue; case Lexer.Tokens.Click: currentBlock.AddStmt(ParseClick()); continue; case Lexer.Tokens.Pause: currentBlock.AddStmt(new PauseStmt() { Line = tok.Line }); continue; case Lexer.Tokens.Continue: currentBlock.AddStmt(new Continue() { Line = tok.Line }); continue; case Lexer.Tokens.IgnoreItem: currentBlock.AddStmt(ParseIgnoreItem()); continue; case Lexer.Tokens.LinesPerCycle: currentBlock.AddStmt(new LinesPerCycle(ParseExpr()) { Line = tok.Line }); continue; case Lexer.Tokens.Wait: currentBlock.AddStmt(new WaitStmt(ParseExpr()) { Line = tok.Line }); continue; case Lexer.Tokens.Label: currentBlock.AddStmt(new Label(tok.TokenValue.TrimEnd(new[] { ':' }).ToLowerInvariant()) { Line = tok.Line }); CurrentIndex++; continue; case Lexer.Tokens.Break: currentBlock.AddStmt(new Break() { Line = tok.Line }); CurrentIndex++; continue; case Lexer.Tokens.Goto: { currentBlock.AddStmt(new Goto(CurrentToken.TokenValue.TrimEnd(new[] { ':' }).ToLowerInvariant()) { Line = tok.Line }); CurrentIndex++; Block block = currentBlock; /* if ( blockstack.Count > 0 && block is Func ) * { * currentBlock = blockstack.Pop(); * currentBlock.AddStmt( block ); * }*/ } continue; case Lexer.Tokens.Event: currentBlock.AddStmt(ParseEvent()); continue; case Lexer.Tokens.FindItem: currentBlock.AddStmt(ParseFindItem()); continue; } if (tok.TokenName == Lexer.Tokens.Import) { // Program.imports.Add( ParseImport() ); } else if (tok.TokenName == Lexer.Tokens.Function) { Block block = currentBlock; if (blockstack.Count > 0 && block is Func) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } Func func = ParseFunc(); if (currentBlock != null) { blockstack.Push(currentBlock); currentBlock = func; } } else if (tok.TokenName == Lexer.Tokens.If) { IfBlock ifblock = ParseIf(); if (currentBlock != null) { blockstack.Push(currentBlock); currentBlock = ifblock; } } /* else if ( tok.TokenName == Lexer.Tokens.ElseIf ) * { * ElseIfBlock elseifblock = ParseElseIf(); * * if ( currentBlock != null ) * { * blockstack.Push( currentBlock ); * currentBlock = elseifblock; * } * }*/ else if (tok.TokenName == Lexer.Tokens.Else) { if (currentBlock != null) { blockstack.Push(currentBlock); currentBlock = new ElseBlock() { Line = tok.Line }; } } else if (tok.TokenName == Lexer.Tokens.For) { blockstack.Push(currentBlock); currentBlock = ParseFor(); } else if (tok.TokenName == Lexer.Tokens.While) { blockstack.Push(currentBlock); currentBlock = ParseWhile(); } else if (tok.TokenName == Lexer.Tokens.Repeat) { if (currentBlock != null) { blockstack.Push(currentBlock); currentBlock = new RepeatBlock() { Line = tok.Line }; } } else if (tok.TokenName == Lexer.Tokens.Set) { Assign a = ParseAssign(); currentBlock.AddStmt(a); } /*else if ( tok.TokenName == Lexer.Tokens.Ident ) * { * if ( tokens.Peek().TokenName == Lexer.Tokens.Equal ) * { * tokens.pos--; * Assign a = ParseAssign(); * currentBlock.AddStmt( a ); * } * else if ( tokens.Peek().TokenName == Lexer.Tokens.LeftParan ) * { * tokens.pos--; * Call c = ParseCall(); * currentBlock.AddStmt( c ); * } * }*/ else if (tok.TokenName == Lexer.Tokens.Return) { Return r = ParseReturn(); currentBlock.AddStmt(r); Block block = currentBlock; if (blockstack.Count > 0 && block is Func) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } else if (tok.TokenName == Lexer.Tokens.RightBrace) { if (currentBlock is Func) { currentBlock.AddStmt(new Return(null)); //tree.Add( currentBlock ); //currentBlock = null; Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } else if (currentBlock is IfBlock || currentBlock is ElseIfBlock || currentBlock is ElseBlock) { //currentBlock.AddStmt( new EndIf() ); Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } else if (currentBlock is RepeatBlock) { Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } else if (currentBlock is ForBlock || currentBlock is WhileBlock) { Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } } else if (tok.TokenName == Lexer.Tokens.EOF) { if (currentBlock is Func) { currentBlock.AddStmt(new Return(null)); //tree.Add( currentBlock ); //currentBlock = null; Block block = currentBlock; if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); currentBlock.AddStmt(block); } } tree.Add(currentBlock); running = false; } else { Console.WriteLine($"Unhandled Token at Line: {tok.Line} " + tok.TokenName + " " + tok.TokenValue); } } return(tree); }