feat: implemented function annotations
This commit is contained in:
parent
5715d40eed
commit
56cebd5742
|
@ -12,5 +12,5 @@ fun main()
|
||||||
#[nomangle,noreturn,entry]
|
#[nomangle,noreturn,entry]
|
||||||
fun _start() {
|
fun _start() {
|
||||||
main()
|
main()
|
||||||
os::exit(0 as i32)
|
std::os::exit(0 as i32)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,5 +7,5 @@ fun _exit(in i32: code)
|
||||||
|
|
||||||
#[noreturn]
|
#[noreturn]
|
||||||
fun exit(in i32: code) {
|
fun exit(in i32: code) {
|
||||||
os::_exit(code)
|
_exit(code)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,20 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/log.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,
|
struct AST_Node_t* AST_new_node(TokenLocation location,
|
||||||
enum AST_SyntaxElement_t kind,
|
enum AST_SyntaxElement_t kind,
|
||||||
const char* value) {
|
const char* value) {
|
||||||
|
@ -26,6 +40,7 @@ struct AST_Node_t* AST_new_node(TokenLocation location,
|
||||||
node->kind = kind;
|
node->kind = kind;
|
||||||
node->value = value;
|
node->value = value;
|
||||||
node->location = location;
|
node->location = location;
|
||||||
|
node->annotation.kind = AnnotationKindNone;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,45 @@ enum AST_SyntaxElement_t {
|
||||||
AST_ELEMENT_COUNT
|
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.
|
* @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.
|
* Every node can have one ancestor (parent) but multiple (also none) children.
|
||||||
|
@ -108,6 +147,8 @@ typedef struct AST_Node_t {
|
||||||
|
|
||||||
TokenLocation location;
|
TokenLocation location;
|
||||||
|
|
||||||
|
AST_Annotation annotation;
|
||||||
|
|
||||||
// children array
|
// children array
|
||||||
GArray* children;
|
GArray* children;
|
||||||
} AST_Node;
|
} AST_Node;
|
||||||
|
|
|
@ -167,7 +167,9 @@ void module_ref_push(ModuleRef* ref, char* name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void module_ref_pop(ModuleRef* ref) {
|
void module_ref_pop(ModuleRef* ref) {
|
||||||
|
if (ref->module_path->len > 0) {
|
||||||
g_array_remove_index(ref->module_path, ref->module_path->len - 1);
|
g_array_remove_index(ref->module_path, ref->module_path->len - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* module_ref_to_str(ModuleRef* ref) {
|
char* module_ref_to_str(ModuleRef* ref) {
|
||||||
|
|
|
@ -66,7 +66,10 @@ char* module_from_basename(char* path) {
|
||||||
*dot = '\0';
|
*dot = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return basename;
|
char* cached_module_name = mem_strdup(MemoryNamespaceOpt, basename);
|
||||||
|
g_free(basename);
|
||||||
|
|
||||||
|
return cached_module_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_files(ModuleFileStack* stack) {
|
void delete_files(ModuleFileStack* stack) {
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
%%
|
%%
|
||||||
"\n" yyLineNumber++;
|
"\n" yyLineNumber++;
|
||||||
|
|
||||||
//.* ;
|
\/\/.* ;
|
||||||
|
|
||||||
|
"#" {DEBUG("\"%s\" tokenized with \'#\'", yytext); return('#');};
|
||||||
|
|
||||||
"::" {return(ModSep);};
|
"::" {return(ModSep);};
|
||||||
":" {DEBUG("\"%s\" tokenized with \':\'", yytext); return(':');};
|
":" {DEBUG("\"%s\" tokenized with \':\'", yytext); return(':');};
|
||||||
|
|
|
@ -2648,11 +2648,17 @@ int createFunction(Function* function, AST_NODE_PTR currentNode) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(currentNode->annotation.kind == AnnotationKindArray
|
||||||
|
&& AST_annotation_array_contains_flag(¤tNode->annotation, "nomangle"))) {
|
||||||
|
|
||||||
// compose function name by appending parent modules
|
// compose function name by appending parent modules
|
||||||
char* modules = module_ref_to_str(currentNode->location.module_ref);
|
char* modules = module_ref_to_str(currentNode->location.module_ref);
|
||||||
char* composed_name = g_strjoin("", modules, "::", function->name, NULL);
|
char* composed_name = g_strjoin("", modules, "::", function->name, NULL);
|
||||||
|
char* cached_composed_name = mem_strdup(MemoryNamespaceSet, composed_name);
|
||||||
g_free(modules);
|
g_free(modules);
|
||||||
function->name = composed_name;
|
g_free(composed_name);
|
||||||
|
function->name = cached_composed_name;
|
||||||
|
}
|
||||||
|
|
||||||
mem_free(functionParameter);
|
mem_free(functionParameter);
|
||||||
functionParameter = NULL;
|
functionParameter = NULL;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <ast/ast.h>
|
#include <ast/ast.h>
|
||||||
#include <sys/col.h>
|
#include <sys/col.h>
|
||||||
#include <io/files.h>
|
#include <io/files.h>
|
||||||
|
#include <mem/cache.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
extern int yylineno;
|
extern int yylineno;
|
||||||
extern ModuleFile* current_file;
|
extern ModuleFile* current_file;
|
||||||
|
@ -26,6 +27,9 @@
|
||||||
%union {
|
%union {
|
||||||
char *string;
|
char *string;
|
||||||
AST_NODE_PTR node_ptr;
|
AST_NODE_PTR node_ptr;
|
||||||
|
AST_Annotation annotation;
|
||||||
|
AST_AnnotationValue annotationvalue;
|
||||||
|
GArray* array;
|
||||||
}
|
}
|
||||||
|
|
||||||
%type <node_ptr> operation
|
%type <node_ptr> operation
|
||||||
|
@ -78,7 +82,11 @@
|
||||||
%type <node_ptr> storage_expr
|
%type <node_ptr> storage_expr
|
||||||
%type <node_ptr> returnstmt
|
%type <node_ptr> returnstmt
|
||||||
%type <node_ptr> moduleref
|
%type <node_ptr> moduleref
|
||||||
|
%type <node_ptr> callable
|
||||||
|
%type <array> annotationlist
|
||||||
|
%type <annotationvalue> annotationvalue
|
||||||
|
%type <annotation> annotation
|
||||||
|
%type <annotation> annotationbind
|
||||||
|
|
||||||
%token KeyInt
|
%token KeyInt
|
||||||
%token KeyFloat
|
%token KeyFloat
|
||||||
|
@ -155,15 +163,55 @@ program: program programbody {AST_push_node(root, $2);
|
||||||
|
|
||||||
programbody: moduleimport {$$ = $1;}
|
programbody: moduleimport {$$ = $1;}
|
||||||
| moduleinclude {$$ = $1;}
|
| moduleinclude {$$ = $1;}
|
||||||
| fundef{$$ = $1;}
|
| callable {$$ = $1;}
|
||||||
| fundecl{$$ = $1;}
|
|
||||||
| procdecl{$$ = $1;}
|
|
||||||
| procdef{$$ = $1;}
|
|
||||||
| box{$$ = $1;}
|
| box{$$ = $1;}
|
||||||
| definition{$$ = $1;}
|
| definition{$$ = $1;}
|
||||||
| decl{$$ = $1;}
|
| decl{$$ = $1;}
|
||||||
| typedef{$$ = $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);}
|
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);
|
| 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));
|
AST_push_node(modref, AST_new_node(new_loc(), AST_Ident, $1));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
import "std"
|
import "std"
|
||||||
|
|
||||||
|
#[nomangle]
|
||||||
fun main() {
|
fun main() {
|
||||||
i32: u = 0 as i32
|
i32: u = 0 as i32
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue