#include "scope.h" #include "variables.h" #include "types.h" #include #include struct t_scope { std::vector variables; int total_size; }; 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() { global.variables.clear(); global.total_size = 0; local.variables.clear(); local.total_size = 0; while (!blocks.empty()) blocks.pop(); are_we_inside_local = false; } const bool scope_is_local() { return are_we_inside_local; } void scope_open_local() { are_we_inside_local = true; blocks.push(0); } 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; while (!blocks.empty()) blocks.pop(); local.variables.clear(); local.total_size = 0; are_we_inside_local = false; return return_value; } 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 int scope_declare_variable(const std::string name, const uint32_t type, const uint32_t 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 uint32_t address = scope.total_size; const t_variable var {name, type, length, address}; 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; } return false; } 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; }