示例#1
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
            });
        }
示例#2
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;
        }
示例#3
0
 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
     });
 }
示例#4
0
        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
            });
        }
示例#5
0
        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
            });
        }
示例#6
0
        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
            });
        }
示例#7
0
        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);
        }
示例#8
0
 private static Stat ParseBreakStat(Lexer.Lexer lexer)
 {
     lexer.NextTokenOfKind(ETokenType.KwBreak, out _, out _);
     return(new BreakStat {
         Line = lexer.Line
     });
 }
示例#9
0
        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);
        }
示例#10
0
        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
            });
        }
示例#11
0
 private static Stat ParseGotoStat(Lexer.Lexer lexer)
 {
     lexer.NextTokenOfKind(ETokenType.KwGoto, out _, out _);
     lexer.NextIdentifier(out _, out var name);
     return(new GotoStat {
         Name = name
     });
 }
示例#12
0
        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
            });
        }
示例#13
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);
        }
示例#14
0
        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
            });
        }
示例#15
0
        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);
        }
示例#16
0
        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
            });
        }
示例#17
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));
     }
 }
示例#18
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);
                }
            }
        }
示例#19
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));
     }
 }
示例#20
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
            });
        }
示例#21
0
        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
            });
        }
示例#22
0
        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
                },
            });
        }
示例#23
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;
                }
            }
        }
示例#24
0
 private static Stat ParseEmptyStat(Lexer.Lexer lexer)
 {
     lexer.NextTokenOfKind(ETokenType.SepSemi, out _, out _);
     return(new EmptyStat());
 }