Implement case statements
This commit is contained in:
@ -275,7 +275,7 @@ namespace elna::boot
|
||||
}
|
||||
|
||||
constant_definition::constant_definition(const struct position position, const std::string& identifier,
|
||||
const bool exported, literal_expression *body)
|
||||
const bool exported, expression *body)
|
||||
: definition(position, identifier, exported), m_body(body)
|
||||
{
|
||||
}
|
||||
@ -285,7 +285,7 @@ namespace elna::boot
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
literal_expression& constant_definition::body()
|
||||
expression& constant_definition::body()
|
||||
{
|
||||
return *m_body;
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
%left "*" "/" "%"
|
||||
|
||||
%type <elna::boot::literal_expression *> literal;
|
||||
%type <std::vector<elna::boot::literal_expression *>> case_labels;
|
||||
%type <std::vector<elna::boot::expression *>> case_labels;
|
||||
%type <elna::boot::switch_case> switch_case;
|
||||
%type <std::vector<elna::boot::switch_case>> switch_cases;
|
||||
%type <elna::boot::constant_definition *> constant_definition;
|
||||
@ -137,7 +137,6 @@ along with GCC; see the file COPYING3. If not see
|
||||
%type <std::vector<elna::boot::type_expression *>> type_expressions;
|
||||
%type <elna::boot::traits_expression *> traits_expression;
|
||||
%type <elna::boot::expression *> expression operand simple_expression;
|
||||
%type <elna::boot::field_access_expression *> qualident;
|
||||
%type <elna::boot::unary_expression *> unary_expression;
|
||||
%type <elna::boot::binary_expression *> binary_expression;
|
||||
%type <std::vector<elna::boot::expression *>> expressions actual_parameter_list;
|
||||
@ -296,34 +295,13 @@ return_statement:
|
||||
$$ = new boot::return_statement(boot::make_position(@1));
|
||||
}
|
||||
literal:
|
||||
INTEGER
|
||||
{
|
||||
$$ = new boot::literal<std::int32_t>(boot::make_position(@1), $1);
|
||||
}
|
||||
| WORD
|
||||
{
|
||||
$$ = new boot::literal<std::uint32_t>(boot::make_position(@1), $1);
|
||||
}
|
||||
| FLOAT
|
||||
{
|
||||
$$ = new boot::literal<double>(boot::make_position(@1), $1);
|
||||
}
|
||||
| BOOLEAN
|
||||
{
|
||||
$$ = new boot::literal<bool>(boot::make_position(@1), $1);
|
||||
}
|
||||
| CHARACTER
|
||||
{
|
||||
$$ = new boot::literal<unsigned char>(boot::make_position(@1), $1.at(0));
|
||||
}
|
||||
| "nil"
|
||||
{
|
||||
$$ = new boot::literal<std::nullptr_t>(boot::make_position(@1), nullptr);
|
||||
}
|
||||
| STRING
|
||||
{
|
||||
$$ = new boot::literal<std::string>(boot::make_position(@1), $1);
|
||||
}
|
||||
INTEGER { $$ = new boot::literal<std::int32_t>(boot::make_position(@1), $1); }
|
||||
| WORD { $$ = new boot::literal<std::uint32_t>(boot::make_position(@1), $1); }
|
||||
| FLOAT { $$ = new boot::literal<double>(boot::make_position(@1), $1); }
|
||||
| BOOLEAN { $$ = new boot::literal<bool>(boot::make_position(@1), $1); }
|
||||
| CHARACTER { $$ = new boot::literal<unsigned char>(boot::make_position(@1), $1.at(0)); }
|
||||
| "nil" { $$ = new boot::literal<std::nullptr_t>(boot::make_position(@1), nullptr); }
|
||||
| STRING { $$ = new boot::literal<std::string>(boot::make_position(@1), $1); }
|
||||
traits_expression:
|
||||
TRAIT "(" type_expressions ")"
|
||||
{
|
||||
@ -439,33 +417,22 @@ type_expressions:
|
||||
| type_expression { $$.push_back($1); }
|
||||
designator_expression:
|
||||
simple_expression "[" expression "]"
|
||||
{
|
||||
$$ = new boot::array_access_expression(boot::make_position(@2), $1, $3);
|
||||
}
|
||||
| qualident { $$ = $1; }
|
||||
{ $$ = new boot::array_access_expression(boot::make_position(@2), $1, $3); }
|
||||
| simple_expression "." IDENTIFIER
|
||||
{ $$ = new boot::field_access_expression(boot::make_position(@2), $1, $3); }
|
||||
| simple_expression "^"
|
||||
{
|
||||
$$ = new boot::dereference_expression(boot::make_position(@1), $1);
|
||||
}
|
||||
{ $$ = new boot::dereference_expression(boot::make_position(@1), $1); }
|
||||
| IDENTIFIER
|
||||
{
|
||||
$$ = new boot::variable_expression(boot::make_position(@1), $1);
|
||||
}
|
||||
qualident: simple_expression "." IDENTIFIER
|
||||
{
|
||||
$$ = new boot::field_access_expression(boot::make_position(@2), $1, $3);
|
||||
}
|
||||
{ $$ = new boot::variable_expression(boot::make_position(@1), $1); }
|
||||
statement:
|
||||
designator_expression ":=" expression
|
||||
{
|
||||
$$ = new boot::assign_statement(boot::make_position(@1), $1, $3);
|
||||
}
|
||||
{ $$ = new boot::assign_statement(boot::make_position(@1), $1, $3); }
|
||||
| while_statement { $$ = $1; }
|
||||
| if_statement { $$ = $1; }
|
||||
| return_statement { $$ = $1; }
|
||||
| call_expression { $$ = $1; }
|
||||
| DEFER statements "end" { $$ = new boot::defer_statement(boot::make_position(@1), std::move($2)); }
|
||||
| CASE expression "of" switch_cases "end"
|
||||
| "defer" statements "end" { $$ = new boot::defer_statement(boot::make_position(@1), std::move($2)); }
|
||||
| "case" expression "of" switch_cases "end"
|
||||
{ $$ = new boot::case_statement(boot::make_position(@1), $2, std::move($4)); }
|
||||
switch_case: case_labels ":" statements { $$ = { .labels = std::move($1), .statements = std::move($3) }; }
|
||||
switch_cases:
|
||||
@ -476,12 +443,12 @@ switch_cases:
|
||||
}
|
||||
| switch_case { $$.push_back($1); }
|
||||
case_labels:
|
||||
literal "," case_labels
|
||||
expression "," case_labels
|
||||
{
|
||||
std::swap($$, $3);
|
||||
$$.emplace($$.cbegin(), $1);
|
||||
}
|
||||
| literal { $$.push_back($1); }
|
||||
| expression { $$.push_back($1); }
|
||||
statements:
|
||||
statement ";" statements
|
||||
{
|
||||
@ -562,7 +529,7 @@ variable_declarations:
|
||||
variable_part:
|
||||
/* no variable declarations */ {}
|
||||
| "var" variable_declarations { std::swap($$, $2); }
|
||||
constant_definition: identifier_definition "=" literal
|
||||
constant_definition: identifier_definition "=" expression
|
||||
{
|
||||
$$ = new boot::constant_definition(boot::make_position(@1), $1.first, $1.second, $3);
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ namespace elna::boot
|
||||
statement->condition().accept(this);
|
||||
for (const switch_case& case_block : statement->cases)
|
||||
{
|
||||
for (literal_expression *const case_label : case_block.labels)
|
||||
for (expression *const case_label : case_block.labels)
|
||||
{
|
||||
case_label->accept(this);
|
||||
}
|
||||
|
@ -292,6 +292,16 @@ namespace elna::boot
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<constant_info> info::is_constant()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<variable_info> info::is_variable()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
type_info::type_info(const type symbol)
|
||||
: symbol(symbol)
|
||||
{
|
||||
@ -317,6 +327,21 @@ namespace elna::boot
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<constant_info> constant_info::is_constant()
|
||||
{
|
||||
return std::static_pointer_cast<constant_info>(shared_from_this());
|
||||
}
|
||||
|
||||
variable_info::variable_info(const std::string& name, const type symbol)
|
||||
: name(name), symbol(symbol)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<variable_info> variable_info::is_variable()
|
||||
{
|
||||
return std::static_pointer_cast<variable_info>(shared_from_this());;
|
||||
}
|
||||
|
||||
std::shared_ptr<symbol_table> builtin_symbol_table()
|
||||
{
|
||||
auto result = std::make_shared<symbol_table>();
|
||||
|
Reference in New Issue
Block a user