feat: implemented function annotations

This commit is contained in:
Sven Vogel 2024-10-10 20:11:42 +02:00
parent 5715d40eed
commit 56cebd5742
10 changed files with 133 additions and 15 deletions

View File

@ -12,5 +12,5 @@ fun main()
#[nomangle,noreturn,entry]
fun _start() {
main()
os::exit(0 as i32)
std::os::exit(0 as i32)
}

View File

@ -7,5 +7,5 @@ fun _exit(in i32: code)
#[noreturn]
fun exit(in i32: code) {
os::_exit(code)
_exit(code)
}

View File

@ -5,6 +5,20 @@
#include <stdio.h>
#include <sys/log.h>
bool AST_annotation_array_contains_flag(AST_Annotation* haystack, const char* needle) {
if (haystack->kind == AnnotationKindArray) {
for (guint i = 0; i < haystack->impl.array->len; i++) {
AST_Annotation child = g_array_index(haystack->impl.array, AST_Annotation, i);
if (child.kind == AnnotationKindFlag && strcmp(child.impl.flag, needle) == 0) {
return true;
}
}
}
return false;
}
struct AST_Node_t* AST_new_node(TokenLocation location,
enum AST_SyntaxElement_t kind,
const char* value) {
@ -26,6 +40,7 @@ struct AST_Node_t* AST_new_node(TokenLocation location,
node->kind = kind;
node->value = value;
node->location = location;
node->annotation.kind = AnnotationKindNone;
return node;
}

View File

@ -89,6 +89,45 @@ enum AST_SyntaxElement_t {
AST_ELEMENT_COUNT
};
typedef enum AST_AnnotationKind_t {
AnnotationKindFlag,
AnnotationKindVariable,
AnnotationKindArray,
AnnotationKindNone
} AST_AnnotationKind;
struct AST_Annotation_t;
typedef enum AST_AnnotationValueKind_t {
AnnotationValueKindAnnotation,
AnnotationValueKindString,
AnnotationValueKindInteger
} AST_AnnotationValueKind;
typedef struct AST_AnnotationValue_t {
AST_AnnotationValueKind kind;
union {
struct AST_Annotation_t* annotation;
char* string;
int64_t integer;
} impl;
} AST_AnnotationValue;
typedef struct AST_Annotation_t {
AST_AnnotationKind kind;
union {
// array of annotation values
GArray* array;
struct {
char* name;
AST_AnnotationValue value;
} variable;
char* flag;
} impl;
} AST_Annotation;
bool AST_annotation_array_contains_flag(AST_Annotation*, const char*);
/**
* @brief A single node which can be joined with other nodes like a graph.
* Every node can have one ancestor (parent) but multiple (also none) children.
@ -108,6 +147,8 @@ typedef struct AST_Node_t {
TokenLocation location;
AST_Annotation annotation;
// children array
GArray* children;
} AST_Node;

View File

@ -167,7 +167,9 @@ void module_ref_push(ModuleRef* ref, char* name) {
}
void module_ref_pop(ModuleRef* ref) {
g_array_remove_index(ref->module_path, ref->module_path->len - 1);
if (ref->module_path->len > 0) {
g_array_remove_index(ref->module_path, ref->module_path->len - 1);
}
}
char* module_ref_to_str(ModuleRef* ref) {

View File

@ -66,7 +66,10 @@ char* module_from_basename(char* path) {
*dot = '\0';
}
return basename;
char* cached_module_name = mem_strdup(MemoryNamespaceOpt, basename);
g_free(basename);
return cached_module_name;
}
void delete_files(ModuleFileStack* stack) {

View File

@ -28,7 +28,9 @@
%%
"\n" yyLineNumber++;
//.* ;
\/\/.* ;
"#" {DEBUG("\"%s\" tokenized with \'#\'", yytext); return('#');};
"::" {return(ModSep);};
":" {DEBUG("\"%s\" tokenized with \':\'", yytext); return(':');};

View File

@ -2648,11 +2648,17 @@ int createFunction(Function* function, AST_NODE_PTR currentNode) {
return SEMANTIC_ERROR;
}
// compose function name by appending parent modules
char* modules = module_ref_to_str(currentNode->location.module_ref);
char* composed_name = g_strjoin("", modules, "::", function->name, NULL);
g_free(modules);
function->name = composed_name;
if (!(currentNode->annotation.kind == AnnotationKindArray
&& AST_annotation_array_contains_flag(&currentNode->annotation, "nomangle"))) {
// compose function name by appending parent modules
char* modules = module_ref_to_str(currentNode->location.module_ref);
char* composed_name = g_strjoin("", modules, "::", function->name, NULL);
char* cached_composed_name = mem_strdup(MemoryNamespaceSet, composed_name);
g_free(modules);
g_free(composed_name);
function->name = cached_composed_name;
}
mem_free(functionParameter);
functionParameter = NULL;

View File

@ -6,6 +6,7 @@
#include <ast/ast.h>
#include <sys/col.h>
#include <io/files.h>
#include <mem/cache.h>
#include <glib.h>
extern int yylineno;
extern ModuleFile* current_file;
@ -26,6 +27,9 @@
%union {
char *string;
AST_NODE_PTR node_ptr;
AST_Annotation annotation;
AST_AnnotationValue annotationvalue;
GArray* array;
}
%type <node_ptr> operation
@ -78,7 +82,11 @@
%type <node_ptr> storage_expr
%type <node_ptr> returnstmt
%type <node_ptr> moduleref
%type <node_ptr> callable
%type <array> annotationlist
%type <annotationvalue> annotationvalue
%type <annotation> annotation
%type <annotation> annotationbind
%token KeyInt
%token KeyFloat
@ -155,15 +163,55 @@ program: program programbody {AST_push_node(root, $2);
programbody: moduleimport {$$ = $1;}
| moduleinclude {$$ = $1;}
| fundef{$$ = $1;}
| fundecl{$$ = $1;}
| procdecl{$$ = $1;}
| procdef{$$ = $1;}
| callable {$$ = $1;}
| box{$$ = $1;}
| definition{$$ = $1;}
| decl{$$ = $1;}
| typedef{$$ = $1;};
callable: fundef {$$=$1;}
| fundecl {$$=$1;}
| procdef {$$=$1;}
| procdecl {$$=$1;}
| annotationbind callable {
$2->annotation = $1;
$$ = $2;
};
annotationvalue: ValStr { AST_AnnotationValue value;
value.impl.string = $1;
value.kind = AnnotationValueKindString;
$$ = value; }
| ValInt { AST_AnnotationValue value;
value.impl.integer = atol($1);
value.kind = AnnotationValueKindInteger;
$$ = value; }
| annotation { AST_AnnotationValue value;
value.impl.annotation = mem_clone(MemoryNamespaceAst, &($1), sizeof(AST_Annotation));
value.kind = AnnotationValueKindAnnotation;
$$ = value; };
annotationlist: annotation ',' annotationlist { g_array_append_val($3, $1); $$ = $3; }
| annotation { GArray* list = mem_new_g_array(MemoryNamespaceSet, sizeof(AST_Annotation));
g_array_append_val(list, $1);
$$ = list; };
annotation: Ident { AST_Annotation annotation;
annotation.kind = AnnotationKindFlag;
annotation.impl.flag = $1;
$$ = annotation; }
| '[' annotationlist ']' { AST_Annotation annotation;
annotation.kind = AnnotationKindArray;
annotation.impl.array = $2;
$$ = annotation; }
| Ident '(' annotationvalue ')' { AST_Annotation annotation;
annotation.kind = AnnotationKindVariable;
annotation.impl.variable.name = $1;
annotation.impl.variable.value = $3;
$$ = annotation; };
annotationbind: '#' annotation { $$ = $2; };
moduleref: Ident {$$ = AST_new_node(new_loc(), AST_Ident, $1);}
| Ident ModSep moduleref {AST_NODE_PTR modref = AST_new_node(new_loc(), AST_ModuleRef, NULL);
AST_push_node(modref, AST_new_node(new_loc(), AST_Ident, $1));

View File

@ -1,6 +1,7 @@
import "std"
#[nomangle]
fun main() {
i32: u = 0 as i32
}