diff --git a/Makefile b/Makefile index 18cb7ce..c37401f 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC := gcc -etapa3: hashmap.o astree.o symbol_table.o parser.o scanner.o main.o +etapa4: hashmap.o astree.o symbol_table.o parser.o scanner.o main.o $(CC) -g -o $@ $^ scanner.c: scanner.l @@ -12,9 +12,9 @@ parser.c: parser.y %.o: %.c $(CC) -c $< -etapa3.tgz: clean - tar cvfz etapa3.tgz * +etapa4.tgz: clean + tar cvfz etapa4.tgz * .PHONY: clean clean: - rm -rf parser.c parser.h scanner.c etapa3 etapa3.tgz *.o *~ + rm -rf parser.c parser.h scanner.c etapa* etapa*.tgz *.o *~ diff --git a/astree.c b/astree.c index 3a316a2..478b36f 100644 --- a/astree.c +++ b/astree.c @@ -522,6 +522,17 @@ static int resolve_expr_type(struct astree *tree){ switch (tree->type) { case AST_SYM: + switch(((struct symtab_item *)tree->symbol->value)->code){ + case SYMBOL_LIT_INT: + case SYMBOL_LIT_REAL: + case SYMBOL_LIT_CHAR: + return ((struct symtab_item *)tree->symbol->value)->data_type; + case SYMBOL_IDENTIFIER: + if(((struct symtab_item *)tree->symbol->value)->id_type == ID_VAR) + return ((struct symtab_item *)tree->symbol->value)->data_type; + case SYMBOL_LIT_STRING: + return TP_INCOMP; + } return ((struct symtab_item *)tree->symbol->value)->data_type; /* Identifiers and Symbols @@ -662,7 +673,7 @@ static void second_pass(struct astree *tree, struct hashmap *declared_variables) /* Iterating in arguments*/ while((call_args != NULL) && (func_args != NULL)){ - func_type = ast_keyword_to_data_type(func_args->children[1]->type); + func_type = ((struct symtab_item*)func_args->children[2]->symbol->value)->data_type; call_type = resolve_expr_type(call_args->children[1]); if((func_type & call_type) == TP_INCOMP){ @@ -732,7 +743,7 @@ static void second_pass(struct astree *tree, struct hashmap *declared_variables) exit(4); } - if(vec_type & exp_type == TP_INCOMP){ + if((vec_type & exp_type) == TP_INCOMP){ fprintf(stderr, "SEMANTIC ERROR: Attribution to vector '%s' with a incompatible type.\n", tree->children[0]->symbol->key); @@ -756,7 +767,7 @@ static void second_pass(struct astree *tree, struct hashmap *declared_variables) var_type = info->data_type; exp_type = resolve_expr_type(tree->children[1]); - if(var_type & exp_type == TP_INCOMP){ + if((var_type & exp_type) == TP_INCOMP){ fprintf(stderr, "SEMANTIC ERROR: Attribution to variable '%s' with a incompatible type.\n", tree->children[0]->symbol->key); @@ -771,7 +782,7 @@ static void second_pass(struct astree *tree, struct hashmap *declared_variables) int func_type, ret_type; struct astree* func = (struct astree*)tree->symbol->value; - func_type = ast_keyword_to_data_type(func->children[0]->children[0]->type); + func_type = ((struct symtab_item*)func->children[0]->children[1]->symbol->value)->data_type; ret_type = resolve_expr_type(tree->children[0]); if((func_type & ret_type) == TP_INCOMP){ @@ -780,7 +791,17 @@ static void second_pass(struct astree *tree, struct hashmap *declared_variables) func->children[0]->children[1]->symbol->key); exit(4); } + } + if (tree->type == AST_READ){ + /* TODO: check if tree->children[0] is a variable*/ + struct symtab_item* info = (struct symtab_item *)tree->children[0]->symbol->value; + if (info->id_type != ID_VAR){ + fprintf(stderr, + "SEMANTIC ERROR: Identifier '%s' isn't a variable to be user in read statement.\n", + tree->children[0]->symbol->key); + exit(4); + } } } diff --git a/semantic.c b/semantic.c new file mode 100644 index 0000000..ecede13 --- /dev/null +++ b/semantic.c @@ -0,0 +1,447 @@ +#include "astree.h" + +static void first_pass(struct astree* tree, struct hashmap *declared_variables, struct astree* func); +static void second_pass(struct astree *tree, struct hashmap *declared_variables); + +/* `yes` is a dummy variable. Our hashmap implementation is being used here as + * a hashset. I.e., we only care about the keys. So `yes` is just a constant + * with no meaning to be put in the value field. */ +static char yes = 1; + +/* Annotate symbol table when tree is a declaration (i.e., of type AST_VAR, + * AST_VEC or AST_FHEADER). */ +static void annotate_declaration(struct astree *tree, struct hashmap *declared_variables) { + struct astree *id_node; + struct astree *type_node; + switch (tree->type) { + case AST_VAR: + id_node = tree->children[0]; + type_node = tree->children[1]; + break; + case AST_VEC: + id_node = tree->children[0]; + type_node = tree->children[1]; + break; + case AST_FHEADER: + id_node = tree->children[1]; + type_node = tree->children[0]; + break; + /* The parameters of function was definied as global variables to + to keep the compiler more simple. If it's needed to keep difference + in scopes variables does it necessary create others symbols tables.*/ + case AST_PARAMS: + /*AST_VAR like*/ + id_node = tree->children[2]; + type_node = tree->children[1]; + break; + } + + /* check redeclarations */ + if (hm_getref(declared_variables, id_node->symbol->key) != NULL) { + fprintf(stderr, "SEMANTIC ERROR: Redeclaration of identifier %s.\n", + id_node->symbol->key); + exit(4); + } + hm_put(declared_variables, id_node->symbol->key, &yes); + + struct symtab_item *item = id_node->symbol->value; + switch (tree->type) { + case AST_VAR: + case AST_PARAMS: + item->id_type = ID_VAR; + break; + case AST_VEC: + item->id_type = ID_VEC; + break; + case AST_FHEADER: + item->id_type = ID_FUN; + item->decl = tree; + break; + } + + switch (type_node->type) { + case AST_KW_BYTE: + item->data_type = TP_BYTE; + break; + case AST_KW_SHORT: + item->data_type = TP_SHORT; + break; + case AST_KW_LONG: + item->data_type = TP_LONG; + break; + case AST_KW_FLOAT: + item->data_type = TP_FLOAT; + break; + case AST_KW_DOUBLE: + item->data_type = TP_DOUBLE; + break; + } +} + +/* Annotate symbol table when tree is a literal or an id (i.e., of + * type AST_SYM) */ +static void annotate_symbol(struct astree *tree) { + struct symtab_item *item = tree->symbol->value; + switch (item->code) { + case SYMBOL_LIT_INT: + item->data_type = TP_SHORT; + break; + case SYMBOL_LIT_REAL: + item->data_type = TP_FLOAT; + break; + case SYMBOL_LIT_CHAR: + item->data_type = TP_BYTE; + break; + case SYMBOL_LIT_STRING: + break; + case SYMBOL_IDENTIFIER: + break; + } +} + +void ast_semantic_check(struct astree *tree) { + struct hashmap declared_variables; + struct astree* func; + hm_initialize(20, 0.6, sizeof(char), &declared_variables); + + first_pass(tree, &declared_variables, func); + second_pass(tree, &declared_variables); + + hm_terminate(&declared_variables); +} + +/* Traverses tree checking: + * 1. redeclarations + * 2. data_type in symbol table + * 3. id_type in symbol table */ +static void first_pass(struct astree *tree, struct hashmap *declared_variables, struct astree* func) { + if (tree == NULL) { + return; + } + + struct hm_item* symbol; + switch (tree->type) { + case AST_SYM: + annotate_symbol(tree); + break; + case AST_VAR: + case AST_VEC: + case AST_FHEADER: + case AST_PARAMS: + annotate_declaration(tree, declared_variables); + break; + case AST_FUNC: + func = tree; + break; + case AST_RETURN: + symbol = (struct hm_item *)calloc(1, sizeof(struct hm_item)); + symbol->value = func; + tree->symbol = symbol; + break; + } + + /* Annotating children before the root seems more intuitive, but I don't think + * it makes any difference. */ + for (int i = 0; i < AST_MAXCHILDREN; i++) + first_pass(tree->children[i], declared_variables, func); + +} + + +static void check_if_declared(struct astree *tree, struct hashmap *declared_variables) { + char *id = tree->symbol->key; + if (hm_getref(declared_variables, id) == NULL) { + fprintf(stderr, "SEMANTIC ERROR: Identifier %s isn't declared.\n", id); + exit(4); + } +} + +static int resolve_expr_type(struct astree *tree){ + if (tree == NULL) + return TP_ALL; + + switch (tree->type) { + case AST_SYM: + switch(((struct symtab_item *)tree->symbol->value)->code){ + case SYMBOL_LIT_INT: + case SYMBOL_LIT_REAL: + case SYMBOL_LIT_CHAR: + return ((struct symtab_item *)tree->symbol->value)->data_type; + case SYMBOL_IDENTIFIER: + if(((struct symtab_item *)tree->symbol->value)->id_type == ID_VAR) + return ((struct symtab_item *)tree->symbol->value)->data_type; + case SYMBOL_LIT_STRING: + return TP_INCOMP; + } + return ((struct symtab_item *)tree->symbol->value)->data_type; + + /* Identifiers and Symbols + IMPORTANT: on AST_VEC_SUB testing only the type + of the vector. The index check will be done in + other step*/ + case AST_VEC_SUB: + return ((struct symtab_item *)tree->children[0]->symbol->value)->data_type; + + /* Arithmetical*/ + case AST_ADD: case AST_SUB: case AST_MUL: + case AST_DIV: + return (resolve_expr_type(tree->children[0]) & + resolve_expr_type(tree->children[1])); + + /* Boolean Operators*/ + case AST_LT: case AST_GT: case AST_LE: + case AST_GE: case AST_EQ: case AST_NE: + case AST_AND: case AST_OR: + if ((resolve_expr_type(tree->children[0]) & + resolve_expr_type(tree->children[1])) != TP_INCOMP) + return TP_BOOLEAN; + + else + return TP_INCOMP; + + /* Unary Boolean Operator*/ + case AST_NOT: + if (resolve_expr_type(tree->children[0]) != TP_INCOMP) + return TP_BOOLEAN; + else + return TP_INCOMP; + + /* Function call + IMPORTANT: verifing only the type of the function, + arguments will be tested in other step. It's help + to modularization and some erros like a call function + that isn't save in a variable. + No test at symtab_get if it's a valid pointer*/ + case AST_CALL: + if (((struct symtab_item *)tree->children[0]->symbol->value)->id_type != ID_FUN) + return TP_INCOMP; + return ((struct symtab_item *)tree->children[0]->symbol->value)->data_type; + + case AST_EXP_BLOCK: + return resolve_expr_type(tree->children[0]); + } +} + + +static int ast_keyword_to_data_type(int keyword){ + switch (keyword) { + case AST_KW_BYTE: + return TP_BYTE; + case AST_KW_SHORT: + return TP_SHORT; + case AST_KW_LONG: + return TP_LONG; + case AST_KW_FLOAT: + return TP_FLOAT; + case AST_KW_DOUBLE: + return TP_DOUBLE; + } +} + +/* Traverses tree checking if: + * 1. variables used are declared + * 2. TODO: variables are used correctly according to their id_type + * 3. TODO: variables are used correctly according to their data_type + * 4. TODO: functions return the data type they were declared with + * 5. TODO: funcion calls have the correct type of arguments + * 6. TODO: vectors indexing is done using integers */ +static void second_pass(struct astree *tree, struct hashmap *declared_variables) { + if (tree == NULL) { + return; + } + + /* Annotating children before the root seems more intuitive, but I don't think + * it makes any difference. */ + for (int i = 0; i < AST_MAXCHILDREN; i++) { + second_pass(tree->children[i], declared_variables); + } + + /* it's a symbol and it's an identifier */ + if ((tree->type == AST_SYM) && + (((struct symtab_item *)tree->symbol->value)->code == SYMBOL_IDENTIFIER)) { + check_if_declared(tree, declared_variables); + } + + if ((tree->type == AST_WHEN) + || (tree->type == AST_WHEN_ELSE) + || (tree->type == AST_WHILE)) { + /* TODO: check if tree->children[0] is a boolean */ + if (resolve_expr_type(tree->children[0]) != TP_BOOLEAN) + exit(4); + } + + if (tree->type == AST_FOR) { + /* TODO: checkfaz necessário if tree->children[1] and tree->children[2] are numeric */ + /* TODO: check if tree->children[0] is a varible compatible with + * tree->children[1] and tree->children[2] */ + int type; + /* Test if identifier is a interger compatible type*/ + type = ((struct symtab_item *)tree->children[0]->symbol->value)->data_type; + if((type & TP_INTEGER) != TP_INTEGER){ + fprintf(stderr, "SEMANTIC ERROR: At a FOR statement identifier %s isn't a integer type.\n", + tree->children[0]->symbol->key); + exit(4); + } + /* Test if expressions are a interger compatible type*/ + type = resolve_expr_type(tree->children[1]); + if((type & TP_INTEGER) != TP_INTEGER){ + fprintf(stderr, + "SEMANTIC ERROR: At a FOR statement iterator isn't a interger type.\n"); + exit(4); + } + type = resolve_expr_type(tree->children[2]); + if((type & TP_INTEGER) != TP_INTEGER){ + fprintf(stderr, + "SEMANTIC ERROR: At a FOR statement iterator isn't a interger type.\n"); + exit(4); + } + } + + if (tree->type == AST_CALL) { + /* TODO: check if tree->children[0] is a function identifier */ + /* TODO: check if tree->children[1] is compatible with the function declaration */ + int func_type, call_type, arg_counter = 0; + struct symtab_item* info = (struct symtab_item *)tree->children[0]->symbol->value; + if(info->id_type != ID_FUN){ + fprintf(stderr, "SEMANTIC ERROR: Identifier '%s' isn't a function name.\n", + tree->children[0]->symbol->key); + exit(4); + } + + struct astree* func_args = ((struct astree*)info->decl)->children[2]; + struct astree* call_args = tree->children[1]; + + /* Iterating in arguments*/ + while((call_args != NULL) && (func_args != NULL)){ + func_type = ((struct symtab_item*)func_args->children[2]->symbol->value)->data_type; + call_type = resolve_expr_type(call_args->children[1]); + + if((func_type & call_type) == TP_INCOMP){ + fprintf(stderr, "SEMANTIC ERROR: Call for funcition '%s' has incompatible data argument %s.\n", + tree->children[0]->symbol->key, func_args->children[2]->symbol->key); + exit(4); + } + + /*Next parameter*/ + func_args = func_args->children[0]; + call_args = call_args->children[0]; + arg_counter ++; + } + if(((call_args != NULL) && (func_args == NULL)) || ((call_args == NULL) && (func_args != NULL))){ + fprintf(stderr, "SEMANTIC ERROR: Call for funcition '%s' has incompatible number of arguments.\n", + tree->children[0]->symbol->key); + exit(4); + } + + } + + if (tree->type == AST_VEC_SUB) { + /* TODO: check if tree->children[0] is a vector identifier */ + /* TODO: check if tree->children[1] is an integer */ + int vec_type, index_type; + struct symtab_item* info = (struct symtab_item *)tree->children[0]->symbol->value; + + if(info->id_type != ID_VEC){ + fprintf(stderr, "SEMANTIC ERROR: Identifier '%s' isn't a vector.\n", + tree->children[0]->symbol->key); + exit(4); + } + + vec_type = info->data_type; + index_type = resolve_expr_type(tree->children[1]); + + if ((index_type & TP_INTEGER) != TP_INTEGER){ + fprintf(stderr, + "SEMANTIC ERROR: Index of vector '%s' isn't a integer type.\n", + tree->children[0]->symbol->key); + exit(4); + } + } + + if (tree->type == AST_VEC_ATTR) { + /* TODO: check if tree->children[0] is a vector identifier */ + /* TODO: check if tree->children[1] is an integer */ + /* TODO: check if tree->children[2] has the same type as the vector */ + int vec_type, exp_type, index_type; + struct symtab_item* info = (struct symtab_item *)tree->children[0]->symbol->value; + + if(info->id_type != ID_VEC){ + fprintf(stderr, "SEMANTIC ERROR: Identifier '%s' isn't a vector.\n", + tree->children[0]->symbol->key); + exit(4); + } + + + vec_type = info->data_type; + index_type = resolve_expr_type(tree->children[1]); + exp_type = resolve_expr_type(tree->children[2]); + + if ((index_type & TP_INTEGER) != TP_INTEGER){ + fprintf(stderr, + "SEMANTIC ERROR: Index of vector '%s' isn't a integer type.\n", + tree->children[0]->symbol->key); + exit(4); + } + + if((vec_type & exp_type) == TP_INCOMP){ + fprintf(stderr, + "SEMANTIC ERROR: Attribution to vector '%s' with a incompatible type.\n", + tree->children[0]->symbol->key); + exit(4); + } + + } + + if (tree->type == AST_VAR_ATTR) { + /* TODO: check if tree->children[0] is a variable identifier */ + /* TODO: check if tree->children[1] has the same type as the varible */ + int var_type, exp_type; + struct symtab_item* info = (struct symtab_item *)tree->children[0]->symbol->value; + + if(info->id_type != ID_VAR){ + fprintf(stderr, "SEMANTIC ERROR: Identifier '%s' isn't a variable.\n", + tree->children[0]->symbol->key); + exit(4); + } + + var_type = info->data_type; + exp_type = resolve_expr_type(tree->children[1]); + + if((var_type & exp_type) == TP_INCOMP){ + fprintf(stderr, + "SEMANTIC ERROR: Attribution to variable '%s' with a incompatible type.\n", + tree->children[0]->symbol->key); + exit(4); + } + } + + if (tree->type == AST_RETURN) { + /* TODO: check if tree->children[1] has as a return statement compatible + * with tree->children[0]->children[0] type. That is, the return + * statement has a type equal to the function identifier's data_type */ + int func_type, ret_type; + struct astree* func = (struct astree*)tree->symbol->value; + + func_type = ((struct symtab_item*)func->children[0]->children[1]->symbol->value)->data_type; + ret_type = resolve_expr_type(tree->children[0]); + + if((func_type & ret_type) == TP_INCOMP){ + fprintf(stderr, + "SEMANTIC ERROR: Return of function '%s' has incompatible type.\n", + func->children[0]->children[1]->symbol->key); + exit(4); + } + } + + if (tree->type == AST_READ){ + /* TODO: check if tree->children[0] is a variable*/ + struct symtab_item* info = (struct symtab_item *)tree->children[0]->symbol->value; + + if (info->id_type != ID_VAR){ + fprintf(stderr, + "SEMANTIC ERROR: Identifier '%s' isn't a variable to be user in read statement.\n", + tree->children[0]->symbol->key); + exit(4); + } + } +} diff --git a/tests/Makefile b/tests/Makefile index 2b83f08..55e75ed 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,5 @@ -ALL_TARGETS := test_hashmap test_astree +COMP_BIN := ../etapa4 +ALL_TARGETS := caller test_hashmap .PHONY = all all: $(ALL_TARGETS) @@ -9,6 +10,12 @@ test_hashmap: test_hashmap.c ../hashmap.c test_astree: test_astree.c ../hashmap.c ../astree.c gcc -Wall -g -I .. -o test_astree $^ -.PHONY = clean +caller: caller.c + gcc -o caller caller.c + +.PHONY = clean semantic_test clean: rm -rf $(ALL_TARGETS) + +semantic_test: caller $(COMP_BIN) + ls -d $(PWD)/semantic/*.txt | xargs ./caller $(COMP_BIN) diff --git a/tests/caller.c b/tests/caller.c new file mode 100644 index 0000000..ef31ce1 --- /dev/null +++ b/tests/caller.c @@ -0,0 +1,59 @@ +#include +#include +#include +/* + This program is used to call a c executable n times for a set of arguments. + IMPORTANT: the called program must execute with only one argument. + + USAGE: + ./caller args + Example: + ./caller ./test 1 2 3 4 5 + It will execute 5 times test program showing the exit status of the program. + + Pratical use: + ls -d $PWD/*.* | xargs ./caller ./test + It will list all files in simple_path and redirect to caller execute with the + name of this file de test program. + + *Semantic Tests* + ls -d $PWD/semantic_tests/*.txt | xargs ./caller ../etapa4 +*/ + + + +static void file_name(char* const path, char *buffer){ + int i, len = strlen(path); + for(i = len; i >= 0; i--) + if(path[i] == '\\' || path[i] == '/') + break; + if(path[i] == '\\' || path[i] == '/') + i++; + strncpy(buffer, &path[i], len); +} + +int main(int argc, char* argv[]){ + int i; + int* result; + char command[2024]; + + if(argc < 2) + fprintf(stderr, "Error. Program to be called not defined!!!\n"); + char *program = argv[1]; + + result = (int *)calloc(argc, sizeof(int)); + + for(i = 2; i < argc ; i++){ + snprintf(command, sizeof(command), "%s %s", program, argv[i]); + result[i] = system(command); + } + + + for(i = 2; i < argc ; i++){ + file_name(argv[i], command); + printf("%-73sexit(%i)\n", command, result[i]/256); + } + + free(result); + return 0; +} diff --git a/tests/for_incomp_type.txt b/tests/for_incomp_type.txt deleted file mode 100644 index 324197e..0000000 --- a/tests/for_incomp_type.txt +++ /dev/null @@ -1,9 +0,0 @@ -a: float 0; -i: short 1; -short main(){ - for (i = 1.0 to 10) - print i " "; - a = 10; - for (a = 1 to 10) - print a " "; -}; diff --git a/tests/fun_dec.txt b/tests/fun_dec.txt deleted file mode 100644 index b798baa..0000000 --- a/tests/fun_dec.txt +++ /dev/null @@ -1,2 +0,0 @@ -long incn (long x, long n) - return x+n; diff --git a/tests/func_test.txt b/tests/func_test.txt deleted file mode 100644 index f44c619..0000000 --- a/tests/func_test.txt +++ /dev/null @@ -1,10 +0,0 @@ -a: short 1; -b: short 2; -short main(){ - for (a = 1 to 10) - print incn(10.1) " "; -}; - -short incn(short n){ -when (n == 1) then return 1 else return 1 > 0; -}; diff --git a/tests/sample_program.txt b/tests/sample_program.txt index f55a4dc..d5516d3 100644 --- a/tests/sample_program.txt +++ b/tests/sample_program.txt @@ -6,6 +6,7 @@ i: long 0; v: long[10] 0 0 0 0 0 0 0 0 0 0; mat: long[10]; f: float 10.55; +jh: double 10.0; c: byte 'x'; d: byte 65; @@ -13,7 +14,8 @@ d: byte 65; long main() { a = 10; - v#2 = v[10-1]; + jh = b; + v#2 = v[a]; for (i = 1 to 10) print i " "; @@ -24,10 +26,10 @@ long main() a = incn(a,1); i = i + 1; - a = (i + a + 1); + a = (i + a + 1.0); }; print "Incrementado algumas vezes fica " a "\n"; - when ((a==5) && (b==10)) then + when (a==5 && b==10) then print "Parou no meio\n"; when (a==11) then ; @@ -43,7 +45,7 @@ long incn (long x, long hg) short voidfunc() ; -long a (short y) { +long hd (short y) { when (y < 0) then { y = y + 1; return y; diff --git a/tests/sample_program_no_inner_scope.txt b/tests/sample_program_no_inner_scope.txt deleted file mode 100644 index 2332f2d..0000000 --- a/tests/sample_program_no_inner_scope.txt +++ /dev/null @@ -1,40 +0,0 @@ -// UFRGS - Compiladores - Marcelo Johann - 2017/1 - -b: long 0; -a: short 0; -i: long 0; -v: long[10] 0 0 0 0 0 0 0 0 0 0; -mat: long[10]; -f: float 10.55; -c: byte 'x'; -d: byte 65; - - -long main() - { - a = 10; - v#2 = v[10-1]; - for (i = 1 to 10) - print i " "; - - print " Digite um numero: \n"; - read i; - while (i<10) - { - a = voidfunc(); - i = i + 1; - a = (i + a + 1); - }; - print "Incrementado algumas vezes fica " a "\n"; - when (a==5 && b==10) then - print "Parou no meio\n"; - when (a==11) then - ; - when (a==11) then else - ; - ;;; - {;}; - {}; - }; - -short voidfunc() ; diff --git a/tests/semantic/correct.txt b/tests/semantic/correct.txt new file mode 100644 index 0000000..4675643 --- /dev/null +++ b/tests/semantic/correct.txt @@ -0,0 +1,48 @@ +a: float 0; +b: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + // Attr check and function call + a = 10; + v#1 = inc(a); + v#2 = hd(a, i); + i = main(); + v#4 = main() + v[3]; + a = main() + inc(a); + i = v[4] + inc(a); + a = v[4] + inc(a) + 4+5; + + // Ctrl commands + for (i = 1 to 10) + print i " "; + + for (i = v[1] to 10) + print i " "; + + while(a==1){ + + }; + + when (a==5 && b==10) then + print "Parou no meio\n"; + + when (!a) then else; + + // Read command + read a; +}; + +short inc(short n){ + return n+1; +}; + +long hd (short y, long x) { + when (y < 0) then { + y = y + 1; + return y; + } else { + return x; + }; +}; diff --git a/tests/duplicated_var_dec.txt b/tests/semantic/dup_var_dec_error1.txt similarity index 100% rename from tests/duplicated_var_dec.txt rename to tests/semantic/dup_var_dec_error1.txt diff --git a/tests/semantic/for_error1.txt b/tests/semantic/for_error1.txt new file mode 100644 index 0000000..dff3b95 --- /dev/null +++ b/tests/semantic/for_error1.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + for (i = 1 > a to 10) + print i " "; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/for_error2.txt b/tests/semantic/for_error2.txt new file mode 100644 index 0000000..58ecb01 --- /dev/null +++ b/tests/semantic/for_error2.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + for (i = 1 to 10 != 8) + print i " "; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/for_error3.txt b/tests/semantic/for_error3.txt new file mode 100644 index 0000000..9e70e1d --- /dev/null +++ b/tests/semantic/for_error3.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + for (i = 1 to 10.0) + print i " "; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/for_error4.txt b/tests/semantic/for_error4.txt new file mode 100644 index 0000000..8a30ec3 --- /dev/null +++ b/tests/semantic/for_error4.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + for (a = 1 to 10) + print i " "; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/func_call_error1.txt b/tests/semantic/func_call_error1.txt new file mode 100644 index 0000000..e320581 --- /dev/null +++ b/tests/semantic/func_call_error1.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = 10; + v#1 = inc(); +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/func_call_error2.txt b/tests/semantic/func_call_error2.txt new file mode 100644 index 0000000..5285da4 --- /dev/null +++ b/tests/semantic/func_call_error2.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = 10; + v#1 = inc(a); +}; + +short inc(){ + return 1; +}; diff --git a/tests/semantic/func_call_error3.txt b/tests/semantic/func_call_error3.txt new file mode 100644 index 0000000..cb00ae0 --- /dev/null +++ b/tests/semantic/func_call_error3.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = 10; + v#1 = inc(a); +}; + +short inc(short n, float b){ + return 1; +}; diff --git a/tests/semantic/func_call_error4.txt b/tests/semantic/func_call_error4.txt new file mode 100644 index 0000000..066c7f8 --- /dev/null +++ b/tests/semantic/func_call_error4.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = 10; + v#1 = inc(a, i); +}; + +short inc(short n){ + return 1; +}; diff --git a/tests/semantic/func_ret_error1.txt b/tests/semantic/func_ret_error1.txt new file mode 100644 index 0000000..7dc2f8b --- /dev/null +++ b/tests/semantic/func_ret_error1.txt @@ -0,0 +1,13 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +long hd (short y) { + when (y < 0) then { + y = y + 1; + return y; + } else { + return !x; + x = x + 1; + }; +}; diff --git a/tests/semantic/func_ret_error2.txt b/tests/semantic/func_ret_error2.txt new file mode 100644 index 0000000..441eecf --- /dev/null +++ b/tests/semantic/func_ret_error2.txt @@ -0,0 +1,13 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +long hd (short y) { + when (y < 0) then { + y = y + 1; + return y > 1; + } else { + return x; + x = x + 1; + }; +}; diff --git a/tests/semantic/read_error1.txt b/tests/semantic/read_error1.txt new file mode 100644 index 0000000..e71d081 --- /dev/null +++ b/tests/semantic/read_error1.txt @@ -0,0 +1,11 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + read v; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/read_error2.txt b/tests/semantic/read_error2.txt new file mode 100644 index 0000000..512d97d --- /dev/null +++ b/tests/semantic/read_error2.txt @@ -0,0 +1,11 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + read inc; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/undeclared_var.txt b/tests/semantic/undec_var_error1.txt similarity index 100% rename from tests/undeclared_var.txt rename to tests/semantic/undec_var_error1.txt diff --git a/tests/semantic/var_attr_error1.txt b/tests/semantic/var_attr_error1.txt new file mode 100644 index 0000000..21ced0c --- /dev/null +++ b/tests/semantic/var_attr_error1.txt @@ -0,0 +1,11 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = v; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/var_attr_error2.txt b/tests/semantic/var_attr_error2.txt new file mode 100644 index 0000000..43b1ffe --- /dev/null +++ b/tests/semantic/var_attr_error2.txt @@ -0,0 +1,11 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = inc; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/var_attr_error3.txt b/tests/semantic/var_attr_error3.txt new file mode 100644 index 0000000..8de2836 --- /dev/null +++ b/tests/semantic/var_attr_error3.txt @@ -0,0 +1,11 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = a && 1; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/var_attr_error4.txt b/tests/semantic/var_attr_error4.txt new file mode 100644 index 0000000..e28abe5 --- /dev/null +++ b/tests/semantic/var_attr_error4.txt @@ -0,0 +1,11 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = a + 1 + !3; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/vec_attr_error1.txt b/tests/semantic/vec_attr_error1.txt new file mode 100644 index 0000000..1e87dae --- /dev/null +++ b/tests/semantic/vec_attr_error1.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = 10; + v = a; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/vec_attr_error2.txt b/tests/semantic/vec_attr_error2.txt new file mode 100644 index 0000000..7a580c8 --- /dev/null +++ b/tests/semantic/vec_attr_error2.txt @@ -0,0 +1,11 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + v#a = 1; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/vec_attr_error3.txt b/tests/semantic/vec_attr_error3.txt new file mode 100644 index 0000000..1f044a9 --- /dev/null +++ b/tests/semantic/vec_attr_error3.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = 10; + v#1 = a < i; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/vec_attr_error4.txt b/tests/semantic/vec_attr_error4.txt new file mode 100644 index 0000000..87519fa --- /dev/null +++ b/tests/semantic/vec_attr_error4.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = 10; + v#1 = inc; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/vec_attr_error5.txt b/tests/semantic/vec_attr_error5.txt new file mode 100644 index 0000000..f2b0493 --- /dev/null +++ b/tests/semantic/vec_attr_error5.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = 10; + v#1.0 = v[1]; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/vec_attr_error6.txt b/tests/semantic/vec_attr_error6.txt new file mode 100644 index 0000000..eae0b9e --- /dev/null +++ b/tests/semantic/vec_attr_error6.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + a = 10; + v#1 = v; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/when_error1.txt b/tests/semantic/when_error1.txt new file mode 100644 index 0000000..a07c313 --- /dev/null +++ b/tests/semantic/when_error1.txt @@ -0,0 +1,12 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + when (b) then + print "Parou no meio\n"; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/semantic/while_error1.txt b/tests/semantic/while_error1.txt new file mode 100644 index 0000000..800ffc0 --- /dev/null +++ b/tests/semantic/while_error1.txt @@ -0,0 +1,13 @@ +a: float 0; +i: short 1; +v: long[10] 0 0 0 0 0 0 0 0 0 0; + +short main(){ + while(a){ + + }; +}; + +short inc(short n){ + return n+1; +}; diff --git a/tests/var_dec.txt b/tests/var_dec.txt deleted file mode 100644 index 1069c41..0000000 --- a/tests/var_dec.txt +++ /dev/null @@ -1,2 +0,0 @@ -a: short 0; -b: short 1; diff --git a/tests/vec_dec.txt b/tests/vec_dec.txt deleted file mode 100644 index fd2d6c1..0000000 --- a/tests/vec_dec.txt +++ /dev/null @@ -1 +0,0 @@ -v: long[10] 0 0 0 0 0 0 0 0 0 0;