commit 66ce184ff6a09bdced8cb831276f44502f5b418d
parent 1428ead8e53fa5551aa10b9ce4d0ccee1239a55b
Author: erai <erai@omiltem.net>
Date: Sun, 29 Sep 2024 21:58:40 -0400
separate typecheck pass
Diffstat:
M | cc0.c | | | 746 | +++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------- |
M | cc1.c | | | 783 | ++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------- |
2 files changed, 998 insertions(+), 531 deletions(-)
diff --git a/cc0.c b/cc0.c
@@ -827,6 +827,9 @@ void( my_translate_pattern)(struct my_peg_compiler* my_c,struct my_peg_node* my_
unsigned long( my_type_isint)(struct my_type* my_t);
unsigned long( my_type_isprim)(struct my_type* my_t);
unsigned long( my_type_sizeof)(struct my_compiler* my_c,struct my_type* my_t);
+void( my_typecheck_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_node* my_n,unsigned long my_rhs);
+void( my_typecheck_func)(struct my_compiler* my_c,struct my_decl* my_d);
+void( my_typecheck_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_node* my_n);
unsigned long( my_unescape)(unsigned char* my_s,unsigned long* my_i,unsigned long my_len,unsigned long* my_ok);
void( my_unify)(struct my_compiler* my_c,struct my_type* my_a,struct my_type* my_b);
unsigned long( my_unlink)(unsigned char* my_name);
@@ -1566,6 +1569,16 @@ void( my_compile)(struct my_compiler* my_c,struct my_node* my_p){
}
(my_d)=((my_next_decl)((my_c),(my_d)));
}
+ (my_d)=((my_first_decl)((my_c)));
+ while (1) {
+ if ((unsigned long)(!(my_d))) {
+ break;
+ }
+ if ((my_d)->my_func_defined) {
+ (my_typecheck_func)((my_c),(my_d));
+ }
+ (my_d)=((my_next_decl)((my_c),(my_d)));
+ }
(my_d)=((my_find)((my_c),((unsigned char *)"_start"),((unsigned char*)0UL),(0UL)));
if ((unsigned long)((my_d)&&((my_d)->my_func_defined))) {
((my_c)->my_start)=((my_d)->my_func_label);
@@ -1598,40 +1611,17 @@ void( my_compile_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
((my_c)->my_colno)=((my_n)->my_colno);
(my_kind)=((my_n)->my_kind);
if ((unsigned long)(((long)(my_kind))==((long)(my_N_STR)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"str is not an lexpr"));
- }
(my_emit_str)(((my_c)->my_as),((my_n)->my_s));
- ((my_n)->my_t)=((my_mktype1)((my_c),(my_TY_PTR),((my_mktype0)((my_c),(my_TY_BYTE)))));
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_NUM)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"num is not an lexpr"));
- }
(my_emit_num)(((my_c)->my_as),((my_n)->my_n));
- ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_CHAR)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"char is not an lexpr"));
- }
(my_emit_num)(((my_c)->my_as),((my_n)->my_n));
- ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_EXPRLIST)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"call is not an lexpr"));
- }
if ((my_n)->my_b) {
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
}
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
- if ((my_n)->my_b) {
- ((my_n)->my_t)=((my_mktype2)((my_c),(my_TY_ARG),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t)));
- } else {
- ((my_n)->my_t)=((my_mktype1)((my_c),(my_TY_ARG),(((my_n)->my_a)->my_t)));
- }
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_CALL)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"call is not an lexpr"));
- }
if ((my_n)->my_b) {
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
}
@@ -1643,57 +1633,34 @@ void( my_compile_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
(my_v)=((my_find)((my_c),((my_d)->my_name),(((my_n)->my_a)->my_s),(0UL)));
if ((unsigned long)((my_v)&&((my_v)->my_var_defined))) {
(my_emit_lea)(((my_c)->my_as),((my_v)->my_var_offset));
- (((my_n)->my_a)->my_t)=((my_v)->my_var_type);
(my_emit_load)(((my_c)->my_as),(((my_n)->my_a)->my_t));
(my_emit_call)(((my_c)->my_as),((my_count_args)((my_c),((((my_n)->my_a)->my_t)->my_arg))));
} else if ((unsigned long)(!((my_strcmp)((((my_n)->my_a)->my_s),((unsigned char *)"_include"))))) {
(my_v)=((my_find)((my_c),(((my_n)->my_a)->my_s),((unsigned char*)0UL),(0UL)));
- if ((unsigned long)(((unsigned long)(!(my_v)))||((unsigned long)(!((my_v)->my_func_defined))))) {
- (my_cdie)((my_c),((unsigned char *)"no such function"));
- }
- (((my_n)->my_a)->my_t)=((my_v)->my_func_type);
(my_compile_include)((my_c),(my_n));
} else {
(my_v)=((my_find)((my_c),(((my_n)->my_a)->my_s),((unsigned char*)0UL),(0UL)));
- if ((unsigned long)(((unsigned long)(!(my_v)))||((unsigned long)(!((my_v)->my_func_defined))))) {
- (my_cdie)((my_c),((unsigned char *)"no such function"));
- }
- (((my_n)->my_a)->my_t)=((my_v)->my_func_type);
(my_emit_lcall)(((my_c)->my_as),((my_v)->my_func_label),((my_count_args)((my_c),((((my_n)->my_a)->my_t)->my_arg))));
}
} else {
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_call)(((my_c)->my_as),((my_count_args)((my_c),((((my_n)->my_a)->my_t)->my_arg))));
}
- if ((unsigned long)(((long)((((my_n)->my_a)->my_t)->my_kind))!=((long)(my_TY_FUNC)))) {
- (my_cdie)((my_c),((unsigned char *)"calling not a function"));
- }
if ((my_n)->my_b) {
(my_unify)((my_c),((((my_n)->my_a)->my_t)->my_arg),(((my_n)->my_b)->my_t));
} else {
(my_unify)((my_c),((((my_n)->my_a)->my_t)->my_arg),((struct my_type*)0UL));
}
- ((my_n)->my_t)=((((my_n)->my_a)->my_t)->my_val);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_DOT)))) {
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(0UL));
if ((unsigned long)(((long)((((my_n)->my_a)->my_t)->my_kind))==((long)(my_TY_PTR)))) {
- if ((unsigned long)(((long)(((((my_n)->my_a)->my_t)->my_val)->my_kind))!=((long)(my_TY_STRUCT)))) {
- (my_cdie)((my_c),((unsigned char *)"dot not a struct"));
- }
(my_v)=((my_find)((my_c),((((((my_n)->my_a)->my_t)->my_val)->my_st)->my_name),(((my_n)->my_b)->my_s),(0UL)));
(my_emit_load)(((my_c)->my_as),(((my_n)->my_a)->my_t));
} else {
- if ((unsigned long)(((long)((((my_n)->my_a)->my_t)->my_kind))!=((long)(my_TY_STRUCT)))) {
- (my_cdie)((my_c),((unsigned char *)"dot not a struct"));
- }
(my_v)=((my_find)((my_c),(((((my_n)->my_a)->my_t)->my_st)->my_name),(((my_n)->my_b)->my_s),(0UL)));
}
- if ((unsigned long)(((unsigned long)(!(my_v)))||((unsigned long)(!((my_v)->my_member_defined))))) {
- (my_cdie)((my_c),((unsigned char *)"no such member"));
- }
(my_emit_num)(((my_c)->my_as),((my_v)->my_member_offset));
(my_emit_add)(((my_c)->my_as));
- ((my_n)->my_t)=((my_v)->my_member_type);
if (my_rhs) {
(my_emit_load)(((my_c)->my_as),((my_n)->my_t));
}
@@ -1701,13 +1668,11 @@ void( my_compile_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
(my_v)=((my_find)((my_c),((my_n)->my_s),((unsigned char*)0UL),(0UL)));
if ((unsigned long)((my_v)&&((my_v)->my_enum_defined))) {
(my_emit_num)(((my_c)->my_as),((my_v)->my_enum_value));
- ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
return;
}
(my_v)=((my_find)((my_c),((my_d)->my_name),((my_n)->my_s),(0UL)));
if ((unsigned long)((my_v)&&((my_v)->my_var_defined))) {
(my_emit_lea)(((my_c)->my_as),((my_v)->my_var_offset));
- ((my_n)->my_t)=((my_v)->my_var_type);
if (my_rhs) {
(my_emit_load)(((my_c)->my_as),((my_n)->my_t));
}
@@ -1716,23 +1681,13 @@ void( my_compile_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
(my_v)=((my_find)((my_c),((my_n)->my_s),((unsigned char*)0UL),(0UL)));
if ((unsigned long)((my_v)&&((my_v)->my_func_defined))) {
(my_emit_ptr)(((my_c)->my_as),((my_v)->my_func_label));
- ((my_n)->my_t)=((my_v)->my_func_type);
return;
}
- (my_cdie)((my_c),((unsigned char *)"no such variable"));
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_ASSIGN)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"assign is not an lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(0UL));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
(my_emit_store)(((my_c)->my_as),((my_n)->my_t));
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_SIZEOF)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"sizeof is not an lexpr"));
- }
(my_out)=((my_mklabel)(((my_c)->my_as)));
(my_emit_jmp)(((my_c)->my_as),(my_out));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(0UL));
@@ -1742,32 +1697,16 @@ void( my_compile_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
} else {
(my_emit_num)(((my_c)->my_as),((my_type_sizeof)((my_c),(((my_n)->my_a)->my_t))));
}
- ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_REF)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"ref is not an lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(0UL));
- ((my_n)->my_t)=((my_mktype1)((my_c),(my_TY_PTR),(((my_n)->my_a)->my_t)));
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_DEREF)))) {
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
- if ((unsigned long)(((long)((((my_n)->my_a)->my_t)->my_kind))!=((long)(my_TY_PTR)))) {
- (my_cdie)((my_c),((unsigned char *)"deref not a pointer"));
- }
- ((my_n)->my_t)=((((my_n)->my_a)->my_t)->my_val);
if (my_rhs) {
(my_emit_load)(((my_c)->my_as),((my_n)->my_t));
}
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_INDEX)))) {
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
- if ((unsigned long)(((long)((((my_n)->my_a)->my_t)->my_kind))!=((long)(my_TY_PTR)))) {
- (my_cdie)((my_c),((unsigned char *)"not a pointer"));
- }
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_b)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"index: not an int"));
- }
- ((my_n)->my_t)=((((my_n)->my_a)->my_t)->my_val);
if ((unsigned long)(((long)(((my_n)->my_t)->my_kind))==((long)(my_TY_BYTE)))) {
(my_emit_num)(((my_c)->my_as),(1UL));
} else {
@@ -1779,81 +1718,30 @@ void( my_compile_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
(my_emit_load)(((my_c)->my_as),((my_n)->my_t));
}
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_LT)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_lt)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"lt: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_GT)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_gt)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"gt: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_LE)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_le)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"le: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_GE)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_ge)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"ge: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_EQ)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_eq)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"eq: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_NE)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_ne)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"ne: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_BNOT)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_no)=((my_mklabel)(((my_c)->my_as)));
(my_out)=((my_mklabel)(((my_c)->my_as)));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
@@ -1863,14 +1751,7 @@ void( my_compile_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
(my_fixup_label)(((my_c)->my_as),(my_no));
(my_emit_num)(((my_c)->my_as),(1UL));
(my_fixup_label)(((my_c)->my_as),(my_out));
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"not an prim"));
- }
- ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_BOR)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_no)=((my_mklabel)(((my_c)->my_as)));
(my_out)=((my_mklabel)(((my_c)->my_as)));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
@@ -1886,17 +1767,7 @@ void( my_compile_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
(my_fixup_label)(((my_c)->my_as),(my_no));
(my_emit_num)(((my_c)->my_as),(0UL));
(my_fixup_label)(((my_c)->my_as),(my_out));
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"not an prim"));
- }
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_b)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"not an prim"));
- }
- ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_BAND)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_no)=((my_mklabel)(((my_c)->my_as)));
(my_out)=((my_mklabel)(((my_c)->my_as)));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
@@ -1908,171 +1779,56 @@ void( my_compile_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
(my_fixup_label)(((my_c)->my_as),(my_no));
(my_emit_num)(((my_c)->my_as),(0UL));
(my_fixup_label)(((my_c)->my_as),(my_out));
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"not an prim"));
- }
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_b)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"not an prim"));
- }
- ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_POS)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"pos: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_NEG)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_neg)(((my_c)->my_as));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"neg: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_NOT)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_not)(((my_c)->my_as));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"not: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_ADD)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_add)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"add: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_SUB)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_sub)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"sub: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_MUL)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_mul)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"mul: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_DIV)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_div)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"div: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_MOD)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_mod)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"mod: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_LSH)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_lsh)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"lsh: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_RSH)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_rsh)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"rsh: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_AND)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_and)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"and: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_OR)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_or)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"or: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_XOR)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_emit_xor)(((my_c)->my_as));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
- if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"xor: not an int"));
- }
- ((my_n)->my_t)=(((my_n)->my_a)->my_t);
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_CAST)))) {
- if ((unsigned long)(!(my_rhs))) {
- (my_cdie)((my_c),((unsigned char *)"not lexpr"));
- }
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
- if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
- (my_cdie)((my_c),((unsigned char *)"not a primitive"));
- }
- ((my_n)->my_t)=((my_prototype)((my_c),((my_n)->my_b)));
} else {
(my_cdie)((my_c),((unsigned char *)"not an expression"));
}
@@ -2145,7 +1901,6 @@ void( my_compile_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
}
(my_no)=((my_mklabel)(((my_c)->my_as)));
if (((my_n)->my_a)->my_a) {
- (my_call_check)((my_c),(((my_n)->my_a)->my_a));
(my_compile_expr)((my_c),(my_d),(((my_n)->my_a)->my_a),(1UL));
(my_emit_jz)(((my_c)->my_as),(my_no));
}
@@ -2184,9 +1939,7 @@ void( my_compile_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
if ((unsigned long)(((long)((((my_d)->my_func_type)->my_val)->my_kind))==((long)(my_TY_VOID)))) {
(my_cdie)((my_c),((unsigned char *)"returning a value in a void function"));
}
- (my_call_check)((my_c),((my_n)->my_a));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
- (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_d)->my_func_type)->my_val));
} else {
if ((unsigned long)(((long)((((my_d)->my_func_type)->my_val)->my_kind))!=((long)(my_TY_VOID)))) {
(my_cdie)((my_c),((unsigned char *)"returning void in a non void function"));
@@ -2204,7 +1957,6 @@ void( my_compile_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
}
(my_emit_jmp)(((my_c)->my_as),((my_v)->my_goto_label));
} else if ((unsigned long)(((long)(my_kind))!=((long)(my_N_VARDECL)))) {
- (my_call_check)((my_c),(my_n));
(my_compile_expr)((my_c),(my_d),(my_n),(1UL));
(my_emit_pop)(((my_c)->my_as),(1UL));
}
@@ -4720,6 +4472,9 @@ void( my_mark_expr_used)(struct my_compiler* my_c,struct my_decl* my_d,struct my
if ((unsigned long)(!(my_n))) {
return;
}
+ ((my_c)->my_filename)=((my_n)->my_filename);
+ ((my_c)->my_lineno)=((my_n)->my_lineno);
+ ((my_c)->my_colno)=((my_n)->my_colno);
(my_kind)=((my_n)->my_kind);
if ((unsigned long)(((long)(my_kind))==((long)(my_N_EXPRLIST)))) {
while (1) {
@@ -4771,6 +4526,9 @@ void( my_mark_stmt_used)(struct my_compiler* my_c,struct my_decl* my_d,struct my
if ((unsigned long)(!(my_n))) {
return;
}
+ ((my_c)->my_filename)=((my_n)->my_filename);
+ ((my_c)->my_lineno)=((my_n)->my_lineno);
+ ((my_c)->my_colno)=((my_n)->my_colno);
(my_kind)=((my_n)->my_kind);
if ((unsigned long)(((long)(my_kind))==((long)(my_N_CONDLIST)))) {
while (1) {
@@ -9377,6 +9135,472 @@ unsigned long( my_type_sizeof)(struct my_compiler* my_c,struct my_type* my_t){
(my_cdie)((my_c),((unsigned char *)"sizeof: invalid type"));
}
}
+void( my_typecheck_expr)(struct my_compiler* my_c,struct my_decl* my_d,struct my_node* my_n,unsigned long my_rhs){
+ struct my_decl* my_v = 0;
+ unsigned long my_kind = 0;
+ ((my_c)->my_filename)=((my_n)->my_filename);
+ ((my_c)->my_lineno)=((my_n)->my_lineno);
+ ((my_c)->my_colno)=((my_n)->my_colno);
+ (my_kind)=((my_n)->my_kind);
+ if ((unsigned long)(((long)(my_kind))==((long)(my_N_STR)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"str is not an lexpr"));
+ }
+ ((my_n)->my_t)=((my_mktype1)((my_c),(my_TY_PTR),((my_mktype0)((my_c),(my_TY_BYTE)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_NUM)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"num is not an lexpr"));
+ }
+ ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_CHAR)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"char is not an lexpr"));
+ }
+ ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_EXPRLIST)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"call is not an lexpr"));
+ }
+ if ((my_n)->my_b) {
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ if ((my_n)->my_b) {
+ ((my_n)->my_t)=((my_mktype2)((my_c),(my_TY_ARG),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t)));
+ } else {
+ ((my_n)->my_t)=((my_mktype1)((my_c),(my_TY_ARG),(((my_n)->my_a)->my_t)));
+ }
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_CALL)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"call is not an lexpr"));
+ }
+ if ((my_n)->my_b) {
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ }
+ if ((unsigned long)(((long)(((my_n)->my_a)->my_kind))==((long)(my_N_IDENT)))) {
+ (my_v)=((my_find)((my_c),(((my_n)->my_a)->my_s),((unsigned char*)0UL),(0UL)));
+ if ((unsigned long)((my_v)&&((my_v)->my_enum_defined))) {
+ (my_cdie)((my_c),((unsigned char *)"type error"));
+ }
+ (my_v)=((my_find)((my_c),((my_d)->my_name),(((my_n)->my_a)->my_s),(0UL)));
+ if ((unsigned long)((my_v)&&((my_v)->my_var_defined))) {
+ (my_emit_lea)(((my_c)->my_as),((my_v)->my_var_offset));
+ (((my_n)->my_a)->my_t)=((my_v)->my_var_type);
+ (my_emit_load)(((my_c)->my_as),(((my_n)->my_a)->my_t));
+ (my_emit_call)(((my_c)->my_as),((my_count_args)((my_c),((((my_n)->my_a)->my_t)->my_arg))));
+ } else if ((unsigned long)(!((my_strcmp)((((my_n)->my_a)->my_s),((unsigned char *)"_include"))))) {
+ (my_v)=((my_find)((my_c),(((my_n)->my_a)->my_s),((unsigned char*)0UL),(0UL)));
+ if ((unsigned long)(((unsigned long)(!(my_v)))||((unsigned long)(!((my_v)->my_func_defined))))) {
+ (my_cdie)((my_c),((unsigned char *)"no such function"));
+ }
+ (((my_n)->my_a)->my_t)=((my_v)->my_func_type);
+ } else {
+ (my_v)=((my_find)((my_c),(((my_n)->my_a)->my_s),((unsigned char*)0UL),(0UL)));
+ if ((unsigned long)(((unsigned long)(!(my_v)))||((unsigned long)(!((my_v)->my_func_defined))))) {
+ (my_cdie)((my_c),((unsigned char *)"no such function"));
+ }
+ (((my_n)->my_a)->my_t)=((my_v)->my_func_type);
+ (my_emit_lcall)(((my_c)->my_as),((my_v)->my_func_label),((my_count_args)((my_c),((((my_n)->my_a)->my_t)->my_arg))));
+ }
+ } else {
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_emit_call)(((my_c)->my_as),((my_count_args)((my_c),((((my_n)->my_a)->my_t)->my_arg))));
+ }
+ if ((unsigned long)(((long)((((my_n)->my_a)->my_t)->my_kind))!=((long)(my_TY_FUNC)))) {
+ (my_cdie)((my_c),((unsigned char *)"calling not a function"));
+ }
+ if ((my_n)->my_b) {
+ (my_unify)((my_c),((((my_n)->my_a)->my_t)->my_arg),(((my_n)->my_b)->my_t));
+ } else {
+ (my_unify)((my_c),((((my_n)->my_a)->my_t)->my_arg),((struct my_type*)0UL));
+ }
+ ((my_n)->my_t)=((((my_n)->my_a)->my_t)->my_val);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_DOT)))) {
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(0UL));
+ if ((unsigned long)(((long)((((my_n)->my_a)->my_t)->my_kind))==((long)(my_TY_PTR)))) {
+ if ((unsigned long)(((long)(((((my_n)->my_a)->my_t)->my_val)->my_kind))!=((long)(my_TY_STRUCT)))) {
+ (my_cdie)((my_c),((unsigned char *)"dot not a struct"));
+ }
+ (my_v)=((my_find)((my_c),((((((my_n)->my_a)->my_t)->my_val)->my_st)->my_name),(((my_n)->my_b)->my_s),(0UL)));
+ } else {
+ if ((unsigned long)(((long)((((my_n)->my_a)->my_t)->my_kind))!=((long)(my_TY_STRUCT)))) {
+ (my_cdie)((my_c),((unsigned char *)"dot not a struct"));
+ }
+ (my_v)=((my_find)((my_c),(((((my_n)->my_a)->my_t)->my_st)->my_name),(((my_n)->my_b)->my_s),(0UL)));
+ }
+ if ((unsigned long)(((unsigned long)(!(my_v)))||((unsigned long)(!((my_v)->my_member_defined))))) {
+ (my_cdie)((my_c),((unsigned char *)"no such member"));
+ }
+ ((my_n)->my_t)=((my_v)->my_member_type);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_IDENT)))) {
+ (my_v)=((my_find)((my_c),((my_n)->my_s),((unsigned char*)0UL),(0UL)));
+ if ((unsigned long)((my_v)&&((my_v)->my_enum_defined))) {
+ ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
+ return;
+ }
+ (my_v)=((my_find)((my_c),((my_d)->my_name),((my_n)->my_s),(0UL)));
+ if ((unsigned long)((my_v)&&((my_v)->my_var_defined))) {
+ ((my_n)->my_t)=((my_v)->my_var_type);
+ return;
+ }
+ (my_v)=((my_find)((my_c),((my_n)->my_s),((unsigned char*)0UL),(0UL)));
+ if ((unsigned long)((my_v)&&((my_v)->my_func_defined))) {
+ ((my_n)->my_t)=((my_v)->my_func_type);
+ return;
+ }
+ (my_cdie)((my_c),((unsigned char *)"no such variable"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_ASSIGN)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"assign is not an lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(0UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_SIZEOF)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"sizeof is not an lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(0UL));
+ ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_REF)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"ref is not an lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(0UL));
+ ((my_n)->my_t)=((my_mktype1)((my_c),(my_TY_PTR),(((my_n)->my_a)->my_t)));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_DEREF)))) {
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ if ((unsigned long)(((long)((((my_n)->my_a)->my_t)->my_kind))!=((long)(my_TY_PTR)))) {
+ (my_cdie)((my_c),((unsigned char *)"deref not a pointer"));
+ }
+ ((my_n)->my_t)=((((my_n)->my_a)->my_t)->my_val);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_INDEX)))) {
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ if ((unsigned long)(((long)((((my_n)->my_a)->my_t)->my_kind))!=((long)(my_TY_PTR)))) {
+ (my_cdie)((my_c),((unsigned char *)"not a pointer"));
+ }
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_b)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"index: not an int"));
+ }
+ ((my_n)->my_t)=((((my_n)->my_a)->my_t)->my_val);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_LT)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"lt: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_GT)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"gt: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_LE)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"le: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_GE)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"ge: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_EQ)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"eq: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_NE)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"ne: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_BNOT)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_emit_num)(((my_c)->my_as),(1UL));
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"not an prim"));
+ }
+ ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_BOR)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"not an prim"));
+ }
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_b)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"not an prim"));
+ }
+ ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_BAND)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"not an prim"));
+ }
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_b)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"not an prim"));
+ }
+ ((my_n)->my_t)=((my_mktype0)((my_c),(my_TY_INT)));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_POS)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"pos: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_NEG)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"neg: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_NOT)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"not: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_ADD)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"add: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_SUB)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"sub: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_MUL)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"mul: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_DIV)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"div: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_MOD)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"mod: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_LSH)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"lsh: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_RSH)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"rsh: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_AND)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"and: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_OR)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"or: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_XOR)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_b),(1UL));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_n)->my_b)->my_t));
+ if ((unsigned long)(!((my_type_isint)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"xor: not an int"));
+ }
+ ((my_n)->my_t)=(((my_n)->my_a)->my_t);
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_CAST)))) {
+ if ((unsigned long)(!(my_rhs))) {
+ (my_cdie)((my_c),((unsigned char *)"not lexpr"));
+ }
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ if ((unsigned long)(!((my_type_isprim)((((my_n)->my_a)->my_t))))) {
+ (my_cdie)((my_c),((unsigned char *)"not a primitive"));
+ }
+ ((my_n)->my_t)=((my_prototype)((my_c),((my_n)->my_b)));
+ } else {
+ (my_cdie)((my_c),((unsigned char *)"not an expression"));
+ }
+}
+void( my_typecheck_func)(struct my_compiler* my_c,struct my_decl* my_d){
+ if ((unsigned long)(!((my_d)->my_func_def))) {
+ return;
+ }
+ (my_typecheck_stmt)((my_c),(my_d),(((my_d)->my_func_def)->my_b));
+}
+void( my_typecheck_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_node* my_n){
+ struct my_decl* my_v = 0;
+ unsigned long my_kind = 0;
+ if ((unsigned long)(!(my_n))) {
+ return;
+ }
+ ((my_c)->my_filename)=((my_n)->my_filename);
+ ((my_c)->my_lineno)=((my_n)->my_lineno);
+ ((my_c)->my_colno)=((my_n)->my_colno);
+ (my_kind)=((my_n)->my_kind);
+ if ((unsigned long)(((long)(my_kind))==((long)(my_N_CONDLIST)))) {
+ while (1) {
+ if ((unsigned long)(!(my_n))) {
+ break;
+ }
+ if (((my_n)->my_a)->my_a) {
+ (my_typecheck_expr)((my_c),(my_d),(((my_n)->my_a)->my_a),(1UL));
+ }
+ (my_typecheck_stmt)((my_c),(my_d),(((my_n)->my_a)->my_b));
+ (my_n)=((my_n)->my_b);
+ }
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_STMTLIST)))) {
+ while (1) {
+ if ((unsigned long)(!(my_n))) {
+ break;
+ }
+ (my_typecheck_stmt)((my_c),(my_d),((my_n)->my_a));
+ (my_n)=((my_n)->my_b);
+ }
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_LOOP)))) {
+ (my_typecheck_stmt)((my_c),(my_d),((my_n)->my_a));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_BREAK)))) {
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_CONTINUE)))) {
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_RETURN)))) {
+ if ((my_n)->my_a) {
+ if ((unsigned long)(((long)((((my_d)->my_func_type)->my_val)->my_kind))==((long)(my_TY_VOID)))) {
+ (my_cdie)((my_c),((unsigned char *)"returning a value in a void function"));
+ }
+ (my_call_check)((my_c),((my_n)->my_a));
+ (my_typecheck_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
+ (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_d)->my_func_type)->my_val));
+ } else {
+ if ((unsigned long)(((long)((((my_d)->my_func_type)->my_val)->my_kind))!=((long)(my_TY_VOID)))) {
+ (my_cdie)((my_c),((unsigned char *)"returning void in a non void function"));
+ }
+ }
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_LABEL)))) {
+ (my_v)=((my_find)((my_c),((my_d)->my_name),(((my_n)->my_a)->my_s),(0UL)));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_GOTO)))) {
+ (my_v)=((my_find)((my_c),((my_d)->my_name),(((my_n)->my_a)->my_s),(0UL)));
+ if ((unsigned long)(((unsigned long)(!(my_v)))||((unsigned long)(!((my_v)->my_goto_defined))))) {
+ (my_cdie)((my_c),((unsigned char *)"label not defined"));
+ }
+ } else if ((unsigned long)(((long)(my_kind))!=((long)(my_N_VARDECL)))) {
+ (my_call_check)((my_c),(my_n));
+ (my_typecheck_expr)((my_c),(my_d),(my_n),(1UL));
+ }
+}
unsigned long( my_unescape)(unsigned char* my_s,unsigned long* my_i,unsigned long my_len,unsigned long* my_ok){
unsigned long my_ch = 0;
unsigned long my_hex = 0;
diff --git a/cc1.c b/cc1.c
@@ -152,6 +152,20 @@ compile(c: *compiler, p: *node) {
d = next_decl(c, d);
}
+ // Typecheck functions
+ d = first_decl(c);
+ loop {
+ if (!d) {
+ break;
+ }
+
+ if d.func_defined {
+ typecheck_func(c, d);
+ }
+
+ d = next_decl(c, d);
+ }
+
// Check usage
d = find(c, "_start", 0:*byte, 0);
if (d && d.func_defined) {
@@ -200,6 +214,10 @@ mark_expr_used(c: *compiler, d: *decl, n: *node) {
return;
}
+ c.filename = n.filename;
+ c.lineno = n.lineno;
+ c.colno = n.colno;
+
kind = n.kind;
if kind == N_EXPRLIST {
loop {
@@ -260,6 +278,10 @@ mark_stmt_used(c: *compiler, d: *decl, n: *node) {
return;
}
+ c.filename = n.filename;
+ c.lineno = n.lineno;
+ c.colno = n.colno;
+
kind = n.kind;
if kind == N_CONDLIST {
loop {
@@ -528,108 +550,7 @@ compile_func(c: *compiler, d: *decl) {
emit_ret(c.as);
}
-hoist_locals(c: *compiler, d: *decl, n: *node, offset: int): int {
- var kind: int;
- var name: *byte;
- var t: *type;
- var v: *decl;
-
- if (!n) {
- return offset;
- }
-
- kind = n.kind;
- if (kind == N_CONDLIST) {
- loop {
- if (!n) {
- return offset;
- }
-
- hoist_locals(c, d, n.a.b, offset);
-
- n = n.b;
- }
- } else if (kind == N_STMTLIST) {
- loop {
- if (!n) {
- return offset;
- }
-
- offset = hoist_locals(c, d, n.a, offset);
-
- n = n.b;
- }
- } else if (kind == N_LOOP) {
- return hoist_locals(c, d, n.a, offset);
- } else if (kind == N_LABEL) {
- name = n.a.s;
- v = find(c, d.name, name, 1);
-
- if (v.goto_defined) {
- cdie(c, "duplicate goto");
- }
- v.goto_defined = 1;
-
- return offset;
- } else if (kind != N_VARDECL) {
- return offset;
- }
-
- name = n.a.s;
- t = prototype(c, n.b);
-
- n.t = t;
-
- v = find(c, d.name, name, 1);
-
- if (v.var_defined) {
- cdie(c, "duplicate variable");
- }
-
- v.var_type = t;
- v.var_defined = 1;
-
- offset = offset + type_sizeof(c, t);
-
- v.var_offset = -offset;
-
- return offset;
-}
-
-compile_include(c: *compiler, n: *node) {
- var filename: *byte;
- var fd: int;
- var blob: *byte;
- var len: int;
-
- if n.b.a.kind != N_STR {
- die("non literal include");
- }
-
- filename = n.b.a.s;
-
- fd = open(filename, O_RDONLY, 0);
- if fd < 0 {
- die("failed to open include");
- }
-
- blob = readall(fd, &len, c.a);
-
- close(fd);
-
- as_opr(c.as, OP_POPR, R_RAX);
- as_opr(c.as, OP_POPR, R_RDI);
- as_opri64(c.as, OP_MOVABS, R_RAX, len);
- as_modrm(c.as, OP_STORE, R_RAX, R_RDI, 0, 0, 0);
- emit_blob(c.as, blob, len);
-
- free(c.a, blob);
-}
-
-// Translate an expression
-compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
- var no: *label;
- var out: *label;
+typecheck_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
var v: *decl;
var kind: int;
@@ -643,24 +564,18 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "str is not an lexpr");
}
- emit_str(c.as, n.s);
-
n.t = mktype1(c, TY_PTR, mktype0(c, TY_BYTE));
} else if (kind == N_NUM) {
if (!rhs) {
cdie(c, "num is not an lexpr");
}
- emit_num(c.as, n.n);
-
n.t = mktype0(c, TY_INT);
} else if (kind == N_CHAR) {
if (!rhs) {
cdie(c, "char is not an lexpr");
}
- emit_num(c.as, n.n);
-
n.t = mktype0(c, TY_INT);
} else if (kind == N_EXPRLIST) {
if (!rhs) {
@@ -668,10 +583,10 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
}
if (n.b) {
- compile_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.b, 1);
}
- compile_expr(c, d, n.a, 1);
+ typecheck_expr(c, d, n.a, 1);
if (n.b) {
n.t = mktype2(c, TY_ARG, n.a.t, n.b.t);
@@ -684,7 +599,7 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
}
if (n.b) {
- compile_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.b, 1);
}
if (n.a.kind == N_IDENT) {
@@ -705,7 +620,6 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "no such function");
}
n.a.t = v.func_type;
- compile_include(c, n);
} else {
v = find(c, n.a.s, 0:*byte, 0);
if (!v || !v.func_defined) {
@@ -715,7 +629,7 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
emit_lcall(c.as, v.func_label, count_args(c, n.a.t.arg));
}
} else {
- compile_expr(c, d, n.a, 1);
+ typecheck_expr(c, d, n.a, 1);
emit_call(c.as, count_args(c, n.a.t.arg));
}
@@ -731,7 +645,7 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
n.t = n.a.t.val;
} else if (kind == N_DOT) {
- compile_expr(c, d, n.a, 0);
+ typecheck_expr(c, d, n.a, 0);
if (n.a.t.kind == TY_PTR) {
if (n.a.t.val.kind != TY_STRUCT) {
@@ -739,8 +653,6 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
}
v = find(c, n.a.t.val.st.name, n.b.s, 0);
-
- emit_load(c.as, n.a.t);
} else {
if (n.a.t.kind != TY_STRUCT) {
cdie(c, "dot not a struct");
@@ -753,35 +665,22 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "no such member");
}
- emit_num(c.as, v.member_offset);
- emit_add(c.as);
-
n.t = v.member_type;
-
- if (rhs) {
- emit_load(c.as, n.t);
- }
} else if (kind == N_IDENT) {
v = find(c, n.s, 0:*byte, 0);
if (v && v.enum_defined) {
- emit_num(c.as, v.enum_value);
n.t = mktype0(c, TY_INT);
return;
}
v = find(c, d.name, n.s, 0);
if (v && v.var_defined) {
- emit_lea(c.as, v.var_offset);
n.t = v.var_type;
- if (rhs) {
- emit_load(c.as, n.t);
- }
return;
}
v = find(c, n.s, 0:*byte, 0);
if (v && v.func_defined) {
- emit_ptr(c.as, v.func_label);
n.t = v.func_type;
return;
}
@@ -792,32 +691,18 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "assign is not an lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 0);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 0);
unify(c, n.a.t, n.b.t);
n.t = n.a.t;
-
- emit_store(c.as, n.t);
} else if (kind == N_SIZEOF) {
if (!rhs) {
cdie(c, "sizeof is not an lexpr");
}
- out = mklabel(c.as);
-
- emit_jmp(c.as, out);
-
- compile_expr(c, d, n.a, 0);
-
- fixup_label(c.as, out);
-
- if (n.a.t.kind == TY_BYTE) {
- emit_num(c.as, 1);
- } else {
- emit_num(c.as, type_sizeof(c, n.a.t));
- }
+ typecheck_expr(c, d, n.a, 0);
n.t = mktype0(c, TY_INT);
} else if (kind == N_REF) {
@@ -825,24 +710,20 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "ref is not an lexpr");
}
- compile_expr(c, d, n.a, 0);
+ typecheck_expr(c, d, n.a, 0);
n.t = mktype1(c, TY_PTR, n.a.t);
} else if (kind == N_DEREF) {
- compile_expr(c, d, n.a, 1);
+ typecheck_expr(c, d, n.a, 1);
if (n.a.t.kind != TY_PTR) {
cdie(c, "deref not a pointer");
}
n.t = n.a.t.val;
-
- if (rhs) {
- emit_load(c.as, n.t);
- }
} else if (kind == N_INDEX) {
- compile_expr(c, d, n.a, 1);
- compile_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
+ typecheck_expr(c, d, n.b, 1);
if (n.a.t.kind != TY_PTR) {
cdie(c, "not a pointer");
@@ -853,27 +734,13 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
}
n.t = n.a.t.val;
-
- if (n.t.kind == TY_BYTE) {
- emit_num(c.as, 1);
- } else {
- emit_num(c.as, type_sizeof(c, n.t));
- }
-
- emit_mul(c.as);
- emit_add(c.as);
-
- if (rhs) {
- emit_load(c.as, n.t);
- }
} else if (kind == N_LT) {
if (!rhs) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_lt(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -887,9 +754,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_gt(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -903,9 +769,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_le(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -919,9 +784,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_ge(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -935,9 +799,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_eq(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -951,9 +814,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_ne(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -967,17 +829,9 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- no = mklabel(c.as);
- out = mklabel(c.as);
-
- compile_expr(c, d, n.a, 1);
+ typecheck_expr(c, d, n.a, 1);
- emit_jz(c.as, no);
- emit_num(c.as, 0);
- emit_jmp(c.as, out);
- fixup_label(c.as, no);
emit_num(c.as, 1);
- fixup_label(c.as, out);
if (!type_isprim(n.a.t)) {
cdie(c, "not an prim");
@@ -989,26 +843,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- no = mklabel(c.as);
- out = mklabel(c.as);
-
- compile_expr(c, d, n.a, 1);
- emit_jz(c.as, no);
- emit_num(c.as, 1);
- emit_jmp(c.as, out);
-
- fixup_label(c.as, no);
- no = mklabel(c.as);
-
- compile_expr(c, d, n.b, 1);
- emit_jz(c.as, no);
- emit_num(c.as, 1);
- emit_jmp(c.as, out);
-
- fixup_label(c.as, no);
- emit_num(c.as, 0);
-
- fixup_label(c.as, out);
+ typecheck_expr(c, d, n.a, 1);
+ typecheck_expr(c, d, n.b, 1);
if (!type_isprim(n.a.t)) {
cdie(c, "not an prim");
@@ -1024,22 +860,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- no = mklabel(c.as);
- out = mklabel(c.as);
-
- compile_expr(c, d, n.a, 1);
- emit_jz(c.as, no);
-
- compile_expr(c, d, n.b, 1);
- emit_jz(c.as, no);
-
- emit_num(c.as, 1);
- emit_jmp(c.as, out);
-
- fixup_label(c.as, no);
- emit_num(c.as, 0);
-
- fixup_label(c.as, out);
+ typecheck_expr(c, d, n.a, 1);
+ typecheck_expr(c, d, n.b, 1);
if (!type_isprim(n.a.t)) {
cdie(c, "not an prim");
@@ -1055,7 +877,7 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.a, 1);
+ typecheck_expr(c, d, n.a, 1);
if (!type_isint(n.a.t)) {
cdie(c, "pos: not an int");
@@ -1067,8 +889,7 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.a, 1);
- emit_neg(c.as);
+ typecheck_expr(c, d, n.a, 1);
if (!type_isint(n.a.t)) {
cdie(c, "neg: not an int");
@@ -1080,8 +901,7 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.a, 1);
- emit_not(c.as);
+ typecheck_expr(c, d, n.a, 1);
if (!type_isint(n.a.t)) {
cdie(c, "not: not an int");
@@ -1093,9 +913,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_add(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -1109,9 +928,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_sub(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -1125,9 +943,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_mul(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -1141,9 +958,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_div(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -1157,9 +973,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_mod(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -1173,9 +988,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_lsh(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -1189,9 +1003,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_rsh(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -1205,9 +1018,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_and(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -1221,9 +1033,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_or(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -1237,9 +1048,8 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_xor(c.as);
+ typecheck_expr(c, d, n.b, 1);
+ typecheck_expr(c, d, n.a, 1);
unify(c, n.a.t, n.b.t);
@@ -1253,7 +1063,7 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
cdie(c, "not lexpr");
}
- compile_expr(c, d, n.a, 1);
+ typecheck_expr(c, d, n.a, 1);
if (!type_isprim(n.a.t)) {
cdie(c, "not a primitive");
}
@@ -1264,6 +1074,443 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
}
}
+typecheck_stmt(c: *compiler, d: *decl, n: *node) {
+ var v: *decl;
+ var kind: int;
+
+ if (!n) {
+ return;
+ }
+
+ c.filename = n.filename;
+ c.lineno = n.lineno;
+ c.colno = n.colno;
+
+ kind = n.kind;
+ if (kind == N_CONDLIST) {
+ loop {
+ if (!n) {
+ break;
+ }
+
+ if (n.a.a) {
+ typecheck_expr(c, d, n.a.a, 1);
+ }
+
+ typecheck_stmt(c, d, n.a.b);
+
+ n = n.b;
+ }
+ } else if (kind == N_STMTLIST) {
+ loop {
+ if (!n) {
+ break;
+ }
+ typecheck_stmt(c, d, n.a);
+ n = n.b;
+ }
+ } else if (kind == N_LOOP) {
+ typecheck_stmt(c, d, n.a);
+ } else if (kind == N_BREAK) {
+ } else if (kind == N_CONTINUE) {
+ } else if (kind == N_RETURN) {
+ if (n.a) {
+ if (d.func_type.val.kind == TY_VOID) {
+ cdie(c, "returning a value in a void function");
+ }
+ call_check(c, n.a);
+ typecheck_expr(c, d, n.a, 1);
+ unify(c, n.a.t, d.func_type.val);
+ } else {
+ if (d.func_type.val.kind != TY_VOID) {
+ cdie(c, "returning void in a non void function");
+ }
+ }
+ } else if (kind == N_LABEL) {
+ v = find(c, d.name, n.a.s, 0);
+ } else if (kind == N_GOTO) {
+ v = find(c, d.name, n.a.s, 0);
+ if (!v || !v.goto_defined) {
+ cdie(c, "label not defined");
+ }
+ } else if (kind != N_VARDECL) {
+ call_check(c, n);
+ typecheck_expr(c, d, n, 1);
+ }
+}
+
+typecheck_func(c: *compiler, d: *decl) {
+ if (!d.func_def) {
+ return;
+ }
+
+ typecheck_stmt(c, d, d.func_def.b);
+}
+
+hoist_locals(c: *compiler, d: *decl, n: *node, offset: int): int {
+ var kind: int;
+ var name: *byte;
+ var t: *type;
+ var v: *decl;
+
+ if (!n) {
+ return offset;
+ }
+
+ kind = n.kind;
+ if (kind == N_CONDLIST) {
+ loop {
+ if (!n) {
+ return offset;
+ }
+
+ hoist_locals(c, d, n.a.b, offset);
+
+ n = n.b;
+ }
+ } else if (kind == N_STMTLIST) {
+ loop {
+ if (!n) {
+ return offset;
+ }
+
+ offset = hoist_locals(c, d, n.a, offset);
+
+ n = n.b;
+ }
+ } else if (kind == N_LOOP) {
+ return hoist_locals(c, d, n.a, offset);
+ } else if (kind == N_LABEL) {
+ name = n.a.s;
+ v = find(c, d.name, name, 1);
+
+ if (v.goto_defined) {
+ cdie(c, "duplicate goto");
+ }
+ v.goto_defined = 1;
+
+ return offset;
+ } else if (kind != N_VARDECL) {
+ return offset;
+ }
+
+ name = n.a.s;
+ t = prototype(c, n.b);
+
+ n.t = t;
+
+ v = find(c, d.name, name, 1);
+
+ if (v.var_defined) {
+ cdie(c, "duplicate variable");
+ }
+
+ v.var_type = t;
+ v.var_defined = 1;
+
+ offset = offset + type_sizeof(c, t);
+
+ v.var_offset = -offset;
+
+ return offset;
+}
+
+compile_include(c: *compiler, n: *node) {
+ var filename: *byte;
+ var fd: int;
+ var blob: *byte;
+ var len: int;
+
+ if n.b.a.kind != N_STR {
+ die("non literal include");
+ }
+
+ filename = n.b.a.s;
+
+ fd = open(filename, O_RDONLY, 0);
+ if fd < 0 {
+ die("failed to open include");
+ }
+
+ blob = readall(fd, &len, c.a);
+
+ close(fd);
+
+ as_opr(c.as, OP_POPR, R_RAX);
+ as_opr(c.as, OP_POPR, R_RDI);
+ as_opri64(c.as, OP_MOVABS, R_RAX, len);
+ as_modrm(c.as, OP_STORE, R_RAX, R_RDI, 0, 0, 0);
+ emit_blob(c.as, blob, len);
+
+ free(c.a, blob);
+}
+
+// Translate an expression
+compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
+ var no: *label;
+ var out: *label;
+ var v: *decl;
+ var kind: int;
+
+ c.filename = n.filename;
+ c.lineno = n.lineno;
+ c.colno = n.colno;
+
+ kind = n.kind;
+ if (kind == N_STR) {
+ emit_str(c.as, n.s);
+ } else if (kind == N_NUM) {
+ emit_num(c.as, n.n);
+ } else if (kind == N_CHAR) {
+ emit_num(c.as, n.n);
+ } else if (kind == N_EXPRLIST) {
+ if (n.b) {
+ compile_expr(c, d, n.b, 1);
+ }
+
+ compile_expr(c, d, n.a, 1);
+ } else if (kind == N_CALL) {
+ if (n.b) {
+ compile_expr(c, d, n.b, 1);
+ }
+
+ if (n.a.kind == N_IDENT) {
+ v = find(c, n.a.s, 0:*byte, 0);
+ if (v && v.enum_defined) {
+ cdie(c, "type error");
+ }
+
+ v = find(c, d.name, n.a.s, 0);
+ if (v && v.var_defined) {
+ emit_lea(c.as, v.var_offset);
+ emit_load(c.as, n.a.t);
+ emit_call(c.as, count_args(c, n.a.t.arg));
+ } else if !strcmp(n.a.s, "_include") {
+ v = find(c, n.a.s, 0:*byte, 0);
+ compile_include(c, n);
+ } else {
+ v = find(c, n.a.s, 0:*byte, 0);
+ emit_lcall(c.as, v.func_label, count_args(c, n.a.t.arg));
+ }
+ } else {
+ compile_expr(c, d, n.a, 1);
+ emit_call(c.as, count_args(c, n.a.t.arg));
+ }
+
+ if (n.b) {
+ unify(c, n.a.t.arg, n.b.t);
+ } else {
+ unify(c, n.a.t.arg, 0: *type);
+ }
+ } else if (kind == N_DOT) {
+ compile_expr(c, d, n.a, 0);
+
+ if (n.a.t.kind == TY_PTR) {
+ v = find(c, n.a.t.val.st.name, n.b.s, 0);
+ emit_load(c.as, n.a.t);
+ } else {
+ v = find(c, n.a.t.st.name, n.b.s, 0);
+ }
+
+ emit_num(c.as, v.member_offset);
+ emit_add(c.as);
+
+ if (rhs) {
+ emit_load(c.as, n.t);
+ }
+ } else if (kind == N_IDENT) {
+ v = find(c, n.s, 0:*byte, 0);
+ if (v && v.enum_defined) {
+ emit_num(c.as, v.enum_value);
+ return;
+ }
+
+ v = find(c, d.name, n.s, 0);
+ if (v && v.var_defined) {
+ emit_lea(c.as, v.var_offset);
+ if (rhs) {
+ emit_load(c.as, n.t);
+ }
+ return;
+ }
+
+ v = find(c, n.s, 0:*byte, 0);
+ if (v && v.func_defined) {
+ emit_ptr(c.as, v.func_label);
+ return;
+ }
+ } else if (kind == N_ASSIGN) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 0);
+
+ emit_store(c.as, n.t);
+ } else if (kind == N_SIZEOF) {
+ out = mklabel(c.as);
+
+ emit_jmp(c.as, out);
+
+ compile_expr(c, d, n.a, 0);
+
+ fixup_label(c.as, out);
+
+ if (n.a.t.kind == TY_BYTE) {
+ emit_num(c.as, 1);
+ } else {
+ emit_num(c.as, type_sizeof(c, n.a.t));
+ }
+ } else if (kind == N_REF) {
+ compile_expr(c, d, n.a, 0);
+ } else if (kind == N_DEREF) {
+ compile_expr(c, d, n.a, 1);
+
+ if (rhs) {
+ emit_load(c.as, n.t);
+ }
+ } else if (kind == N_INDEX) {
+ compile_expr(c, d, n.a, 1);
+ compile_expr(c, d, n.b, 1);
+
+ if (n.t.kind == TY_BYTE) {
+ emit_num(c.as, 1);
+ } else {
+ emit_num(c.as, type_sizeof(c, n.t));
+ }
+
+ emit_mul(c.as);
+ emit_add(c.as);
+
+ if (rhs) {
+ emit_load(c.as, n.t);
+ }
+ } else if (kind == N_LT) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_lt(c.as);
+ } else if (kind == N_GT) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_gt(c.as);
+ } else if (kind == N_LE) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_le(c.as);
+ } else if (kind == N_GE) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_ge(c.as);
+ } else if (kind == N_EQ) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_eq(c.as);
+ } else if (kind == N_NE) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_ne(c.as);
+ } else if (kind == N_BNOT) {
+ no = mklabel(c.as);
+ out = mklabel(c.as);
+
+ compile_expr(c, d, n.a, 1);
+
+ emit_jz(c.as, no);
+ emit_num(c.as, 0);
+ emit_jmp(c.as, out);
+ fixup_label(c.as, no);
+ emit_num(c.as, 1);
+ fixup_label(c.as, out);
+ } else if (kind == N_BOR) {
+ no = mklabel(c.as);
+ out = mklabel(c.as);
+
+ compile_expr(c, d, n.a, 1);
+ emit_jz(c.as, no);
+ emit_num(c.as, 1);
+ emit_jmp(c.as, out);
+
+ fixup_label(c.as, no);
+ no = mklabel(c.as);
+
+ compile_expr(c, d, n.b, 1);
+ emit_jz(c.as, no);
+ emit_num(c.as, 1);
+ emit_jmp(c.as, out);
+
+ fixup_label(c.as, no);
+ emit_num(c.as, 0);
+
+ fixup_label(c.as, out);
+ } else if (kind == N_BAND) {
+ no = mklabel(c.as);
+ out = mklabel(c.as);
+
+ compile_expr(c, d, n.a, 1);
+ emit_jz(c.as, no);
+
+ compile_expr(c, d, n.b, 1);
+ emit_jz(c.as, no);
+
+ emit_num(c.as, 1);
+ emit_jmp(c.as, out);
+
+ fixup_label(c.as, no);
+ emit_num(c.as, 0);
+
+ fixup_label(c.as, out);
+ } else if (kind == N_POS) {
+ compile_expr(c, d, n.a, 1);
+ } else if (kind == N_NEG) {
+ compile_expr(c, d, n.a, 1);
+ emit_neg(c.as);
+ } else if (kind == N_NOT) {
+ compile_expr(c, d, n.a, 1);
+ emit_not(c.as);
+ } else if (kind == N_ADD) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_add(c.as);
+ } else if (kind == N_SUB) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_sub(c.as);
+ } else if (kind == N_MUL) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_mul(c.as);
+ } else if (kind == N_DIV) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_div(c.as);
+ } else if (kind == N_MOD) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_mod(c.as);
+ } else if (kind == N_LSH) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_lsh(c.as);
+ } else if (kind == N_RSH) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_rsh(c.as);
+ } else if (kind == N_AND) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_and(c.as);
+ } else if (kind == N_OR) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_or(c.as);
+ } else if (kind == N_XOR) {
+ compile_expr(c, d, n.b, 1);
+ compile_expr(c, d, n.a, 1);
+ emit_xor(c.as);
+ } else if (kind == N_CAST) {
+ compile_expr(c, d, n.a, 1);
+ } else {
+ cdie(c, "not an expression");
+ }
+}
+
call_check(c: *compiler, n: *node): int {
var result: int;
var ret: int;
@@ -1354,7 +1601,6 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) {
no = mklabel(c.as);
if (n.a.a) {
- call_check(c, n.a.a);
compile_expr(c, d, n.a.a, 1);
emit_jz(c.as, no);
}
@@ -1395,9 +1641,7 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) {
if (d.func_type.val.kind == TY_VOID) {
cdie(c, "returning a value in a void function");
}
- call_check(c, n.a);
compile_expr(c, d, n.a, 1);
- unify(c, n.a.t, d.func_type.val);
} else {
if (d.func_type.val.kind != TY_VOID) {
cdie(c, "returning void in a non void function");
@@ -1415,7 +1659,6 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) {
}
emit_jmp(c.as, v.goto_label);
} else if (kind != N_VARDECL) {
- call_check(c, n);
compile_expr(c, d, n, 1);
emit_pop(c.as, 1);
}