diff --git a/src/code_defs.h b/src/code_defs.h index 2961e1c..e569e83 100755 --- a/src/code_defs.h +++ b/src/code_defs.h @@ -64,7 +64,7 @@ struct Statement { Tag var_type; }; FnSig *func; - Tag vtype; + void *els; // "Bodge" - pointer to else for if's }; }; diff --git a/src/exec_common.h b/src/exec_common.h index 34efa18..dce68f4 100644 --- a/src/exec_common.h +++ b/src/exec_common.h @@ -8,4 +8,6 @@ void runtime_err(char *s); int evaluate(Value val); +Value is(Tag tag, Value b); + void symbol_map_add_bi(HashMap *map); diff --git a/src/interpreter.c b/src/interpreter.c index dfadb3a..19a89c4 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -6,6 +6,7 @@ #include "types.h" #include "code_defs.h" #include "byte_defs.h" +#include "exec_common.h" Value vars[SYMBOL_MAP_S]; @@ -31,11 +32,16 @@ Value execute(Statement *stat){ break; case BI_var: case BI_let: + // Init the relevant value for correct "is" + vars[stat->var_id].tag = stat->var_type; break; - // TODO case BI_if: if(evaluate(execute(stat->children[0]))) execute(stat->children[1]); + else { + if(stat->els) + execute(((Statement*)stat->els)->children[0]); + } case BI_else: break; case BI_while: @@ -45,8 +51,8 @@ Value execute(Statement *stat){ case BI_fn: case BI_import: break; - // TODO case BI_is: + returnv = is(stat->var_type, execute(stat->children[0])); break; // TODO case BI_cast: diff --git a/src/parse_utils.c b/src/parse_utils.c index 096b63b..9306bf4 100644 --- a/src/parse_utils.c +++ b/src/parse_utils.c @@ -103,7 +103,7 @@ FnSig bi_sig[] = { }; -Statement *make_operation(i32 type, i32 extrainf, char *name, i32 nparam, ...){ +Statement *make_operation(i32 type, Tag vtype, char *name, i32 nparam, ...){ Statement *stat = &stack->statements[stack->curr_statement++]; if(nparam) stat->children = malloc(sizeof(void*)*nparam); @@ -114,10 +114,11 @@ Statement *make_operation(i32 type, i32 extrainf, char *name, i32 nparam, ...){ va_start(prm, nparam); Statement *param = va_arg(prm, Statement*); - if(!type){ - i32 len = strcspn(name, " \t\n"); + if(!type || type == ST_Call){ + i32 len = strcspn(name, " \t\n()"); char *name2 = strndup(name, len); MapItem *ret = hashmap_get(&stack->symbol_map, name2); + free(name2); if(!ret) yyerror("Undefined identifer"); if(nparam > 1 && ret->type != T_fn) @@ -132,9 +133,13 @@ Statement *make_operation(i32 type, i32 extrainf, char *name, i32 nparam, ...){ type = ST_Call; stat->func = fnsig; } - if(param->child_n > fnsig->n_param) - yyerror("Too many parameters to function"); + if(nparam){ + if(param->child_n > fnsig->n_param) + yyerror("Too many parameters to function"); + } } + if(type == BI_is || type == BI_cast) + stat->var_type = vtype; stat->type = type; if(nparam) diff --git a/src/parser.h b/src/parser.h index 6b0eb8c..88382de 100644 --- a/src/parser.h +++ b/src/parser.h @@ -24,7 +24,7 @@ Statement *make_block(Statement *first); Statement *add_block(Statement *block, Statement *add); -Statement *make_operation(i32 type, i32 extainf, char *str, i32 nparam, ...); +Statement *make_operation(i32 type, Tag vtype, char *str, i32 nparam, ...); void set_entry_point(Statement *statement); diff --git a/src/parser.y b/src/parser.y index 207bb77..6cd49fe 100644 --- a/src/parser.y +++ b/src/parser.y @@ -60,7 +60,7 @@ fn_args: expr: '(' G_IDENT ')' - {$$ = make_operation(ST_Call,0,$2,0);} + {$$ = make_operation(ST_Call,ntag,$2,0);} | '(' VAR G_IDENT ')' { $$ = declare(BI_var,ntag,$3);} | '(' VAR type G_IDENT ')' @@ -78,23 +78,25 @@ expr: | '(' LET type G_IDENT expr ')' {} | '(' IF expr expr_list ')' - {$$ = make_operation(BI_if, 0, NULL, 2, $3, $4);} + {$$ = make_operation(BI_if, ntag, NULL, 2, $3, $4);} | '(' IF expr expr_list ')' '(' ELSE expr_list ')' - {Statement *st = make_block(make_operation(BI_if, 0, NULL, 2, $3, $4)); - $$ = add_block(st, make_operation(BI_else, 0, NULL, 1, $8)); + {Statement *ifs = make_operation(BI_if, ntag, NULL, 2, $3, $4); + Statement *els = make_operation(BI_else, ntag, NULL, 1, $8); + ifs->els = els; + $$ = add_block(make_block(ifs),els); } | '(' WHILE expr expr_list ')' - {} + {$$ = make_operation(BI_while, ntag, NULL, 2, $3, $4);} | '(' FN '(' fn_args ')' expr_list ')' {} | '(' BLOCK expr_list ')' {$$ = $3;} | '(' G_IDENT expr_list ')' - {$$ = make_operation(ST_None, 0, $2, 1, $3);} + {$$ = make_operation(ST_None, ntag, $2, 1, $3);} | '(' IS type expr ')' - {} + {$$ = make_operation(BI_is, $3, NULL, 1, $4);} | '(' type expr ')' - {} + {$$ = make_operation(BI_cast, $2, NULL, 1, $3);} | G_IDENT {$$ = variable_get($1);} | CST diff --git a/src/types.h b/src/types.h index 11a3916..b68655a 100755 --- a/src/types.h +++ b/src/types.h @@ -19,6 +19,8 @@ typedef unsigned int uint; #define PACKED __attribute__((__packed__)) #endif +#define NOPOS __attribute__((designated_init)) + enum ValTypes { T_null = 0, T_int = 1,