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);};
|
||||
\"\"\"([^\"\n]|\\\n)*\"\"\" {
|
||||
yytext = yytext +3;
|
||||
yytext[yyleng - 4] = 0;
|
||||
yytext[yyleng - 6] = 0;
|
||||
|
||||
DEBUG("\"%s\" tokenized with \'ValMultistr\'", yytext); yylval.string = strdup(yytext); return(ValMultistr);};
|
||||
[ \r\t] { /* ignore whitespace */ };
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <yacc/parser.tab.h>
|
||||
#include <sys/col.h>
|
||||
#include <lex/util.h>
|
||||
#include <set/set.h>
|
||||
|
||||
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
||||
|
||||
|
@ -74,7 +75,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
root = AST_new_node(AST_Module, NULL);
|
||||
yyparse();
|
||||
|
||||
create_set(root);
|
||||
FILE *output = fopen("test.txt", "w");
|
||||
AST_fprint_graphviz(output, root);
|
||||
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 {
|
||||
const char* name;
|
||||
Type type;
|
||||
Type *type;
|
||||
AST_NODE_PTR nodePtr;
|
||||
} Typedefine;
|
||||
|
||||
|
@ -129,7 +129,7 @@ typedef struct Typedefine_t {
|
|||
*/
|
||||
typedef struct TypeValue_t {
|
||||
// the type
|
||||
Type type;
|
||||
Type *type;
|
||||
// UTF-8 representation of the type's value
|
||||
const char* value;
|
||||
AST_NODE_PTR nodePtr;
|
||||
|
@ -160,7 +160,7 @@ typedef enum IO_Qualifier_t {
|
|||
*
|
||||
*/
|
||||
typedef struct ParameterDeclaration_t {
|
||||
Type type;
|
||||
Type *type;
|
||||
IO_Qualifier qualifier;
|
||||
AST_NODE_PTR nodePtr;
|
||||
} ParameterDeclaration;
|
||||
|
@ -173,7 +173,7 @@ typedef struct ParameterDefinition_t {
|
|||
ParameterDeclaration declaration;
|
||||
// value to initalize the declaration with
|
||||
// NOTE: type of initializer and declaration MUST be equal
|
||||
Expression initializer;
|
||||
Expression *initializer;
|
||||
AST_NODE_PTR nodePtr;
|
||||
} ParameterDefinition;
|
||||
|
||||
|
@ -207,7 +207,7 @@ typedef struct FunctionDefinition_t {
|
|||
GArray* parameter;
|
||||
AST_NODE_PTR nodePtr;
|
||||
// body of function
|
||||
Block body;
|
||||
Block *body;
|
||||
// name of function
|
||||
const char* name;
|
||||
} FunctionDefinition;
|
||||
|
@ -239,7 +239,7 @@ typedef enum StorageQualifier_t {
|
|||
|
||||
typedef struct VariableDeclaration_t {
|
||||
StorageQualifier qualifier;
|
||||
Type type;
|
||||
Type *type;
|
||||
AST_NODE_PTR nodePtr;
|
||||
} VariableDeclaration;
|
||||
|
||||
|
@ -251,7 +251,7 @@ typedef struct VariableDeclaration_t {
|
|||
*/
|
||||
typedef struct VariableDefiniton_t {
|
||||
VariableDeclaration declaration;
|
||||
Expression initializer;
|
||||
Expression *initializer;
|
||||
AST_NODE_PTR nodePtr;
|
||||
} VariableDefiniton;
|
||||
|
||||
|
@ -286,7 +286,7 @@ typedef struct Variable_t {
|
|||
*
|
||||
*/
|
||||
typedef struct TypeCast_t {
|
||||
Type targetType;
|
||||
Type *targetType;
|
||||
Expression* operand;
|
||||
AST_NODE_PTR nodePtr;
|
||||
} TypeCast;
|
||||
|
@ -299,7 +299,7 @@ typedef struct TypeCast_t {
|
|||
*
|
||||
*/
|
||||
typedef struct Transmute_t {
|
||||
Type targetType;
|
||||
Type *targetType;
|
||||
Expression* operand;
|
||||
AST_NODE_PTR nodePtr;
|
||||
} Transmute;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <sys/log.h>
|
||||
#include <ast/ast.h>
|
||||
#include <sys/col.h>
|
||||
|
||||
extern int yylineno;
|
||||
|
||||
|
||||
|
@ -132,7 +133,8 @@
|
|||
%left '(' ')'
|
||||
|
||||
%%
|
||||
program: program programbody {AST_push_node(root, $2);}
|
||||
program: program programbody {AST_push_node(root, $2);
|
||||
}
|
||||
| programbody {AST_push_node(root, $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, $2);
|
||||
AST_push_node(decl, $4);
|
||||
$$ = decl;}
|
||||
$$ = decl;};
|
||||
|
||||
|
||||
definition: decl '=' expr { AST_NODE_PTR def = AST_new_node(AST_Def, NULL);
|
||||
|
|
Loading…
Reference in New Issue