Assign variables
This commit is contained in:
@ -6,7 +6,6 @@ namespace elna::source
|
||||
{
|
||||
using source_position = elna::source::position;
|
||||
using source_error = elna::source::error;
|
||||
using source_result = elna::source::result<std::vector<token>>;
|
||||
|
||||
std::pair<text_iterator, text_iterator> text_iterators(const std::string &buffer)
|
||||
{
|
||||
@ -225,7 +224,83 @@ namespace elna::source
|
||||
return "Unexpected token";
|
||||
}
|
||||
|
||||
source_result lex(const std::string& buffer)
|
||||
lexer::lexer(std::vector<token>&& tokens, const position last_position)
|
||||
: tokens(std::move(tokens)), iterator(this->tokens.cbegin()), eof(token(token::type::eof, last_position))
|
||||
{
|
||||
}
|
||||
|
||||
lexer& lexer::operator++()
|
||||
{
|
||||
++iterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const token& lexer::operator*() const
|
||||
{
|
||||
return *iterator;
|
||||
}
|
||||
|
||||
const token *lexer::operator->() const
|
||||
{
|
||||
return iterator.base();
|
||||
}
|
||||
|
||||
const token& lexer::current() const noexcept
|
||||
{
|
||||
if (iterator == tokens.cend())
|
||||
{
|
||||
return this->eof;
|
||||
}
|
||||
return *iterator;
|
||||
}
|
||||
|
||||
bool lexer::current(const token::type token_type) const noexcept
|
||||
{
|
||||
return current().of() == token_type;
|
||||
}
|
||||
|
||||
void lexer::add_error(const token& expected)
|
||||
{
|
||||
m_errors.push_back(std::make_unique<unexpected_token>(expected));
|
||||
}
|
||||
|
||||
std::optional<std::reference_wrapper<const token>> lexer::advance(const token::type token_type)
|
||||
{
|
||||
if (iterator != tokens.cend() && iterator->of() == token_type)
|
||||
{
|
||||
return std::make_optional<>(std::cref(*iterator++));
|
||||
}
|
||||
add_error(current());
|
||||
return std::optional<std::reference_wrapper<const token>>();
|
||||
}
|
||||
|
||||
const token& lexer::look_ahead() const
|
||||
{
|
||||
auto tmp = iterator;
|
||||
++tmp;
|
||||
if (iterator == tokens.cend() || tmp == tokens.cend())
|
||||
{
|
||||
return eof;
|
||||
}
|
||||
return *tmp;
|
||||
}
|
||||
|
||||
bool lexer::look_ahead(const token::type token_type) const
|
||||
{
|
||||
return look_ahead().of() == token_type;
|
||||
}
|
||||
|
||||
bool lexer::skip(const token::type token_type)
|
||||
{
|
||||
return advance(token_type).has_value();
|
||||
}
|
||||
|
||||
const std::list<std::unique_ptr<error>>& lexer::errors() const noexcept
|
||||
{
|
||||
return m_errors;
|
||||
}
|
||||
|
||||
result<lexer> lex(const std::string& buffer)
|
||||
{
|
||||
std::vector<token> tokens;
|
||||
auto [iterator, text_end] = text_iterators(buffer);
|
||||
@ -322,12 +397,10 @@ namespace elna::source
|
||||
}
|
||||
else
|
||||
{
|
||||
return source_result(unexpected_character{ std::string{ *iterator }, iterator.position() });
|
||||
return result<lexer>(unexpected_character{ std::string{ *iterator }, iterator.position() });
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
tokens.push_back(token(token::type::eof, iterator.position()));
|
||||
|
||||
return source_result(std::move(tokens));
|
||||
return result<lexer>(std::in_place, std::move(tokens), iterator.position());
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,60 @@
|
||||
|
||||
namespace elna::source
|
||||
{
|
||||
void empty_visitor::visit(declaration *declaration)
|
||||
{
|
||||
}
|
||||
|
||||
void empty_visitor::visit(definition *definition)
|
||||
{
|
||||
definition->body().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(bang_statement *statement)
|
||||
{
|
||||
statement->body().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(compound_statement *statement)
|
||||
{
|
||||
for (auto& nested_statement : statement->statements())
|
||||
{
|
||||
nested_statement->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void empty_visitor::visit(assign_statement *statement)
|
||||
{
|
||||
statement->rvalue().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(block *block)
|
||||
{
|
||||
for (const auto& block_definition : block->definitions())
|
||||
{
|
||||
block_definition->accept(this);
|
||||
}
|
||||
for (const auto& block_declaration : block->declarations())
|
||||
{
|
||||
block_declaration->accept(this);
|
||||
}
|
||||
block->body().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(binary_expression *expression)
|
||||
{
|
||||
expression->lhs().accept(this);
|
||||
expression->rhs().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(variable_expression *variable)
|
||||
{
|
||||
}
|
||||
|
||||
void empty_visitor::visit(integer_literal *number)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* AST node.
|
||||
*/
|
||||
@ -48,7 +102,9 @@ namespace elna::source
|
||||
block::block(std::vector<std::unique_ptr<definition>>&& definitions,
|
||||
std::vector<std::unique_ptr<declaration>>&& declarations,
|
||||
std::unique_ptr<statement>&& body)
|
||||
: m_definitions(std::move(definitions)), m_declarations(std::move(declarations)), m_body(std::move(body))
|
||||
: m_definitions(std::move(definitions)),
|
||||
m_declarations(std::move(declarations)), m_body(std::move(body)),
|
||||
m_table(std::make_shared<symbol_table>())
|
||||
{
|
||||
}
|
||||
|
||||
@ -72,6 +128,11 @@ namespace elna::source
|
||||
return m_declarations;
|
||||
}
|
||||
|
||||
std::shared_ptr<symbol_table> block::table()
|
||||
{
|
||||
return m_table;
|
||||
}
|
||||
|
||||
integer_literal::integer_literal(const std::int32_t value)
|
||||
: m_number(value)
|
||||
{
|
||||
@ -175,13 +236,28 @@ namespace elna::source
|
||||
return m_statements;
|
||||
}
|
||||
|
||||
void assignment_statement::accept(parser_visitor *visitor)
|
||||
void assign_statement::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
parser::parser(const std::vector<token>& tokens)
|
||||
: tokens(tokens.cbegin()), end(tokens.cend())
|
||||
assign_statement::assign_statement(const std::string& lvalue, std::unique_ptr<expression>&& rvalue)
|
||||
: m_lvalue(lvalue), m_rvalue(std::move(rvalue))
|
||||
{
|
||||
}
|
||||
|
||||
std::string& assign_statement::lvalue() noexcept
|
||||
{
|
||||
return m_lvalue;
|
||||
}
|
||||
|
||||
expression& assign_statement::rvalue()
|
||||
{
|
||||
return *m_rvalue;
|
||||
}
|
||||
|
||||
parser::parser(lexer&& tokens)
|
||||
: iterator(std::move(tokens))
|
||||
{
|
||||
}
|
||||
|
||||
@ -190,27 +266,32 @@ namespace elna::source
|
||||
return parse_block();
|
||||
}
|
||||
|
||||
const std::list<std::unique_ptr<error>>& parser::errors() const noexcept
|
||||
{
|
||||
return iterator.errors();
|
||||
}
|
||||
|
||||
std::unique_ptr<expression> parser::parse_factor()
|
||||
{
|
||||
if (tokens->of() == source::token::type::identifier)
|
||||
if (iterator->of() == source::token::type::identifier)
|
||||
{
|
||||
auto result = std::make_unique<variable_expression>(tokens->identifier());
|
||||
++tokens;
|
||||
auto result = std::make_unique<variable_expression>(iterator->identifier());
|
||||
++iterator;
|
||||
return result;
|
||||
}
|
||||
else if (tokens->of() == source::token::token::type::number)
|
||||
else if (iterator->of() == source::token::token::type::number)
|
||||
{
|
||||
auto result = std::make_unique<integer_literal>(tokens->number());
|
||||
++tokens;
|
||||
auto result = std::make_unique<integer_literal>(iterator->number());
|
||||
++iterator;
|
||||
return result;
|
||||
}
|
||||
else if (tokens->of() == source::token::type::left_paren)
|
||||
else if (iterator->of() == source::token::type::left_paren)
|
||||
{
|
||||
++tokens;
|
||||
++iterator;
|
||||
|
||||
auto expression = parse_expression();
|
||||
|
||||
++tokens;
|
||||
++iterator;
|
||||
|
||||
return expression;
|
||||
}
|
||||
@ -220,14 +301,14 @@ namespace elna::source
|
||||
std::unique_ptr<expression> parser::parse_term()
|
||||
{
|
||||
auto lhs = parse_factor();
|
||||
if (lhs == nullptr || tokens == end || tokens->of() != source::token::type::factor_operator)
|
||||
if (lhs == nullptr || iterator.current().of() != source::token::type::factor_operator)
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
while (tokens->of() == source::token::type::factor_operator)
|
||||
while (iterator->of() == source::token::type::factor_operator)
|
||||
{
|
||||
auto _operator = tokens->identifier()[0];
|
||||
++tokens;
|
||||
auto _operator = iterator->identifier()[0];
|
||||
++iterator;
|
||||
|
||||
auto rhs = parse_factor();
|
||||
lhs = std::make_unique<binary_expression>(std::move(lhs),
|
||||
@ -239,14 +320,14 @@ namespace elna::source
|
||||
std::unique_ptr<expression> parser::parse_expression()
|
||||
{
|
||||
auto term = parse_term();
|
||||
if (term == nullptr || tokens == end || tokens->of() != source::token::type::term_operator)
|
||||
if (term == nullptr || iterator.current().of() != source::token::type::term_operator)
|
||||
{
|
||||
return term;
|
||||
}
|
||||
while (tokens->of() == source::token::type::term_operator)
|
||||
while (iterator->of() == source::token::type::term_operator)
|
||||
{
|
||||
auto _operator = tokens->identifier()[0];
|
||||
++tokens;
|
||||
auto _operator = iterator->identifier()[0];
|
||||
++iterator;
|
||||
|
||||
auto rhs = parse_term();
|
||||
term = std::make_unique<binary_expression>(std::move(term),
|
||||
@ -257,22 +338,22 @@ namespace elna::source
|
||||
|
||||
std::unique_ptr<definition> parser::parse_definition()
|
||||
{
|
||||
auto definition_identifier = advance(token::type::identifier);
|
||||
auto definition_identifier = iterator.advance(token::type::identifier);
|
||||
|
||||
if (!definition_identifier.has_value())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (!skip(token::type::equals))
|
||||
if (!iterator.skip(token::type::equals))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (tokens->of() == source::token::type::number)
|
||||
if (iterator->of() == source::token::type::number)
|
||||
{
|
||||
auto result = std::make_unique<definition>(definition_identifier.value().get().identifier(),
|
||||
std::make_unique<integer_literal>(tokens->number()));
|
||||
++tokens;
|
||||
std::make_unique<integer_literal>(iterator->number()));
|
||||
++iterator;
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
@ -280,7 +361,7 @@ namespace elna::source
|
||||
|
||||
std::unique_ptr<declaration> parser::parse_declaration()
|
||||
{
|
||||
auto declaration_identifier = advance(token::type::identifier);
|
||||
auto declaration_identifier = iterator.advance(token::type::identifier);
|
||||
|
||||
if (!declaration_identifier.has_value())
|
||||
{
|
||||
@ -291,21 +372,25 @@ namespace elna::source
|
||||
|
||||
std::unique_ptr<statement> parser::parse_statement()
|
||||
{
|
||||
if (tokens->of() == source::token::type::bang)
|
||||
if (iterator.look_ahead(token::type::assignment))
|
||||
{
|
||||
return parse_assign_statement();
|
||||
}
|
||||
else if (iterator.current(token::type::bang))
|
||||
{
|
||||
return parse_bang_statement();
|
||||
}
|
||||
else if (tokens->of() == source::token::type::begin)
|
||||
else if (iterator.current(token::type::begin))
|
||||
{
|
||||
return parse_compound_statement();
|
||||
}
|
||||
errors.push_back(std::make_unique<unexpected_token>(unexpected_token{ *tokens }));
|
||||
iterator.add_error(*iterator);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<bang_statement> parser::parse_bang_statement()
|
||||
{
|
||||
if (!advance(token::type::bang))
|
||||
if (!iterator.advance(token::type::bang))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -321,7 +406,7 @@ namespace elna::source
|
||||
|
||||
std::unique_ptr<compound_statement> parser::parse_compound_statement()
|
||||
{
|
||||
if (!advance(token::type::begin))
|
||||
if (!iterator.advance(token::type::begin))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -332,18 +417,18 @@ namespace elna::source
|
||||
{
|
||||
result->statements().push_back(std::move(next_statement));
|
||||
|
||||
if (tokens->of() == token::type::semicolon)
|
||||
if (iterator->of() == token::type::semicolon)
|
||||
{
|
||||
++tokens;
|
||||
++iterator;
|
||||
}
|
||||
else if (tokens->of() == token::type::end)
|
||||
else if (iterator->of() == token::type::end)
|
||||
{
|
||||
++tokens;
|
||||
++iterator;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.push_back(std::make_unique<unexpected_token>(*tokens));
|
||||
iterator.add_error(*iterator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -351,33 +436,49 @@ namespace elna::source
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<assign_statement> parser::parse_assign_statement()
|
||||
{
|
||||
auto name = iterator.advance(token::type::identifier);
|
||||
if (!name.has_value() || !iterator.skip(token::type::assignment))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
auto rvalue = parse_expression();
|
||||
|
||||
if (rvalue == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<assign_statement>(name.value().get().identifier(), std::move(rvalue));
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<definition>> parser::parse_definitions()
|
||||
{
|
||||
std::vector<std::unique_ptr<definition>> definitions;
|
||||
|
||||
if (tokens->of() != token::type::let)
|
||||
if (iterator->of() != token::type::let)
|
||||
{
|
||||
return definitions;
|
||||
}
|
||||
++tokens; // Skip const.
|
||||
++iterator; // Skip const.
|
||||
|
||||
std::unique_ptr<definition> parsed_definition;
|
||||
while ((parsed_definition = parse_definition()) != nullptr)
|
||||
{
|
||||
definitions.push_back(std::move(parsed_definition));
|
||||
|
||||
if (tokens->of() == source::token::type::comma)
|
||||
if (iterator->of() == source::token::type::comma)
|
||||
{
|
||||
++tokens;
|
||||
++iterator;
|
||||
}
|
||||
else if (tokens->of() == source::token::type::semicolon)
|
||||
else if (iterator->of() == source::token::type::semicolon)
|
||||
{
|
||||
++tokens;
|
||||
++iterator;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.push_back(std::make_unique<unexpected_token>(*tokens));
|
||||
iterator.add_error(*iterator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -388,29 +489,29 @@ namespace elna::source
|
||||
{
|
||||
std::vector<std::unique_ptr<declaration>> declarations;
|
||||
|
||||
if (tokens->of() != token::type::var)
|
||||
if (iterator->of() != token::type::var)
|
||||
{
|
||||
return declarations;
|
||||
}
|
||||
++tokens; // Skip var.
|
||||
++iterator; // Skip var.
|
||||
|
||||
std::unique_ptr<declaration> parsed_declaration;
|
||||
while ((parsed_declaration = parse_declaration()) != nullptr)
|
||||
{
|
||||
declarations.push_back(std::move(parsed_declaration));
|
||||
|
||||
if (tokens->of() == token::type::comma)
|
||||
if (iterator->of() == token::type::comma)
|
||||
{
|
||||
++tokens;
|
||||
++iterator;
|
||||
}
|
||||
else if (tokens->of() == token::type::semicolon)
|
||||
else if (iterator->of() == token::type::semicolon)
|
||||
{
|
||||
++tokens;
|
||||
++iterator;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.push_back(std::make_unique<unexpected_token>(*tokens));
|
||||
iterator.add_error(*iterator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -430,25 +531,4 @@ namespace elna::source
|
||||
return std::make_unique<block>(std::move(definitions),
|
||||
std::move(declarations), std::move(parsed_statement));
|
||||
}
|
||||
|
||||
std::optional<std::reference_wrapper<const token>> parser::advance(const token::type token_type)
|
||||
{
|
||||
if (tokens->of() == token_type)
|
||||
{
|
||||
return std::make_optional<>(std::cref(*tokens++));
|
||||
}
|
||||
errors.push_back(std::make_unique<unexpected_token>(*tokens));
|
||||
return std::optional<std::reference_wrapper<const token>>();
|
||||
}
|
||||
|
||||
bool parser::skip(const token::type token_type)
|
||||
{
|
||||
if (tokens->of() == token_type)
|
||||
{
|
||||
++tokens;
|
||||
return true;
|
||||
}
|
||||
errors.push_back(std::make_unique<unexpected_token>(*tokens));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -16,4 +16,72 @@ namespace elna::source
|
||||
{
|
||||
return this->m_position.column;
|
||||
}
|
||||
|
||||
name_collision::name_collision(const std::string& name, const position current, const position previous)
|
||||
: error(current), name(name), previous(previous)
|
||||
{
|
||||
}
|
||||
|
||||
std::string name_collision::what() const
|
||||
{
|
||||
return "Name '" + name + "' was already defined";
|
||||
}
|
||||
|
||||
std::shared_ptr<info> symbol_table::lookup(const std::string& name)
|
||||
{
|
||||
auto entry = entries.find(name);
|
||||
if (entry == entries.cend())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return entry->second;
|
||||
}
|
||||
}
|
||||
|
||||
void symbol_table::enter(const std::string& name, std::shared_ptr<info> entry)
|
||||
{
|
||||
entries.insert_or_assign(name, entry);
|
||||
}
|
||||
|
||||
info::~info()
|
||||
{
|
||||
}
|
||||
|
||||
info::info()
|
||||
{
|
||||
}
|
||||
|
||||
constant_info::constant_info(const std::int32_t value)
|
||||
: m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
constant_info::~constant_info()
|
||||
{
|
||||
}
|
||||
|
||||
std::int32_t constant_info::value() const noexcept
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
variable_info::~variable_info()
|
||||
{
|
||||
}
|
||||
|
||||
procedure_info::~procedure_info()
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t procedure_info::stack_size() const noexcept
|
||||
{
|
||||
return this->local_stack_size;
|
||||
}
|
||||
|
||||
void procedure_info::stack_size(const std::size_t size) noexcept
|
||||
{
|
||||
this->local_stack_size = size;
|
||||
}
|
||||
}
|
||||
|
38
source/semantic.cpp
Normal file
38
source/semantic.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "elna/source/semantic.hpp"
|
||||
#include <cstdlib>
|
||||
|
||||
namespace elna::source
|
||||
{
|
||||
void name_analysis_visitor::visit(definition *definition)
|
||||
{
|
||||
this->table->enter(definition->identifier(),
|
||||
std::make_shared<constant_info>(constant_info(definition->body().number())));
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(declaration *declaration)
|
||||
{
|
||||
this->table->enter(declaration->identifier(),
|
||||
std::make_shared<variable_info>(variable_info()));
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(block *block)
|
||||
{
|
||||
this->table = block->table();
|
||||
empty_visitor::visit(block);
|
||||
this->table->enter("main",
|
||||
std::make_shared<procedure_info>());
|
||||
}
|
||||
|
||||
void allocator_visitor::visit(declaration *declaration)
|
||||
{
|
||||
this->offset -= sizeof(std::int32_t);
|
||||
}
|
||||
|
||||
void allocator_visitor::visit(block *block)
|
||||
{
|
||||
this->offset = 0;
|
||||
empty_visitor::visit(block);
|
||||
std::dynamic_pointer_cast<procedure_info>(block->table()->lookup("main"))
|
||||
->stack_size(std::abs(this->offset));
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
#include "elna/source/symboltable.hpp"
|
||||
|
||||
namespace elna::source
|
||||
{
|
||||
name_collision::name_collision(const std::string& name, const position current, const position previous)
|
||||
: error(current), name(name), previous(previous)
|
||||
{
|
||||
}
|
||||
|
||||
std::string name_collision::what() const
|
||||
{
|
||||
return "Name '" + name + "' was already defined";
|
||||
}
|
||||
|
||||
std::shared_ptr<info> symbol_table::lookup(const std::string& name)
|
||||
{
|
||||
auto entry = entries.find(name);
|
||||
if (entry == entries.cend())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return entry->second;
|
||||
}
|
||||
}
|
||||
|
||||
void symbol_table::enter(const std::string& name, std::shared_ptr<info> entry)
|
||||
{
|
||||
entries.insert_or_assign(name, entry);
|
||||
}
|
||||
|
||||
info::~info()
|
||||
{
|
||||
}
|
||||
|
||||
info::info()
|
||||
{
|
||||
}
|
||||
|
||||
constant_info::constant_info(const std::int32_t value)
|
||||
: m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
constant_info::~constant_info()
|
||||
{
|
||||
}
|
||||
|
||||
std::int32_t constant_info::value() const noexcept
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
variable_info::variable_info(std::size_t offset)
|
||||
: m_offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
variable_info::~variable_info()
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t variable_info::offset() const noexcept
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(declaration *declaration)
|
||||
{
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(definition *definition)
|
||||
{
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(bang_statement *statement)
|
||||
{
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(compound_statement *statement)
|
||||
{
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(assignment_statement *statement)
|
||||
{
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(block *block)
|
||||
{
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(integer_literal *number)
|
||||
{
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(variable_expression *variable)
|
||||
{
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(binary_expression *expression)
|
||||
{
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user