diff --git a/scope.cpp b/scope.cpp index 2991042..cbf6bfa 100644 --- a/scope.cpp +++ b/scope.cpp @@ -1,50 +1,93 @@ #include "scope.h" +#include "variables.h" +#include "types.h" #include -#include "heap.h" - -struct t_variable { - //char name[MAX_IDENTIFIER_LENGTH]; - std::string name; - int type; - int length; - int address; -}; - -struct t_struct { - //char name[MAX_IDENTIFIER_LENGTH]; - std::string name; - std::vector members; -}; +#include struct t_scope { std::vector variables; - t_scope* parent_scope; + int total_size; }; -static t_scope scope_global; -static t_scope* scope_current = &scope_global; +static t_scope global; +static t_scope local; +static std::stack blocks; +static bool are_we_inside_local = false; +static t_variable *current_var = NULL; void scope_init() { - scope_current = &scope_global; - scope_global.variables.clear(); + global.variables.clear(); + global.total_size = 0; + local.variables.clear(); + local.total_size = 0; + while (!blocks.empty()) blocks.pop(); + are_we_inside_local = false; } void scope_open_local() { - t_scope* new_scope = new t_scope; - new_scope->parent_scope = scope_current; - scope_current = new_scope; + are_we_inside_local = true; } -void scope_close_local() { - t_scope* closing_scope = scope_current; - scope_current = scope_current->parent_scope; - delete closing_scope; +const int scope_close_local() { + if (!blocks.empty()) { + // Malament, no havem tancat algĂșn block. No se si es detectarĂ  abans per altra part. Per ara anem a deixar este comentari. + } + const int return_value = local.total_size; + local.variables.clear(); + local.total_size = 0; + are_we_inside_local = false; + return return_value; } -const int scope_declare_variable(const std::string name, const int type, const int length) { - for (t_variable v : scope_current->variables) { if (v.name == name) return -1; } - const int address = heap_get_address(); +void scope_open_block() { + blocks.push(local.variables.size()); +} + +void scope_close_block() { + const int size_before_block = blocks.top(); + blocks.pop(); + while (local.variables.size() > size_before_block) local.variables.pop_back(); +} + +const uint32_t scope_declare_variable(const std::string name, const int type, const int length) { + t_scope& scope = (are_we_inside_local ? local : global); + if (are_we_inside_local) { + for (int i = blocks.top(); i < scope.variables.size(); i++ ) if (scope.variables[i].name == name) return -1; + } else { + for (t_variable v : scope.variables) if (v.name == name) return -1; + } + const int address = scope.total_size; const t_variable var {name, type, length, address}; - scope_current->variables.push_back(var); + scope.variables.push_back(var); + scope.total_size += types_get_length(type) + (length == 0 ? 1 : length); return address; } + +const bool scope_variable_exists(const std::string name) { + t_scope& scope = (are_we_inside_local ? local : global); + for (t_variable v : scope.variables) if (v.name == name) { + current_var = &v; + return true; + } +} + +const uint32_t scope_get_variable_address() { + if (current_var == NULL) { + // ERROR INTERN + } + return current_var->address; +} + +const int scope_get_variable_size() { + if (current_var == NULL) { + // ERROR INTERN + } + return current_var->length; +} + +const int scope_get_variable_type() { + if (current_var == NULL) { + // ERROR INTERN + } + return current_var->type; +} diff --git a/scope.h b/scope.h index b634e16..6771304 100644 --- a/scope.h +++ b/scope.h @@ -1,8 +1,16 @@ #pragma once #include +#include void scope_init(); void scope_open_local(); -void scope_close_local(); -const int scope_declare_variable(const std::string name, const int type, const int length); -//scope_get_variable... \ No newline at end of file +const int scope_close_local(); +void scope_open_block(); +void scope_close_block(); + +const uint32_t scope_declare_variable(const std::string name, const int type, const int length); + +const bool scope_variable_exists(const std::string name); +const uint32_t scope_get_variable_address(); +const int scope_get_variable_size(); +const int scope_get_variable_type(); diff --git a/types.cpp b/types.cpp new file mode 100644 index 0000000..f7d693e --- /dev/null +++ b/types.cpp @@ -0,0 +1,60 @@ +#include "types.h" +#include "variables.h" +#include + +struct t_struct { + std::string name; + int size; + std::vector members; +}; +static std::vector types; + +void types_init() { + types.clear(); + const t_struct type_number {"number", 4}; types.push_back(type_number); + const t_struct type_string {"string", 4}; types.push_back(type_string); +} + +const int types_add(const std::string name) { + for (auto t : types) if (t.name == name) return -1; + t_struct new_type; new_type.name = name; + types.push_back(new_type); + return types.size()-1; +} + +const int types_exist(const std::string name) { + for (int i = 0; i < types.size(); i++) if (types[i].name == name) return i; + return -1; +} + +const int types_get_length(const uint32_t type) { + if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai + return types[type].size; +} + +const int types_add_variable(const uint32_t type, const std::string name, const int var_type, const int length) { + if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai + for (auto m : types[type].members) if (m.name == name) return -1; + const t_variable new_var {name, var_type, length}; + types[type].members.push_back(new_var); + types[type].size += types_get_length(var_type) + length; + return types[type].members.size()-1; +} + +const int types_variable_exists(const uint32_t type, const std::string name) { + if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai + for (int i = 0; i < types[type].members.size(); i++) if (types[type].members[i].name == name) return i; + return -1; +} + +const int types_get_variable_type(const uint32_t type, const uint32_t variable) { + if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai + if (variable >= types[type].members.size()) return -1; // ERROR INTERN: No deuria donar-se mai + return types[type].members[variable].type; +} + +const int types_get_variable_length(const uint32_t type, const uint32_t variable) { + if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai + if (variable >= types[type].members.size()) return -1; // ERROR INTERN: No deuria donar-se mai + return types[type].members[variable].length; +} \ No newline at end of file diff --git a/types.h b/types.h new file mode 100644 index 0000000..7af3e28 --- /dev/null +++ b/types.h @@ -0,0 +1,13 @@ +#pragma once +#include + +void types_init(); + +const int types_add(const std::string name); +const int types_exist(const std::string name); +const int types_get_length(const uint32_t type); + +const int types_add_variable(const uint32_t type, const std::string name, const uint32_t var_type, const int length); +const int types_variable_exists(const uint32_t type, const std::string name); +const int types_get_variable_type(const uint32_t type, const uint32_t variable); +const int types_get_variable_length(const uint32_t type, const uint32_t variable); diff --git a/variables.h b/variables.h new file mode 100644 index 0000000..3bddd4c --- /dev/null +++ b/variables.h @@ -0,0 +1,8 @@ +#pragma once + +struct t_variable { + std::string name; + int type; + int length; + int address; +};