From 19a24f859cd7fcf581442319499ae24b3e7385a4 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 3 Mar 2021 11:28:14 +0200 Subject: [PATCH] Store a pointer to operator info rather than the token in expressions Also make it a property of Expression rather than the subtypes. --- source/glsl/debug.cpp | 7 ++++--- source/glsl/evaluate.cpp | 19 ++++++++++--------- source/glsl/generate.cpp | 12 +++++------- source/glsl/optimize.cpp | 6 +++--- source/glsl/output.cpp | 15 ++++++++------- source/glsl/parser.cpp | 24 +++++++++++++----------- source/glsl/parser.h | 2 +- source/glsl/syntax.cpp | 20 +++++++++++++++----- source/glsl/syntax.h | 12 ++++++------ 9 files changed, 65 insertions(+), 52 deletions(-) diff --git a/source/glsl/debug.cpp b/source/glsl/debug.cpp index 5397372e..04d7aac8 100644 --- a/source/glsl/debug.cpp +++ b/source/glsl/debug.cpp @@ -156,12 +156,13 @@ void DumpTree::visit(MemberAccess &memacc) void DumpTree::visit(UnaryExpression &unary) { - annotated_branch(format("Unary: %s, %sfix", unary.oper, (unary.prefix ? "pre" : "suff")), *unary.expression); + string text = format("Unary: %s, %sfix", unary.oper->token, (unary.oper->type==Operator::PREFIX ? "pre" : "post")); + annotated_branch(text, *unary.expression); } void DumpTree::visit(BinaryExpression &binary) { - append(format("Binary: %s%s", binary.oper, binary.after)); + append(format("Binary: %s", (binary.oper->token[0]=='[' ? "[]" : binary.oper->token))); begin_sub(); binary.left->visit(*this); last_branch(); @@ -171,7 +172,7 @@ void DumpTree::visit(BinaryExpression &binary) void DumpTree::visit(Assignment &assign) { - append(format("Assignment: %s%s", assign.oper, (assign.self_referencing ? " (self-referencing)" : ""))); + append(format("Assignment: %s%s", assign.oper->token, (assign.self_referencing ? " (self-referencing)" : ""))); begin_sub(); if(assign.target_declaration) append(format("Target: %%%d %s %s", get_label(*assign.target_declaration), assign.target_declaration->type, assign.target_declaration->name)); diff --git a/source/glsl/evaluate.cpp b/source/glsl/evaluate.cpp index 4bbdb2f6..915b2a6f 100644 --- a/source/glsl/evaluate.cpp +++ b/source/glsl/evaluate.cpp @@ -55,7 +55,7 @@ void ExpressionEvaluator::visit(UnaryExpression &unary) if(!result_valid) return; - if(unary.oper=="!") + if(unary.oper->token[0]=='!') result = !result; else result_valid = false; @@ -74,21 +74,22 @@ void ExpressionEvaluator::visit(BinaryExpression &binary) if(!result_valid) return; - if(binary.oper=="<") + std::string oper = binary.oper->token; + if(oper=="<") result = (left_result") + else if(oper==">") result = (left_result>result); - else if(binary.oper==">=") + else if(oper==">=") result = (left_result>=result); - else if(binary.oper=="==") + else if(oper=="==") result = (left_result==result); - else if(binary.oper=="!=") + else if(oper=="!=") result = (left_result!=result); - else if(binary.oper=="&&") + else if(oper=="&&") result = (left_result && result); - else if(binary.oper=="||") + else if(oper=="||") result = (left_result || result); else result_valid = false; diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 842ca4f6..6b336f31 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -230,7 +230,7 @@ void VariableResolver::visit(MemberAccess &memacc) void VariableResolver::visit(BinaryExpression &binary) { - if(binary.oper=="[") + if(binary.oper->token[0]=='[') { { SetForScope set(record_target, false); @@ -261,7 +261,7 @@ void VariableResolver::visit(Assignment &assign) self_referencing = false; assign.right->visit(*this); - assign.self_referencing = (self_referencing || assign.oper!="="); + assign.self_referencing = (self_referencing || assign.oper->token[0]!='='); assign.target_declaration = assignment_target; } @@ -460,7 +460,7 @@ ExpressionStatement &InterfaceGenerator::insert_assignment(const string &left, E VariableReference *ref = new VariableReference; ref->name = left; assign->left = ref; - assign->oper = "="; + assign->oper = &Operator::get_operator("=", Operator::BINARY); assign->right = right; ExpressionStatement *stmt = new ExpressionStatement; @@ -622,9 +622,8 @@ void InterfaceGenerator::visit(Passthrough &pass) BinaryExpression *subscript = new BinaryExpression; subscript->left = ref; - subscript->oper = "["; + subscript->oper = &Operator::get_operator("[", Operator::BINARY); subscript->right = pass.subscript; - subscript->after = "]"; MemberAccess *memacc = new MemberAccess; memacc->left = subscript; @@ -644,9 +643,8 @@ void InterfaceGenerator::visit(Passthrough &pass) { BinaryExpression *subscript = new BinaryExpression; subscript->left = ref; - subscript->oper = "["; + subscript->oper = &Operator::get_operator("[", Operator::BINARY); subscript->right = pass.subscript; - subscript->after = "]"; insert_assignment(out_name, subscript); } else diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index d26c6e2d..8cbf24e1 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -305,7 +305,7 @@ void ConstantConditionEliminator::visit(Block &block) void ConstantConditionEliminator::visit(UnaryExpression &unary) { if(VariableReference *var = dynamic_cast(unary.expression.get())) - if(unary.oper=="++" || unary.oper=="--") + if(unary.oper->token[1]=='+' || unary.oper->token[1]=='-') variable_values.erase(var->declaration); } @@ -441,13 +441,13 @@ void UnusedVariableRemover::visit(MemberAccess &memacc) void UnusedVariableRemover::visit(UnaryExpression &unary) { TraversingVisitor::visit(unary); - if(unary.oper=="++" || unary.oper=="--") + if(unary.oper->token[1]=='+' || unary.oper->token[1]=='-') side_effects = true; } void UnusedVariableRemover::visit(BinaryExpression &binary) { - if(binary.oper=="[") + if(binary.oper->token[0]=='[') { if(assignment_target) assign_to_subscript = true; diff --git a/source/glsl/output.cpp b/source/glsl/output.cpp index 81f33573..7d502739 100644 --- a/source/glsl/output.cpp +++ b/source/glsl/output.cpp @@ -112,25 +112,26 @@ void Formatter::visit(MemberAccess &memacc) void Formatter::visit(UnaryExpression &unary) { - if(unary.prefix) - append(unary.oper); + if(unary.oper->type==Operator::PREFIX) + append(unary.oper->token); unary.expression->visit(*this); - if(!unary.prefix) - append(unary.oper); + if(unary.oper->type==Operator::POSTFIX) + append(unary.oper->token); } void Formatter::visit(BinaryExpression &binary) { binary.left->visit(*this); - append(binary.oper); + append(binary.oper->token); binary.right->visit(*this); - append(binary.after); + if(binary.oper->token[0]=='[') + append(']'); } void Formatter::visit(Assignment &assign) { assign.left->visit(*this); - append(format(" %s ", assign.oper)); + append(format(" %s ", assign.oper->token)); assign.right->visit(*this); } diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index 1f0d7124..c6f3f5be 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -456,6 +456,7 @@ RefPtr Parser::parse_expression(unsigned precedence) { RefPtr memacc = new MemberAccess; memacc->left = left; + memacc->oper = oper; tokenizer.parse_token(); memacc->member = expect_identifier(); left = memacc; @@ -463,13 +464,13 @@ RefPtr Parser::parse_expression(unsigned precedence) else if(oper && oper->type==Operator::POSTFIX) { RefPtr unary = new UnaryExpression; - unary->oper = tokenizer.parse_token(); - unary->prefix = false; + unary->oper = oper; + tokenizer.parse_token(); unary->expression = left; left = unary; } else if(oper && oper->type==Operator::BINARY) - left = parse_binary(left, oper); + left = parse_binary(left, *oper); else throw parse_error(tokenizer.get_location(), token, "an operator"); left_var = 0; @@ -500,8 +501,8 @@ RefPtr Parser::parse_expression(unsigned precedence) else if(oper && oper->type==Operator::PREFIX) { RefPtr unary = new UnaryExpression; - unary->oper = tokenizer.parse_token(); - unary->prefix = true; + unary->oper = oper; + tokenizer.parse_token(); unary->expression = parse_expression(oper->precedence); left = unary; } @@ -511,19 +512,19 @@ RefPtr Parser::parse_expression(unsigned precedence) } } -RefPtr Parser::parse_binary(const RefPtr &left, const Operator *oper) +RefPtr Parser::parse_binary(const RefPtr &left, const Operator &oper) { - RefPtr binary = (oper->precedence==16 ? new Assignment : new BinaryExpression); + RefPtr binary = (oper.precedence==16 ? new Assignment : new BinaryExpression); binary->left = left; - binary->oper = tokenizer.parse_token(); - if(binary->oper=="[") + binary->oper = &oper; + tokenizer.expect(oper.token); + if(oper.token[0]=='[') { binary->right = parse_expression(); tokenizer.expect("]"); - binary->after = "]"; } else - binary->right = parse_expression(oper->precedence+(oper->assoc==Operator::RIGHT_TO_LEFT)); + binary->right = parse_expression(oper.precedence+(oper.assoc==Operator::RIGHT_TO_LEFT)); return binary; } @@ -532,6 +533,7 @@ RefPtr Parser::parse_function_call(const VariableReference &var) RefPtr call = new FunctionCall; call->name = var.name; call->constructor = is_type(call->name); + call->oper = &Operator::get_operator("(", Operator::POSTFIX); tokenizer.expect("("); while(tokenizer.peek_token()!=")") { diff --git a/source/glsl/parser.h b/source/glsl/parser.h index bce9698f..376ccc6c 100644 --- a/source/glsl/parser.h +++ b/source/glsl/parser.h @@ -70,7 +70,7 @@ private: template void parse_block(Block &, bool, RefPtr (Parser::*)()); RefPtr parse_expression(unsigned = 0); - RefPtr parse_binary(const RefPtr &, const Operator *); + RefPtr parse_binary(const RefPtr &, const Operator &); RefPtr parse_function_call(const VariableReference &); RefPtr parse_struct_declaration(); RefPtr parse_variable_declaration(); diff --git a/source/glsl/syntax.cpp b/source/glsl/syntax.cpp index 90e26c39..c60b33bf 100644 --- a/source/glsl/syntax.cpp +++ b/source/glsl/syntax.cpp @@ -1,3 +1,4 @@ +#include #include "syntax.h" #include "visitor.h" @@ -10,7 +11,7 @@ namespace SL { const Operator Operator::operators[] = { { "[", 2, BINARY, LEFT_TO_RIGHT }, - { "(", 2, BINARY, LEFT_TO_RIGHT }, + { "(", 2, POSTFIX, LEFT_TO_RIGHT }, { ".", 2, BINARY, LEFT_TO_RIGHT }, { "++", 2, POSTFIX, LEFT_TO_RIGHT }, { "--", 2, POSTFIX, LEFT_TO_RIGHT }, @@ -56,6 +57,14 @@ const Operator Operator::operators[] = { { 0 }, 18, NO_OPERATOR, LEFT_TO_RIGHT } }; +const Operator &Operator::get_operator(const string &token, Type type) +{ + for(const Operator *i=operators; i->type; ++i) + if(i->type==type && i->token==token) + return *i; + throw key_error(token); +} + template NodeContainer::NodeContainer(const NodeContainer &c): @@ -90,6 +99,11 @@ void Block::visit(NodeVisitor &visitor) } +Expression::Expression(): + oper(0) +{ } + + void Literal::visit(NodeVisitor &visitor) { visitor.visit(*this); @@ -151,10 +165,6 @@ void MemberAccess::visit(NodeVisitor &visitor) } -UnaryExpression::UnaryExpression(): - prefix(true) -{ } - void UnaryExpression::visit(NodeVisitor &visitor) { visitor.visit(*this); diff --git a/source/glsl/syntax.h b/source/glsl/syntax.h index e7c642ba..682a0f5a 100644 --- a/source/glsl/syntax.h +++ b/source/glsl/syntax.h @@ -39,6 +39,8 @@ struct Operator Associativity assoc; static const Operator operators[]; + + static const Operator &get_operator(const std::string &, Type); }; enum @@ -127,6 +129,10 @@ struct Block: Node struct Expression: Node { + const Operator *oper; + + Expression(); + virtual Expression *clone() const = 0; }; @@ -188,11 +194,7 @@ struct MemberAccess: Expression struct UnaryExpression: Expression { - std::string oper; NodePtr expression; - bool prefix; - - UnaryExpression(); virtual UnaryExpression *clone() const { return new UnaryExpression(*this); } virtual void visit(NodeVisitor &); @@ -201,9 +203,7 @@ struct UnaryExpression: Expression struct BinaryExpression: Expression { NodePtr left; - std::string oper; NodePtr right; - std::string after; virtual BinaryExpression *clone() const { return new BinaryExpression(*this); } virtual void visit(NodeVisitor &); -- 2.43.0