Beispiel #1
0
        // factor ::= assignment | dot | call | primary { <'*' | '/' | '%' > primary }
        // call ::= args
        // dot ::= "." ident
        private SyntaxNode ParseFactorNode()
        {
            var Left = ParsePrimaryNode();

            if (Left == null)
            {
                return(null);
            }

            while (!TokenStream_.IsEnd())
            {
                var Tok = TokenStream_.Peek();
                switch (Tok.Type)
                {
                case TokenType.Operator:
                    switch (Tok.Code)
                    {
                    case "*":
                    case "/":
                    case "%":
                        TokenStream_.Take();
                        var Right = ParsePrimaryNode();
                        if (Right == null)
                        {
                            return(null);
                        }

                        Left = new SyntaxBinaryExpressionNode(Tok, Left, Right);
                        break;

                    case "=":
                        TokenStream_.Take();
                        var Val = ParseExprNode();
                        if (Val == null)
                        {
                            return(null);
                        }

                        Left = new SyntaxAssignmentExpressionNode(Tok, Left, Val);
                        break;

                    default:
                        return(Left);
                    }
                    break;

                case TokenType.Delimiter:
                    switch (Tok.Code)
                    {
                    case ".":
                        TokenStream_.Take();

                        if (Left.GetType() != SyntaxNodeType.Identifier)
                        {
                            ExitCode_ = new ExitFailedCode(". must use for class ident");
                            return(null);
                        }

                        if (!TokenStream_.TakeExpect(TokenType.Identifier, out Token CallIdent))
                        {
                            ExitCode_ = new ExitUnexpectedSymbolCode(CallIdent);
                            return(null);
                        }

                        Left = new SyntaxDotClassExpressionNode(Left as SyntaxIdentifierNode, new SyntaxIdentifierNode(CallIdent));
                        break;

                    case "(":
                        var ArgsNode = ParseArgumentListNode();
                        if (ArgsNode == null)
                        {
                            return(null);
                        }

                        Left = new SyntaxCallFunctionExpressionNode(Left, ArgsNode);
                        break;

                    case "[":
                        var IndexNode = ParseIndexNode();
                        if (IndexNode == null)
                        {
                            return(null);
                        }

                        Left = new SyntaxIndexElementsExpressionNode(Left, IndexNode);
                        break;

                    default:
                        return(Left);
                    }
                    break;

                default:
                    return(Left);
                }
            }

            return(Left);
        }
Beispiel #2
0
        public LiteValue Visit(SyntaxAssignmentExpressionNode Node, LiteEnv Env)
        {
            var LeftNode = Node.GetLeft();

            if (LeftNode.GetType() == SyntaxNodeType.Identifier)
            {
                var Ident = (LeftNode as SyntaxIdentifierNode).GetValue();

                var Val = Node.GetRight().Accept(this, Env);
                Env.Set(Ident, Val);
                return(Val);
            }
            if (LeftNode.GetType() == SyntaxNodeType.DotClassExpression)
            {
                var DotNode    = LeftNode as SyntaxDotClassExpressionNode;
                var Mem        = DotNode.GetCallIdentNode() as SyntaxIdentifierNode;
                var LiteObjVal = DotNode.GetClassIdentNode().Accept(this, Env);
                if (LiteObjVal.Type != LiteValueType.Object)
                {
                    Logger.DError($"bad object access : {LiteObjVal}");
                    return(LiteValue.Error);
                }

                var LiteObj = ObjectTable.GetObject((int)LiteObjVal.Numeric);
                if (LiteObj == null)
                {
                    Logger.DError($"bad object access : {LiteObjVal}");
                    return(LiteValue.Error);
                }

                var ExpVal = Node.GetRight().Accept(this, Env);
                if (ExpVal == LiteValue.Error)
                {
                    return(ExpVal);
                }

                return(LiteObj.Write(Mem.GetValue(), ExpVal));
            }

            if (LeftNode.GetType() == SyntaxNodeType.IndexElementsExpression)
            {
                var IdxNode = LeftNode as SyntaxIndexElementsExpressionNode;
                var Val     = IdxNode.GetElementIdentNode().Accept(this, Env);
                if (Val.Type == LiteValueType.Elements)
                {
                    var EleObj = ElementsTable.GetElements((int)Val.Numeric);
                    if (EleObj == null)
                    {
                        Logger.DError($"bad elements access : {Val}");
                        return(LiteValue.Error);
                    }

                    var Idx = IdxNode.GetIndexNode().Accept(this, Env);
                    if (Idx.Type != LiteValueType.Numeric)
                    {
                        Logger.DError($"elements index must be number");
                        return(LiteValue.Error);
                    }

                    var ExpVal = Node.GetRight().Accept(this, Env);
                    if (ExpVal == LiteValue.Error)
                    {
                        return(ExpVal);
                    }

                    return(EleObj.Set((int)Idx.Numeric, ExpVal));
                }
                else
                {
                    Logger.DError($"unknown elements type : {Val}");
                }
            }

            Logger.DError($"unexpected '=' near {Node.GetLeft()}");
            return(LiteValue.Error);
        }