elna/source/ast.cc

1024 lines
24 KiB
C++
Raw Permalink Normal View History

2024-12-27 10:51:46 +01:00
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
2024-12-23 13:54:11 +01:00
#include "elna/source/ast.h"
2024-12-21 00:08:48 +01:00
2024-12-23 13:54:11 +01:00
namespace elna
{
namespace source
2024-12-21 00:08:48 +01:00
{
2025-01-11 13:32:37 +01:00
void empty_visitor::visit(variable_declaration *)
2024-12-21 00:08:48 +01:00
{
}
void empty_visitor::visit(constant_definition *definition)
{
definition->body().accept(this);
}
void empty_visitor::visit(procedure_definition *definition)
{
2025-01-16 15:09:58 +01:00
for (auto parameter : definition->parameters)
2024-12-21 00:08:48 +01:00
{
parameter->accept(this);
}
2025-01-16 15:09:58 +01:00
if (definition->body() != nullptr)
{
definition->body()->accept(this);
}
2024-12-21 00:08:48 +01:00
}
2025-01-07 14:37:30 +01:00
void empty_visitor::visit(type_definition *definition)
{
definition->body().accept(this);
}
2025-01-18 21:30:11 +01:00
void empty_visitor::visit(call_expression *statement)
2024-12-21 00:08:48 +01:00
{
for (auto& argument : statement->arguments())
{
argument->accept(this);
}
}
2025-01-18 21:30:11 +01:00
void empty_visitor::visit(expression_statement *statement)
{
statement->body().accept(this);
}
2024-12-21 00:08:48 +01:00
void empty_visitor::visit(compound_statement *statement)
{
for (const auto nested_statement : statement->statements)
2024-12-21 00:08:48 +01:00
{
nested_statement->accept(this);
}
}
void empty_visitor::visit(assign_statement *statement)
{
statement->rvalue().accept(this);
}
void empty_visitor::visit(if_statement *statement)
{
statement->prerequisite().accept(this);
statement->body().accept(this);
}
void empty_visitor::visit(while_statement *statement)
{
statement->prerequisite().accept(this);
statement->body().accept(this);
}
2025-01-18 21:30:11 +01:00
void empty_visitor::visit(return_statement *statement)
{
expression *return_expression = statement->return_expression();
if (return_expression != nullptr)
{
return_expression->accept(this);
}
}
2024-12-21 00:08:48 +01:00
void empty_visitor::visit(block *block)
{
2025-01-16 15:09:58 +01:00
for (const auto definition : block->value_definitions)
2024-12-21 00:08:48 +01:00
{
2025-01-11 13:32:37 +01:00
definition->accept(this);
2024-12-21 00:08:48 +01:00
}
2025-01-16 15:09:58 +01:00
for (const auto body_statement : block->body)
{
body_statement->accept(this);
}
2024-12-21 00:08:48 +01:00
}
void empty_visitor::visit(program *program)
{
for (auto definition : program->type_definitions)
{
definition->accept(this);
}
2024-12-23 13:54:11 +01:00
visit(reinterpret_cast<block *>(program));
2024-12-21 00:08:48 +01:00
}
void empty_visitor::visit(binary_expression *expression)
{
expression->lhs().accept(this);
expression->rhs().accept(this);
}
void empty_visitor::visit(unary_expression *expression)
{
expression->operand().accept(this);
}
2025-01-05 00:06:51 +01:00
void empty_visitor::visit(basic_type_expression *)
2024-12-21 00:08:48 +01:00
{
}
2025-01-07 14:37:30 +01:00
void empty_visitor::visit(array_type_expression *expression)
2025-01-06 15:08:23 +01:00
{
2025-01-07 14:37:30 +01:00
expression->base().accept(this);
2025-01-06 15:08:23 +01:00
}
2025-01-08 23:23:27 +01:00
void empty_visitor::visit(pointer_type_expression *expression)
{
expression->base().accept(this);
}
void empty_visitor::visit(record_type_expression *expression)
{
for (auto& field : expression->fields)
{
field.second->accept(this);
}
}
void empty_visitor::visit(union_type_expression *expression)
{
for (auto& field : expression->fields)
2025-01-08 23:23:27 +01:00
{
field.second->accept(this);
}
}
2025-01-03 22:18:35 +01:00
void empty_visitor::visit(variable_expression *)
2024-12-21 00:08:48 +01:00
{
}
2025-01-07 14:37:30 +01:00
void empty_visitor::visit(array_access_expression *expression)
{
expression->base().accept(this);
expression->index().accept(this);
}
2025-01-08 23:23:27 +01:00
void empty_visitor::visit(field_access_expression *expression)
{
expression->base().accept(this);
}
void empty_visitor::visit(dereference_expression *expression)
{
expression->base().accept(this);
}
2025-01-03 22:18:35 +01:00
void empty_visitor::visit(number_literal<std::int32_t> *)
2024-12-31 18:10:34 +01:00
{
}
2025-01-03 22:18:35 +01:00
void empty_visitor::visit(number_literal<double> *)
2024-12-21 00:08:48 +01:00
{
}
2025-01-03 22:18:35 +01:00
void empty_visitor::visit(number_literal<bool> *)
2025-01-01 23:02:19 +01:00
{
}
2025-01-15 01:48:09 +01:00
void empty_visitor::visit(number_literal<unsigned char> *)
2025-01-03 22:18:35 +01:00
{
}
void empty_visitor::visit(string_literal *)
2024-12-21 00:08:48 +01:00
{
}
2025-01-06 15:08:23 +01:00
operand::~operand()
2024-12-21 00:08:48 +01:00
{
}
integer_operand::integer_operand(const std::int32_t value)
: m_value(value)
{
}
2025-01-06 15:08:23 +01:00
std::int32_t integer_operand::value() const
2024-12-21 00:08:48 +01:00
{
return m_value;
}
variable_operand::variable_operand(const std::string& name)
: m_name(name)
{
}
2025-01-06 15:08:23 +01:00
const std::string& variable_operand::name() const
2024-12-21 00:08:48 +01:00
{
return m_name;
}
temporary_variable::temporary_variable(const std::size_t counter)
: m_counter(counter)
{
}
2025-01-06 15:08:23 +01:00
std::size_t temporary_variable::counter() const
2024-12-21 00:08:48 +01:00
{
return m_counter;
}
label_operand::label_operand(const std::size_t counter)
: m_counter(counter)
{
}
2025-01-06 15:08:23 +01:00
std::size_t label_operand::counter() const
2024-12-21 00:08:48 +01:00
{
return m_counter;
}
node::node(const struct position position)
: source_position(position)
{
}
2025-01-06 15:08:23 +01:00
const struct position& node::position() const
2024-12-21 00:08:48 +01:00
{
return this->source_position;
}
statement::statement(const struct position position)
: node(position)
{
}
expression::expression(const struct position position)
: node(position)
{
}
2025-01-05 00:06:51 +01:00
type_expression::type_expression(const struct position position)
: node(position)
{
}
basic_type_expression *type_expression::is_basic()
{
return nullptr;
}
2025-01-06 15:08:23 +01:00
array_type_expression *type_expression::is_array()
{
return nullptr;
}
2025-01-08 23:23:27 +01:00
record_type_expression *type_expression::is_record()
{
return nullptr;
}
union_type_expression *type_expression::is_union()
{
return nullptr;
}
2025-01-08 23:23:27 +01:00
pointer_type_expression *type_expression::is_pointer()
{
return nullptr;
}
2025-01-05 00:06:51 +01:00
basic_type_expression::basic_type_expression(
const struct position position, const std::string& name)
2025-01-06 15:08:23 +01:00
: type_expression(position), m_name(name)
2024-12-21 00:08:48 +01:00
{
}
2025-01-05 00:06:51 +01:00
void basic_type_expression::accept(parser_visitor *visitor)
2024-12-21 00:08:48 +01:00
{
visitor->visit(this);
}
2025-01-06 15:08:23 +01:00
const std::string& basic_type_expression::base_name()
2024-12-21 00:08:48 +01:00
{
2025-01-06 15:08:23 +01:00
return m_name;
2024-12-21 00:08:48 +01:00
}
2025-01-05 00:06:51 +01:00
basic_type_expression *basic_type_expression::is_basic()
2024-12-21 00:08:48 +01:00
{
2025-01-05 00:06:51 +01:00
return this;
2024-12-21 00:08:48 +01:00
}
2025-01-06 15:08:23 +01:00
array_type_expression::array_type_expression(const struct position position, type_expression *base,
const std::uint32_t size)
: type_expression(position), m_base(base), size(size)
{
}
void array_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
type_expression& array_type_expression::base()
{
return *m_base;
}
array_type_expression *array_type_expression::is_array()
{
return this;
}
array_type_expression::~array_type_expression()
{
delete m_base;
}
2025-01-08 23:23:27 +01:00
pointer_type_expression::pointer_type_expression(const struct position position, type_expression *base)
: type_expression(position), m_base(base)
{
}
void pointer_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
type_expression& pointer_type_expression::base()
{
return *m_base;
}
pointer_type_expression *pointer_type_expression::is_pointer()
{
return this;
}
pointer_type_expression::~pointer_type_expression()
{
delete m_base;
}
composite_type_expression::composite_type_expression(const struct position position,
fields_t&& fields)
: type_expression(position), fields(std::move(fields))
{
}
composite_type_expression::~composite_type_expression()
{
for (auto& field_declaration : fields)
{
delete field_declaration.second;
}
}
2025-01-08 23:23:27 +01:00
record_type_expression::record_type_expression(const struct position position,
fields_t&& fields)
: composite_type_expression(position, std::move(fields))
2025-01-08 23:23:27 +01:00
{
}
void record_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
record_type_expression *record_type_expression::is_record()
2025-01-08 23:23:27 +01:00
{
return this;
2025-01-08 23:23:27 +01:00
}
union_type_expression::union_type_expression(const struct position position,
fields_t&& fields)
: composite_type_expression(position, std::move(fields))
{
}
union_type_expression *union_type_expression::is_union()
2025-01-08 23:23:27 +01:00
{
return this;
}
void union_type_expression::accept(parser_visitor *visitor)
2025-01-10 23:17:18 +01:00
{
visitor->visit(this);
2025-01-10 23:17:18 +01:00
}
2025-01-11 13:32:37 +01:00
variable_declaration::variable_declaration(const struct position position, const std::string& identifier,
type_expression *type)
: definition(position, identifier), m_type(type)
2024-12-21 00:08:48 +01:00
{
}
2025-01-11 13:32:37 +01:00
variable_declaration::~variable_declaration()
{
delete m_type;
}
2025-01-11 13:32:37 +01:00
void variable_declaration::accept(parser_visitor *visitor)
2024-12-21 00:08:48 +01:00
{
visitor->visit(this);
}
2025-01-11 13:32:37 +01:00
type_expression& variable_declaration::type()
2024-12-21 00:08:48 +01:00
{
return *m_type;
}
definition::definition(const struct position position, const std::string& identifier)
: node(position), m_identifier(identifier)
{
}
2025-01-06 15:08:23 +01:00
std::string& definition::identifier()
2024-12-21 00:08:48 +01:00
{
return m_identifier;
}
constant_definition::constant_definition(const struct position position, const std::string& identifier,
2025-01-15 01:48:09 +01:00
literal *body)
: definition(position, identifier), m_body(body)
2024-12-21 00:08:48 +01:00
{
}
void constant_definition::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
2025-01-15 01:48:09 +01:00
literal& constant_definition::body()
2024-12-21 00:08:48 +01:00
{
return *m_body;
}
constant_definition::~constant_definition()
{
delete m_body;
}
2024-12-21 00:08:48 +01:00
procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
2025-01-18 21:30:11 +01:00
std::vector<variable_declaration *>&& parameters, type_expression *return_type, block *body)
: definition(position, identifier), m_return_type(return_type), m_body(body), parameters(std::move(parameters))
2024-12-21 00:08:48 +01:00
{
}
void procedure_definition::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
2025-01-16 15:09:58 +01:00
block *procedure_definition::body()
2024-12-21 00:08:48 +01:00
{
2025-01-16 15:09:58 +01:00
return m_body;
2024-12-21 00:08:48 +01:00
}
2025-01-18 21:30:11 +01:00
type_expression *procedure_definition::return_type()
{
return m_return_type;
}
procedure_definition::~procedure_definition()
{
2025-01-16 15:09:58 +01:00
if (m_body != nullptr)
{
delete m_body;
}
for (auto parameter : parameters)
{
delete parameter;
}
}
2025-01-07 14:37:30 +01:00
type_definition::type_definition(const struct position position, const std::string& identifier,
type_expression *body)
: definition(position, identifier), m_body(body)
{
}
void type_definition::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
type_expression& type_definition::body()
{
return *m_body;
}
type_definition::~type_definition()
{
delete m_body;
}
block::block(const struct position position, std::vector<definition *>&& value_definitions,
2025-01-16 15:09:58 +01:00
std::vector<statement *>&& body)
: node(position), value_definitions(std::move(value_definitions)), body(std::move(body))
2024-12-21 00:08:48 +01:00
{
}
void block::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
block::~block()
{
2025-01-16 15:09:58 +01:00
for (auto definition : this->value_definitions)
{
2025-01-11 13:32:37 +01:00
delete definition;
}
2025-01-16 15:09:58 +01:00
for (auto body_statement : this->body)
{
delete body_statement;
}
}
program::program(const struct position position,
std::vector<definition *>&& type_definitions,
2025-01-16 15:09:58 +01:00
std::vector<definition *>&& value_definitions, std::vector<statement *>&& body)
: block(position, std::move(value_definitions), std::move(body)),
type_definitions(std::move(type_definitions))
2024-12-21 00:08:48 +01:00
{
}
void program::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
program::~program()
{
for (auto definition : type_definitions)
{
delete definition;
}
}
2025-01-15 01:48:09 +01:00
literal::literal(const struct position position)
: expression(position)
2024-12-21 00:08:48 +01:00
{
}
2025-01-03 22:18:35 +01:00
string_literal::string_literal(const struct position position, const std::string& value)
2025-01-15 01:48:09 +01:00
: literal(position), m_string(value)
2025-01-03 22:18:35 +01:00
{
}
void string_literal::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
2025-01-06 15:08:23 +01:00
const std::string& string_literal::string() const
2025-01-03 22:18:35 +01:00
{
return m_string;
}
2025-01-07 14:37:30 +01:00
designator_expression::designator_expression(const struct position position)
: expression(position)
{
}
2024-12-21 00:08:48 +01:00
variable_expression::variable_expression(const struct position position, const std::string& name)
2025-01-07 14:37:30 +01:00
: designator_expression(position), m_name(name)
2024-12-21 00:08:48 +01:00
{
}
void variable_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
2025-01-06 15:08:23 +01:00
const std::string& variable_expression::name() const
2024-12-21 00:08:48 +01:00
{
return m_name;
}
2025-01-07 14:37:30 +01:00
variable_expression *variable_expression::is_variable()
{
return this;
}
array_access_expression::array_access_expression(const struct position position,
designator_expression *base, expression *index)
: designator_expression(position), m_base(base), m_index(index)
{
}
void array_access_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
expression& array_access_expression::index()
{
return *m_index;
}
designator_expression& array_access_expression::base()
{
return *m_base;
}
array_access_expression *array_access_expression::is_array_access()
{
return this;
}
array_access_expression::~array_access_expression()
{
delete m_base;
}
2025-01-08 23:23:27 +01:00
field_access_expression::field_access_expression(const struct position position,
designator_expression *base, const std::string& field)
: designator_expression(position), m_base(base), m_field(field)
{
}
void field_access_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
designator_expression& field_access_expression::base()
{
return *m_base;
}
std::string& field_access_expression::field()
{
return m_field;
}
field_access_expression *field_access_expression::is_field_access()
{
return this;
}
field_access_expression::~field_access_expression()
{
delete m_base;
}
dereference_expression::dereference_expression(const struct position position,
designator_expression *base)
: designator_expression(position), m_base(base)
{
}
void dereference_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
designator_expression& dereference_expression::base()
{
return *m_base;
}
dereference_expression *dereference_expression::is_dereference()
{
return this;
}
dereference_expression::~dereference_expression()
{
delete m_base;
}
binary_expression::binary_expression(const struct position position, expression *lhs,
expression *rhs, const unsigned char operation)
2024-12-21 00:08:48 +01:00
: expression(position), m_lhs(std::move(lhs)), m_rhs(std::move(rhs))
{
switch (operation)
{
case '+':
this->m_operator = binary_operator::sum;
break;
case '-':
this->m_operator = binary_operator::subtraction;
break;
case '*':
this->m_operator = binary_operator::multiplication;
break;
case '/':
this->m_operator = binary_operator::division;
break;
case '=':
this->m_operator = binary_operator::equals;
break;
case 'n':
this->m_operator = binary_operator::not_equals;
break;
case '<':
this->m_operator = binary_operator::less;
break;
case 'l':
this->m_operator = binary_operator::less_equal;
break;
case '>':
this->m_operator = binary_operator::greater;
break;
case 'g':
this->m_operator = binary_operator::greater_equal;
break;
2025-01-13 11:55:19 +01:00
case 'o':
this->m_operator = binary_operator::disjunction;
break;
case 'a':
this->m_operator = binary_operator::conjunction;
break;
2024-12-21 00:08:48 +01:00
default:
2024-12-23 13:54:11 +01:00
__builtin_unreachable();
2024-12-21 00:08:48 +01:00
}
}
void binary_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
expression& binary_expression::lhs()
{
return *m_lhs;
}
expression& binary_expression::rhs()
{
return *m_rhs;
}
2025-01-06 15:08:23 +01:00
binary_operator binary_expression::operation() const
2024-12-21 00:08:48 +01:00
{
return m_operator;
}
binary_expression::~binary_expression()
{
delete m_lhs;
delete m_rhs;
}
unary_expression::unary_expression(const struct position position, expression *operand,
2024-12-21 00:08:48 +01:00
const unsigned char operation)
: expression(position), m_operand(std::move(operand))
{
switch (operation)
{
case '@':
this->m_operator = unary_operator::reference;
break;
2025-01-13 11:55:19 +01:00
case '!':
this->m_operator = unary_operator::negation;
break;
2024-12-21 00:08:48 +01:00
default:
2024-12-23 13:54:11 +01:00
__builtin_unreachable();
2024-12-21 00:08:48 +01:00
}
}
void unary_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
expression& unary_expression::operand()
{
return *m_operand;
}
2025-01-06 15:08:23 +01:00
unary_operator unary_expression::operation() const
2024-12-21 00:08:48 +01:00
{
return this->m_operator;
}
unary_expression::~unary_expression()
{
delete m_operand;
}
2025-01-18 21:30:11 +01:00
call_expression::call_expression(const struct position position, const std::string& name)
: expression(position), m_name(name)
2024-12-21 00:08:48 +01:00
{
}
2025-01-18 21:30:11 +01:00
void call_expression::accept(parser_visitor *visitor)
2024-12-21 00:08:48 +01:00
{
visitor->visit(this);
}
2025-01-18 21:30:11 +01:00
std::string& call_expression::name()
2024-12-21 00:08:48 +01:00
{
return m_name;
}
2025-01-18 21:30:11 +01:00
std::vector<expression *>& call_expression::arguments()
2024-12-21 00:08:48 +01:00
{
return m_arguments;
}
2025-01-18 21:30:11 +01:00
call_expression::~call_expression()
{
for (auto argument : m_arguments)
{
delete argument;
}
}
2025-01-18 21:30:11 +01:00
expression_statement::expression_statement(const struct position position, expression *body)
: statement(position), m_body(body)
{
}
void expression_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
expression& expression_statement::body()
{
return *m_body;
}
expression_statement::~expression_statement()
{
delete m_body;
}
compound_statement::compound_statement(const struct position position, std::vector<statement *>&& statements)
2025-01-18 21:30:11 +01:00
: node(position), statements(std::move(statements))
2024-12-21 00:08:48 +01:00
{
}
void compound_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
compound_statement::~compound_statement()
{
for (auto statement : statements)
{
delete statement;
}
}
2025-01-18 21:30:11 +01:00
return_statement::return_statement(const struct position position, expression *return_expression)
: statement(position), m_return_expression(return_expression)
{
}
void return_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
expression *return_statement::return_expression()
{
return m_return_expression;
}
return_statement::~return_statement()
{
if (m_return_expression != nullptr)
{
delete m_return_expression;
}
}
2024-12-21 00:08:48 +01:00
void assign_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
2025-01-07 14:37:30 +01:00
assign_statement::assign_statement(const struct position position, designator_expression *lvalue,
expression *rvalue)
: statement(position), m_lvalue(lvalue), m_rvalue(rvalue)
2024-12-21 00:08:48 +01:00
{
}
2025-01-07 14:37:30 +01:00
variable_expression *designator_expression::is_variable()
{
return nullptr;
}
array_access_expression *designator_expression::is_array_access()
{
return nullptr;
}
2025-01-08 23:23:27 +01:00
field_access_expression *designator_expression::is_field_access()
{
return nullptr;
}
dereference_expression *designator_expression::is_dereference()
{
return nullptr;
}
2025-01-07 14:37:30 +01:00
designator_expression& assign_statement::lvalue()
2024-12-21 00:08:48 +01:00
{
2025-01-07 14:37:30 +01:00
return *m_lvalue;
2024-12-21 00:08:48 +01:00
}
expression& assign_statement::rvalue()
{
return *m_rvalue;
}
assign_statement::~assign_statement()
{
delete m_rvalue;
}
if_statement::if_statement(const struct position position, expression *prerequisite,
compound_statement *body, compound_statement *alternative)
: statement(position), m_prerequisite(prerequisite), m_body(body),
m_alternative(alternative)
2024-12-21 00:08:48 +01:00
{
}
void if_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
expression& if_statement::prerequisite()
{
return *m_prerequisite;
}
compound_statement& if_statement::body()
2024-12-21 00:08:48 +01:00
{
return *m_body;
}
compound_statement *if_statement::alternative()
2024-12-30 23:12:47 +01:00
{
return m_alternative;
}
if_statement::~if_statement()
{
delete m_prerequisite;
delete m_body;
if (m_alternative != nullptr)
{
delete m_alternative;
}
}
while_statement::while_statement(const struct position position, expression *prerequisite,
compound_statement *body)
: statement(position), m_prerequisite(prerequisite), m_body(body)
2024-12-21 00:08:48 +01:00
{
}
void while_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
expression& while_statement::prerequisite()
{
return *m_prerequisite;
}
compound_statement& while_statement::body()
2024-12-21 00:08:48 +01:00
{
return *m_body;
}
2024-12-28 14:33:35 +01:00
while_statement::~while_statement()
{
delete m_prerequisite;
delete m_body;
}
2024-12-28 14:33:35 +01:00
const char *print_binary_operator(const binary_operator operation)
{
switch (operation)
{
case binary_operator::sum:
return "+";
case binary_operator::subtraction:
return "-";
case binary_operator::multiplication:
return "*";
case binary_operator::division:
return "/";
case binary_operator::equals:
return "=";
case binary_operator::not_equals:
return "/=";
case binary_operator::less:
return "<";
case binary_operator::less_equal:
return "<=";
case binary_operator::greater:
return ">";
case binary_operator::greater_equal:
return ">=";
2025-01-13 11:55:19 +01:00
case binary_operator::conjunction:
return "and";
case binary_operator::disjunction:
return "or";
2024-12-28 14:33:35 +01:00
}
2025-01-03 22:18:35 +01:00
__builtin_unreachable();
2024-12-28 14:33:35 +01:00
};
2024-12-21 00:08:48 +01:00
}
2024-12-23 13:54:11 +01:00
}