Skip to content

Commit

Permalink
Trying to find the bug on return :/
Browse files Browse the repository at this point in the history
  • Loading branch information
jefersonla committed Nov 10, 2016
1 parent b48ca92 commit 33c827e
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 33 deletions.
4 changes: 2 additions & 2 deletions analisador-semantico.y
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ programa : bloco {
/* -- Block are sections of code -- */
bloco : comando_list comandoret {
/* Allocate Token and Childs */
allocateTokenAndChilds(&$$, TI_BLOCO, 2, $1, $2);
allocateTokenAndChilds(&$$, TI_BLOCO_RETURN, 2, $1, $2);

/* Allocate a concatenation of token text strings */
allocateTokenText($$, 5, "[bloco", $1->token_str, " ", $2->token_str, "]");
Expand Down Expand Up @@ -578,7 +578,7 @@ term_elseif : term_elseif T_ELSEIF exp T_THEN bloco {

comandoret : T_RETURN listaexp T_SEMICOL {
/* Allocate Token and append childs */
allocateTokenAndChilds( &$$, TI_RETURN_EXPLIST, 2, $1, $2);
allocateTokenAndChilds( &$$, TI_RETURN_EXPLIST, 3, $1, $2, $3);

/* Allocate a concatenation of token text strings */
allocateTokenText( $$, 3,
Expand Down
122 changes: 96 additions & 26 deletions codegen_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,14 +858,33 @@ bool cgenIf(TokenNode *if_token, SymbolTable *actual_symbol_table){
}

/* Get all blocks */
block_list = listGetTokensByType(list_elseif->child_list, TI_BLOCO);
block_list = newTokenList();

/* Check if block list is valid */
/* Check if the list of blocks is valid */
if(block_list == NULL){
printError("BLOCK LIST IS INVALID!");
return false;
}

/* Now as we have two types of block we should do it manually */
/* Pick all blocks of elseif */
for(i = 1; i <= list_elseif->child_list->length; i++){

/* Get the token node */
token_node = listGetTokenByIndex(list_elseif->child_list, i);

/* Check if this token node is valid or not */
if(token_node == NULL){
printError("INVALID TOKEN NODE!");
return false;
}

/* If this token is an expression add him to the token list */
if(IS_BLOCK(token_node->token_type)){
listAddToken(block_list, token_node);
}
}

/* Add the other 'else if' conditionals */
for(i = 1; i <= exp_list->length; i++){

Expand Down Expand Up @@ -970,7 +989,7 @@ bool cgenIf(TokenNode *if_token, SymbolTable *actual_symbol_table){
* @param actual_symbol_table The actual or previous symbol table.
* @return true if there's no error on execution and false otherwise.
*/
bool cgenFunction(TokenNode *function_def_token, SymbolTable *actual_symbol_table) {
bool cgenFunction(TokenNode *function_def_token, SymbolTable *actual_symbol_table){
int i;
SymbolTable *new_table;
SymbolTable *new_params_table;
Expand Down Expand Up @@ -1075,14 +1094,23 @@ bool cgenFunction(TokenNode *function_def_token, SymbolTable *actual_symbol_tabl
/* Pop local variables on stack */
addInstructionMainQueueFormated(mips_pop_params, (new_table->shift_address));

/* Finish function definition poping Record Activation */
addInstructionMainQueueFormated(mips_end_function_def, (t_name->lex_str));

/* Pop parameters on stack */
addInstructionMainQueueFormated(mips_pop_params, (new_params_table->shift_address));

/* Add final part */
addInstructionMainQueueFormated(mips_end_function_def2, (t_name->lex_str));
/*
Check if we have a block with return or not. Functions which return values, should push the return and jr
acordingle, and the other who don't have values to return should pop local variables and jump to end_function_%s.
Functions who have more than one return rule, NEED TO RETURN THE SAME QUANTITY OF EXPRESSIONS! OF THE MAIN RETURN!
On void functions (functions without a return)
*/
if(block_token->token_type == TI_BLOCO){

/* Finish function definition poping Record Activation */
addInstructionMainQueueFormated(mips_end_function_def, (t_name->lex_str));

/* Pop parameters on stack */
addInstructionMainQueueFormated(mips_pop_params, (new_params_table->shift_address));

/* Add final part */
addInstructionMainQueueFormated(mips_end_function_def2, (t_name->lex_str));
}

/* Delete local symbol table and parameters symbol table */
deleteSymbolTable(&new_table);
Expand Down Expand Up @@ -1398,6 +1426,9 @@ bool cgenCommand(TokenNode *command_token, SymbolTable *actual_symbol_table){
bool cgenCommandReturn(TokenNode *command_return_token, SymbolTable *actual_symbol_table){
int num_exp;
int return_shift;
char *function_name;
TokenNode *token_name;
TokenNode *root_token;
TokenNode *list_exp_token;

/* Check if token return command is valid */
Expand Down Expand Up @@ -1451,31 +1482,70 @@ bool cgenCommandReturn(TokenNode *command_return_token, SymbolTable *actual_symb
*/
if(command_return_token->token_type == TI_RETURN){
/* Empty return */
num_exp = 0;
/* Pop local variables on stack */
addInstructionMainQueueFormated(mips_pop_params, (actual_symbol_table->shift_address));

/* Assign a null value to our list_exp_token */
list_exp_token = NULL;
}
else{
/* Get list of expressions */
list_exp_token = listGetTokenByIndex(command_return_token->child_list, 2);
root_token = command_return_token->root_token;

/* Check the integrity of this pointer */
if(list_exp_token == NULL){
printError("FAILED TO RETRIEVE LIST EXP TOKEN!");
/* Recurse and get the name of the function which is being returned */
while(root_token != NULL){

printf("0x%X -- %s\n", root_token->token_type, root_token->token_str);

/* If the actual token is of the type we wanted stop */
if((root_token->token_type == TI_FUNCTION) || (root_token->token_type == TI_FUNCTION_PARAM)){
break;
}

/* Get the next 'previous token' */
root_token = root_token->root_token;
}

/* If we can't find a function definition we are on main, and need to use a specific jump to end */
if(root_token == NULL){
instructionQueueEnqueueInstruction(main_instruction_queue, "\tj end_main_function # End of main\n", true);

/* Return success */
return true;
}

/* Get token name of a function definition */
token_name = listGetTokenByIndex(root_token->child_list, 2);

/* Check if this token name is valid */
if(token_name == NULL){
printError("INVALID FUNCTION NAME!");
return false;
}

/* List of exp returned */
num_exp = (list_exp_token->child_list->length / 2) + 1;
/* Pick the pointer of the string of the function name */
function_name = token_name->lex_str;

/* Add jump to function return */
addInstructionMainQueueFormated(mips_end_of_function, function_name);

/* Return success */
return true;
}
/* Get list of expressions */
list_exp_token = listGetTokenByIndex(command_return_token->child_list, 2);

/* Check the integrity of this pointer */
if(list_exp_token == NULL){
printError("FAILED TO RETRIEVE LIST EXP TOKEN!");
return false;
}

/* List of exp returned */
num_exp = (list_exp_token->child_list->length / 2) + 1;


/* Calculate the necessary shift */
return_shift = num_exp * 4;

/* Perform shift if it's need */


/* Return success */
return true;
}
Expand Down Expand Up @@ -1507,8 +1577,8 @@ bool cgenBlockCode(TokenNode *block_token, SymbolTable *previous_scope){
/* Generate command list code */
cgenCommandList(command_list_token, previous_scope);

/* Check if there are a return command */
if(block_token->child_list->length > 1){
/* Check if this block has a return command */
if(block_token->token_type == TI_BLOCO_RETURN){

/* Command return assign */
command_return_token = listGetTokenByIndex(block_token->child_list, 2);
Expand Down
3 changes: 3 additions & 0 deletions codegen_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ extern const char mips_start_function_def[];
/* Continuation of function definition */
extern const char mips_start_function_def2[];

/* Empty return */
extern const char mips_end_of_function[];

/* End of function definition */
extern const char mips_end_function_def[];

Expand Down
5 changes: 5 additions & 0 deletions codegen_models.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,11 +585,16 @@ const char mips_start_function_def2[] =

/* -- BLOCK -- */

/* Empty return */
const char mips_end_of_function[] =
"end_function_%s: # Jump to the end of this void function\n";

/* End of function definition */
const char mips_end_function_def[] =
"end_function_%s:\n"
"\tlw $ra, 4($sp)\n"
"\tlw $fp, 8($sp)\n"
"\tlw $a0, " GLOBAL_SYSTEM_VARIABLE_PREFIX "nil_val # Load nil as return\n"
"\taddiu $sp, $sp, 8\n";

/* -- POP PARAMETERS -- */
Expand Down
12 changes: 8 additions & 4 deletions parser.defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
#define PARSER_DEFS_H

/* Non Terminals Defines */
#define TI_PROGRAMA 0xCAF1
#define TI_BLOCO 0xCAF2
#define TI_PROGRAMA 0xCAF0
#define TI_BLOCO 0xCAF1
#define TI_BLOCO_RETURN 0xCAF2
#define TI_COMANDO 0xCAF3
#define TI_COMANDORET 0xCAF4
#define TI_EXP 0xCAF5
Expand All @@ -14,6 +15,9 @@
#define TI_TERM_ELSEIF 0xCAFA
#define TI_LABEL 0xCAFB

/* Check if it is a block */
#define IS_BLOCK(X) ((X == TI_BLOCO) || (X == TI_BLOCO_RETURN))

/* Extra Non Terminals */
#define TI_BLOCO_COMANDO 0xCAFC
#define TI_ASSIGN 0xCAFE
Expand All @@ -31,11 +35,11 @@
#define TI_RETURN 0xCB0A

/* Expressions */
#define IS_FUNCTION(X) ((X == TI_CALL_FUNCTION) || (X == TI_CALL_FUNCTION_PAR))
#define IS_CALL_FUNCTION(X) ((X == TI_CALL_FUNCTION) || (X == TI_CALL_FUNCTION_PAR))
#define IS_NUMBER(X) (X == T_NUMBER)
#define IS_NAME(X) (X == T_NAME)
#define IS_NIL(X) (X == T_NIL)
#define IS_EXPRESSION(X) (((X >= 0xCB0B) && (X <= 0xCB24)) || IS_FUNCTION(X) || IS_NUMBER(X) || IS_NAME(X) || IS_NIL(X))
#define IS_EXPRESSION(X) (((X >= 0xCB0B) && (X <= 0xCB24)) || IS_CALL_FUNCTION(X) || IS_NUMBER(X) || IS_NAME(X) || IS_NIL(X))

/* Unary Operands */
#define IS_UNARY_OPERAND(X) ((X >= 0xCB0B) && (X <= 0xCB0D))
Expand Down
14 changes: 13 additions & 1 deletion test4.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,16 @@ for i = 0, 10 do
end
print(i)
print(1222333444)
end
end

function z()
for i = 0, 10 do
print(i)

if i == 5 then
return
end
end
end

z()

0 comments on commit 33c827e

Please sign in to comment.