private static void ParseFieldList(Lexer.Lexer lexer, out List <Exp> ks, out List <Exp> vs) { ks = null; vs = null; if (lexer.LookAhead() != ETokenType.SepRCurly) { ParseField(lexer, out var k, out var v); ks = new List <Exp> { k }; vs = new List <Exp> { v }; while (IsFieldSep(lexer.LookAhead())) { lexer.NextToken(out _, out _, out _); if (lexer.LookAhead() != ETokenType.SepRCurly) { ParseField(lexer, out k, out v); ks.Add(k); vs.Add(v); } else { break; } } } }
private static Exp ParseExp5(Lexer.Lexer lexer) { var exp = ParseExp4(lexer); if (lexer.LookAhead() != ETokenType.OpConcat) { return(exp); } var line = 0; var exps = new List <Exp> { exp }; while (lexer.LookAhead() == ETokenType.OpConcat) { lexer.NextToken(out line, out _, out _); exps.Add(ParseExp4(lexer)); } return(new ConcatExp { Line = line, Exps = exps }); }
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 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 List<Exp> ParseRetExps(Lexer.Lexer lexer) { if (lexer.LookAhead() != ETokenType.KwReturn) return null; lexer.NextToken(out _, out _, out _); var ret = new List<Exp>(); switch (lexer.LookAhead()) { case ETokenType.Eof: case ETokenType.KwEnd: case ETokenType.KwElse: case ETokenType.KwElseIf: case ETokenType.KwUntil: return ret; case ETokenType.SepSemi: lexer.NextToken(out _, out _, out _); return ret; default: var exps = ParseExpList(lexer); if (lexer.LookAhead() == ETokenType.SepSemi) lexer.NextToken(out _, out _, out _); return exps; } }
private static Exp ParseExp6(Lexer.Lexer lexer) { var exp = ParseExp5(lexer); while (true) { switch (lexer.LookAhead()) { case ETokenType.OpShl: case ETokenType.OpShr: { lexer.NextToken(out var line, out var op, out _); var shx = new BinopExp { Line = line, Op = op, Exp1 = exp, Exp2 = ParseExp5(lexer) }; exp = OptimizeBitwiseBinaryOp(shx); break; } default: return(exp); } } }
private static Exp ParseExp3(Lexer.Lexer lexer) { var exp = ParseExp2(lexer); while (true) { switch (lexer.LookAhead()) { case ETokenType.OpMul: case ETokenType.OpMod: case ETokenType.OpDiv: case ETokenType.OpIDiv: { lexer.NextToken(out var line, out var op, out _); var arith = new BinopExp { Line = line, Op = op, Exp1 = exp, Exp2 = ParseExp2(lexer) }; exp = OptimizeArithBinaryOp(arith); break; } default: return(exp); } } }
private static Exp ParseExp10(Lexer.Lexer lexer) { var exp = ParseExp9(lexer); while (true) { switch (lexer.LookAhead()) { case ETokenType.OpLt: case ETokenType.OpGt: case ETokenType.OpNe: case ETokenType.OpLe: case ETokenType.OpGe: case ETokenType.OpEq: { lexer.NextToken(out var line, out var op, out _); exp = new BinopExp { Line = line, Op = op, Exp1 = exp, Exp2 = ParseExp9(lexer) }; break; } default: return(exp); } } }
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 List<Stat> ParseStats(Lexer.Lexer lexer) { var stats = new List<Stat>(); while (!IsReturnOrBlockEnd(lexer.LookAhead())) { var stat = ParseStat(lexer); if (!(stat is EmptyStat)) stats.Add(stat); } return stats; }
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 void ParseFuncName(Lexer.Lexer lexer, out Exp exp, out bool hasColon) { hasColon = false; lexer.NextIdentifier(out var line, out var name); exp = new NameExp { Line = line, Name = name }; while (lexer.LookAhead() == ETokenType.SepDot) { lexer.NextToken(out _, out _, out _); lexer.NextIdentifier(out line, out name); var idx = new StringExp { Line = line, Str = name }; exp = new TableAccessExp { LastLine = line, KeyExp = idx, PrefixExp = exp, }; } if (lexer.LookAhead() == ETokenType.SepColon) { lexer.NextToken(out _, out _, out _); lexer.NextIdentifier(out line, out name); var idx = new StringExp { Line = line, Str = name }; exp = new TableAccessExp { LastLine = line, PrefixExp = exp, KeyExp = idx, }; hasColon = true; } }
private static List <Exp> ParseExpList(Lexer.Lexer lexer) { var exps = new List <Exp> { ParseExp(lexer) }; while (lexer.LookAhead() == ETokenType.SepComma) { lexer.NextToken(out _, out _, out _); exps.Add(ParseExp(lexer)); } return(exps); }
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 List <Exp> FinishVarList(Lexer.Lexer lexer, Exp prefixExp) { var vars = new List <Exp> { CheckVar(lexer, prefixExp) }; while (lexer.LookAhead() == ETokenType.SepComma) { lexer.NextToken(out _, out _, out _); var exp = ParsePrefixExp(lexer); vars.Add(CheckVar(lexer, exp)); } return(vars); }
private static List <string> FinishNameList(Lexer.Lexer lexer, string name) { var names = new List <string> { name }; while (lexer.LookAhead() == ETokenType.SepComma) { lexer.NextToken(out _, out _, out _); lexer.NextIdentifier(out _, out var tokenName); names.Add(tokenName); } return(names); }
private static StringExp ParseNameExp(Lexer.Lexer lexer) { if (lexer.LookAhead() == ETokenType.SepColon) { lexer.NextToken(out _, out _, out _); lexer.NextIdentifier(out var line, out var name); return(new StringExp { Line = line, Str = name, }); } return(null); }
private static Exp ParseExp7(Lexer.Lexer lexer) { var exp = ParseExp6(lexer); while (lexer.LookAhead() == ETokenType.OpBAnd) { lexer.NextToken(out var line, out var op, out _); var band = new BinopExp { Line = line, Op = op, Exp1 = exp, Exp2 = ParseExp6(lexer) }; } return(exp); }
private static Exp ParseExp1(Lexer.Lexer lexer) { var exp = ParseExp0(lexer); if (lexer.LookAhead() == ETokenType.OpPow) { lexer.NextToken(out var line, out var op, out _); exp = new BinopExp { Line = line, Op = op, Exp1 = exp, Exp2 = ParseExp2(lexer) }; } return(OptimizePow(exp)); }
private static Exp ParseExp11(Lexer.Lexer lexer) { var exp = ParseExp10(lexer); while (lexer.LookAhead() == ETokenType.OpAnd) { lexer.NextToken(out var line, out var op, out _); var land = new BinopExp { Line = line, Op = op, Exp1 = exp, Exp2 = ParseExp10(lexer) }; exp = OptimizeLogicalAnd(land); } return(exp); }
private static Exp ParseExp8(Lexer.Lexer lexer) { var exp = ParseExp7(lexer); while (lexer.LookAhead() == ETokenType.OpBXor) { lexer.NextToken(out var line, out var op, out _); var bxor = new BinopExp { Line = line, Op = op, Exp1 = exp, Exp2 = ParseExp7(lexer) }; exp = OptimizeBitwiseBinaryOp(bxor); } return(exp); }
private static Exp ParsePrefixExp(Lexer.Lexer lexer) { Exp exp; if (lexer.LookAhead() == ETokenType.Identifier) { lexer.NextIdentifier(out var line, out var name); exp = new NameExp { Line = line, Name = name }; } else { exp = ParseParensExp(lexer); } return(FinishPrefixExp(lexer, exp)); }
private static Stat ParseStat(Lexer.Lexer lexer) { switch (lexer.LookAhead()) { case ETokenType.SepSemi: return(ParseEmptyStat(lexer)); case ETokenType.KwBreak: return(ParseBreakStat(lexer)); case ETokenType.SepLabel: return(ParseLabelStat(lexer)); case ETokenType.KwGoto: return(ParseGotoStat(lexer)); case ETokenType.KwDo: return(ParseDoStat(lexer)); case ETokenType.KwWhile: return(ParseWhileStat(lexer)); case ETokenType.KwRepeat: return(ParseRepeatStat(lexer)); case ETokenType.KwIf: return(ParseIfStat(lexer)); case ETokenType.KwFor: return(ParseForStat(lexer)); case ETokenType.KwFunction: return(ParseFuncDefStat(lexer)); case ETokenType.KwLocal: return(ParseLocalAssignOrFuncDefStat(lexer)); default: return(ParseAssignOrFuncCallStat(lexer)); } }
private static Stat FinishLocalVarDeclStat(Lexer.Lexer lexer) { lexer.NextIdentifier(out _, out var name0); var nameList = FinishNameList(lexer, name0); List <Exp> expList = null; if (lexer.LookAhead() == ETokenType.OpAssign) { lexer.NextToken(out _, out _, out _); expList = ParseExpList(lexer); } var lastLine = lexer.Line; return(new LocalVarDeclStat { ExpList = expList, LastLine = lastLine, NameList = nameList }); }
private static Exp ParseExp2(Lexer.Lexer lexer) { switch (lexer.LookAhead()) { case ETokenType.OpUnm: case ETokenType.OpBNot: case ETokenType.OpLen: case ETokenType.OpNot: { lexer.NextToken(out var line, out var op, out _); var exp = new UnopExp { Line = line, Op = op, Exp = ParseExp2(lexer) }; return(OptimizeUnaryOp(exp)); } } return(ParseExp1(lexer)); }
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 }); }
public Token NextToken() { return(input.LookAhead()); }
private static Exp ParseExp0(Lexer.Lexer lexer) { switch (lexer.LookAhead()) { case ETokenType.Vararg: { lexer.NextToken(out var line, out _, out _); return(new VarargExp { Line = line }); } case ETokenType.KwNil: { lexer.NextToken(out var line, out _, out _); return(new NilExp { Line = line }); } case ETokenType.KwTrue: { lexer.NextToken(out var line, out _, out _); return(new TrueExp { Line = line }); } case ETokenType.KwFalse: { lexer.NextToken(out var line, out _, out _); return(new FalseExp { Line = line }); } case ETokenType.String: { lexer.NextToken(out var line, out _, out var token); return(new StringExp { Line = line, Str = token }); } case ETokenType.Number: { return(ParseNumberExp(lexer)); } case ETokenType.SepLCurly: { return(ParseTableConstructorExp(lexer)); } case ETokenType.KwFunction: { lexer.NextToken(out _, out _, out _); return(ParseFuncDefExp(lexer)); } default: return(ParsePrefixExp(lexer)); } }