Skip to content

Commit

Permalink
Improve location handling in expressions.
Browse files Browse the repository at this point in the history
  • Loading branch information
dillof committed Aug 16, 2024
1 parent 77b00e0 commit 6b88774
Show file tree
Hide file tree
Showing 45 changed files with 268 additions and 242 deletions.
1 change: 0 additions & 1 deletion src/BaseExpression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BaseExpression.h"

#include "Expression.h"
#include "ParseException.h"


std::ostream& operator<<(std::ostream& stream, const std::shared_ptr<BaseExpression>& node) {
Expand Down
2 changes: 1 addition & 1 deletion src/BaseExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Environment;
class BaseExpression {
public:
BaseExpression() = default;
explicit BaseExpression(Location location): location(location) {}
explicit BaseExpression(const Location& location): location(location) {}
virtual ~BaseExpression() = default;

[[nodiscard]] virtual bool has_value() const {return value().has_value();}
Expand Down
44 changes: 22 additions & 22 deletions src/BinaryExpression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ std::optional<Expression> BinaryExpression::evaluated(const EvaluationContext& c
return {};
}

return Expression(new_left.value_or(left), operation, new_right.value_or(right));
return Expression(location, new_left.value_or(left), operation, new_right.value_or(right));
}

void BinaryExpression::serialize_sub(std::ostream& stream) const {
Expand Down Expand Up @@ -124,7 +124,7 @@ void BinaryExpression::serialize_sub(std::ostream& stream) const {
stream << right << ')';
}

Expression BinaryExpression::create(const Expression& left, Expression::BinaryOperation operation, const Expression& right) {
Expression BinaryExpression::create(const Location& location, const Expression& left, Expression::BinaryOperation operation, const Expression& right) {
// TODO: check that types are compatible

if (left.has_value() && right.has_value()) {
Expand Down Expand Up @@ -205,7 +205,7 @@ Expression BinaryExpression::create(const Expression& left, Expression::BinaryOp
break;
}

return Expression(value);
return Expression(location, value);
}
else {
switch (operation) {
Expand All @@ -222,11 +222,11 @@ Expression BinaryExpression::create(const Expression& left, Expression::BinaryOp
auto left_right_value = *left_binary->right.value();
if (left_binary->operation == Expression::ADD) {
// (N + A) + B -> N + (A+B)
return {left_binary->left, Expression::ADD, Expression(left_right_value + right_value)};
return {location, left_binary->left, Expression::ADD, Expression({left_binary->right.location(), right.location()}, left_right_value + right_value)};
}
else if (left_binary->operation == Expression::SUBTRACT) {
// (N - A) + B -> N + (-A+B)
return {left_binary->left, Expression::ADD, Expression(-left_right_value + right_value)};
return {location, left_binary->left, Expression::ADD, Expression({left_binary->right.location(), right.location()}, -left_right_value + right_value)};
}
}
}
Expand All @@ -243,11 +243,11 @@ Expression BinaryExpression::create(const Expression& left, Expression::BinaryOp
auto right_left_value = *right_binary->left.value();
if (right_binary->operation == Expression::ADD) {
// A + (B + N) -> N + (A+B)
return {right_binary->right, Expression::ADD, Expression(left_value + right_left_value)};
return {location, right_binary->right, Expression::ADD, Expression({left.location(), right_binary->left.location()}, left_value + right_left_value)};
}
else if (right_binary->operation == Expression::SUBTRACT) {
// A + (B - N) -> (A+B) - N
return {Expression(left_value + right_left_value), Expression::SUBTRACT, right_binary->right};
return {location, Expression({left.location(), right_binary->left.location()}, left_value + right_left_value), Expression::SUBTRACT, right_binary->right};
}
}
}
Expand All @@ -257,43 +257,43 @@ Expression BinaryExpression::create(const Expression& left, Expression::BinaryOp

case Expression::BinaryOperation::EQUAL:
if (left.minimum_value() > right.maximum_value() || left.maximum_value() < right.minimum_value()) {
return Expression(false);
return Expression(location, false);
}
break;

case Expression::BinaryOperation::GREATER:
if (left.minimum_value() > right.maximum_value()) {
return Expression(true);
return Expression(location, true);
}
else if (left.maximum_value() <= right.minimum_value()) {
return Expression(false);
return Expression(location, false);
}
break;

case Expression::BinaryOperation::GREATER_EQUAL:
if (left.minimum_value() >= right.maximum_value()) {
return Expression(true);
return Expression(location, true);
}
else if (left.maximum_value() < right.minimum_value()) {
return Expression(false);
return Expression(location, false);
}
break;

case Expression::BinaryOperation::LESS:
if (left.minimum_value() >= right.maximum_value()) {
return Expression(false);
return Expression(location, false);
}
else if (left.maximum_value() < right.minimum_value()) {
return Expression(true);
return Expression(location, true);
}
break;

case Expression::BinaryOperation::LESS_EQUAL:
if (left.minimum_value() > right.maximum_value()) {
return Expression(false);
return Expression(location, false);
}
else if (left.maximum_value() <= right.minimum_value()) {
return Expression(true);
return Expression(location, true);
}
break;

Expand All @@ -319,7 +319,7 @@ Expression BinaryExpression::create(const Expression& left, Expression::BinaryOp

case Expression::BinaryOperation::NOT_EQUAL:
if (left.minimum_value() > right.maximum_value() || left.maximum_value() < right.minimum_value()) {
return Expression(true);
return Expression(location, true);
}
break;

Expand All @@ -338,7 +338,7 @@ Expression BinaryExpression::create(const Expression& left, Expression::BinaryOp
}
if (left.has_value() && left.value() == Value(uint64_t{0})) {
// 0 - N -> -N
return {Expression::UnaryOperation::MINUS, right};
return {location, Expression::UnaryOperation::MINUS, right};
}
// This special case is for resolving relative addressing within an object.
if (left.is_binary() && right.is_binary()) {
Expand All @@ -351,7 +351,7 @@ Expression BinaryExpression::create(const Expression& left, Expression::BinaryOp
auto left_variable = left_binary->left.variable_name();
auto right_variable = right_binary->left.variable_name();
if ((!left_variable.empty() && left_variable == right_variable) || (left_binary->left.is_object_name() && right_binary->left.is_object_name())) {
return {left_binary->right, operation, right_binary->right};
return {location, left_binary->right, operation, right_binary->right};
}

}
Expand All @@ -364,7 +364,7 @@ Expression BinaryExpression::create(const Expression& left, Expression::BinaryOp
if (!left_variable.empty() && right_binary->operation == Expression::BinaryOperation::ADD) {
auto right_variabel = right_binary->left.variable_name();
if (left_variable == right_variabel) {
return {Expression::UnaryOperation::MINUS, right_binary->right};
return {location, Expression::UnaryOperation::MINUS, right_binary->right};
}
}
}
Expand All @@ -385,7 +385,7 @@ Expression BinaryExpression::create(const Expression& left, Expression::BinaryOp
auto left_variable = left.variable_name();
auto right_variable = right.variable_name();
if (!left_variable.empty() && left_variable == right_variable) {
return Expression(uint64_t{0});
return Expression(location, uint64_t{0});
}
}
break;
Expand Down Expand Up @@ -440,7 +440,7 @@ Expression BinaryExpression::create(const Expression& left, Expression::BinaryOp
break;
}
}
return Expression(std::make_shared<BinaryExpression>(left, operation, right));
return Expression(std::make_shared<BinaryExpression>(location, left, operation, right));
}

std::optional<Value> BinaryExpression::minimum_value() const {
Expand Down
6 changes: 3 additions & 3 deletions src/BinaryExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

class BinaryExpression: public BaseExpression {
public:
BinaryExpression(Expression left, Expression::BinaryOperation operation, Expression right): left(std::move(left)), operation(operation), right(std::move(right)) {}
BinaryExpression(const Location& location, Expression left, Expression::BinaryOperation operation, Expression right): BaseExpression(location), left(std::move(left)), operation(operation), right(std::move(right)) {}

[[nodiscard]] std::optional<Value> minimum_value() const override;
[[nodiscard]] std::optional<Value> maximum_value() const override;
Expand All @@ -48,16 +48,16 @@ class BinaryExpression: public BaseExpression {
right.collect_objects(objects);}

protected:
[[nodiscard]] Expression static create(const Expression& left, Expression::BinaryOperation operation, const Expression& right);
[[nodiscard]] Expression static create(const Location& location, const Expression& left, Expression::BinaryOperation operation, const Expression& right);
[[nodiscard]] std::optional<Expression> evaluated(const EvaluationContext& context) const override;

void serialize_sub(std::ostream& stream) const override;

friend class Expression;

private:
Expression::BinaryOperation operation;
Expression left;
Expression::BinaryOperation operation;
Expression right;
};

Expand Down
15 changes: 7 additions & 8 deletions src/BodyParser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ObjectNameExpression.h"
#include "ParseException.h"
#include "TokenNode.h"
#include <complex>

const Symbol BodyParser::symbol_pc = Symbol(".pc");
const Token BodyParser::token_binary_file = Token(Token::DIRECTIVE, "binary_file");
Expand Down Expand Up @@ -89,8 +88,7 @@ Body BodyParser::parse() {
throw ParseException(token, "unclosed symbol body");

case Token::DIRECTIVE: {
auto visibility = VisibilityHelper::from_token(token);
if (visibility) {
if (auto visibility = VisibilityHelper::from_token(token)) {
handle_name(*visibility, tokenizer.expect(Token::NAME, TokenGroup::newline));
break;
}
Expand Down Expand Up @@ -198,8 +196,9 @@ Symbol BodyParser::get_label(bool& is_anonymous) {
}

Expression BodyParser::get_pc(Symbol label) const {
auto label_expression = label ? Expression(Location(), nullptr, label) : Expression({}, LabelExpressionType::PREVIOUS_UNNAMED);
return {ObjectNameExpression::create(nullptr), Expression::BinaryOperation::ADD, label_expression};
// TODO: location
auto label_expression = label ? Expression(tokenizer.current_location(), nullptr, label) : Expression(tokenizer.current_location(), LabelExpressionType::PREVIOUS_UNNAMED);
return {tokenizer.current_location(), ObjectNameExpression::create(tokenizer.current_location(), nullptr), Expression::BinaryOperation::ADD, label_expression};
}

void BodyParser::parse_directive(const Token& directive) {
Expand All @@ -225,7 +224,7 @@ void BodyParser::parse_else() {
throw Exception(".else outside .if");
}
pop_body();
push_clause(Expression(Value(true)));
push_clause(Expression(tokenizer.current_location(), true));
tokenizer.expect(Token::curly_open);
}

Expand Down Expand Up @@ -275,7 +274,7 @@ void BodyParser::parse_label(Visibility visibility, const Token& name) {

void BodyParser::parse_memory() {
auto expression_parser = ExpressionParser(tokenizer);
auto bank = Expression(uint64_t{0});
auto bank = Expression({}, uint64_t{0});
auto start_address = expression_parser.parse();
tokenizer.expect(Token::comma);
auto end_address = expression_parser.parse();
Expand Down Expand Up @@ -582,7 +581,7 @@ void BodyParser::parse_binary_file() {
else if (start > 0) {
data = data.substr(*start);
}
auto elements = std::vector<DataBodyElement>{DataBodyElement{Expression{Value{data}}, {}}};
auto elements = std::vector<DataBodyElement>{DataBodyElement{Expression{filename.location, Value(data)}, {}}};
current_body->append(Body(elements));
}
else {
Expand Down
11 changes: 6 additions & 5 deletions src/DefinedExpression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,26 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ParseException.h"
#include "VariableExpression.h"

Expression DefinedExpression::create(const std::vector<Expression>& arguments) {
Expression DefinedExpression::create(const Location& location, const std::vector<Expression>& arguments) {
if (arguments.size() != 1) {
throw ParseException(Location(), "invalid number of arguments");
throw ParseException(location, "invalid number of arguments");
}
auto& argument = arguments[0];

if (!argument.is_variable()) {
throw ParseException(argument.location(), "symbol argument required");
}

return Expression(std::make_shared<DefinedExpression>(argument.as_variable()->variable()));
return Expression(std::make_shared<DefinedExpression>(location, argument.as_variable()->variable()));
}


std::optional<Expression> DefinedExpression::evaluated(const EvaluationContext& context) const {
if (context.defines.contains(symbol)) {
return Expression(true);
return Expression(location, true);
}
else {
return Expression(false);
return Expression(location, false);
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/DefinedExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

class DefinedExpression: public BaseExpression {
public:
explicit DefinedExpression(Symbol symbol): symbol{symbol} {}
explicit DefinedExpression(const Location& location, Symbol symbol): BaseExpression(location), symbol{symbol} {}

static Expression create(const std::vector<Expression>& arguments);
static Expression create(const Location& location, const std::vector<Expression>& arguments);

[[nodiscard]] std::optional<Expression> evaluated(const EvaluationContext& context) const override;
[[nodiscard]] std::optional<Value::Type> type() const override {return Value::BOOLEAN;}
Expand All @@ -50,6 +50,4 @@ class DefinedExpression: public BaseExpression {
Symbol symbol;
};



#endif //DEFINEDEXPRESSIN_H
11 changes: 6 additions & 5 deletions src/ExistsExpression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,23 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ParseException.h"
#include "VariableExpression.h"

Expression ExistsExpression::create(const std::vector<Expression>& arguments) {
Expression ExistsExpression::create(const Location& location, const std::vector<Expression>& arguments) {
if (arguments.size() != 1) {
throw ParseException(Location(), "invalid number of arguments");
throw ParseException(location, "invalid number of arguments");
}
auto& argument = arguments[0];

if (!argument.is_variable()) {
throw ParseException(argument.location(), "symbol argument required");
throw ParseException(location, "symbol argument required");
}

return Expression(std::make_shared<ExistsExpression>(argument.as_variable()->variable()));
return Expression(std::make_shared<ExistsExpression>(location, argument.as_variable()->variable()));
}


std::optional<Expression> ExistsExpression::evaluated(const EvaluationContext& context) const {
// TODO: evaluate in resolve phase.
return Expression(false);
return Expression(location, false);
}

void ExistsExpression::serialize_sub(std::ostream& stream) const {
Expand Down
4 changes: 2 additions & 2 deletions src/ExistsExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

class ExistsExpression : public BaseExpression {
public:
explicit ExistsExpression(Symbol symbol): symbol{symbol} {}
explicit ExistsExpression(const Location& location, Symbol symbol): BaseExpression(location), symbol{symbol} {}

static Expression create(const std::vector<Expression>& arguments);
static Expression create(const Location& location, const std::vector<Expression>& arguments);

[[nodiscard]] std::optional<Expression> evaluated(const EvaluationContext& context) const override;
[[nodiscard]] std::optional<Value::Type> type() const override {return Value::BOOLEAN;}
Expand Down
Loading

0 comments on commit 6b88774

Please sign in to comment.