コード例 #1
0
        Expr ParseBinaryExpr(bool lhs, int prec1)
        {
            Expr x = ParseUnaryExpr(lhs);

            for (var prec = GetTokenPrecedence(); prec > prec1; prec--)
            {
                while (true)
                {
                    var opprec = GetTokenPrecedence();
                    if (opprec != prec)
                    {
                        break;
                    }

                    var op    = CurrTokenType;
                    var oppos = CurrTokenPos;

                    Next();

                    ScopeMgr.Resolve(x);

                    var y = ParseBinaryExpr(false, prec + 1);


                    ScopeMgr.Resolve(y);

                    x = new BinaryExpr(x, y, op, oppos);
                }
            }


            return(x);
        }
コード例 #2
0
        List <Expr> ParseRHSList()
        {
            var list = ParseExprList(false);

            foreach (var x in list)
            {
                ScopeMgr.Resolve(x);
            }

            return(list);
        }
コード例 #3
0
ファイル: ParseDecl.cs プロジェクト: mind-owner/PhotonSharp
        Stmt ParseClassDecl( )
        {
            List <Ident> memberVar = new List <Ident>();

            var defpos = CurrTokenPos;

            Expect(TokenType.Class);

            var className = ParseIdent();

            var scope = ScopeMgr.OpenClassScope(className.Name, defpos);


            Ident parentName = null;
            var   colonPos   = CurrTokenPos;

            if (CurrTokenType == TokenType.Colon)
            {
                Next();

                parentName = ParseIdent();
            }

            Expect(TokenType.LBrace);


            var decl = new ClassDeclare(className, parentName, scope, memberVar, defpos);

            if (parentName != null)
            {
                decl.ColonPos = colonPos;
            }

            className.Symbol = ScopeManager.Declare(decl, ScopeMgr.PackageScope, className.Name, className.DefinePos, SymbolUsage.Class);

            while (CurrTokenType != TokenType.RBrace)
            {
                var param = ParseIdent();
                memberVar.Add(param);

                ScopeManager.Declare(param, scope, param.Name, param.DefinePos, SymbolUsage.Member);
            }

            ScopeMgr.CloseScope();

            Next();

            return(decl);
        }
コード例 #4
0
        void ResolveSelectorElement(Expr x, Ident sel, TokenPos dotpos)
        {
            var xident = x as Ident;

            if (xident == null)
            {
                return;
            }

            if (xident.Symbol == null)
            {
                throw new CompileException(string.Format("{0} not defined", xident.Name), dotpos);
            }

            switch (xident.Symbol.Usage)
            {
            // 包.函数名
            case SymbolUsage.Package:
            {
                var pkg = Exe.GetPackageByName(xident.Name);
                if (pkg == null)
                {
                    throw new CompileException("package not found: " + xident.Name, dotpos);
                }

                // 包必须有一个顶级作用域
                if (pkg.TopScope == null)
                {
                    throw new CompileException("package should have a scope: " + xident.Name, dotpos);
                }


                ScopeMgr.Resolve(sel, pkg.TopScope);
            }
            break;

            // 实例.函数名
            case SymbolUsage.Variable:
            case SymbolUsage.Parameter:
            case SymbolUsage.SelfParameter:
            {
            }
            break;

            default:
                throw new CompileException("unknown usage", dotpos);
            }
        }
コード例 #5
0
ファイル: ParseStmt.cs プロジェクト: mind-owner/PhotonSharp
        BlockStmt ParseBlockStmt()
        {
            var defPos = CurrTokenPos;

            Expect(TokenType.LBrace);

            ScopeMgr.OpenScope(ScopeType.Block, defPos);

            var list = ParseStatmentList();

            ScopeMgr.CloseScope();

            var rpos = CurrTokenPos;

            Expect(TokenType.RBrace);

            return(new BlockStmt(list, defPos, rpos));
        }
コード例 #6
0
ファイル: ParseStmt.cs プロジェクト: mind-owner/PhotonSharp
        BlockStmt ParseBody(Scope s)
        {
            var lpos = CurrTokenPos;

            Expect(TokenType.LBrace);

            ScopeMgr.TopScope = s;

            var list = ParseStatmentList();

            ScopeMgr.CloseScope();

            var rpos = CurrTokenPos;

            Expect(TokenType.RBrace);

            return(new BlockStmt(list, lpos, rpos));
        }
コード例 #7
0
ファイル: ParseStmt.cs プロジェクト: mind-owner/PhotonSharp
        Stmt ParseForStmt()
        {
            var defPos = CurrTokenPos;

            Expect(TokenType.For);

            var forscope = ScopeMgr.OpenScope(ScopeType.For, defPos);

            Stmt s1 = null;
            Stmt s2 = null;
            Stmt s3 = null;

            // 可能是foreach
            if (CurrTokenType != TokenType.SemiColon)
            {
                var idents = ParseIdentList();

                foreach (var i in idents)
                {
                    ScopeManager.Declare(i, ScopeMgr.TopScope, i.Name, i.DefinePos, SymbolUsage.Variable);
                }

                var opPos = CurrTokenPos;

                switch (CurrTokenType)
                {
                // for numeral
                case TokenType.Assign:
                {
                    Next();

                    var values = ParseRHSList();

                    var lhs = new List <Expr>();
                    foreach (var id in idents)
                    {
                        lhs.Add(id);
                    }

                    s1 = new AssignStmt(lhs, values, opPos, TokenType.Assign);
                }
                break;

                // for k, v in x {}
                case TokenType.In:
                {
                    Next();

                    var x = ParseRHS();

                    var body = ParseBlockStmt();

                    ScopeMgr.CloseScope();

                    if (idents.Count != 2)
                    {
                        throw new CompileException("Expect key & value in for-range", CurrTokenPos);
                    }

                    return(new ForRangeStmt(idents[0], idents[1], x, opPos, defPos, forscope, body));
                }

                default:
                    throw new CompileException("Expect '=' or 'in' in for statement", CurrTokenPos);
                }
            }

            // s1和s2之间的分号
            Expect(TokenType.SemiColon);

            if (CurrTokenType != TokenType.SemiColon)
            {
                s2 = ParseSimpleStmt();
            }

            // s2和s3之间的分号
            Expect(TokenType.SemiColon);

            if (CurrTokenType != TokenType.LBrace)
            {
                s3 = ParseSimpleStmt();
            }

            var body2 = ParseBlockStmt();

            ScopeMgr.CloseScope();

            Expr condition = null;

            if (s2 != null)
            {
                condition = (s2 as ExprStmt).X[0];
            }

            return(new ForStmt(s1, condition, s3, defPos, forscope, body2));
        }
コード例 #8
0
        Expr ParseOperand(bool lhs)
        {
            var defPos = CurrTokenPos;

            switch (CurrTokenType)
            {
            case TokenType.Identifier:     // a = b
            {
                var x = ParseIdent();

                ScopeMgr.Resolve(x);

                return(x);
            }

            case TokenType.Base:     // a= base.foo()
            {
                Next();

                return(new BaseLit(defPos));
            }

            case TokenType.Number:
            case TokenType.QuotedString:
            {
                var x = new BasicLit(_token.Value, CurrTokenType, CurrTokenPos);
                Next();
                return(x);
            }

            case TokenType.LParen:     // () 括号表达式
            {
                Next();

                var x = ParseExpr(false);

                var rparenPos = CurrTokenPos;
                Expect(TokenType.RParen);

                return(new ParenExpr(x, defPos, rparenPos));
            }

            case TokenType.LBracket:     // a = [] 数组初始化
            {
                Next();

                List <Expr> values = new List <Expr>();

                while (CurrTokenType != TokenType.RBracket &&
                       CurrTokenType != TokenType.EOF)
                {
                    values.Add(ParseOperand(false));


                    if (CurrTokenType == TokenType.RBracket ||
                        CurrTokenType == TokenType.EOF)
                    {
                        break;
                    }

                    Expect(TokenType.Comma);
                }


                var rPos = CurrTokenPos;
                Expect(TokenType.RBracket);

                return(new ArrayExpr(values, defPos, rPos));
            }

            case TokenType.LBrace:     // a = {} Map初始化
            {
                Next();

                Dictionary <BasicLit, Expr> mapValues = new Dictionary <BasicLit, Expr>();

                while (CurrTokenType != TokenType.RBrace &&
                       CurrTokenType != TokenType.EOF)
                {
                    var key = ParseBasicLit();

                    Expect(TokenType.Colon);

                    var value = ParseRHS();

                    mapValues.Add(key, value);

                    if (CurrTokenType == TokenType.RBrace ||
                        CurrTokenType == TokenType.EOF)
                    {
                        break;
                    }

                    Expect(TokenType.Comma);
                }


                var rPos = CurrTokenPos;
                Expect(TokenType.RBrace);

                return(new MapExpr(mapValues, defPos, rPos));
            }

            case TokenType.Func:     // a = func( ) {}
            {
                Next();

                var scope     = ScopeMgr.OpenScope(ScopeType.Closure, defPos);
                var paramlist = ParseParameters(scope, false);

                var body = ParseBody(scope);

                var funclit = new FuncLit(body, new FuncType(defPos, paramlist, scope));

                return(funclit);
            }
            }

            throw new CompileException("Unknown operand", CurrTokenPos);
        }
コード例 #9
0
        Expr ParsePrimaryExpr(bool lhs)
        {
            var x = ParseOperand(lhs);

            bool parsing = true;

            int callTimes = 0;

            while (parsing)
            {
                switch (CurrTokenType)
                {
                // a.b
                case TokenType.Dot:
                {
                    var dotpos = CurrTokenPos;
                    Next();

                    ScopeMgr.Resolve(x);



                    switch (CurrTokenType)
                    {
                    case TokenType.Identifier:
                    {
                        var sel = ParseIdent();

                        ResolveSelectorElement(x, sel, dotpos);

                        x = new SelectorExpr(x, sel, dotpos);
                    }
                    break;

                    default:
                        throw new CompileException("expect selector", CurrTokenPos);
                    }
                }
                break;

                // a[index]
                case TokenType.LBracket:
                {
                    var lpos = CurrTokenPos;

                    ScopeMgr.Resolve(x);

                    Next();

                    var index = ParseRHSList();

                    var rpos = CurrTokenPos;
                    Expect(TokenType.RBracket);

                    x = new IndexExpr(x, index[0], lpos, rpos);
                }
                break;

                case TokenType.LParen:
                {
                    callTimes++;

                    // 函数调用不能连续, foo()()是不可以的
                    if (callTimes > 1)
                    {
                        throw new CompileException("invalid call statement", CurrTokenPos);
                    }

                    ScopeMgr.Resolve(x);

                    x = ParseCallExpr(x);
                }
                break;

                default:
                    parsing = false;
                    break;
                }
            }


            return(x);
        }
コード例 #10
0
ファイル: ParseDecl.cs プロジェクト: mind-owner/PhotonSharp
        Stmt ParseFuncDecl()
        {
            var funcPos = CurrTokenPos;

            Expect(TokenType.Func);

            var scope = ScopeMgr.OpenScope(ScopeType.Function, funcPos);

            Ident funcName;
            Ident className = null;

            var NameA = ParseIdent();

            Scope funcAtScope;

            if (CurrTokenType == TokenType.Dot)
            {
                Next();

                funcName = ParseIdent();

                className = NameA;

                funcAtScope = ScopeMgr.GetClassScope(className.Name);

                // 主定义文件还未出现, 所以暂时创建空的scope
                if (funcAtScope == null)
                {
                    funcAtScope = ScopeMgr.OpenClassScope(className.Name, funcPos);
                    ScopeMgr.CloseScope();
                }
            }
            else
            {
                funcAtScope = ScopeMgr.PackageScope;
                funcName    = NameA;
            }


            var paramlist = ParseParameters(scope, className != null);

            if (CurrTokenType == TokenType.LBrace)
            {
                var decl = new FuncDeclare(funcName, new FuncType(funcPos, paramlist, scope));
                decl.ClassName = className;

                funcName.Symbol = ScopeManager.Declare(decl, funcAtScope, funcName.Name, funcName.DefinePos, SymbolUsage.Func);


                decl.Body = ParseBody(scope);

                decl.BuildRelation();



                return(decl);
            }
            else
            {
                // 声明已经结束
                ScopeMgr.CloseScope();

                // 函数前置声明
                var decl = new DelegateDeclare(funcName, new FuncType(funcPos, paramlist, scope));

                funcName.Symbol = ScopeManager.Declare(decl, ScopeMgr.PackageScope, funcName.Name, funcName.DefinePos, SymbolUsage.Delegate);

                return(decl);
            }
        }