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 {
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;
i32 child_n;
void *parent;
@ -96,16 +97,18 @@ typedef struct {
// Debug messages
// TODO
i32 curr_line;
i32 curr_column;
//i32 max_statement; // Unused while parsing
//i32 curr_statement;
i32 curr_scope; // Current local scope (id)
i32 scope_id;
i32 curr_scope;
i32 scope_stack[256];
HashMap symbol_map;
i32 fn_n;
FnSig *funcs;
i32 stack_size;
i32 curr_statement;
Statement statements[];
} ASTStack;

View file

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

View file

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

View file

@ -45,6 +45,8 @@ int make_stack(){
return 1;
if(heap_hashmap(&stack->symbol_map, SYMBOL_MAP_S))
return 1;
stack->funcs = NULL;
stack->fn_n = 0;
stack->stack_size = 2048;
symbol_map_add_bi(&stack->symbol_map);
@ -52,10 +54,26 @@ int make_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(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] = {
"",
"int",
@ -73,27 +91,8 @@ Tag get_type(char *str){
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 *stat = &stack->statements[stack->curr_statement++];
Statement *stat = get_statement();
stat->type = ST_Const;
stat->cons = (Value){{.v4B = {.value=val}},{.is_array = 0, .type = T_int}};
stat->is_const = 1;
@ -102,7 +101,7 @@ Statement *make_iconst(i32 val){
}
Statement *make_fconst(float val){
Statement *stat = &stack->statements[stack->curr_statement++];
Statement *stat = get_statement();
stat->type = ST_Const;
stat->cons = (Value){{.v4B = {.vfl=val}},{.is_array=0,.type=T_float}};
stat->is_const = 1;
@ -111,7 +110,7 @@ Statement *make_fconst(float val){
}
Statement *make_strconst(char *str){
Statement *stat = &stack->statements[stack->curr_statement++];
Statement *stat = get_statement();
stat->type = ST_Const;
stat->is_const = 1;
i32 len = strcspn(str, "\"");
@ -125,7 +124,7 @@ Statement *declare(i32 type, Tag vtype, char *name, Statement *assign){
printf("declare : %d\n", vtype.type);
#endif
name[len] = '\0';
Statement *stat = &stack->statements[stack->curr_statement++];
Statement *stat = get_statement();
stat->type = type;
if(hashmap_get(&stack->symbol_map, name)){
yyerror("Redeclaring existing identifier");
@ -149,7 +148,7 @@ Statement *declare(i32 type, Tag vtype, char *name, Statement *assign){
}
Statement *variable_get(char *name){
Statement *stat = &stack->statements[stack->curr_statement++];
Statement *stat = get_statement();
MapItem *ret = hashmap_get(&stack->symbol_map, name);
if(!ret)
yyerror("Undefined identifier");
@ -161,7 +160,7 @@ Statement *variable_get(char *name){
}
Statement *make_block(Statement *first){
Statement *stat = &stack->statements[stack->curr_statement++];
Statement *stat = get_statement();
stat->type = ST_Block;
stat->children = malloc(sizeof(void*));
stat->children[0] = first;
@ -180,7 +179,7 @@ Statement *add_block(Statement *block, Statement *add){
FnSig assign_sig = {.n_param = 1};
Statement *make_operation(i32 type, Tag vtype, char *name, i32 nparam, ...){
Statement *stat = &stack->statements[stack->curr_statement++];
Statement *stat = get_statement();
if(nparam)
stat->children = malloc(sizeof(void*)*nparam);
stat->child_n = 0;
@ -232,6 +231,53 @@ Statement *make_operation(i32 type, Tag vtype, char *name, i32 nparam, ...){
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
void set_entry_point(Statement *statement){
printf("set_entry_point\n");

View file

@ -23,6 +23,15 @@
#pragma once
typedef struct {
// 0 is function name/output type
char *names[9];
Tag types[9];
i32 n_args;
} FnArgs;
void yyerror(char *s);
int make_stack();
@ -32,9 +41,7 @@ void free_stack();
Tag get_type(char *str);
Statement *make_iconst(i32 val);
Statement *make_fconst(float val);
//TODO
Statement *make_strconst(char *str);
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 *make_block(Statement *first);
Statement *add_block(Statement *block, Statement *add);
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);

View file

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

View file

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