first implementation of the sematic analysis

This commit is contained in:
Felix Müller 2024-05-31 16:17:06 +02:00
parent 0edf2f7b17
commit 5a06c17fa4
6 changed files with 281 additions and 13 deletions

View File

@ -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 */ };

View File

@ -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);

257
src/set/set.c Normal file
View File

@ -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;
}

8
src/set/set.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _SET_H_
#define _SET_H_
#include <ast/ast.h>
void create_set(AST_NODE_PTR rootNodePtr );
#endif

View File

@ -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;

View File

@ -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);