// 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); }
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); }