// expr ::= term { <op> term } // op := "<" | ">" | "<=" | ">=" | "==" | "~=" | "&&" | "||" | ...... (see lang desc) private SyntaxNode ParseExprNode() { var Left = ParseTermNode(); if (Left == null) { return(null); } while (!TokenStream_.IsEnd()) { var Tok = TokenStream_.Peek(); switch (Tok.Type) { case TokenType.Operator: TokenStream_.Take(); var Right = ParseTermNode(); if (Right == null) { return(null); } Left = new SyntaxBinaryExpressionNode(Tok, Left, Right); break; default: return(Left); } } return(Left); }
public LiteValue Visit(SyntaxBinaryExpressionNode Node, LiteEnv Env) { var ValLeft = Node.GetLeft().Accept(this, Env); var ValRight = Node.GetRight().Accept(this, Env); var Op = Node.GetOperator().Code; switch (Op) { case "<": return(ValLeft < ValRight ? LiteValue.True : LiteValue.False); case "<=": return(ValLeft <= ValRight ? LiteValue.True : LiteValue.False); case ">": return(ValLeft > ValRight ? LiteValue.True : LiteValue.False); case ">=": return(ValLeft >= ValRight ? LiteValue.True : LiteValue.False); case "==": return(ValLeft == ValRight ? LiteValue.True : LiteValue.False); case "~=": return(ValLeft != ValRight ? LiteValue.True : LiteValue.False); case "+": return(ValLeft + ValRight); case "-": return(ValLeft - ValRight); case "*": return(ValLeft * ValRight); case "/": return(ValLeft / ValRight); case "%": return(ValLeft % ValRight); default: Logger.DError($"unknown op : {Op}"); 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); }