feat: implemented function annotations
This commit is contained in:
parent
5715d40eed
commit
56cebd5742
|
@ -12,5 +12,5 @@ fun main()
|
|||
#[nomangle,noreturn,entry]
|
||||
fun _start() {
|
||||
main()
|
||||
os::exit(0 as i32)
|
||||
std::os::exit(0 as i32)
|
||||
}
|
||||
|
|
|
@ -7,5 +7,5 @@ fun _exit(in i32: code)
|
|||
|
||||
#[noreturn]
|
||||
fun exit(in i32: code) {
|
||||
os::_exit(code)
|
||||
_exit(code)
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -167,8 +167,10 @@ void module_ref_push(ModuleRef* ref, char* name) {
|
|||
}
|
||||
|
||||
void module_ref_pop(ModuleRef* ref) {
|
||||
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) {
|
||||
GString* string = g_string_new("");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
%%
|
||||
"\n" yyLineNumber++;
|
||||
|
||||
//.* ;
|
||||
\/\/.* ;
|
||||
|
||||
"#" {DEBUG("\"%s\" tokenized with \'#\'", yytext); return('#');};
|
||||
|
||||
"::" {return(ModSep);};
|
||||
":" {DEBUG("\"%s\" tokenized with \':\'", yytext); return(':');};
|
||||
|
|
|
@ -2648,11 +2648,17 @@ int createFunction(Function* function, AST_NODE_PTR currentNode) {
|
|||
return SEMANTIC_ERROR;
|
||||
}
|
||||
|
||||
if (!(currentNode->annotation.kind == AnnotationKindArray
|
||||
&& AST_annotation_array_contains_flag(¤tNode->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);
|
||||
function->name = composed_name;
|
||||
g_free(composed_name);
|
||||
function->name = cached_composed_name;
|
||||
}
|
||||
|
||||
mem_free(functionParameter);
|
||||
functionParameter = NULL;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
import "std"
|
||||
|
||||
#[nomangle]
|
||||
fun main() {
|
||||
i32: u = 0 as i32
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue