Skip to content

Commit

Permalink
Added basic support for accessing function parameters.
Browse files Browse the repository at this point in the history
  • Loading branch information
Goubermouche committed Dec 27, 2023
1 parent 429f955 commit 91f6660
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 17 deletions.
10 changes: 7 additions & 3 deletions source/compiler/compiler/type_system/variable_registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,19 @@ namespace sigma {

auto variable_registry::create_load(utility::string_table_key identifier, ir::data_type type, u16 alignment) const -> handle<ir::node> {
const handle<variable> variable = m_active_scope->get_variable(identifier);
if(variable != nullptr) {
return m_context.builder.create_load(variable->value, type, alignment, false);
ASSERT(variable, "attempting to load an invalid variable");

if(variable->flags & variable::FUNCTION_PARAMETER) {
return variable->value;
}

return nullptr;
return m_context.builder.create_load(variable->value, type, alignment, false);
}

void variable_registry::create_store(utility::string_table_key identifier, handle<ir::node> value, u16 alignment) const {
const handle<variable> variable = m_active_scope->get_variable(identifier);
// ASSERT(!(variable->flags & variable::FUNCTION_PARAMETER), "not implemented");

if (variable != nullptr) {
m_context.builder.create_store(variable->value, value, alignment, false);
return;
Expand Down
13 changes: 12 additions & 1 deletion source/compiler/compiler/type_system/variable_registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,17 @@ namespace sigma {
struct backend_context;

class variable_registry {
public:
struct variable {
enum variable_flags {
NONE = 0,

// variable is a function parameter, function parameters don't need to be loaded
FUNCTION_PARAMETER = 1
};

handle<ir::node> value;
variable_flags flags;
data_type type;
};

Expand All @@ -22,7 +31,7 @@ namespace sigma {
std::unordered_map<utility::string_table_key, variable> variables;
u16 trace_index = 0;
};
public:

variable_registry(backend_context& context);

// NOTE: since we have two step analysis we need to traverse the scope system twice - first,
Expand Down Expand Up @@ -57,4 +66,6 @@ namespace sigma {
scope m_global_scope;
handle<scope> m_active_scope;
};

FLAG_ENUM(variable_registry::variable::variable_flags);
} // namespace sigma
15 changes: 7 additions & 8 deletions source/compiler/test/main.s
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@
// ret 0;
// }

i32 main() {
i32 value = 0;

if(false) {}
else {
value = 100;
}
i32 test(i32 x) {
// x = x + 10;
ret x;
}

printf("value is: %d\n", value);
i32 main() {
i32 val = test(100);
printf("val : %d\n", val);
ret 0;
}
12 changes: 12 additions & 0 deletions source/ir_translator/ir_translator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ namespace sigma {
m_context.function_registry.declare_local_function(signature);
m_context.variable_registry.trace_push_scope();

// TODO: handle varargs
// push temporaries for function parameters
for (u64 i = 0; i < signature.parameter_types.get_size(); ++i) {
// TODO: create proxies?
const auto variable = m_context.variable_registry.get_variable(signature.parameter_types[i].identifier_key);
ASSERT(variable, "function parameter pre declaration is invalid");

const handle<ir::node> value = m_context.builder.get_function_parameter(i);
variable->flags |= variable_registry::variable::FUNCTION_PARAMETER;
variable->value = value;
}

// handle inner statements
for (const handle<node>& statement : function_node->children) {
translate_node(statement);
Expand Down
16 changes: 11 additions & 5 deletions source/type_checker/type_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,29 @@ namespace sigma {

auto type_checker::type_check_function_declaration(handle<node> function_node, data_type expected) -> utility::result<data_type> {
SUPPRESS_C4100(expected);
const auto& property = function_node->get<function_signature>();
const auto& signature = function_node->get<function_signature>();

// check if the function hasn't been declared before
if(m_context.function_registry.contains_function(property)) {
if(m_context.function_registry.contains_function(signature)) {
return utility::error::create(
utility::error::code::FUNCTION_ALREADY_DECLARED,
m_context.syntax.string_table.get(property.identifier_key)
m_context.syntax.string_table.get(signature.identifier_key)
);
}

// register the function
m_context.function_registry.pre_declare_local_function(property);
m_context.function_registry.pre_declare_local_function(signature);
m_context.variable_registry.push_scope();

// TODO: handle varargs
// push temporaries for function parameters
for(const named_data_type& parameter : signature.parameter_types) {
m_context.variable_registry.pre_declare_variable(parameter.identifier_key, parameter.type);
}

// type check inner statements
for(const handle<node>& statement : function_node->children) {
TRY(type_check_node(statement, property.return_type));
TRY(type_check_node(statement, signature.return_type));
}

m_context.variable_registry.pop_scope();
Expand Down

0 comments on commit 91f6660

Please sign in to comment.