|
@@ -1397,8 +1397,8 @@ ShaderLanguage::Operator ShaderLanguage::get_token_operator(TokenType p_type) {
|
|
|
|
|
|
Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_expr) {
|
|
|
|
|
|
- Vector<Node*> expressions;
|
|
|
- Vector<TokenType> operators;
|
|
|
+ Vector<Expression> expression;
|
|
|
+ //Vector<TokenType> operators;
|
|
|
|
|
|
while(true) {
|
|
|
|
|
@@ -1605,34 +1605,33 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
|
|
|
parser.advance();
|
|
|
expr=varname;
|
|
|
|
|
|
- } else if (parser.get_token_type()==TK_OP_NEG || parser.get_token_type()==TK_OP_NOT) {
|
|
|
+ } else if (parser.get_token_type()==TK_OP_SUB || parser.get_token_type()==TK_OP_NOT) {
|
|
|
|
|
|
//single prefix operators
|
|
|
TokenType token_type=parser.get_token_type();
|
|
|
parser.advance();
|
|
|
- Node *subexpr=NULL;
|
|
|
- Error err = parse_expression(parser,p_parent,&subexpr);
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
+ //Node *subexpr=NULL;
|
|
|
+ //Error err = parse_expression(parser,p_parent,&subexpr);
|
|
|
+ //if (err)
|
|
|
+ // return err;
|
|
|
+
|
|
|
+ //OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
|
|
|
+
|
|
|
+ Expression e;
|
|
|
+ e.is_op=true;
|
|
|
|
|
|
- OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
|
|
|
switch(token_type) {
|
|
|
- case TK_OP_NEG: op->op=OP_NEG; break;
|
|
|
- case TK_OP_NOT: op->op=OP_NOT; break;
|
|
|
+ case TK_OP_SUB: e.op=TK_OP_NEG; break;
|
|
|
+ case TK_OP_NOT: e.op=TK_OP_NOT; break;
|
|
|
//case TK_OP_PLUS_PLUS: op->op=OP_PLUS_PLUS; break;
|
|
|
//case TK_OP_MINUS_MINUS: op->op=OP_MINUS_MINUS; break;
|
|
|
default: ERR_FAIL_V(ERR_BUG);
|
|
|
}
|
|
|
|
|
|
- op->arguments.push_back(subexpr);
|
|
|
-
|
|
|
- expr=validate_operator(parser,op);
|
|
|
+ expression.push_back(e);
|
|
|
|
|
|
- if (!expr) {
|
|
|
+ continue;
|
|
|
|
|
|
- parser.set_error("Invalid argument for negation operator");
|
|
|
- return ERR_PARSE_ERROR;
|
|
|
- }
|
|
|
|
|
|
} else {
|
|
|
print_line("found bug?");
|
|
@@ -1798,48 +1797,64 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
|
|
|
|
|
|
} */
|
|
|
|
|
|
-
|
|
|
- expressions.push_back(expr);
|
|
|
+ Expression e;
|
|
|
+ e.is_op=false;
|
|
|
+ e.node=expr;
|
|
|
+ expression.push_back(e);
|
|
|
|
|
|
|
|
|
if (is_token_operator(parser.get_token_type())) {
|
|
|
|
|
|
- operators.push_back(parser.get_token_type());
|
|
|
+ Expression o;
|
|
|
+ o.is_op=true;
|
|
|
+ o.op=parser.get_token_type();
|
|
|
+ expression.push_back(o);
|
|
|
parser.advance();
|
|
|
} else {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- ERR_FAIL_COND_V(expressions.size()!=(operators.size()+1),ERR_BUG);
|
|
|
+
|
|
|
|
|
|
/* Reduce the set set of expressions and place them in an operator tree, respecting precedence */
|
|
|
|
|
|
- while(expressions.size()>1) {
|
|
|
+ while(expression.size()>1) {
|
|
|
|
|
|
int next_op=-1;
|
|
|
int min_priority=0xFFFFF;
|
|
|
+ bool is_unary=false;
|
|
|
+
|
|
|
+ for(int i=0;i<expression.size();i++) {
|
|
|
|
|
|
- for(int i=0;i<operators.size();i++) {
|
|
|
+ if (!expression[i].is_op) {
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool unary=false;
|
|
|
|
|
|
int priority;
|
|
|
- switch(operators[i]) {
|
|
|
+ switch(expression[i].op) {
|
|
|
+
|
|
|
+ case TK_OP_NOT: priority=0; unary=true; break;
|
|
|
+ case TK_OP_NEG: priority=0; unary=true; break;
|
|
|
|
|
|
- case TK_OP_MUL: priority=0; break;
|
|
|
- case TK_OP_DIV: priority=0; break;
|
|
|
+ case TK_OP_MUL: priority=1; break;
|
|
|
+ case TK_OP_DIV: priority=1; break;
|
|
|
|
|
|
- case TK_OP_ADD: priority=1; break;
|
|
|
- case TK_OP_SUB: priority=1; break;
|
|
|
+ case TK_OP_ADD: priority=2; break;
|
|
|
+ case TK_OP_SUB: priority=2; break;
|
|
|
|
|
|
// shift left/right =2
|
|
|
|
|
|
- case TK_OP_LESS: priority=3; break;
|
|
|
- case TK_OP_LESS_EQUAL: priority=3; break;
|
|
|
- case TK_OP_GREATER: priority=3; break;
|
|
|
- case TK_OP_GREATER_EQUAL: priority=3; break;
|
|
|
+ case TK_OP_LESS: priority=4; break;
|
|
|
+ case TK_OP_LESS_EQUAL: priority=4; break;
|
|
|
+ case TK_OP_GREATER: priority=4; break;
|
|
|
+ case TK_OP_GREATER_EQUAL: priority=4; break;
|
|
|
|
|
|
- case TK_OP_EQUAL: priority=4; break;
|
|
|
- case TK_OP_NOT_EQUAL: priority=4; break;
|
|
|
+ case TK_OP_EQUAL: priority=5; break;
|
|
|
+ case TK_OP_NOT_EQUAL: priority=5; break;
|
|
|
|
|
|
//bit and =5
|
|
|
//bit xor =6
|
|
@@ -1865,6 +1880,7 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
|
|
|
// <= is used for right to left
|
|
|
next_op=i;
|
|
|
min_priority=priority;
|
|
|
+ is_unary=unary;
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -1872,7 +1888,92 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
|
|
|
ERR_FAIL_COND_V(next_op==-1,ERR_BUG);
|
|
|
|
|
|
// OK! create operator..
|
|
|
+ // OK! create operator..
|
|
|
+ if (is_unary) {
|
|
|
+
|
|
|
+ int expr_pos=next_op;
|
|
|
+ while(expression[expr_pos].is_op) {
|
|
|
+
|
|
|
+ expr_pos++;
|
|
|
+ if (expr_pos==expression.size()) {
|
|
|
+ //can happen..
|
|
|
+ parser.set_error("Unexpected end of expression..");
|
|
|
+ return ERR_BUG;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //consecutively do unary opeators
|
|
|
+ for(int i=expr_pos-1;i>=next_op;i--) {
|
|
|
+
|
|
|
+ OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
|
|
|
+ op->op=get_token_operator(expression[i].op);
|
|
|
+ op->arguments.push_back(expression[i+1].node);
|
|
|
+
|
|
|
+ expression[i].is_op=false;
|
|
|
+ expression[i].node=validate_operator(parser,op);
|
|
|
+ if (!expression[i].node) {
|
|
|
+
|
|
|
+ String at;
|
|
|
+ for(int i=0;i<op->arguments.size();i++) {
|
|
|
+ if (i>0)
|
|
|
+ at+=" and ";
|
|
|
+ at+=get_datatype_name(compute_node_type(op->arguments[i]));
|
|
|
+
|
|
|
+ }
|
|
|
+ parser.set_error("Invalid argument to unary operator "+String(token_names[op->op])+": "+at);
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+ expression.remove(i+1);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+
|
|
|
+ if (next_op <1 || next_op>=(expression.size()-1)) {
|
|
|
+ parser.set_error("Parser bug..");
|
|
|
+ ERR_FAIL_V(ERR_BUG);
|
|
|
+ }
|
|
|
+
|
|
|
+ OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
|
|
|
+ op->op=get_token_operator(expression[next_op].op);
|
|
|
+
|
|
|
+ if (expression[next_op-1].is_op) {
|
|
|
+
|
|
|
+ parser.set_error("Parser bug..");
|
|
|
+ ERR_FAIL_V(ERR_BUG);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (expression[next_op+1].is_op) {
|
|
|
+ // this is not invalid and can really appear
|
|
|
+ // but it becomes invalid anyway because no binary op
|
|
|
+ // can be followed by an unary op in a valid combination,
|
|
|
+ // due to how precedence works, unaries will always dissapear first
|
|
|
+
|
|
|
+ parser.set_error("Parser bug..");
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ op->arguments.push_back(expression[next_op-1].node); //expression goes as left
|
|
|
+ op->arguments.push_back(expression[next_op+1].node); //next expression goes as right
|
|
|
+
|
|
|
+ //replace all 3 nodes by this operator and make it an expression
|
|
|
+ expression[next_op-1].node=validate_operator(parser,op);
|
|
|
+ if (!expression[next_op-1].node) {
|
|
|
+
|
|
|
+ String at;
|
|
|
+ for(int i=0;i<op->arguments.size();i++) {
|
|
|
+ if (i>0)
|
|
|
+ at+=" and ";
|
|
|
+ at+=get_datatype_name(compute_node_type(op->arguments[i]));
|
|
|
+
|
|
|
+ }
|
|
|
+ parser.set_error("Invalid arguments to operator "+String(token_names[op->op])+": "+at);
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+ expression.remove(next_op);
|
|
|
+ expression.remove(next_op);
|
|
|
+ }
|
|
|
|
|
|
+#if 0
|
|
|
OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
|
|
|
op->op=get_token_operator(operators[next_op]);
|
|
|
|
|
@@ -1896,10 +1997,11 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
|
|
|
|
|
|
expressions.remove(next_op+1);
|
|
|
operators.remove(next_op);
|
|
|
+#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
- *r_expr=expressions[0];
|
|
|
+ *r_expr=expression[0].node;
|
|
|
|
|
|
return OK;
|
|
|
|