summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkugwa <kugwa2000@gmail.com>2015-12-08 01:40:52 +0800
committerkugwa <kugwa2000@gmail.com>2015-12-08 01:40:52 +0800
commit1eb637f6f8d72a2ed09ec4b3548ed176f2d91504 (patch)
tree844fcf473e78c14a20173c86300ba60586079a6a
parent2a48042298c8b6bb8cee62aafd3763ec302c954a (diff)
downloadcompiler2015-1eb637f6f8d72a2ed09ec4b3548ed176f2d91504.tar
compiler2015-1eb637f6f8d72a2ed09ec4b3548ed176f2d91504.tar.gz
compiler2015-1eb637f6f8d72a2ed09ec4b3548ed176f2d91504.tar.bz2
compiler2015-1eb637f6f8d72a2ed09ec4b3548ed176f2d91504.tar.lz
compiler2015-1eb637f6f8d72a2ed09ec4b3548ed176f2d91504.tar.xz
compiler2015-1eb637f6f8d72a2ed09ec4b3548ed176f2d91504.tar.zst
compiler2015-1eb637f6f8d72a2ed09ec4b3548ed176f2d91504.zip
Can declare functions with empty blocks
get_array_size() is modified to handle empty dimension fields.
-rw-r--r--src/semantic-analysis.c91
1 files changed, 73 insertions, 18 deletions
diff --git a/src/semantic-analysis.c b/src/semantic-analysis.c
index 181f5db..fbab897 100644
--- a/src/semantic-analysis.c
+++ b/src/semantic-analysis.c
@@ -208,24 +208,28 @@ static size_t *get_array_size(CcmmcAst *id_array, size_t *array_dimension)
size_t *array_size = malloc(sizeof(size_t) * dim_count);
ERR_FATAL_CHECK(array_size, malloc);
for (dim = id_array->child; dim != NULL; dim = dim->right_sibling, dim_index++) {
- CcmmcValueConst value = eval_const_expr(dim);
- if (value.kind == CCMMC_KIND_CONST_ERROR) {
- free(array_size);
- return NULL;
+ if (dim->type_node == CCMMC_AST_NODE_NUL)
+ array_size[dim_index] = 0;
+ else {
+ CcmmcValueConst value = eval_const_expr(dim);
+ if (value.kind == CCMMC_KIND_CONST_ERROR) {
+ free(array_size);
+ return NULL;
+ }
+ if (value.kind != CCMMC_KIND_CONST_INT) {
+ fprintf(stderr, ERROR("Array subscript is not an integer."),
+ dim->line_number);
+ free(array_size);
+ return NULL;
+ }
+ if (value.const_int <= 0) {
+ fprintf(stderr, ERROR("Array size must be positive."),
+ dim->line_number);
+ free(array_size);
+ return NULL;
+ }
+ array_size[dim_index] = value.const_int;
}
- if (value.kind != CCMMC_KIND_CONST_INT) {
- fprintf(stderr, ERROR("Array subscript is not an integer."),
- dim->line_number);
- free(array_size);
- return NULL;
- }
- if (value.const_int <= 0) {
- fprintf(stderr, ERROR("Array size must be positive."),
- dim->line_number);
- free(array_size);
- return NULL;
- }
- array_size[dim_index] = value.const_int;
}
*array_dimension = dim_count;
@@ -461,9 +465,60 @@ static bool process_variable(
return any_error;
}
-static bool process_function(CcmmcAst *function_decl, CcmmcSymbolTable *table)
+static bool process_function(CcmmcAst *func_decl, CcmmcSymbolTable *table)
{
bool any_error = false;
+ size_t param_count = 0;
+ CcmmcSymbolType *param_list = NULL;
+ size_t i;
+ CcmmcAst *param;
+
+ // Create an entry for the function in global scope
+ if (func_decl->child->right_sibling->right_sibling->child != NULL){
+ for (param = func_decl->child->right_sibling->right_sibling->child; param != NULL; param = param->right_sibling, param_count++);
+ param_list = malloc(sizeof(CcmmcSymbolType) * param_count);
+ for (param = func_decl->child->right_sibling->right_sibling->child, i = 0; i < param_count; param = param->right_sibling, i++) {
+ param_list[i].type_base = ccmmc_symbol_table_retrive(table, param->child->value_id.name)->type.type_base;
+ if (param->child->right_sibling->value_id.kind == CCMMC_KIND_ID_ARRAY)
+ param_list[i].array_size = get_array_size(param->child->right_sibling, &param_list[i].array_dimension);
+ else
+ param_list[i].array_dimension = 0;
+ param_list[i].param_valid = false;
+ }
+ }
+ CcmmcSymbolType func_type = {
+ .type_base = ccmmc_symbol_table_retrive(table, func_decl->child->value_id.name)->type.type_base,
+ .array_dimension = 0,
+ .param_valid = true,
+ .param_count = param_count,
+ .param_list = param_list };
+ ccmmc_symbol_table_insert(table, func_decl->child->right_sibling->value_id.name, CCMMC_SYMBOL_KIND_FUNCTION, func_type);
+
+ // Push a new scope for the function
+ ccmmc_symbol_table_open_scope(table);
+ // Insert builtin types
+ ccmmc_symbol_table_insert(table, "int", CCMMC_SYMBOL_KIND_TYPE,
+ (CcmmcSymbolType){ .type_base = CCMMC_AST_VALUE_INT });
+ ccmmc_symbol_table_insert(table, "float", CCMMC_SYMBOL_KIND_TYPE,
+ (CcmmcSymbolType){ .type_base = CCMMC_AST_VALUE_FLOAT });
+ ccmmc_symbol_table_insert(table, "void", CCMMC_SYMBOL_KIND_TYPE,
+ (CcmmcSymbolType){ .type_base = CCMMC_AST_VALUE_VOID });
+ // Insert the parameters
+ CcmmcSymbol *func = ccmmc_symbol_table_retrive(table, func_decl->child->right_sibling->value_id.name);
+ for (param = func_decl->child->right_sibling->right_sibling->child, i = 0; i < param_count; param = param->right_sibling, i++) {
+ if (ccmmc_symbol_scope_exist(table->current, param->child->right_sibling->value_id.name)) {
+ any_error = true;
+ fprintf (stderr, ERROR("ID `%s' redeclared."),
+ param->child->right_sibling->line_number, param->child->right_sibling->value_id.name);
+ continue;
+ }
+ ccmmc_symbol_table_insert(table, param->child->right_sibling->value_id.name, CCMMC_SYMBOL_KIND_VARIABLE, func->type.param_list[i]);
+ }
+
+ // Process the list of local declarations
+
+ // Process the list of statements
+
return any_error;
}