Also make it a property of Expression rather than the subtypes.
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();
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));
if(!result_valid)
return;
- if(unary.oper=="!")
+ if(unary.oper->token[0]=='!')
result = !result;
else
result_valid = false;
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;
void VariableResolver::visit(BinaryExpression &binary)
{
- if(binary.oper=="[")
+ if(binary.oper->token[0]=='[')
{
{
SetForScope<bool> set(record_target, false);
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;
}
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;
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;
{
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
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);
}
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;
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);
}
{
RefPtr<MemberAccess> memacc = new MemberAccess;
memacc->left = left;
+ memacc->oper = oper;
tokenizer.parse_token();
memacc->member = expect_identifier();
left = memacc;
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;
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;
}
}
}
-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;
}
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()!=")")
{
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();
+#include <msp/core/maputils.h>
#include "syntax.h"
#include "visitor.h"
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 },
{ { 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):
}
+Expression::Expression():
+ oper(0)
+{ }
+
+
void Literal::visit(NodeVisitor &visitor)
{
visitor.visit(*this);
}
-UnaryExpression::UnaryExpression():
- prefix(true)
-{ }
-
void UnaryExpression::visit(NodeVisitor &visitor)
{
visitor.visit(*this);
Associativity assoc;
static const Operator operators[];
+
+ static const Operator &get_operator(const std::string &, Type);
};
enum
struct Expression: Node
{
+ const Operator *oper;
+
+ Expression();
+
virtual Expression *clone() const = 0;
};
struct UnaryExpression: Expression
{
- std::string oper;
NodePtr<Expression> expression;
- bool prefix;
-
- UnaryExpression();
virtual UnaryExpression *clone() const { return new UnaryExpression(*this); }
virtual void visit(NodeVisitor &);
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 &);