Skip to content

Commit c5e7626

Browse files
committed
Strongly type call parameters and list index assignments, pass make test
1 parent 2811e3f commit c5e7626

File tree

8 files changed

+183
-52
lines changed

8 files changed

+183
-52
lines changed

compiler/compiler.c

Lines changed: 113 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ void compileStmt(i64_array* program, Stmt* stmt)
187187
symbol_y->value_type == V_INT || symbol_y->value_type == V_FLOAT
188188
))
189189
symbol_x->value_type = symbol_y->value_type;
190+
191+
strongly_type(symbol_x, symbol_y, NULL, stmt->v.assign_stmt->y, symbol_x->value_type);
192+
190193
switch (symbol_x->value_type) {
191194
case V_BOOL:
192195
push_instr(program, LII);
@@ -378,6 +381,8 @@ void compileStmt(i64_array* program, Stmt* stmt)
378381
break;
379382
}
380383

384+
strongly_type(symbol, NULL, NULL, stmt->v.assign_stmt->y, symbol->value_type);
385+
381386
switch (symbol->type) {
382387
case K_STRING:
383388
if (symbol->value_type == V_REF) {
@@ -1156,6 +1161,9 @@ unsigned short compileExpr(i64_array* program, Expr* expr)
11561161
Expr* expr = expr_list->exprs[expr_list->expr_count - i];
11571162
enum ValueType value_type = compileExpr(program, expr) - 1;
11581163
Symbol* parameter = function->parameters[i - 1];
1164+
1165+
strongly_type(parameter, NULL, function, expr, value_type);
1166+
11591167
enum Type type = parameter->type;
11601168
i64 addr = parameter->addr;
11611169

@@ -1682,24 +1690,28 @@ void compileDecl(i64_array* program, Decl* decl)
16821690
case VarDecl_kind: {
16831691
enum ValueType value_type = compileExpr(program, decl->v.var_decl->expr) - 1;
16841692
enum Type type = compileSpec(program, decl->v.var_decl->type_spec);
1693+
enum Type secondary_type = K_ANY;
1694+
if (decl->v.var_decl->type_spec->v.type_spec->sub_type_spec != NULL)
1695+
secondary_type = decl->v.var_decl->type_spec->v.type_spec->type;
1696+
Symbol* symbol = NULL;
16851697

16861698
switch (type) {
16871699
case K_BOOL:
1688-
store_bool(
1700+
symbol = store_bool(
16891701
program,
16901702
decl->v.var_decl->ident->v.ident->name,
16911703
false
16921704
);
16931705
break;
16941706
case K_NUMBER:
16951707
if (value_type == V_FLOAT) {
1696-
store_float(
1708+
symbol = store_float(
16971709
program,
16981710
decl->v.var_decl->ident->v.ident->name,
16991711
false
17001712
);
17011713
} else {
1702-
store_int(
1714+
symbol = store_int(
17031715
program,
17041716
decl->v.var_decl->ident->v.ident->name,
17051717
false
@@ -1727,7 +1739,7 @@ void compileDecl(i64_array* program, Decl* decl)
17271739
break;
17281740
}
17291741

1730-
store_string(
1742+
symbol = store_string(
17311743
program,
17321744
decl->v.var_decl->ident->v.ident->name,
17331745
len,
@@ -1739,22 +1751,22 @@ void compileDecl(i64_array* program, Decl* decl)
17391751
case K_ANY: {
17401752
switch (value_type) {
17411753
case V_BOOL:
1742-
store_bool(
1754+
symbol = store_bool(
17431755
program,
17441756
decl->v.var_decl->ident->v.ident->name,
17451757
true
17461758
);
17471759
break;
17481760
case V_INT: {
1749-
store_int(
1761+
symbol = store_int(
17501762
program,
17511763
decl->v.var_decl->ident->v.ident->name,
17521764
true
17531765
);
17541766
break;
17551767
}
17561768
case V_FLOAT: {
1757-
store_float(
1769+
symbol = store_float(
17581770
program,
17591771
decl->v.var_decl->ident->v.ident->name,
17601772
true
@@ -1785,7 +1797,7 @@ void compileDecl(i64_array* program, Decl* decl)
17851797
break;
17861798
}
17871799

1788-
store_string(
1800+
symbol = store_string(
17891801
program,
17901802
decl->v.var_decl->ident->v.ident->name,
17911803
len,
@@ -1795,19 +1807,19 @@ void compileDecl(i64_array* program, Decl* decl)
17951807
break;
17961808
}
17971809
case V_LIST:
1798-
store_any(
1810+
symbol = store_any(
17991811
program,
18001812
decl->v.var_decl->ident->v.ident->name
18011813
);
18021814
break;
18031815
case V_DICT:
1804-
store_any(
1816+
symbol = store_any(
18051817
program,
18061818
decl->v.var_decl->ident->v.ident->name
18071819
);
18081820
break;
18091821
case V_REF:
1810-
store_any(
1822+
symbol = store_any(
18111823
program,
18121824
decl->v.var_decl->ident->v.ident->name
18131825
);
@@ -1832,7 +1844,7 @@ void compileDecl(i64_array* program, Decl* decl)
18321844
break;
18331845
}
18341846

1835-
store_list(
1847+
symbol = store_list(
18361848
program,
18371849
decl->v.var_decl->ident->v.ident->name,
18381850
len,
@@ -1855,7 +1867,7 @@ void compileDecl(i64_array* program, Decl* decl)
18551867
break;
18561868
}
18571869

1858-
store_dict(
1870+
symbol = store_dict(
18591871
program,
18601872
decl->v.var_decl->ident->v.ident->name,
18611873
len,
@@ -1866,6 +1878,8 @@ void compileDecl(i64_array* program, Decl* decl)
18661878
default:
18671879
break;
18681880
}
1881+
1882+
symbol->secondary_type = secondary_type;
18691883
break;
18701884
}
18711885
case TimesDo_kind: {
@@ -2310,6 +2324,9 @@ unsigned short compileSpec(i64_array* program, Spec* spec)
23102324
break;
23112325
case FieldSpec_kind: {
23122326
enum Type type = compileSpec(program, spec->v.field_spec->type_spec);
2327+
enum Type secondary_type = K_ANY;
2328+
if (spec->v.field_spec->type_spec->v.type_spec->sub_type_spec != NULL)
2329+
secondary_type = spec->v.field_spec->type_spec->v.type_spec->type;
23132330

23142331
Symbol* parameter = NULL;
23152332
union Value value;
@@ -2337,6 +2354,7 @@ unsigned short compileSpec(i64_array* program, Spec* spec)
23372354
default:
23382355
break;
23392356
}
2357+
parameter->secondary_type = secondary_type;
23402358

23412359
parameter->addr = program->heap;
23422360
program->heap += 2;
@@ -2345,6 +2363,9 @@ unsigned short compileSpec(i64_array* program, Spec* spec)
23452363
}
23462364
case OptionalFieldSpec_kind: {
23472365
enum Type type = compileSpec(program, spec->v.optional_field_spec->type_spec);
2366+
enum Type secondary_type = K_ANY;
2367+
if (spec->v.optional_field_spec->type_spec->v.type_spec->sub_type_spec != NULL)
2368+
secondary_type = spec->v.optional_field_spec->type_spec->v.type_spec->type;
23482369

23492370
Symbol* parameter = NULL;
23502371
union Value value;
@@ -2372,6 +2393,7 @@ unsigned short compileSpec(i64_array* program, Spec* spec)
23722393
default:
23732394
break;
23742395
}
2396+
parameter->secondary_type = secondary_type;
23752397

23762398
parameter->addr = program->heap;
23772399
program->heap += 2;
@@ -3507,3 +3529,81 @@ void compile_functions(ASTRoot* ast_root, i64_array* program)
35073529
popModuleStack();
35083530
}
35093531
}
3532+
3533+
void strongly_type(Symbol* symbol_x, Symbol* symbol_y, _Function* function, Expr* expr, enum ValueType value_type)
3534+
{
3535+
if (expr != NULL) {
3536+
if ((symbol_x->type == K_LIST || symbol_x->type == K_DICT) && symbol_x->secondary_type != K_ANY) {
3537+
switch (expr->kind) {
3538+
case CompositeLit_kind: {
3539+
CompositeLit* composite_lit = expr->v.composite_lit;
3540+
for (unsigned long i = composite_lit->elts->expr_count; 0 < i; i--) {
3541+
Expr* elt = composite_lit->elts->exprs[i - 1];
3542+
switch (elt->kind) {
3543+
case CompositeLit_kind: {
3544+
if (function != NULL)
3545+
throw_error(E_ILLEGAL_VARIABLE_TYPE_FOR_FUNCTION_PARAMETER, symbol_x->name, function->name);
3546+
break;
3547+
}
3548+
case BasicLit_kind: {
3549+
BasicLit* basic_lit = elt->v.basic_lit;
3550+
strongly_type_basic_check(E_ILLEGAL_VARIABLE_TYPE_FOR_FUNCTION_PARAMETER, symbol_x->name, function->name, symbol_x->secondary_type, basic_lit->value_type);
3551+
break;
3552+
}
3553+
case KeyValueExpr_kind: {
3554+
KeyValueExpr* key_value_expr = elt->v.key_value_expr;
3555+
if (key_value_expr->value->kind == BasicLit_kind) {
3556+
BasicLit* basic_lit = key_value_expr->value->v.basic_lit;
3557+
strongly_type_basic_check(E_ILLEGAL_VARIABLE_TYPE_FOR_FUNCTION_PARAMETER, symbol_x->name, function->name, symbol_x->secondary_type, basic_lit->value_type);
3558+
}
3559+
break;
3560+
}
3561+
default:
3562+
break;
3563+
}
3564+
}
3565+
break;
3566+
}
3567+
case BasicLit_kind: {
3568+
BasicLit* basic_lit = expr->v.basic_lit;
3569+
strongly_type_basic_check(E_ILLEGAL_ELEMENT_TYPE_FOR_TYPED_LIST, getValueTypeName(basic_lit->value_type), symbol_x->name, symbol_x->secondary_type, basic_lit->value_type);
3570+
break;
3571+
}
3572+
default:
3573+
break;
3574+
}
3575+
}
3576+
}
3577+
3578+
if (function != NULL && value_type != V_ANY) {
3579+
strongly_type_basic_check(E_ILLEGAL_VARIABLE_TYPE_FOR_FUNCTION_PARAMETER, symbol_x->name, function->name, symbol_x->type, value_type);
3580+
}
3581+
}
3582+
3583+
void strongly_type_basic_check(unsigned short code, char *str1, char *str2, enum Type type, enum ValueType value_type)
3584+
{
3585+
switch (type) {
3586+
case K_BOOL:
3587+
if (value_type != V_BOOL)
3588+
throw_error(code, str1, str2);
3589+
break;
3590+
case K_NUMBER:
3591+
if (value_type != V_INT && value_type != V_FLOAT)
3592+
throw_error(code, str1, str2);
3593+
break;
3594+
case K_STRING:
3595+
if (value_type != V_STRING)
3596+
throw_error(code, str1, str2);
3597+
break;
3598+
case K_LIST:
3599+
if (value_type != V_LIST)
3600+
throw_error(code, str1, str2);
3601+
break;
3602+
case K_DICT:
3603+
if (value_type != V_DICT)
3604+
throw_error(code, str1, str2);
3605+
break;
3606+
default:
3607+
break;
3608+
}
3609+
}

compiler/compiler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ bool declare_function(Stmt* stmt, File* file, i64_array* program);
7878
void declare_functions(ASTRoot* ast_root, i64_array* program);
7979
void compile_functions(ASTRoot* ast_root, i64_array* program);
8080

81+
void strongly_type(Symbol* symbol_x, Symbol* symbol_y, _Function* function, Expr* expr, enum ValueType value_type);
82+
void strongly_type_basic_check(unsigned short code, char *str1, char *str2, enum Type type, enum ValueType value_type);
83+
8184
cpu *interactive_c;
8285

8386
#endif

parser/parser.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ extern bool disable_complex_mode;
2626
extern char *suggestions[1000];
2727
extern unsigned long long suggestions_length;
2828

29+
bool compiling_a_function = false;
30+
2931
#ifndef CHAOS_COMPILER
3032
static struct option long_options[] =
3133
{
@@ -262,7 +264,9 @@ void compile_interactive()
262264
compileImports(_ast_root, interactive_program);
263265
_ast_root->files[0]->imports_handled = false;
264266
declare_functions(_ast_root, interactive_program);
267+
compiling_a_function = true;
265268
compile_functions(_ast_root, interactive_program);
269+
compiling_a_function = false;
266270
current_file_index = 0;
267271

268272
push_instr(interactive_program, HLT);
@@ -281,7 +285,10 @@ void compile_interactive()
281285
if (any_stmts) {
282286
Stmt* stmt = _ast_root->files[0]->stmt_list->stmts[0];
283287
is_function = declare_function(stmt, _ast_root->files[0], interactive_program);
288+
if (stmt->kind == DeclStmt_kind && stmt->v.decl_stmt->decl->kind == FuncDecl_kind)
289+
compiling_a_function = true;
284290
compileStmt(interactive_program, stmt);
291+
compiling_a_function = false;
285292
push_instr(interactive_program, HLT);
286293
interactive_program->hlt_count++;
287294
if (!is_function)
@@ -405,21 +412,9 @@ void absorbError() {
405412
fprintf(stderr, "\n");
406413
fflush(stderr);
407414

408-
if (loop_execution_mode) longjmp(InteractiveShellLoopErrorAbsorber, 1);
409-
for (unsigned i = function_call_stack.size; i > 0; i--) {
410-
FunctionCall* function_call = function_call_stack.arr[i - 1];
411-
if (function_call_stack.size < 2 && decision_symbol_chain != NULL) {
412-
removeSymbol(decision_symbol_chain);
413-
decision_symbol_chain = NULL;
414-
}
415-
// callFunctionCleanUpSymbols(function_call);
416-
removeSymbolsByScope(function_call);
417-
if (function_call->dont_pop_module_stack) {
418-
popExecutedFunctionStack();
419-
} else {
420-
callFunctionCleanUpCommon();
421-
}
422-
free(function_call);
415+
if (compiling_a_function) {
416+
removeFunction(end_function);
417+
compiling_a_function = false;
423418
}
424419

425420
if (main_interpreted_module != NULL) {

parser/parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ i64 prev_stmt_count;
6464
i64 prev_import_count;
6565
i64_array* interactive_program;
6666
bool interactively_importing;
67+
bool compiling_a_function;
6768

6869
int initParser(int argc, char** argv);
6970
void compile_interactive();

tests/shell/function.kaos

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ num def fb()
1414
num a = 5
1515
return a
1616
end
17-
fb()
17+
print fb()
1818

1919
// Print the function return on function calls from modules
20-
module1.sub(7, 3)
20+
print module1.sub(7, 3)
2121

2222
// Test for not printing function returns on function decision execution mode
2323
num def f1()
@@ -43,5 +43,4 @@ end {
4343
default : f3()
4444
}
4545

46-
add(3, 5)
4746
print add(3, 5)

tests/shell/function.out

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
Chaos Error (most recent call last):
2-
File: "~/chaos/__interactive__.kaos", line 7, in <module>
2+
File: "~/chaos/__interactive__.kaos", line 7
33
asdasd1()
44
Undefined function: asdasd1 in <module>
55
Absorbed by Interactive Shell
66
hey
77
Chaos Error (most recent call last):
8-
File: "~/chaos/__interactive__.kaos", line 11, in <module>
8+
File: "~/chaos/__interactive__.kaos", line 11
99
asdasd2()
1010
Undefined function: asdasd2 in <module>
1111
Absorbed by Interactive Shell
1212
5
1313
4
1414
101
15-
101

0 commit comments

Comments
 (0)