diff --git a/src/Parser.fu b/src/Parser.fu index 3e10c6b..b4f4dc4 100644 --- a/src/Parser.fu +++ b/src/Parser.fu @@ -39,6 +39,7 @@ class Parser { case Token.Type_OperatorMod: case Token.Type_OperatorAdd: case Token.Type_OperatorSub: + case Token.Type_Literal: while(RPNStack.Count != 0 && RPNStack.Peek().GetTokType() >= type){ Token op2 = RPNStack.Pop(); TokensInRPN.AddToEnd(op2); @@ -56,9 +57,6 @@ class Parser { TokensInRPN.AddToEnd(op2); } break; - case Token.Type_Literal: - ThrowError($"token '{tok.GetStr()}' isn't implemented"); - break; default: ThrowError($"unexpected token type '{type}'"); break; @@ -80,30 +78,31 @@ class Parser { while(tokenNode != null){ Token tok = tokenNode.GetValue(); int type = tok.GetTokType(); + string() str = tok.GetStr(); switch(type){ case Token.Type_Number: NumericExpression# num = new NumericExpression(); - num.Init(StringToDouble(tok.GetStr())); + num.Init(StringToDouble(str)); expressionStack.Push(num); break; case Token.Type_OperatorPow: - PushOperatorExpression(expressionStack, tok, new OperatorExpressionPow()); + PushOperatorExpression(expressionStack, str, new OperatorExpressionPow()); break; case Token.Type_OperatorMul: - PushOperatorExpression(expressionStack, tok, new OperatorExpressionMul()); + PushOperatorExpression(expressionStack, str, new OperatorExpressionMul()); break; case Token.Type_OperatorDiv: - PushOperatorExpression(expressionStack, tok, new OperatorExpressionDiv()); + PushOperatorExpression(expressionStack, str, new OperatorExpressionDiv()); break; case Token.Type_OperatorMod: - PushOperatorExpression(expressionStack, tok, new OperatorExpressionMod()); + PushOperatorExpression(expressionStack, str, new OperatorExpressionMod()); break; case Token.Type_OperatorAdd: - PushOperatorExpression(expressionStack, tok, new OperatorExpressionAdd()); + PushOperatorExpression(expressionStack, str, new OperatorExpressionAdd()); break; case Token.Type_OperatorSub: - PushOperatorExpression(expressionStack, tok, new OperatorExpressionSub()); + PushOperatorExpression(expressionStack, str, new OperatorExpressionSub()); break; case Token.Type_BracketClose: ThrowError("unexpected '('"); @@ -112,19 +111,46 @@ class Parser { ThrowError("unexpected ')'"); break; case Token.Type_Literal: - ThrowError($"token '{tok.GetStr()}' isn't implemented"); + switch(str){ + case "sin": + PushFunctionExpression(expressionStack, str, new FunctionCallExpressionSin()); + break; + case "cos": + PushFunctionExpression(expressionStack, str, new FunctionCallExpressionCos()); + break; + case "tan": + PushFunctionExpression(expressionStack, str, new FunctionCallExpressionTan()); + break; + case "asin": + PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAsin()); + break; + case "acos": + PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAcos()); + break; + case "atan": + PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAtan()); + break; + case "log": + PushFunctionExpression(expressionStack, str, new FunctionCallExpressionLog()); + break; + default: { + ThrowError($"invalid literal '{str}'"); + } + break; + } break; - default: + default: { ThrowError($"unexpected token type '{type}'"); - break; + } + break; } tokenNode = tokenNode.GetNext(); } - if(expressionStack.Count == 1) - RootExpression = expressionStack.Pop(); - else RootExpression = new NumericExpression(); // NaN + if(expressionStack.Count != 1) + ThrowError(""); + RootExpression = expressionStack.Pop(); } // returns the number or NaN @@ -146,9 +172,9 @@ class Parser { return d; } - void PushOperatorExpression(Stack! expressionStack, Token tok, OperatorExpression# opExpr) { + void PushOperatorExpression(Stack! expressionStack, string tokStr, OperatorExpression# opExpr) { if(expressionStack.Count < 2){ - ThrowError($"unexpected operator '{tok.GetStr()}'"); + ThrowError($"unexpected operator '{tokStr}'"); return; } IExpression b = expressionStack.Pop(); @@ -156,6 +182,15 @@ class Parser { opExpr.Init(a, b); expressionStack.Push(opExpr); } + void PushFunctionExpression(Stack! expressionStack, string tokStr, FunctionCallExpression# fExpr) { + if(expressionStack.Count < 1){ + ThrowError($"unexpected function call '{tokStr}'"); + return; + } + IExpression x = expressionStack.Pop(); + fExpr.Init(x); + expressionStack.Push(fExpr); + } static void ThrowError(string errmsg){ #if C diff --git a/src/Token.fu b/src/Token.fu index 50bc540..258498d 100644 --- a/src/Token.fu +++ b/src/Token.fu @@ -6,16 +6,16 @@ class Token { // The Type is also the priority of the token in calculation (see Parser). int Type; + public const int Type_Literal=11; public const int Type_OperatorPow=10; public const int Type_OperatorMul=9; public const int Type_OperatorMod=8; public const int Type_OperatorDiv=7; public const int Type_OperatorAdd=6; public const int Type_OperatorSub=5; - public const int Type_BracketOpen=4; - public const int Type_BracketClose=3; - public const int Type_Number=2; - public const int Type_Literal=1; + public const int Type_BracketOpen=3; + public const int Type_BracketClose=2; + public const int Type_Number=1; internal static Token() Create(string str, int startIndex, int length, int type){ Token() tok = {