Skip to content

Commit

Permalink
Checking type of a expression, crash at symtab_get function, checking…
Browse files Browse the repository at this point in the history
… for/while/when/else.
  • Loading branch information
bfbechlin committed Jun 8, 2017
1 parent 7b99770 commit f62e891
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 52 deletions.
173 changes: 141 additions & 32 deletions astree.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
#include <stdlib.h>
#include <stdio.h>

/*REMOVE!!!*/
static const char *data_type_to_string[] = {
"", "double", "", "float", "", "long", "", "",
"", "", "", "", "", "", "", "short",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "byte",
"boolean"
};

struct astree *ast_create(int type, struct hm_item *symbol,
struct astree *c0,
struct astree *c1,
Expand Down Expand Up @@ -107,6 +116,12 @@ void ast_fprint(FILE *stream, int level, struct astree *tree) {
}
}

static void print_identation(FILE* stream, int level){
int i;
for(i = 0; i < level; i++)
fprintf(stream, " ");
}

void ast_make_source(FILE* stream, struct astree* tree, int level){
if (tree == NULL)
return;
Expand Down Expand Up @@ -343,12 +358,6 @@ void ast_make_source(FILE* stream, struct astree* tree, int level){
}
}

void print_identation(FILE* stream, int level){
int i;
for(i = 0; i < level; i++)
fprintf(stream, " ");
}

static void first_pass(struct astree* tree, struct hashmap *declared_variables);
static void second_pass(struct astree *tree, struct hashmap *declared_variables);

Expand All @@ -370,19 +379,18 @@ static void annotate_declaration(struct astree *tree, struct hashmap *declared_v
case AST_VEC:
id_node = tree->children[0];
type_node = tree->children[1];
first_pass(tree->children[2], declared_variables);
first_pass(tree->children[3], declared_variables);
break;
case AST_FHEADER:
id_node = tree->children[1];
type_node = tree->children[0];

/* TODO: Since here tree->children[2]->children[2] is a list of parameters,
* we might have to create a new scope for those variables declared here.
* Right now, this accomplishes nothing, since this node is of type
* AST_IDENTIFIER. Test program with the argument of `tests/fun_dec.txt`
* to see. */
first_pass(tree->children[2], declared_variables);
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;
}

Expand All @@ -396,6 +404,7 @@ static void annotate_declaration(struct astree *tree, struct hashmap *declared_v
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:
Expand Down Expand Up @@ -431,10 +440,10 @@ 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_LONG;
item->data_type = TP_SHORT;
break;
case SYMBOL_LIT_REAL:
item->data_type = TP_DOUBLE;
item->data_type = TP_FLOAT;
break;
case SYMBOL_LIT_CHAR:
item->data_type = TP_BYTE;
Expand Down Expand Up @@ -478,6 +487,7 @@ static void first_pass(struct astree *tree, struct hashmap *declared_variables)
case AST_VAR:
case AST_VEC:
case AST_FHEADER:
case AST_PARAMS:
annotate_declaration(tree, declared_variables);
break;
}
Expand All @@ -491,6 +501,73 @@ static void check_if_declared(struct astree *tree, struct hashmap *declared_vari
}
}

static int resolve_expr_type(struct astree *tree){
if (tree == NULL)
return TP_ALL;

struct symtab_item* item;

switch (tree->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_SYM: case AST_VEC_SUB:
return ((struct symtab_item *)tree->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 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:
printf("%s\n", tree->children[0]->symbol->key);
return TP_ALL;
/*
//Quebrando código!!!
symtab_get(tree->children[0]->symbol->key, item);
if (item->id_type != ID_FUN)
return TP_INCOMP;
return item->data_type;
*/
case AST_EXP_BLOCK:
return resolve_expr_type(tree->children[0]);
}
}

/* Search for a child node */
static int search_return(struct astree *tree, struct astree **node,
struct astree **father){
}

/* Traverses tree checking if:
* 1. variables used are declared
* 2. TODO: variables are used correctly according to their id_type
Expand All @@ -515,29 +592,39 @@ static void second_pass(struct astree *tree, struct hashmap *declared_variables)
check_if_declared(tree, declared_variables);
}

if ( (tree->type == AST_ADD)
|| (tree->type == AST_SUB)
|| (tree->type == AST_MUL)
|| (tree->type == AST_DIV)
|| (tree->type == AST_LT)
|| (tree->type == AST_GT)
|| (tree->type == AST_LE)
|| (tree->type == AST_GE)
|| (tree->type == AST_EQ)
|| (tree->type == AST_NE)) {
/* TODO: check if tree->children[0] and tree->children[1] are numeric */
}

if ( (tree->type == AST_WHEN)
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: check if tree->children[1] and tree->children[2] are numeric */
/* 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) {
Expand All @@ -558,11 +645,33 @@ static void second_pass(struct astree *tree, struct hashmap *declared_variables)
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 is a incompatible type.\n",
tree->children[0]->symbol->key);
exit(4);
}
}

if (tree->type == AST_FUNC) {
/* 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 */
struct astree *node = tree->children[0]->children[1];
unsigned int func_type =
((struct symtab_item *)node->symbol->value)->data_type;

}
}
3 changes: 0 additions & 3 deletions astree.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ void ast_fprint(FILE *stream, int level, struct astree *tree);
/* Recreate the program trought tree to a stream. */
void ast_make_source(FILE* stream, struct astree* tree, int level);

/* Internal function to help make source*/
void print_identation(FILE* stream, int level);

/* Does a semantic check on `tree`. */
void ast_semantic_check(struct astree* tree);
#endif /* ifndef AST_H */
19 changes: 11 additions & 8 deletions symbol_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
#include "hashmap.h"
#include "symbol_table.h"

struct hashmap hash;
static struct hashmap hash;

void symtab_init(void){
hm_initialize(8, 0.5, sizeof(struct symtab_item), &hash);
}

struct hm_item *symtab_insert(char* symbol, int code){
struct hm_item *symtab_insert(const char* symbol, int code){
struct symtab_item item;
item.code = code;
item.data_type = 0;
Expand All @@ -20,17 +20,20 @@ struct hm_item *symtab_insert(char* symbol, int code){
return hm_getref(&hash, symbol);
}

int symtab_get(const char* symbol, struct symtab_item* dummy){
return hm_get(&hash, symbol, (void*) dummy);
}

void symtab_print(void){
hm_fprint(stdout, &hash, 0);
}

static const char *data_type_to_string[] = {
"",
"byte",
"short",
"long",
"float",
"double"
"", "double", "", "float", "", "long", "", "",
"", "", "", "", "", "", "", "short",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "byte",
"boolean"
};

static const char *id_type_to_string[] = {
Expand Down
27 changes: 18 additions & 9 deletions symbol_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,23 @@
#define SYMBOL_LIT_STRING 4
#define SYMBOL_IDENTIFIER 5

#define ID_VAR 1;
#define ID_VEC 2;
#define ID_FUN 3;
#define ID_VAR 1
#define ID_VEC 2
#define ID_FUN 3

#define TP_BYTE 1;
#define TP_SHORT 2;
#define TP_LONG 3;
#define TP_FLOAT 4;
#define TP_DOUBLE 5;

#define TP_DOUBLE 1
#define TP_FLOAT 3
#define TP_LONG 5
#define TP_SHORT 15
#define TP_BYTE 31
#define TP_BOOLEAN 32

/* Test masks compatibility*/
#define TP_ALL ~(0)
#define TP_INCOMP 0
#define TP_INTEGER 5
#define TP_FLOATING 1

/**
* Symbols are:
Expand Down Expand Up @@ -46,7 +54,8 @@ struct symtab_item {
};

void symtab_init(void);
struct hm_item *symtab_insert(char* symbol, int code);
struct hm_item *symtab_insert(const char* symbol, int code);
int symtab_get(const char* symbol, struct symtab_item* dummy);
void symtab_print(void);
void symtab_fprint_item(FILE *stream, struct symtab_item *item);
void symtab_destroy(void);
Expand Down
9 changes: 9 additions & 0 deletions tests/for_incomp_type.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
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 " ";
};

0 comments on commit f62e891

Please sign in to comment.