private static Stat ParseIfStat(Lexer.Lexer lexer) { var exps = new List <Exp>(); var blocks = new List <Block>(); lexer.NextTokenOfKind(ETokenType.KwIf, out _, out _); exps.Add(ParseExp(lexer)); lexer.NextTokenOfKind(ETokenType.KwThen, out _, out _); blocks.Add(ParseBlock(lexer)); while (lexer.LookAhead() == ETokenType.KwElseIf) { lexer.NextToken(out _, out _, out _); exps.Add(ParseExp(lexer)); lexer.NextTokenOfKind(ETokenType.KwThen, out _, out _); blocks.Add(ParseBlock(lexer)); } if (lexer.LookAhead() == ETokenType.KwElse) { lexer.NextToken(out _, out _, out _); exps.Add(new TrueExp { Line = lexer.Line }); blocks.Add(ParseBlock(lexer)); } lexer.NextTokenOfKind(ETokenType.KwEnd, out _, out _); return(new IfStat { Exps = exps, Blocks = blocks }); }
private static void ParseField(Lexer.Lexer lexer, out Exp k, out Exp v) { k = null; v = null; if (lexer.LookAhead() == ETokenType.SepLBracket) { lexer.NextToken(out _, out _, out _); k = ParseExp(lexer); lexer.NextTokenOfKind(ETokenType.SepRBracket, out _, out _); lexer.NextTokenOfKind(ETokenType.OpAssign, out _, out _); v = ParseExp(lexer); return; } var exp = ParseExp(lexer); if (exp is NameExp nameExp) { if (lexer.LookAhead() == ETokenType.OpAssign) { lexer.NextToken(out _, out _, out _); k = new StringExp { Line = nameExp.Line, Str = nameExp.Name }; v = ParseExp(lexer); return; } } v = exp; }
private static Stat ParseLabelStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.SepLabel, out _, out _); lexer.NextIdentifier(out _, out var name); lexer.NextTokenOfKind(ETokenType.SepLabel, out _, out _); return(new LabelStat { Name = name }); }
private static Stat ParseDoStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.KwDo, out _, out _); var block = ParseBlock(lexer); lexer.NextTokenOfKind(ETokenType.KwEnd, out _, out _); return(new DoStat { Block = block }); }
private static Stat ParseRepeatStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.KwRepeat, out _, out _); var block = ParseBlock(lexer); lexer.NextTokenOfKind(ETokenType.KwUntil, out _, out _); var exp = ParseExp(lexer); return(new RepeatStat { Block = block, Exp = exp }); }
private static Stat ParseWhileStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.KwWhile, out _, out _); var exp = ParseExp(lexer); lexer.NextTokenOfKind(ETokenType.KwDo, out _, out _); var block = ParseBlock(lexer); lexer.NextTokenOfKind(ETokenType.KwEnd, out _, out _); return(new WhileStat { Exp = exp, Block = block }); }
private static Exp ParseParensExp(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.SepLParen, out _, out _); var exp = ParseExp(lexer); lexer.NextTokenOfKind(ETokenType.SepRParen, out _, out _); if (exp is VarargExp || exp is FuncCallExp || exp is NameExp || exp is TableAccessExp) { return new ParensExp { Exp = exp } } ; return(exp); }
private static Stat ParseBreakStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.KwBreak, out _, out _); return(new BreakStat { Line = lexer.Line }); }
public static Block Parse(string chunk, string chunkName) { var lexer = new Lexer.Lexer(chunk, chunkName); var block = ParseBlock(lexer); lexer.NextTokenOfKind(ETokenType.Eof, out _, out _); return(block); }
private static Exp ParseTableConstructorExp(Lexer.Lexer lexer) { var line = lexer.Line; lexer.NextTokenOfKind(ETokenType.SepLCurly, out _, out _); ParseFieldList(lexer, out var keyExps, out var valExps); lexer.NextTokenOfKind(ETokenType.SepRCurly, out _, out _); var lastLine = lexer.Line; return(new TableConstructorExp { Line = line, LastLine = lastLine, KeyExps = keyExps, ValExps = valExps }); }
private static Stat ParseGotoStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.KwGoto, out _, out _); lexer.NextIdentifier(out _, out var name); return(new GotoStat { Name = name }); }
private static FuncDefExp ParseFuncDefExp(Lexer.Lexer lexer) { var line = lexer.Line; lexer.NextTokenOfKind(ETokenType.SepLParen, out _, out _); ParseParList(lexer, out var parList, out var isVararg); lexer.NextTokenOfKind(ETokenType.SepRParen, out _, out _); var block = ParseBlock(lexer); lexer.NextTokenOfKind(ETokenType.KwEnd, out var lastLine, out _); return(new FuncDefExp { Line = line, LastLine = lastLine, ParList = parList, IsVararg = isVararg, Block = block }); }
private static List <Exp> ParseArgs(Lexer.Lexer lexer) { List <Exp> ret = null; switch (lexer.LookAhead()) { case ETokenType.SepLParen: { lexer.NextToken(out _, out _, out _); if (lexer.LookAhead() != ETokenType.SepRParen) { ret = ParseExpList(lexer); } lexer.NextTokenOfKind(ETokenType.SepRParen, out _, out _); break; } case ETokenType.SepLCurly: { ret = new List <Exp> { ParseTableConstructorExp(lexer) }; break; } default: { lexer.NextTokenOfKind(ETokenType.String, out var line, out var str); ret = new List <Exp> { new StringExp { Line = line, Str = str } }; break; } } return(ret); }
private static Stat FinishForInStat(Lexer.Lexer lexer, string name) { var nameList = FinishNameList(lexer, name); lexer.NextTokenOfKind(ETokenType.KwIn, out _, out _); var expList = ParseExpList(lexer); lexer.NextTokenOfKind(ETokenType.KwDo, out var lineOfDo, out _); var block = ParseBlock(lexer); lexer.NextTokenOfKind(ETokenType.KwEnd, out _, out _); return(new ForInStat { LineOfDo = lineOfDo, Block = block, ExpList = expList, NameList = nameList }); }
private static Exp CheckVar(Lexer.Lexer lexer, Exp exp) { if (exp is NameExp || exp is TableAccessExp) { return(exp); } lexer.NextTokenOfKind(ETokenType.Unknown, out _, out _); Debug.Panic("unreachable!"); return(null); }
private static Stat FinishLocalFunctionDefStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.KwFunction, out _, out _); lexer.NextIdentifier(out _, out var name); var fdExp = ParseFuncDefExp(lexer); return(new LocalFuncDefStat { Name = name, Exp = fdExp }); }
private static Stat ParseLocalAssignOrFuncDefStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.KwLocal, out _, out _); if (lexer.LookAhead() == ETokenType.KwFunction) { return(FinishLocalFunctionDefStat(lexer)); } else { return(FinishLocalVarDeclStat(lexer)); } }
private static Exp FinishPrefixExp(Lexer.Lexer lexer, Exp exp) { while (true) { switch (lexer.LookAhead()) { case ETokenType.SepLBracket: { lexer.NextToken(out _, out _, out _); var keyExp = ParseExp(lexer); lexer.NextTokenOfKind(ETokenType.SepRBracket, out _, out _); exp = new TableAccessExp { LastLine = lexer.Line, PrefixExp = exp, KeyExp = keyExp }; break; } case ETokenType.SepDot: { lexer.NextToken(out _, out _, out _); lexer.NextIdentifier(out var line, out var name); var keyExp = new StringExp { Line = line, Str = name }; exp = new TableAccessExp { LastLine = line, PrefixExp = exp, KeyExp = keyExp }; break; } case ETokenType.SepColon: case ETokenType.SepLParen: case ETokenType.SepLCurly: case ETokenType.String: { exp = FinishFuncCallExp(lexer, exp); break; } default: return(exp); } } }
private static Stat ParseForStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.KwFor, out var lineOfToken, out _); lexer.NextIdentifier(out _, out var name); if (lexer.LookAhead() == ETokenType.OpAssign) { return(FinishForNumStat(lexer, lineOfToken, name)); } else { return(FinishForInStat(lexer, name)); } }
private static Stat FinishForNumStat(Lexer.Lexer lexer, int lineOfToken, string name) { lexer.NextTokenOfKind(ETokenType.OpAssign, out _, out _); var initExp = ParseExp(lexer); lexer.NextTokenOfKind(ETokenType.SepComma, out _, out _); var limitExp = ParseExp(lexer); Exp stepExp; if (lexer.LookAhead() == ETokenType.SepComma) { lexer.NextToken(out _, out _, out _); stepExp = ParseExp(lexer); } else { stepExp = new IntegerExp { Line = lexer.Line, Val = 1 }; } lexer.NextTokenOfKind(ETokenType.KwDo, out var lineOfDo, out _); var block = ParseBlock(lexer); lexer.NextTokenOfKind(ETokenType.KwEnd, out _, out _); return(new ForNumStat { LineOfFor = lineOfToken, LineOfDo = lineOfDo, Block = block, InitExp = initExp, LimitExp = limitExp, StepExp = stepExp, VarName = name }); }
private static Stat ParseAssignStat(Lexer.Lexer lexer, Exp prefixExp) { var varList = FinishVarList(lexer, prefixExp); lexer.NextTokenOfKind(ETokenType.OpAssign, out _, out _); var expList = ParseExpList(lexer); var lastLine = lexer.Line; return(new AssignStat { LastLine = lastLine, ExpList = expList, VarList = varList }); }
private static Stat ParseFuncDefStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.KwFunction, out _, out _); ParseFuncName(lexer, out var fnExp, out var hasColon); var fdExp = ParseFuncDefExp(lexer); if (hasColon) { fdExp.ParList.Insert(0, "self"); } return(new AssignStat { LastLine = fdExp.Line, VarList = new List <Exp> { fnExp }, ExpList = new List <Exp> { fdExp }, }); }
private static void ParseParList(Lexer.Lexer lexer, out List <string> parList, out bool isVararg) { parList = new List <string>(); isVararg = false; switch (lexer.LookAhead()) { case ETokenType.SepRParen: return; case ETokenType.Vararg: { lexer.NextToken(out _, out _, out _); isVararg = true; return; } } lexer.NextIdentifier(out _, out var name); parList.Add(name); while (lexer.LookAhead() == ETokenType.SepComma) { lexer.NextToken(out _, out _, out _); if (lexer.LookAhead() == ETokenType.Identifier) { lexer.NextIdentifier(out _, out name); parList.Add(name); } else { lexer.NextTokenOfKind(ETokenType.Vararg, out _, out _); isVararg = true; break; } } }
private static Stat ParseEmptyStat(Lexer.Lexer lexer) { lexer.NextTokenOfKind(ETokenType.SepSemi, out _, out _); return(new EmptyStat()); }