More work towards scopes

This commit is contained in:
attilavs2 2025-03-25 12:13:21 +01:00
parent 909badb818
commit adedde0253
7 changed files with 115 additions and 47 deletions

View file

@ -72,7 +72,8 @@ enum BuiltinStatements {
struct Statement { struct Statement {
i32 type; i32 type;
i32 is_const; // Statement is constant, != is a constant - TODO : implem i16 is_const; // Statement is constant, != is a constant - TODO : implem
i16 scope;
void **children; void **children;
i32 child_n; i32 child_n;
void *parent; void *parent;
@ -96,16 +97,18 @@ typedef struct {
// Debug messages // Debug messages
// TODO // TODO
i32 curr_line; i32 curr_line;
i32 curr_column;
//i32 max_statement; // Unused while parsing i32 scope_id;
//i32 curr_statement; i32 curr_scope;
i32 scope_stack[256];
i32 curr_scope; // Current local scope (id)
HashMap symbol_map; HashMap symbol_map;
i32 fn_n;
FnSig *funcs;
i32 stack_size; i32 stack_size;
i32 curr_statement;
Statement statements[]; Statement statements[];
} ASTStack; } ASTStack;

View file

@ -95,7 +95,7 @@ MapItem *hashmap_insert(HashMap *map, char *str){
if(!map->bit_free[hsh/32]){ if(!map->bit_free[hsh/32]){
map->buffer[hsh].hash = hsh; map->buffer[hsh].hash = hsh;
map->buffer[hsh].id = map->curr_id++; map->buffer[hsh].id = map->curr_id++;
strncpy(map->buffer[hsh].str, str, 32); strncpy(map->buffer[hsh].str, str, 36);
set_bit(map->bit_free, hsh); set_bit(map->bit_free, hsh);
map->item_n++; map->item_n++;
return &map->buffer[hsh]; return &map->buffer[hsh];
@ -117,7 +117,7 @@ MapItem *hashmap_insert(HashMap *map, char *str){
if(!taken){ if(!taken){
map->buffer[pos].hash = hsh; map->buffer[pos].hash = hsh;
map->buffer[pos].id = map->curr_id++; map->buffer[pos].id = map->curr_id++;
strncpy(map->buffer[pos].str, str, 32); strncpy(map->buffer[pos].str, str, 36);
set_bit(map->bit_free, hsh); set_bit(map->bit_free, hsh);
map->item_n++; map->item_n++;
return &map->buffer[pos]; return &map->buffer[pos];
@ -134,7 +134,7 @@ MapItem *hashmap_get(HashMap *map, char *str){
i32 c_hash = map->buffer[pos].hash; i32 c_hash = map->buffer[pos].hash;
match = c_hash == fhash; match = c_hash == fhash;
if(match) if(match)
match = !strncmp(str,map->buffer[pos].str,32); match = !strncmp(str,map->buffer[pos].str,36);
pos++; pos++;
} while(!match && pos < map->curr_len && pos-fhash < RELOCATE_TRY_MAX); } while(!match && pos < map->curr_len && pos-fhash < RELOCATE_TRY_MAX);
pos--; pos--;

View file

@ -31,11 +31,11 @@
typedef struct { typedef struct {
i32 hash; i32 hash;
char str[32]; char str[36];
i32 id; i32 id;
void *fnsig; void *fnsig;
i32 type; i16 type;
i32 is_const; i16 is_const;
} MapItem; } MapItem;

View file

@ -45,6 +45,8 @@ int make_stack(){
return 1; return 1;
if(heap_hashmap(&stack->symbol_map, SYMBOL_MAP_S)) if(heap_hashmap(&stack->symbol_map, SYMBOL_MAP_S))
return 1; return 1;
stack->funcs = NULL;
stack->fn_n = 0;
stack->stack_size = 2048; stack->stack_size = 2048;
symbol_map_add_bi(&stack->symbol_map); symbol_map_add_bi(&stack->symbol_map);
@ -52,10 +54,26 @@ int make_stack(){
} }
void free_stack(){ void free_stack(){
for(int i = 0; i < stack->curr_statement){
Statement *stat = &stack->statements[i];
if(stat->child_n)
free(stat->children);
}
free(stack->funcs);
free_hashmap(&stack->symbol_map); free_hashmap(&stack->symbol_map);
free(stack); free(stack);
} }
Statement *get_statement(){
if(stack->curr_statement >= stack->stack_size){
stack = realloc(stack, sizeof(ASTStack)+sizeof(Statement)*(stack->stack_size+2048));
if(!stack)
yyerror("Failed to extend stack");
stack->stack_size += 2048;
}
return &stack->statements[stack->curr_statement++];
}
char *bi_type_names[6] = { char *bi_type_names[6] = {
"", "",
"int", "int",
@ -73,27 +91,8 @@ Tag get_type(char *str){
return (Tag){0,0,0}; return (Tag){0,0,0};
} }
void mangle_name(i32 scope, char *name){
}
// Syntaxically, there can only be one active fnlist at a time
Tag _fnlist[8];
i32 _fnl_pos;
void make_fnlist(char *name, Tag type){
_fnl_pos = 1;
_fnlist[0] = type;
}
void append_fnlist(char *name, Tag type){
if(_fnl_pos >= 8)
yyerror("Too many parameters to function");
_fnlist[fnl_pos++] = type;
}
Statement *make_iconst(i32 val){ Statement *make_iconst(i32 val){
Statement *stat = &stack->statements[stack->curr_statement++]; Statement *stat = get_statement();
stat->type = ST_Const; stat->type = ST_Const;
stat->cons = (Value){{.v4B = {.value=val}},{.is_array = 0, .type = T_int}}; stat->cons = (Value){{.v4B = {.value=val}},{.is_array = 0, .type = T_int}};
stat->is_const = 1; stat->is_const = 1;
@ -102,7 +101,7 @@ Statement *make_iconst(i32 val){
} }
Statement *make_fconst(float val){ Statement *make_fconst(float val){
Statement *stat = &stack->statements[stack->curr_statement++]; Statement *stat = get_statement();
stat->type = ST_Const; stat->type = ST_Const;
stat->cons = (Value){{.v4B = {.vfl=val}},{.is_array=0,.type=T_float}}; stat->cons = (Value){{.v4B = {.vfl=val}},{.is_array=0,.type=T_float}};
stat->is_const = 1; stat->is_const = 1;
@ -111,7 +110,7 @@ Statement *make_fconst(float val){
} }
Statement *make_strconst(char *str){ Statement *make_strconst(char *str){
Statement *stat = &stack->statements[stack->curr_statement++]; Statement *stat = get_statement();
stat->type = ST_Const; stat->type = ST_Const;
stat->is_const = 1; stat->is_const = 1;
i32 len = strcspn(str, "\""); i32 len = strcspn(str, "\"");
@ -125,7 +124,7 @@ Statement *declare(i32 type, Tag vtype, char *name, Statement *assign){
printf("declare : %d\n", vtype.type); printf("declare : %d\n", vtype.type);
#endif #endif
name[len] = '\0'; name[len] = '\0';
Statement *stat = &stack->statements[stack->curr_statement++]; Statement *stat = get_statement();
stat->type = type; stat->type = type;
if(hashmap_get(&stack->symbol_map, name)){ if(hashmap_get(&stack->symbol_map, name)){
yyerror("Redeclaring existing identifier"); yyerror("Redeclaring existing identifier");
@ -149,7 +148,7 @@ Statement *declare(i32 type, Tag vtype, char *name, Statement *assign){
} }
Statement *variable_get(char *name){ Statement *variable_get(char *name){
Statement *stat = &stack->statements[stack->curr_statement++]; Statement *stat = get_statement();
MapItem *ret = hashmap_get(&stack->symbol_map, name); MapItem *ret = hashmap_get(&stack->symbol_map, name);
if(!ret) if(!ret)
yyerror("Undefined identifier"); yyerror("Undefined identifier");
@ -161,7 +160,7 @@ Statement *variable_get(char *name){
} }
Statement *make_block(Statement *first){ Statement *make_block(Statement *first){
Statement *stat = &stack->statements[stack->curr_statement++]; Statement *stat = get_statement();
stat->type = ST_Block; stat->type = ST_Block;
stat->children = malloc(sizeof(void*)); stat->children = malloc(sizeof(void*));
stat->children[0] = first; stat->children[0] = first;
@ -180,7 +179,7 @@ Statement *add_block(Statement *block, Statement *add){
FnSig assign_sig = {.n_param = 1}; FnSig assign_sig = {.n_param = 1};
Statement *make_operation(i32 type, Tag vtype, char *name, i32 nparam, ...){ Statement *make_operation(i32 type, Tag vtype, char *name, i32 nparam, ...){
Statement *stat = &stack->statements[stack->curr_statement++]; Statement *stat = get_statement();
if(nparam) if(nparam)
stat->children = malloc(sizeof(void*)*nparam); stat->children = malloc(sizeof(void*)*nparam);
stat->child_n = 0; stat->child_n = 0;
@ -232,6 +231,53 @@ Statement *make_operation(i32 type, Tag vtype, char *name, i32 nparam, ...){
return stat; return stat;
} }
void push_scope(){
if(stack->curr_scope >= 256)
yyerror("Scopes are too deep");
stack->scope_stack[stack->curr_scope++] = stack->scope_id++;
}
void pop_scope(){
if(stack->curr_scope <= 0)
yyerror("Weird scope error");
stack->curr_scope--;
}
char _mangle_tmp[36];
// 3 digit "Base64" scope id + { (invalid identifier char) + name
char *mangle_name(i32 scope, char *name){
// Scope 0 is global so we just return the name
if(!scope)
return name;
for(int i = 0; i < 3; i++){
_mangle_tmp[i] = (scope & 63) + ' ';
scope >>= 6;
}
_mangle_tmp[3] = '{';
strncpy(&_mangle_tmp[4], name, 32);
return _mangle_tmp;
}
FnArgs _fnargs;
FnArgs *make_fnargs(char *name, Tag type){
_fnargs.n_args = 1;
_fnargs.names[0] = name;
_fnargs.types[0] = type;
return &_fnargs;
}
FnArgs *add_fnargs(char *name, Tag type){
_fnargs.names[_fnargs.n_args] = name;
_fnargs.types[_fnargs.n_args++] = type;
return &_fnargs;
}
Statement *make_function(FnArgs *fn_args, Statement *statements){
Statement *stat = get_statement();
}
// TODO // TODO
void set_entry_point(Statement *statement){ void set_entry_point(Statement *statement){
printf("set_entry_point\n"); printf("set_entry_point\n");

View file

@ -23,6 +23,15 @@
#pragma once #pragma once
typedef struct {
// 0 is function name/output type
char *names[9];
Tag types[9];
i32 n_args;
} FnArgs;
void yyerror(char *s); void yyerror(char *s);
int make_stack(); int make_stack();
@ -32,9 +41,7 @@ void free_stack();
Tag get_type(char *str); Tag get_type(char *str);
Statement *make_iconst(i32 val); Statement *make_iconst(i32 val);
Statement *make_fconst(float val); Statement *make_fconst(float val);
//TODO
Statement *make_strconst(char *str); Statement *make_strconst(char *str);
Statement *declare(i32 type, Tag vtype, char *name, Statement *assign); Statement *declare(i32 type, Tag vtype, char *name, Statement *assign);
@ -42,9 +49,14 @@ Statement *declare(i32 type, Tag vtype, char *name, Statement *assign);
Statement *variable_get(char *name); Statement *variable_get(char *name);
Statement *make_block(Statement *first); Statement *make_block(Statement *first);
Statement *add_block(Statement *block, Statement *add); Statement *add_block(Statement *block, Statement *add);
Statement *make_operation(i32 type, Tag vtype, char *str, i32 nparam, ...); Statement *make_operation(i32 type, Tag vtype, char *str, i32 nparam, ...);
void push_scope();
void pop_scope();
FnArgs *make_fnargs(char *name, Tag type);
FnArgs *add_fnargs(char *name, Tag type);
void set_entry_point(Statement *statement); void set_entry_point(Statement *statement);

View file

@ -40,7 +40,10 @@
"if" return IF; "if" return IF;
"else" return ELSE; "else" return ELSE;
"while" return WHILE; "while" return WHILE;
"fn" return FN; "fn" {
push_scope();
return FN;
}
"var" return VAR; "var" return VAR;
"let" return LET; "let" return LET;
"block" return BLOCK; "block" return BLOCK;

View file

@ -37,6 +37,7 @@
char *str; char *str;
Statement *st; Statement *st;
Tag tag; Tag tag;
FnArgs *args;
} }
%nonassoc <str> G_IDENT %nonassoc <str> G_IDENT
@ -54,6 +55,7 @@
%type <st> expr expr_list %type <st> expr expr_list
%type <tag> type %type <tag> type
%type <args> fn_args
%% %%
@ -78,13 +80,13 @@ type:
fn_args: fn_args:
G_IDENT G_IDENT
{} {$$ = make_fnargs($1, atag);}
| G_IDENT type | G_IDENT type
{} {$$ = make_fnargs($1, $2);}
| fn_args G_IDENT | fn_args G_IDENT
{} {$$ = add_fnargs($2, atag);}
| fn_args G_IDENT type | fn_args G_IDENT type
{} {$$ = add_fnargs($2, $3);}
; ;
expr: expr:
@ -117,7 +119,9 @@ expr:
| '(' WHILE expr expr_list ')' | '(' WHILE expr expr_list ')'
{$$ = make_operation(BI_while, ntag, NULL, 2, $3, $4);} {$$ = make_operation(BI_while, ntag, NULL, 2, $3, $4);}
| '(' FN '(' fn_args ')' expr_list ')' | '(' FN '(' fn_args ')' expr_list ')'
{} {$$ = make_function($4, $6);
pop_scope();
}
| '(' BLOCK expr_list ')' | '(' BLOCK expr_list ')'
{$$ = $3;} {$$ = $3;}
| '(' G_IDENT expr_list ')' | '(' G_IDENT expr_list ')'