first implementation of the sematic analysis
This commit is contained in:
parent
0edf2f7b17
commit
5a06c17fa4
|
@ -99,7 +99,7 @@
|
||||||
DEBUG("\"%s\" tokenized with \'ValStr\'", yytext); yylval.string = strdup(yytext); return(ValStr);};
|
DEBUG("\"%s\" tokenized with \'ValStr\'", yytext); yylval.string = strdup(yytext); return(ValStr);};
|
||||||
\"\"\"([^\"\n]|\\\n)*\"\"\" {
|
\"\"\"([^\"\n]|\\\n)*\"\"\" {
|
||||||
yytext = yytext +3;
|
yytext = yytext +3;
|
||||||
yytext[yyleng - 4] = 0;
|
yytext[yyleng - 6] = 0;
|
||||||
|
|
||||||
DEBUG("\"%s\" tokenized with \'ValMultistr\'", yytext); yylval.string = strdup(yytext); return(ValMultistr);};
|
DEBUG("\"%s\" tokenized with \'ValMultistr\'", yytext); yylval.string = strdup(yytext); return(ValMultistr);};
|
||||||
[ \r\t] { /* ignore whitespace */ };
|
[ \r\t] { /* ignore whitespace */ };
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <yacc/parser.tab.h>
|
#include <yacc/parser.tab.h>
|
||||||
#include <sys/col.h>
|
#include <sys/col.h>
|
||||||
#include <lex/util.h>
|
#include <lex/util.h>
|
||||||
|
#include <set/set.h>
|
||||||
|
|
||||||
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
||||||
|
|
||||||
|
@ -74,7 +75,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
root = AST_new_node(AST_Module, NULL);
|
root = AST_new_node(AST_Module, NULL);
|
||||||
yyparse();
|
yyparse();
|
||||||
|
create_set(root);
|
||||||
FILE *output = fopen("test.txt", "w");
|
FILE *output = fopen("test.txt", "w");
|
||||||
AST_fprint_graphviz(output, root);
|
AST_fprint_graphviz(output, root);
|
||||||
fclose(output);
|
fclose(output);
|
||||||
|
|
|
@ -0,0 +1,257 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ast/ast.h>
|
||||||
|
#include <set/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/log.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
GHashTable *declaredComposites;//pointer to composites with names,
|
||||||
|
GHashTable *declaredBoxes;//pointer to typeboxes
|
||||||
|
GArray *Scope;//last object is current scope
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Type *findType(AST_NODE_PTR currentNode){
|
||||||
|
|
||||||
|
const char *typekind = currentNode->children[currentNode->child_count -1]->value;
|
||||||
|
if (0 == strcmp(typekind, "int")||0 == strcmp(typekind, "float")){
|
||||||
|
|
||||||
|
Type *type = malloc(sizeof(Type));
|
||||||
|
type->nodePtr = currentNode;
|
||||||
|
if(AST_Typekind != currentNode->children[0]->kind){
|
||||||
|
DEBUG("Type is a Composite");
|
||||||
|
type->kind = TypeKindComposite;
|
||||||
|
|
||||||
|
|
||||||
|
CompositeType composite;
|
||||||
|
composite.nodePtr = currentNode;
|
||||||
|
|
||||||
|
|
||||||
|
if(0 == strcmp(typekind, "int")){
|
||||||
|
composite.primitive = Int;
|
||||||
|
}else{
|
||||||
|
composite.primitive = Float;
|
||||||
|
}
|
||||||
|
composite.sign = Signed;
|
||||||
|
|
||||||
|
size_t scalelist = 0;
|
||||||
|
if(AST_Sign == currentNode->children[0]->kind){
|
||||||
|
if(0 == strcmp(currentNode->children[0]->value, "unsigned")){
|
||||||
|
composite.sign = Unsigned;
|
||||||
|
}
|
||||||
|
scalelist = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
composite.scale = 1.0;
|
||||||
|
if(AST_List == currentNode->children[scalelist]->kind){
|
||||||
|
for (size_t i = 0; i < currentNode->children[scalelist]->child_count; i++){
|
||||||
|
if (0 == strcmp(currentNode->children[scalelist]->children[i]->value, "short") || 0 == strcmp(currentNode->children[scalelist]->children[i]->value, "half")){
|
||||||
|
composite.scale /= 2;
|
||||||
|
}else{
|
||||||
|
composite.scale *= 2;
|
||||||
|
}
|
||||||
|
if (0.25 > composite.scale || 8 > composite.scale) {
|
||||||
|
//TODO scale not right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type->impl.composite = composite;
|
||||||
|
|
||||||
|
|
||||||
|
}else{
|
||||||
|
type->kind = TypeKindPrimitive;
|
||||||
|
if(0 == strcmp(typekind, "int")){
|
||||||
|
type->impl.primitive = Int;
|
||||||
|
}else{
|
||||||
|
type->impl.primitive = Float;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}else if(g_hash_table_contains(declaredBoxes, typekind)){
|
||||||
|
if(AST_Typekind != currentNode->children[0]->kind){
|
||||||
|
//TODO composite Box try
|
||||||
|
}
|
||||||
|
return (Type *) g_hash_table_lookup(declaredBoxes, typekind);
|
||||||
|
}else if(g_hash_table_contains(declaredComposites, typekind)){
|
||||||
|
if(AST_Typekind != currentNode->children[0]->kind){
|
||||||
|
Type *composite = malloc(sizeof(Type));
|
||||||
|
|
||||||
|
*composite = *(Type*) g_hash_table_lookup(declaredComposites, typekind);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t scalelist = 0;
|
||||||
|
if(AST_Sign == currentNode->children[0]->kind){
|
||||||
|
if(0 == strcmp(currentNode->children[0]->value, "unsigned")){
|
||||||
|
composite->impl.composite.sign = Unsigned;
|
||||||
|
}else if(0 == strcmp(currentNode->children[0]->value, "unsigned")){
|
||||||
|
composite->impl.composite.sign = Signed;
|
||||||
|
}
|
||||||
|
scalelist = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(AST_List == currentNode->children[scalelist]->kind){
|
||||||
|
for (size_t i = 0; i < currentNode->children[scalelist]->child_count; i++){
|
||||||
|
if (0 == strcmp(currentNode->children[scalelist]->children[i]->value, "short") || 0 == strcmp(currentNode->children[scalelist]->children[i]->value, "half")){
|
||||||
|
composite->impl.composite.scale /= 2;
|
||||||
|
}else{
|
||||||
|
composite->impl.composite.scale *= 2;
|
||||||
|
}
|
||||||
|
if (0.25 > composite->impl.composite.scale || 8 > composite->impl.composite.scale) {
|
||||||
|
//TODO scale not right
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return composite;
|
||||||
|
}
|
||||||
|
return (Type *) g_hash_table_lookup(declaredComposites, typekind);
|
||||||
|
}else{
|
||||||
|
//TODO doesnt know typekind
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
StorageQualifier Qualifier_from_string(const char *str) {
|
||||||
|
if (!strncmp(str, "local", 5)) return Local;
|
||||||
|
if (!strncmp(str, "static", 6)) return Static;
|
||||||
|
if (!strncmp(str, "global", 6)) return Global;
|
||||||
|
PANIC("Provided string is not a storagequalifier: %s", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable **create_decl(AST_NODE_PTR currentNode){
|
||||||
|
DEBUG("create declaration");
|
||||||
|
Variable **variables = malloc(currentNode->children[currentNode->child_count -1]->child_count * sizeof(Variable));
|
||||||
|
|
||||||
|
VariableDeclaration decl;
|
||||||
|
decl.nodePtr = currentNode;
|
||||||
|
|
||||||
|
DEBUG("Child Count: %i", currentNode->child_count);
|
||||||
|
for (size_t i = 0; i < currentNode->child_count; i++){
|
||||||
|
|
||||||
|
switch(currentNode->children[i]->kind){
|
||||||
|
case AST_Storage:
|
||||||
|
DEBUG("fill Qualifier");
|
||||||
|
decl.qualifier = Qualifier_from_string(currentNode->children[i]->value);
|
||||||
|
break;
|
||||||
|
case AST_Type:
|
||||||
|
DEBUG("fill Type");
|
||||||
|
decl.type = findType(currentNode->children[i]);
|
||||||
|
break;
|
||||||
|
case AST_IdentList:
|
||||||
|
for(size_t i = 0; i < currentNode->children[currentNode->child_count -1]->child_count; i++){
|
||||||
|
Variable *variable = malloc(sizeof(Variable));
|
||||||
|
variable->kind = VariableKindDeclaration;
|
||||||
|
variable->nodePtr = currentNode;
|
||||||
|
variable->name = currentNode->children[currentNode->child_count -1]->children[i]->value;
|
||||||
|
variable->impl.declaration = decl;
|
||||||
|
variables[i] = variable;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//TODO PANIC maybe
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return variables;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isVariableInScope(const char* name){
|
||||||
|
|
||||||
|
for(size_t i = 0; i < Scope->len; i++){
|
||||||
|
if(g_hash_table_contains(((GHashTable **) Scope->data)[i], name))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fillTablesWithVars(GHashTable *variableTable,GHashTable *currentScope , Variable** content, size_t amount){
|
||||||
|
DEBUG("filling vars in scope and table");
|
||||||
|
for(size_t i = 0; i < amount; i++){
|
||||||
|
if(isVariableInScope(content[i]->name)){
|
||||||
|
DEBUG("this var already exist: ",content[i]->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_hash_table_insert(variableTable, (gpointer) content[i]->name, content[i] );
|
||||||
|
g_hash_table_insert(currentScope, (gpointer) content[i]->name, content[i] );
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Module *create_set(AST_NODE_PTR currentNode){
|
||||||
|
DEBUG("create root Module");
|
||||||
|
//create tables for types
|
||||||
|
declaredComposites = g_hash_table_new(g_str_hash,g_str_equal);
|
||||||
|
declaredBoxes = g_hash_table_new(g_str_hash,g_str_equal);
|
||||||
|
|
||||||
|
//create scope
|
||||||
|
Scope = g_array_new(FALSE, FALSE, sizeof(GHashTable*));
|
||||||
|
|
||||||
|
|
||||||
|
//building current scope for module
|
||||||
|
GHashTable *globalscope = malloc(sizeof(GHashTable*));
|
||||||
|
globalscope = g_hash_table_new(g_str_hash,g_str_equal);
|
||||||
|
g_array_append_val(Scope, globalscope);
|
||||||
|
|
||||||
|
Module *rootModule = malloc(sizeof(Module));
|
||||||
|
|
||||||
|
GHashTable *boxes = g_hash_table_new(g_str_hash,g_str_equal);
|
||||||
|
GHashTable *types = g_hash_table_new(g_str_hash,g_str_equal);
|
||||||
|
GHashTable *functions = g_hash_table_new(g_str_hash,g_str_equal);
|
||||||
|
GHashTable *variables = g_hash_table_new(g_str_hash,g_str_equal);
|
||||||
|
GArray *imports = g_array_new(FALSE, FALSE, sizeof(const char*));
|
||||||
|
|
||||||
|
rootModule->boxes = boxes;
|
||||||
|
rootModule->types = types;
|
||||||
|
rootModule->functions = functions;
|
||||||
|
rootModule->variables = variables;
|
||||||
|
rootModule->imports = imports;
|
||||||
|
|
||||||
|
DEBUG("created Module struct");
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t i = 0; i < currentNode->child_count; i++){
|
||||||
|
DEBUG("created Child: %i" ,currentNode->children[i]->kind);
|
||||||
|
switch(currentNode->children[i]->kind){
|
||||||
|
|
||||||
|
case AST_Decl:
|
||||||
|
if (1 == fillTablesWithVars(variables,globalscope,create_decl(currentNode->children[i]) ,currentNode->children[i]->children[currentNode->children[i]->child_count -1]->child_count)){
|
||||||
|
//TODO behandlung, wenn var schon existiert
|
||||||
|
DEBUG("var already exists");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DEBUG("filled successfull the module and scope with vars");
|
||||||
|
break;
|
||||||
|
case AST_Def:
|
||||||
|
case AST_Box:
|
||||||
|
case AST_Fun:
|
||||||
|
case AST_Import:
|
||||||
|
DEBUG("create Import");
|
||||||
|
g_array_append_val(imports, currentNode->children[i]->value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
INFO("Provided source file could not be parsed beecause of semantic error.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef _SET_H_
|
||||||
|
#define _SET_H_
|
||||||
|
|
||||||
|
#include <ast/ast.h>
|
||||||
|
|
||||||
|
void create_set(AST_NODE_PTR rootNodePtr );
|
||||||
|
|
||||||
|
#endif
|
|
@ -117,7 +117,7 @@ typedef struct Type_t {
|
||||||
|
|
||||||
typedef struct Typedefine_t {
|
typedef struct Typedefine_t {
|
||||||
const char* name;
|
const char* name;
|
||||||
Type type;
|
Type *type;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Typedefine;
|
} Typedefine;
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ typedef struct Typedefine_t {
|
||||||
*/
|
*/
|
||||||
typedef struct TypeValue_t {
|
typedef struct TypeValue_t {
|
||||||
// the type
|
// the type
|
||||||
Type type;
|
Type *type;
|
||||||
// UTF-8 representation of the type's value
|
// UTF-8 representation of the type's value
|
||||||
const char* value;
|
const char* value;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
|
@ -160,7 +160,7 @@ typedef enum IO_Qualifier_t {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct ParameterDeclaration_t {
|
typedef struct ParameterDeclaration_t {
|
||||||
Type type;
|
Type *type;
|
||||||
IO_Qualifier qualifier;
|
IO_Qualifier qualifier;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} ParameterDeclaration;
|
} ParameterDeclaration;
|
||||||
|
@ -173,7 +173,7 @@ typedef struct ParameterDefinition_t {
|
||||||
ParameterDeclaration declaration;
|
ParameterDeclaration declaration;
|
||||||
// value to initalize the declaration with
|
// value to initalize the declaration with
|
||||||
// NOTE: type of initializer and declaration MUST be equal
|
// NOTE: type of initializer and declaration MUST be equal
|
||||||
Expression initializer;
|
Expression *initializer;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} ParameterDefinition;
|
} ParameterDefinition;
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ typedef struct FunctionDefinition_t {
|
||||||
GArray* parameter;
|
GArray* parameter;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
// body of function
|
// body of function
|
||||||
Block body;
|
Block *body;
|
||||||
// name of function
|
// name of function
|
||||||
const char* name;
|
const char* name;
|
||||||
} FunctionDefinition;
|
} FunctionDefinition;
|
||||||
|
@ -239,7 +239,7 @@ typedef enum StorageQualifier_t {
|
||||||
|
|
||||||
typedef struct VariableDeclaration_t {
|
typedef struct VariableDeclaration_t {
|
||||||
StorageQualifier qualifier;
|
StorageQualifier qualifier;
|
||||||
Type type;
|
Type *type;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} VariableDeclaration;
|
} VariableDeclaration;
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ typedef struct VariableDeclaration_t {
|
||||||
*/
|
*/
|
||||||
typedef struct VariableDefiniton_t {
|
typedef struct VariableDefiniton_t {
|
||||||
VariableDeclaration declaration;
|
VariableDeclaration declaration;
|
||||||
Expression initializer;
|
Expression *initializer;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} VariableDefiniton;
|
} VariableDefiniton;
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ typedef struct Variable_t {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct TypeCast_t {
|
typedef struct TypeCast_t {
|
||||||
Type targetType;
|
Type *targetType;
|
||||||
Expression* operand;
|
Expression* operand;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} TypeCast;
|
} TypeCast;
|
||||||
|
@ -299,7 +299,7 @@ typedef struct TypeCast_t {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct Transmute_t {
|
typedef struct Transmute_t {
|
||||||
Type targetType;
|
Type *targetType;
|
||||||
Expression* operand;
|
Expression* operand;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Transmute;
|
} Transmute;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
#include <ast/ast.h>
|
#include <ast/ast.h>
|
||||||
#include <sys/col.h>
|
#include <sys/col.h>
|
||||||
|
|
||||||
extern int yylineno;
|
extern int yylineno;
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,7 +133,8 @@
|
||||||
%left '(' ')'
|
%left '(' ')'
|
||||||
|
|
||||||
%%
|
%%
|
||||||
program: program programbody {AST_push_node(root, $2);}
|
program: program programbody {AST_push_node(root, $2);
|
||||||
|
}
|
||||||
| programbody {AST_push_node(root, $1);};
|
| programbody {AST_push_node(root, $1);};
|
||||||
|
|
||||||
programbody: moduleimport {$$ = $1;}
|
programbody: moduleimport {$$ = $1;}
|
||||||
|
@ -365,7 +367,7 @@ decl: type ':' identlist {AST_NODE_PTR decl = AST_new_node(AST_Decl, NULL);
|
||||||
AST_push_node(decl, $1);
|
AST_push_node(decl, $1);
|
||||||
AST_push_node(decl, $2);
|
AST_push_node(decl, $2);
|
||||||
AST_push_node(decl, $4);
|
AST_push_node(decl, $4);
|
||||||
$$ = decl;}
|
$$ = decl;};
|
||||||
|
|
||||||
|
|
||||||
definition: decl '=' expr { AST_NODE_PTR def = AST_new_node(AST_Def, NULL);
|
definition: decl '=' expr { AST_NODE_PTR def = AST_new_node(AST_Def, NULL);
|
||||||
|
|
Loading…
Reference in New Issue