Move type definitions to the program node

This commit is contained in:
2025-01-12 10:35:24 +01:00
parent 7985704981
commit b45b00a3f6
11 changed files with 236 additions and 82 deletions

View File

@ -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;

View File

@ -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>

View File

@ -4,7 +4,7 @@
#pragma once
#include <cstddef>
#include "elna/source/types.h"
#include <string>
namespace elna
{

View 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;
}
};
}
}