function call literals parsing

This commit is contained in:
Timerix22 2023-12-23 14:06:31 +06:00
parent 8fe03105b7
commit 2a4f92fe35
2 changed files with 57 additions and 22 deletions

View File

@ -39,6 +39,7 @@ class Parser {
case Token.Type_OperatorMod: case Token.Type_OperatorMod:
case Token.Type_OperatorAdd: case Token.Type_OperatorAdd:
case Token.Type_OperatorSub: case Token.Type_OperatorSub:
case Token.Type_Literal:
while(RPNStack.Count != 0 && RPNStack.Peek().GetTokType() >= type){ while(RPNStack.Count != 0 && RPNStack.Peek().GetTokType() >= type){
Token op2 = RPNStack.Pop(); Token op2 = RPNStack.Pop();
TokensInRPN.AddToEnd(op2); TokensInRPN.AddToEnd(op2);
@ -56,9 +57,6 @@ class Parser {
TokensInRPN.AddToEnd(op2); TokensInRPN.AddToEnd(op2);
} }
break; break;
case Token.Type_Literal:
ThrowError($"token '{tok.GetStr()}' isn't implemented");
break;
default: default:
ThrowError($"unexpected token type '{type}'"); ThrowError($"unexpected token type '{type}'");
break; break;
@ -80,30 +78,31 @@ class Parser {
while(tokenNode != null){ while(tokenNode != null){
Token tok = tokenNode.GetValue(); Token tok = tokenNode.GetValue();
int type = tok.GetTokType(); int type = tok.GetTokType();
string() str = tok.GetStr();
switch(type){ switch(type){
case Token.Type_Number: case Token.Type_Number:
NumericExpression# num = new NumericExpression(); NumericExpression# num = new NumericExpression();
num.Init(StringToDouble(tok.GetStr())); num.Init(StringToDouble(str));
expressionStack.Push(num); expressionStack.Push(num);
break; break;
case Token.Type_OperatorPow: case Token.Type_OperatorPow:
PushOperatorExpression(expressionStack, tok, new OperatorExpressionPow()); PushOperatorExpression(expressionStack, str, new OperatorExpressionPow());
break; break;
case Token.Type_OperatorMul: case Token.Type_OperatorMul:
PushOperatorExpression(expressionStack, tok, new OperatorExpressionMul()); PushOperatorExpression(expressionStack, str, new OperatorExpressionMul());
break; break;
case Token.Type_OperatorDiv: case Token.Type_OperatorDiv:
PushOperatorExpression(expressionStack, tok, new OperatorExpressionDiv()); PushOperatorExpression(expressionStack, str, new OperatorExpressionDiv());
break; break;
case Token.Type_OperatorMod: case Token.Type_OperatorMod:
PushOperatorExpression(expressionStack, tok, new OperatorExpressionMod()); PushOperatorExpression(expressionStack, str, new OperatorExpressionMod());
break; break;
case Token.Type_OperatorAdd: case Token.Type_OperatorAdd:
PushOperatorExpression(expressionStack, tok, new OperatorExpressionAdd()); PushOperatorExpression(expressionStack, str, new OperatorExpressionAdd());
break; break;
case Token.Type_OperatorSub: case Token.Type_OperatorSub:
PushOperatorExpression(expressionStack, tok, new OperatorExpressionSub()); PushOperatorExpression(expressionStack, str, new OperatorExpressionSub());
break; break;
case Token.Type_BracketClose: case Token.Type_BracketClose:
ThrowError("unexpected '('"); ThrowError("unexpected '('");
@ -112,19 +111,46 @@ class Parser {
ThrowError("unexpected ')'"); ThrowError("unexpected ')'");
break; break;
case Token.Type_Literal: 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; break;
default: default: {
ThrowError($"unexpected token type '{type}'"); ThrowError($"unexpected token type '{type}'");
break; }
break;
} }
tokenNode = tokenNode.GetNext(); tokenNode = tokenNode.GetNext();
} }
if(expressionStack.Count == 1) if(expressionStack.Count != 1)
RootExpression = expressionStack.Pop(); ThrowError("");
else RootExpression = new NumericExpression(); // NaN RootExpression = expressionStack.Pop();
} }
// returns the number or NaN // returns the number or NaN
@ -146,9 +172,9 @@ class Parser {
return d; return d;
} }
void PushOperatorExpression(Stack<IExpression#>! expressionStack, Token tok, OperatorExpression# opExpr) { void PushOperatorExpression(Stack<IExpression#>! expressionStack, string tokStr, OperatorExpression# opExpr) {
if(expressionStack.Count < 2){ if(expressionStack.Count < 2){
ThrowError($"unexpected operator '{tok.GetStr()}'"); ThrowError($"unexpected operator '{tokStr}'");
return; return;
} }
IExpression b = expressionStack.Pop(); IExpression b = expressionStack.Pop();
@ -156,6 +182,15 @@ class Parser {
opExpr.Init(a, b); opExpr.Init(a, b);
expressionStack.Push(opExpr); expressionStack.Push(opExpr);
} }
void PushFunctionExpression(Stack<IExpression#>! 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){ static void ThrowError(string errmsg){
#if C #if C

View File

@ -6,16 +6,16 @@ class Token {
// The Type is also the priority of the token in calculation (see Parser). // The Type is also the priority of the token in calculation (see Parser).
int Type; int Type;
public const int Type_Literal=11;
public const int Type_OperatorPow=10; public const int Type_OperatorPow=10;
public const int Type_OperatorMul=9; public const int Type_OperatorMul=9;
public const int Type_OperatorMod=8; public const int Type_OperatorMod=8;
public const int Type_OperatorDiv=7; public const int Type_OperatorDiv=7;
public const int Type_OperatorAdd=6; public const int Type_OperatorAdd=6;
public const int Type_OperatorSub=5; public const int Type_OperatorSub=5;
public const int Type_BracketOpen=4; public const int Type_BracketOpen=3;
public const int Type_BracketClose=3; public const int Type_BracketClose=2;
public const int Type_Number=2; public const int Type_Number=1;
public const int Type_Literal=1;
internal static Token() Create(string str, int startIndex, int length, int type){ internal static Token() Create(string str, int startIndex, int length, int type){
Token() tok = { Token() tok = {