public LiteValue Visit(SyntaxDotClassExpressionNode Node, LiteEnv Env) { var Val = Node.GetClassIdentNode().Accept(this, Env); var Mem = (Node.GetCallIdentNode() as SyntaxIdentifierNode).GetValue(); if (Val.Type == LiteValueType.Class) { if (Mem == "New") { var Cls = ClassTable.GetClass((int)Val.Numeric); var ObjEnv = Cls.MakeEnv(); var LiteObj = new LiteObject(ObjEnv); var Obj = ObjectTable.AddObjectEx(LiteObj); ObjEnv.SetSelf("this", Obj); LiteObj.InitObject(this, Cls, ObjEnv); return(Obj); } } else if (Val.Type == LiteValueType.Object) { var LiteObj = ObjectTable.GetObject((int)Val.Numeric); if (LiteObj == null) { Logger.DError($"bad member access : {Val}"); return(LiteValue.Error); } return(LiteObj.Read(Mem)); } else { Logger.DError($"unknown class type : {Val}"); } return(LiteValue.Error); }
// 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); }