]> git.tdb.fi Git - libs/gl.git/commitdiff
Store a pointer to operator info rather than the token in expressions
authorMikko Rasa <tdb@tdb.fi>
Wed, 3 Mar 2021 09:28:14 +0000 (11:28 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 3 Mar 2021 15:28:20 +0000 (17:28 +0200)
Also make it a property of Expression rather than the subtypes.

source/glsl/debug.cpp
source/glsl/evaluate.cpp
source/glsl/generate.cpp
source/glsl/optimize.cpp
source/glsl/output.cpp
source/glsl/parser.cpp
source/glsl/parser.h
source/glsl/syntax.cpp
source/glsl/syntax.h

index 5397372e611bd7108c3e3da0fc254e4bc9a575b4..04d7aac8ca2c442755efcc1c376f103e6fd3220d 100644 (file)
@@ -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));
index 4bbdb2f60f436528b733905d604bad4100780497..915b2a6fe2cce1a6f8dcc4cd275029f1225ba6a2 100644 (file)
@@ -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<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 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;
index 842ca4f6cdd5ab1f68bb47b3bb657490b9bb9d6a..6b336f3179de690b2967cd85fe5da0cafff130ab 100644 (file)
@@ -230,7 +230,7 @@ void VariableResolver::visit(MemberAccess &memacc)
 
 void VariableResolver::visit(BinaryExpression &binary)
 {
-       if(binary.oper=="[")
+       if(binary.oper->token[0]=='[')
        {
                {
                        SetForScope<bool> 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
index d26c6e2d519179ac531dd2a635c85e605d98e9e8..8cbf24e1be0309a2c8304051cc185d9316836974 100644 (file)
@@ -305,7 +305,7 @@ void ConstantConditionEliminator::visit(Block &block)
 void ConstantConditionEliminator::visit(UnaryExpression &unary)
 {
        if(VariableReference *var = dynamic_cast<VariableReference *>(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;
index 81f335735e80eb433fd746ae85216dc59b309e83..7d502739903a6cd8708cfc758aac470cad2fa17f 100644 (file)
@@ -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);
 }
 
index 1f0d712467f3b43c2d9990dfa277bb1c46d0ff42..c6f3f5be3cdd186818cbee6322ad966dff46181d 100644 (file)
@@ -456,6 +456,7 @@ RefPtr<Expression> Parser::parse_expression(unsigned precedence)
                        {
                                RefPtr<MemberAccess> memacc = new MemberAccess;
                                memacc->left = left;
+                               memacc->oper = oper;
                                tokenizer.parse_token();
                                memacc->member = expect_identifier();
                                left = memacc;
@@ -463,13 +464,13 @@ RefPtr<Expression> Parser::parse_expression(unsigned precedence)
                        else if(oper && oper->type==Operator::POSTFIX)
                        {
                                RefPtr<UnaryExpression> 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<Expression> Parser::parse_expression(unsigned precedence)
                        else if(oper && oper->type==Operator::PREFIX)
                        {
                                RefPtr<UnaryExpression> 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<Expression> Parser::parse_expression(unsigned precedence)
        }
 }
 
-RefPtr<BinaryExpression> Parser::parse_binary(const RefPtr<Expression> &left, const Operator *oper)
+RefPtr<BinaryExpression> Parser::parse_binary(const RefPtr<Expression> &left, const Operator &oper)
 {
-       RefPtr<BinaryExpression> binary = (oper->precedence==16 ? new Assignment : new BinaryExpression);
+       RefPtr<BinaryExpression> 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<FunctionCall> Parser::parse_function_call(const VariableReference &var)
        RefPtr<FunctionCall> 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()!=")")
        {
index bce9698f7d608a4b3c18417bf2eef1d149f54a81..376ccc6cd77fa996d02aeff1aa0baf59aea6167b 100644 (file)
@@ -70,7 +70,7 @@ private:
        template<typename T>
        void parse_block(Block &, bool, RefPtr<T> (Parser::*)());
        RefPtr<Expression> parse_expression(unsigned = 0);
-       RefPtr<BinaryExpression> parse_binary(const RefPtr<Expression> &, const Operator *);
+       RefPtr<BinaryExpression> parse_binary(const RefPtr<Expression> &, const Operator &);
        RefPtr<FunctionCall> parse_function_call(const VariableReference &);
        RefPtr<StructDeclaration> parse_struct_declaration();
        RefPtr<VariableDeclaration> parse_variable_declaration();
index 90e26c39a37c24d663dc8846bb172f65007ec694..c60b33bf5bad26b86d2b0abc53b7ba442b451ce2 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/core/maputils.h>
 #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<typename C>
 NodeContainer<C>::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);
index e7c642ba4abe0c9f4b2d8b91b065a85e499f0362..682a0f5aeeaa2246b01226df25536a23a91d9c7a 100644 (file)
@@ -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> 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<Expression> left;
-       std::string oper;
        NodePtr<Expression> right;
-       std::string after;
 
        virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
        virtual void visit(NodeVisitor &);