Feeling eepy
This commit is contained in:
parent
2236d1c85f
commit
d8d8efe117
13 changed files with 89 additions and 53 deletions
3
Makefile
3
Makefile
|
@ -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}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
)
|
)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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");
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 ')'
|
||||||
|
|
Loading…
Add table
Reference in a new issue