Feeling eepy

This commit is contained in:
attilavs2 2025-03-30 00:07:15 +01:00
parent 2236d1c85f
commit d8d8efe117
13 changed files with 89 additions and 53 deletions

View file

@ -39,6 +39,9 @@ yacc: src/parser.y src/parser.l
cd src && bison -y -d parser.y && lex parser.l cd src && bison -y -d parser.y && lex parser.l
$(CC) -c src/y.tab.c -o build-tmp/y.tab.o $(CFLAGS) $(CC) -c src/y.tab.c -o build-tmp/y.tab.o $(CFLAGS)
$(CC) -c src/lex.yy.c -o build-tmp/lex.yy.o $(CFLAGS) $(CC) -c src/lex.yy.c -o build-tmp/lex.yy.o $(CFLAGS)
ifneq ($(filter $(OBJS), build-tmp/y.tab.o),build-tmp/y.tab.o)
$(eval OBJS += build-tmp/y.tab.o build-tmp/lex.yy.o)
endif
build-tmp/%.o : $(SRC_DIR)/%.c build-tmp/%.o : $(SRC_DIR)/%.c
${CC} -c $< -o $@ ${CFLAGS} ${CC} -c $< -o $@ ${CFLAGS}

View file

@ -14,8 +14,7 @@ Pre-requisites:
- GNU Make - GNU Make
### Unix ### Unix
Running `make` (or `gmake` for BSDs), maybe twice depending on your version of make, Running `make` (or `gmake` for BSDs), should work on most Unix systems.
should work on most Unix systems.
It produces an executable called `flisp.amd64` It produces an executable called `flisp.amd64`
### Windows ### Windows

View file

@ -6,10 +6,10 @@
(var:int n 0) (var:int n 0)
(while (< n 40) (while (< n 40)
(c b) (set c b)
(b (+ a b)) (set b (+ a b))
(a c) (set a c)
(n (+ n 1)) (set n (+ n 1))
) )
(i (+ i 1)) (set i (+ i 1))
) )

View file

@ -20,7 +20,7 @@
(if (= guess number) (if (= guess number)
(write "You won !") (write "You won !")
(newline) (newline)
(won 1) (set won 1)
) )
) )
(if (! won) (if (! won)

View file

@ -27,44 +27,44 @@
enum StatementTypes { enum StatementTypes {
ST_None = 0, // Not processed yet ST_None = 0, // Not processed yet
ST_Call = 1, // Any kind of function call ST_Call = 1, // Builtin function call
ST_Const = 2, // Constant ST_Const = 2, // Constant
ST_Var = 3, // Free variable ST_Var = 3, // Free variable
ST_Block = 4, // Scope blocks ST_Block = 4, // Scope blocks
ST_Varuse = 5, // Variable assign/potential func call ST_Varuse = 5, // Variable func call
ST_Set = 6, // Set variable
ST__end ST__end
}; };
// Special expressions and ones that map directly to bytecode // Special expressions and ones that map directly to bytecode
// Should mesh with StatementTypes
enum BuiltinStatements { enum BuiltinStatements {
BI_var = 6, BI_var = ST__end,
BI_let = 7, BI_let,
BI_if = 8, BI_if,
BI_else = 9, BI_else,
BI_while = 10, BI_while,
BI_fn = 11, BI_fn,
BI_import = 12, BI_import,
BI_is = 13, BI_is,
BI_cast = 14, BI_cast,
BI_add = 15, BI_add,
BI_sub = 16, BI_sub,
BI_mul = 17, BI_mul,
BI_div = 18, BI_div,
BI_mod = 19, BI_mod,
BI_sml = 20, BI_sml,
BI_sml_eq = 21, BI_sml_eq,
BI_eq = 22, BI_eq,
BI_gt_eq = 23, BI_gt_eq,
BI_gt = 24, BI_gt,
BI_not = 25, BI_not,
BI_and = 26, BI_and,
BI_or = 27, BI_or,
BI_len = 28, BI_len,
BI_push = 29, BI_push,
BI_pop = 30, BI_pop,
BI_write = 31, BI_write,
BI_nwline = 32, BI_nwline,
BI__end BI__end
}; };
@ -113,4 +113,3 @@ typedef struct {
} ASTStack; } ASTStack;
_Static_assert((int)BI_var >= ST__end, "Overlap between BI and ST enums");

View file

@ -210,6 +210,9 @@ void print_ast1(Statement *base, i32 indent){
case ST_Varuse: case ST_Varuse:
printf("(use<%d>\n", base->var_id); printf("(use<%d>\n", base->var_id);
break; break;
case ST_Set:
printf("(set<%d>\n", base->var_id);
break;
case BI_var: case BI_var:
printf("(var<%d>:<%d>\n", base->var_id, base->var_type.type); printf("(var<%d>:<%d>\n", base->var_id, base->var_type.type);
break; break;
@ -605,7 +608,7 @@ Value eq(Value a, Value b){
returnv.v4B.value = a.v4B.value == b.v4B.value; returnv.v4B.value = a.v4B.value == b.v4B.value;
break; break;
case T_float: case T_float:
returnv.v4B.value = abs(a.v4B.vfl-b.v4B.vfl) > FL_EPSILON; returnv.v4B.value = fabs(a.v4B.vfl-b.v4B.vfl) > FL_EPSILON;
break; break;
default: default:
runtime_err("Eq : Invalid types"); runtime_err("Eq : Invalid types");

View file

@ -31,6 +31,7 @@ int heap_hashmap(HashMap *map, i32 size){
map->curr_len = size; map->curr_len = size;
map->buffer = malloc(sizeof(MapItem)*size); map->buffer = malloc(sizeof(MapItem)*size);
map->bit_free = malloc(sizeof(u32)*size/32); map->bit_free = malloc(sizeof(u32)*size/32);
map->item_n = 0;
#if LOG #if LOG
printf("Hashmap alloc : %ldKiB\n", printf("Hashmap alloc : %ldKiB\n",
(sizeof(MapItem)*size + sizeof(u32)*size/32)/1024); (sizeof(MapItem)*size + sizeof(u32)*size/32)/1024);

View file

@ -94,13 +94,8 @@ Value execute(Statement *stat){
params = (Statement**)((Statement*)stat->children[0])->children; params = (Statement**)((Statement*)stat->children[0])->children;
fncall(fn, params); fncall(fn, params);
} }
else { else
#if LOG runtime_err("Calling invalid type");
printf("stvar : %d\n", vars[stat->var_id].tag.type);
#endif
assign(&vars[stat->var_id], execute(stat->children[0]));
}
break; break;
case ST_None: case ST_None:
runtime_err("ST_None to process !"); runtime_err("ST_None to process !");
@ -116,6 +111,9 @@ Value execute(Statement *stat){
returnv = execute(stat->children[i]); returnv = execute(stat->children[i]);
} }
break; break;
case ST_Set:
assign(&vars[stat->var_id], execute(stat->children[0]));
break;
case BI_var: case BI_var:
case BI_let: case BI_let:
// Init the relevant value for correct type checks // Init the relevant value for correct type checks
@ -156,6 +154,8 @@ Value execute(Statement *stat){
returnv = fncall(fn, params); returnv = fncall(fn, params);
break; break;
} }
default:
break;
} }
return returnv; return returnv;
} }

View file

@ -61,6 +61,8 @@ int main(int argc, char *argv[]){
yyparse(); yyparse();
free_stack(); free_stack();
alloc_clean();
fclose(yyin); fclose(yyin);
return 0; return 0;

View file

@ -55,6 +55,7 @@ int make_stack(){
symbol_map_add_bi(&stack->symbol_map); symbol_map_add_bi(&stack->symbol_map);
stack->scope_id = 1; stack->scope_id = 1;
stack->curr_scope = 1; stack->curr_scope = 1;
stack->curr_statement = 0;
return 0; return 0;
} }
@ -70,6 +71,11 @@ void free_stack(){
free(stack); free(stack);
} }
void clean_name(char *name){
i32 len = strcspn(name, " \t\n)");
name[len] = '\0';
}
Statement *get_statement(){ Statement *get_statement(){
if(stack->curr_statement >= stack->stack_size){ if(stack->curr_statement >= stack->stack_size){
stack = realloc(stack, sizeof(ASTStack)+sizeof(Statement)*(stack->stack_size+2048)); stack = realloc(stack, sizeof(ASTStack)+sizeof(Statement)*(stack->stack_size+2048));
@ -138,16 +144,14 @@ void mangle_name(char *dst, i32 scope, char *name){
} }
Statement *declare(i32 type, Tag vtype, char *name, Statement *assign){ Statement *declare(i32 type, Tag vtype, char *name, Statement *assign){
i32 len = strcspn(name, " \t\n)");
#if LOG #if LOG
printf("declare : %d\n", vtype.type); printf("declare : %d\n", vtype.type);
#endif #endif
name[len] = '\0'; clean_name(name);
Statement *stat = get_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");
}
MapItem *ret = hashmap_insert(&stack->symbol_map, name); MapItem *ret = hashmap_insert(&stack->symbol_map, name);
ret->type = *((i16*)&vtype); ret->type = *((i16*)&vtype);
#if LOG #if LOG
@ -158,6 +162,8 @@ Statement *declare(i32 type, Tag vtype, char *name, Statement *assign){
if(assign){ if(assign){
stat->child_n = 1; stat->child_n = 1;
stat->children = malloc(sizeof(void*)); stat->children = malloc(sizeof(void*));
if(!stat->children)
yyerror("Failed to alloc");
stat->children[0] = assign; stat->children[0] = assign;
} }
else else
@ -167,6 +173,7 @@ Statement *declare(i32 type, Tag vtype, char *name, Statement *assign){
} }
Statement *variable_get(char *name){ Statement *variable_get(char *name){
clean_name(name);
Statement *stat = get_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)
@ -178,6 +185,22 @@ Statement *variable_get(char *name){
return stat; return stat;
} }
Statement *set_var(char *name, Statement *expr){
clean_name(name);
Statement *stat = get_statement();
MapItem *ret = hashmap_get(&stack->symbol_map, name);
if(!ret)
yyerror("Undefined indentifier");
stat->type = ST_Set;
stat->var_id = ret->id;
stat->var_type = *((Tag*)&ret->type);
stat->children = malloc(sizeof(void*));
if(!stat->children)
yyerror("Failed to alloc");
stat->children[0] = expr;
return stat;
}
Statement *make_block(Statement *first){ Statement *make_block(Statement *first){
Statement *stat = get_statement(); Statement *stat = get_statement();
stat->type = ST_Block; stat->type = ST_Block;
@ -287,6 +310,7 @@ FnArgs *add_fnargs(FnArgs *args, char *name, Tag type){
Statement *make_function(FnArgs *fn_args, Statement *statements){ Statement *make_function(FnArgs *fn_args, Statement *statements){
printf("make_function : %s\n", fn_args->names[0]); printf("make_function : %s\n", fn_args->names[0]);
Statement *stat = get_statement(); Statement *stat = get_statement();
stat->type = BI_fn;
free(fn_args); free(fn_args);
return stat; return stat;
} }

View file

@ -47,6 +47,7 @@ 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);
Statement *variable_get(char *name); Statement *variable_get(char *name);
Statement *set_var(char *name, Statement *expr);
Statement *make_block(Statement *first); Statement *make_block(Statement *first);
Statement *add_block(Statement *block, Statement *add); Statement *add_block(Statement *block, Statement *add);

View file

@ -28,7 +28,7 @@
%% %%
#.+\n ; #.*\n ;
":vec" return VEC; ":vec" return VEC;
@ -48,6 +48,7 @@
"let" return LET; "let" return LET;
"block" return BLOCK; "block" return BLOCK;
"is" return IS; "is" return IS;
"set" return SET;
\"[^"\n]*["\n] { \"[^"\n]*["\n] {
yylval.st = make_strconst(yytext+1); yylval.st = make_strconst(yytext+1);

View file

@ -45,6 +45,7 @@
%token VEC %token VEC
%token VAR %token VAR
%token LET %token LET
%token SET
%token IF %token IF
%token ELSE %token ELSE
%token WHILE %token WHILE
@ -108,6 +109,8 @@ expr:
{} {}
| '(' LET type G_IDENT expr ')' | '(' LET type G_IDENT expr ')'
{} {}
| '(' SET G_IDENT expr ')'
{$$ = set_var($3, $4);}
| '(' IF expr expr_list ')' | '(' IF expr expr_list ')'
{$$ = make_operation(BI_if, ntag, NULL, 2, $3, $4);} {$$ = make_operation(BI_if, ntag, NULL, 2, $3, $4);}
| '(' IF expr expr_list ')' '(' ELSE expr_list ')' | '(' IF expr expr_list ')' '(' ELSE expr_list ')'
@ -125,7 +128,7 @@ expr:
| '(' BLOCK expr_list ')' | '(' BLOCK expr_list ')'
{$$ = $3;} {$$ = $3;}
| '(' G_IDENT expr_list ')' | '(' G_IDENT expr_list ')'
{$$ = make_operation(ST_None, ntag, $2, 1, $3);} {$$ = make_operation(ST_Call, ntag, $2, 1, $3);}
| '(' IS type expr ')' | '(' IS type expr ')'
{$$ = make_operation(BI_is, $3, NULL, 1, $4);} {$$ = make_operation(BI_is, $3, NULL, 1, $4);}
| '(' type expr ')' | '(' type expr ')'