示例#1
0
        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;
                    }
                }
            }
        }
示例#2
0
        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
            });
        }
示例#3
0
        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;
        }
示例#4
0
        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
            });
        }
示例#5
0
        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;
            }
        }
示例#6
0
        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);
                }
            }
        }
示例#7
0
        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);
                }
            }
        }
示例#8
0
        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);
                }
            }
        }
示例#9
0
        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);
        }
示例#10
0
        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;
        }
示例#11
0
 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));
     }
 }
示例#12
0
        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);
                }
            }
        }
示例#13
0
 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));
     }
 }
示例#14
0
        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;
            }
        }
示例#15
0
        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);
        }
示例#16
0
        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;
                }
            }
        }
示例#17
0
        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);
        }
示例#18
0
        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);
        }
示例#19
0
        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);
        }
示例#20
0
        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);
        }
示例#21
0
        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));
        }
示例#22
0
        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);
        }
示例#23
0
        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);
        }
示例#24
0
        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));
        }
示例#25
0
        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));
            }
        }
示例#26
0
        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
            });
        }
示例#27
0
        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));
        }
示例#28
0
        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
            });
        }
示例#29
0
 public Token NextToken()
 {
     return(input.LookAhead());
 }
示例#30
0
        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));
            }
        }