Move type definitions to the program node
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "elna/source/ast.h"
|
||||
#include "elna/source/symbol.h"
|
||||
#include "elna/gcc/elna-tree.h"
|
||||
|
||||
#include "config.h"
|
||||
@ -20,7 +21,7 @@ namespace gcc
|
||||
{
|
||||
tree current_statements{ NULL_TREE };
|
||||
tree current_expression{ NULL_TREE };
|
||||
std::unordered_map<std::string, tree> symbol_map;
|
||||
std::shared_ptr<source::symbol_table<tree>> symbol_map;
|
||||
tree main_fndecl{ NULL_TREE };
|
||||
tree_chain variable_chain;
|
||||
|
||||
@ -31,6 +32,8 @@ namespace gcc
|
||||
tree_symbol_mapping leave_scope();
|
||||
|
||||
public:
|
||||
generic_visitor();
|
||||
|
||||
void visit(source::program *program) override;
|
||||
void visit(source::procedure_definition *definition) override;
|
||||
void visit(source::call_statement *statement) override;
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "elna/source/result.h"
|
||||
#include "elna/source/types.h"
|
||||
|
||||
namespace elna
|
||||
{
|
||||
@ -210,7 +209,6 @@ namespace source
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<operand> place;
|
||||
std::shared_ptr<const type> data_type;
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -596,19 +594,16 @@ namespace source
|
||||
|
||||
class block : public node
|
||||
{
|
||||
std::vector<definition *> m_definitions;
|
||||
statement *m_body;
|
||||
|
||||
public:
|
||||
std::vector<definition *> value_definitions;
|
||||
|
||||
block(const struct position position, std::vector<definition *>&& definitions,
|
||||
std::vector<definition *>&& value_definitions,
|
||||
block(const struct position position, std::vector<definition *>&& value_definitions,
|
||||
statement *body);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
statement& body();
|
||||
std::vector<definition *>& definitions();
|
||||
|
||||
virtual ~block() override;
|
||||
};
|
||||
@ -616,9 +611,13 @@ namespace source
|
||||
class program : public block
|
||||
{
|
||||
public:
|
||||
program(const struct position position, std::vector<definition *>&& definitions,
|
||||
std::vector<definition *> type_definitions;
|
||||
|
||||
program(const struct position position, std::vector<definition *>&& type_definitions,
|
||||
std::vector<definition *>&& value_definitions, statement *body);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
virtual ~program() override;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -4,7 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include "elna/source/types.h"
|
||||
#include <string>
|
||||
|
||||
namespace elna
|
||||
{
|
||||
|
106
include/elna/source/symbol.h
Normal file
106
include/elna/source/symbol.h
Normal file
@ -0,0 +1,106 @@
|
||||
// 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/.
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace elna
|
||||
{
|
||||
namespace source
|
||||
{
|
||||
/**
|
||||
* Generic language entity information.
|
||||
*/
|
||||
template<typename T>
|
||||
class info
|
||||
{
|
||||
public:
|
||||
T payload;
|
||||
|
||||
info(T payload)
|
||||
: payload(payload)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
std::shared_ptr<info<T>> make_info(T payload)
|
||||
{
|
||||
return std::make_shared<info<T>>(info(payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* Symbol table.
|
||||
*/
|
||||
template<typename T>
|
||||
class symbol_table
|
||||
{
|
||||
public:
|
||||
using symbol_ptr = std::shared_ptr<info<T>>;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, symbol_ptr> entries;
|
||||
std::shared_ptr<symbol_table> outer_scope;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs a new symbol with an optional outer scope.
|
||||
*
|
||||
* \param scope Outer scope.
|
||||
*/
|
||||
explicit symbol_table(std::shared_ptr<symbol_table> scope = nullptr)
|
||||
: outer_scope(scope)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for symbol in the table by name. Returns nullptr if the symbol
|
||||
* can not be found.
|
||||
*
|
||||
* \param name Symbol name.
|
||||
* \return Symbol from the table if found.
|
||||
*/
|
||||
symbol_ptr lookup(const std::string& name)
|
||||
{
|
||||
auto entry = entries.find(name);
|
||||
|
||||
if (entry != entries.cend())
|
||||
{
|
||||
return entry->second;
|
||||
}
|
||||
if (this->outer_scope != nullptr)
|
||||
{
|
||||
return this->outer_scope->lookup(name);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers new symbol.
|
||||
*
|
||||
* \param name Symbol name.
|
||||
* \param entry Symbol information.
|
||||
*
|
||||
* \return Whether the insertion took place.
|
||||
*/
|
||||
bool enter(const std::string& name, symbol_ptr entry)
|
||||
{
|
||||
return entries.insert({ name, entry }).second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the outer scope or nullptr if the this is the global scope.
|
||||
*
|
||||
* \return Outer scope.
|
||||
*/
|
||||
std::shared_ptr<symbol_table> scope()
|
||||
{
|
||||
return this->outer_scope;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user