From: fennecdjay Date: Wed, 24 Apr 2019 00:06:41 +0000 (+0200) Subject: big comiit :sad: X-Git-Tag: nightly~2530 X-Git-Url: http://10.11.0.4:5575/?a=commitdiff_plain;h=7e3ac90b82588af784132431c0c3441292306c15;p=gwion.git big comiit :sad: --- diff --git a/help/test.sh b/help/test.sh index 9ef98726..23edf17c 100644 --- a/help/test.sh +++ b/help/test.sh @@ -1,5 +1,6 @@ #!/bin/bash +: "${PRG:=gwion}" : "${VALGRIND:=valgrind}" : "${GWION_TEST_DIR:=/tmp}" : "${GWION_TEST_PREFIX:=gwt_}" @@ -180,10 +181,10 @@ test_gw(){ vlog=${GWION_TEST_DIR}/${GWION_TEST_PREFIX}$(printf "%04i" "$n").valgrind.log rlog=${GWION_TEST_DIR}/${GWION_TEST_PREFIX}$(printf "%04i" "$n").log if [ "$VALGRIND" == "NO_VALGRIND" ] - then ./gwion "$GWOPT" -d "$DRIVER" "$file" > "$slog" 2>"$elog" |: + then ./"$PRG" "$GWOPT" -d "$DRIVER" "$file" > "$slog" 2>"$elog" |: else "$VALGRIND" --suppressions=help/supp --log-file="$vlog" \ - ./gwion "$GWOPT" -d "$DRIVER" "$file" > "$slog" 2>"$elog" |: + ./"$PRG" "$GWOPT" -d "$DRIVER" "$file" > "$slog" 2>"$elog" |: fi ret=$? #enable skip diff --git a/include/env.h b/include/env.h index 11ce53bc..50756c3b 100644 --- a/include/env.h +++ b/include/env.h @@ -11,6 +11,7 @@ struct Switch_ { Vector vec; vtype iter; size_t default_case_index; + size_t depth; uint ok; }; @@ -50,14 +51,14 @@ ANN Type type_decl_resolve(const Env, const Type_Decl*); ANEW ANN m_str tl2str(const Env, const Type_List); // in type_decl.c ANN m_bool compat_func(const __restrict__ Func_Def, const __restrict__ Func_Def); ANN Type known_type(const Env env, const Type_Decl*); -ANN m_bool env_access(const Env env, const ae_flag flag, const uint pos); -ANN m_bool env_storage(const Env env, ae_flag flag, const uint pos); +ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos); +ANN m_bool env_storage(const Env env, ae_flag flag, const loc_t pos); ANN void env_add_type(const Env, const Type); ANN Type find_type(const Env, ID_List); -ANN m_bool already_defined(const Env env, const Symbol s, const uint pos); +ANN m_bool already_defined(const Env env, const Symbol s, const loc_t pos); ANN m_bool type_engine_check_prog(const Env, const Ast); ANN Func get_func(const Env, const Func_Def); ANN m_bool traverse_func_template(const Env env, const Func_Def def, const Type_List types); ANN ID_List str2list(const Env, const m_str path, m_uint* array_depth); -ANN void env_err(const Env, const uint pos, const m_str fmt, ...); +ANN2(1,3) void env_err(const Env, const struct YYLTYPE *pos, const m_str fmt, ...); #endif diff --git a/include/escape.h b/include/escape.h index ad75d95b..805a569a 100644 --- a/include/escape.h +++ b/include/escape.h @@ -1,6 +1,6 @@ #ifndef __ESCAPE #define __ESCAPE char* escape_table(void); -ANN m_int str2char(const Emitter, const m_str, const uint); -ANN m_bool escape_str(const Emitter, m_str, const uint); +ANN m_int str2char(const Emitter, const m_str, const loc_t); +ANN m_bool escape_str(const Emitter, m_str, const loc_t); #endif diff --git a/include/gwi.h b/include/gwi.h index 9438c037..9bf83375 100644 --- a/include/gwi.h +++ b/include/gwi.h @@ -55,5 +55,6 @@ struct Gwi_ { DL_Oper oper; void* addr; Templater templater; + loc_t loc; }; #endif diff --git a/include/gwion.h b/include/gwion.h index 97766423..9db27f2f 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -13,10 +13,12 @@ struct Gwion_ { struct Map_ freearg; SymTable *st; MemPool p; + struct Vector_ child; }; ANN m_bool gwion_ini(const Gwion, struct Arg_*); ANN VM* gwion_cpy(const VM*); ANN void gwion_run(const Gwion gwion); ANN void gwion_end(const Gwion gwion); +void free_code_instr(const Vector v, const Gwion gwion); #endif diff --git a/include/import.h b/include/import.h index b9765198..5ef706b9 100644 --- a/include/import.h +++ b/include/import.h @@ -23,7 +23,8 @@ typedef struct Gwi_* Gwi; #define _CHECK_OP(op, check, func)\ CHECK_BB(gwi_oper_add(gwi, opck_##check))\ CHECK_BB(gwi_oper_end(gwi, op_##op, func)) -#define ERR_N(a,...) { err_msg(a,__VA_ARGS__); return t_null; } +#define GWI_LOC new_loc(gwi->gwion->p, __LINE__) + ANN VM* gwi_vm(const Gwi); ANN2(1,2) ANEW Type gwi_mk_type(const Gwi, const m_str, const m_uint, const Type); diff --git a/include/object.h b/include/object.h index 1b3e326b..9d3bfbc8 100644 --- a/include/object.h +++ b/include/object.h @@ -7,7 +7,7 @@ struct M_Object_ { // Nspc nspc;// Vector vtable; struct pool* p; - size_t ref; + volatile size_t ref; }; ANN void instantiate_object(const VM_Shred, const Type); @@ -19,7 +19,8 @@ ANEW M_Object new_string(MemPool, const VM_Shred, const m_str); ANEW M_Object new_string2(MemPool, const VM_Shred, const m_str); ANEW M_Object gwion_new_string(const struct Gwion_*, const m_str); ANEW M_Object new_shred(const VM_Shred, const m_bool); -ANN void fork_launch(const M_Object, const m_uint); +ANN void fork_launch(const VM*, const M_Object, const m_uint); +ANN void fork_clean(const VM *vm, const Vector v); ANN void __release(const M_Object, const VM_Shred); ANN void exception(const VM_Shred, const m_str); ANN void broadcast(const M_Object); diff --git a/include/operator.h b/include/operator.h index c34e34f7..533db1af 100644 --- a/include/operator.h +++ b/include/operator.h @@ -9,7 +9,7 @@ struct Op_Import { opck ck; opem em; uintptr_t data; - uint pos; + loc_t pos; Operator op; m_bool mut; }; diff --git a/include/optim.h b/include/optim.h index 158075b9..f90783e4 100644 --- a/include/optim.h +++ b/include/optim.h @@ -2,10 +2,10 @@ #define __OPTIM #ifdef OPTIMIZE #define OPTIMIZE_CONST(a) CHECK_BO(optimize_const(a)) -ANN m_bool optimize_const(MemPool mp, const Exp_Binary*); +ANN m_bool optimize_const(const Env, const Exp_Binary*); //ANN2(1) void constprop_prim(const Exp_Primary* p, m_uint* ptr); #else #define OPTIMIZE_CONST(a) #endif -m_bool constant_folding(MemPool mp, const Exp_Binary* bin); +m_bool constant_folding(const Env, const Exp_Binary*); #endif diff --git a/include/parse.h b/include/parse.h index 02ac871d..fdab1b64 100644 --- a/include/parse.h +++ b/include/parse.h @@ -8,6 +8,8 @@ #define ERR_B(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return GW_ERROR; } #undef ERR_O #define ERR_O(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return NULL; } +#undef ERR_N +#define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return t_null; } #define RET_NSPC(exp) \ ++env->scope->depth; \ diff --git a/include/plug.h b/include/plug.h index db19cbfc..32cbd810 100644 --- a/include/plug.h +++ b/include/plug.h @@ -23,8 +23,8 @@ ANN void free_plug(const Gwion gwion); #define GWMODEND_NAME gwmodend #define GWDRIVER_NAME gwmodend #define GWMODSTR(a) m_str GWMODSTR_NAME() { return #a; } -#define GWMODINI(a) ANN2(1) void* GWMODINI_NAME(const Gwion gwion, const Vector args) -#define GWMODEND(a) ANN void GWMODEND_NAME(const Gwion gwion, void* self) +#define GWMODINI(a) ANN2(1) void* GWMODINI_NAME(const Gwion gwion NUSED, const Vector args NUSED) +#define GWMODEND(a) ANN void GWMODEND_NAME(const Gwion gwion NUSED, void* self NUSED) #define GWDRIVER(a) ANN void GWDRIVER_NAME(DriverData* d) ANN Vector split_args(MemPool, const m_str str); diff --git a/include/switch.h b/include/switch.h index fc99ca9c..b6080cb8 100644 --- a/include/switch.h +++ b/include/switch.h @@ -6,16 +6,17 @@ ANN void switch_expset(const Env env, const Exp); ANN Exp switch_expget(const Env env); ANN void switch_pc(const Env env, const m_uint pc); ANN void switch_dynpc(const Env env, const m_int val, const m_uint pc); -ANN m_bool switch_dup(const Env env, const m_int value, const uint pos); +ANN m_bool switch_dup(const Env env, const m_int value, const loc_t pos); ANN m_bool switch_pop(const Env env); -ANN void switch_end(const Env env); +ANN m_bool switch_end(const Env env, const loc_t pos); ANN m_uint switch_idx(const Env); ANN Vector switch_vec(const Env); ANN m_bool switch_add(const Env env, const Stmt_Switch stmt); -ANN m_bool switch_default(const Env env, const m_uint pc, const uint pos); -ANN m_bool switch_inside(const Env env, const uint pos); +ANN m_bool switch_default(const Env env, const m_uint pc, const loc_t pos); +ANN m_bool switch_inside(const Env env, const loc_t pos); ANN m_bool switch_dyn(const Env env); -ANN m_bool switch_reset(const Env env); -ANN m_bool switch_release(const Scope); -ANN void switch_get(const Env env, const Stmt_Switch stmt); +ANN m_bool switch_decl(const Env env, const loc_t pos); +ANN void switch_reset(const Env env); +ANN void switch_release(const Scope); +ANN void switch_get(const Env env, const Stmt_Switch stmt); #endif diff --git a/include/traverse.h b/include/traverse.h index da037c27..bd1f9db3 100644 --- a/include/traverse.h +++ b/include/traverse.h @@ -8,4 +8,37 @@ m_bool traverse_stmt_union(const Env, const Stmt_Union); m_bool traverse_stmt_enum(const Env, const Stmt_Enum); m_bool traverse_stmt_fptr(const Env, const Stmt_Fptr ); m_bool traverse_decl(const Env, const Exp_Decl*); + +ANN m_bool scan0_ast(const Env env, Ast ast); +ANN m_bool scan1_ast(const Env env, Ast ast); +ANN m_bool scan2_ast(const Env env, Ast ast); +ANN m_bool check_ast(const Env env, Ast ast); + +ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl); +ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl); +ANN Type check_exp_decl(const Env env, const Exp_Decl* decl); + +ANN m_bool scan1_func_def(const Env env, const Func_Def def); +ANN m_bool scan2_func_def(const Env env, const Func_Def def); +ANN m_bool check_func_def(const Env env, const Func_Def def); + +ANN m_bool scan0_stmt_fptr(const Env env, const Stmt_Fptr def); +ANN m_bool scan1_stmt_fptr(const Env env, const Stmt_Fptr def); +ANN m_bool scan2_stmt_fptr(const Env env, const Stmt_Fptr def); +//ANN m_bool check_stmt_fptr(const Env env, const Stmt_Fptr def); + +ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union def); +ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union def); +ANN m_bool scan2_stmt_union(const Env env, const Stmt_Union def); +ANN m_bool check_stmt_union(const Env env, const Stmt_Union def); + +ANN m_bool scan0_stmt_enum(const Env env, const Stmt_Enum def); +ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum def); +//ANN m_bool scan2_stmt_enum(const Env env, const Stmt_Enum def); +ANN m_bool check_stmt_enum(const Env env, const Stmt_Enum def); + +ANN m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt); +ANN m_bool scan1_class_def(const Env env, const Class_Def def); +ANN m_bool scan2_class_def(const Env env, const Class_Def def); +ANN m_bool check_class_def(const Env env, const Class_Def def); #endif diff --git a/include/type.h b/include/type.h index 83f0efd0..a8edfa2c 100644 --- a/include/type.h +++ b/include/type.h @@ -29,7 +29,7 @@ ANN m_str get_type_name(const Env, const m_str, const m_uint); ANN Value find_value(const Type, const Symbol); ANN Func find_func(const Type, const Symbol); ANN m_bool isa(const Type, const Type) __attribute__((pure)); -ANN m_bool isres(const Env, const Symbol, const uint pos); +ANN m_bool isres(const Env, const Symbol, const loc_t pos); ANN Type array_type(const Env, const Type, const m_uint); ANN Type find_common_anc(const Type, const Type) __attribute__((pure)); ANN m_uint id_list_len(ID_List); diff --git a/include/vm.h b/include/vm.h index c326c5db..5b6522c2 100644 --- a/include/vm.h +++ b/include/vm.h @@ -71,7 +71,7 @@ ANN static inline void vm_shred_exit(const VM_Shred shred) { shreduler_remove(sh void free_vm_shred(const VM_Shred shred)__attribute__((hot, nonnull)); ANN void vm_run(const VM* vm) __attribute__((hot)); -ANEW VM* new_vm(MemPool); +ANEW VM* new_vm(MemPool, const m_bool); ANN void free_vm(VM* vm); ANN m_uint vm_add_shred(const VM* vm, const VM_Shred shred)__attribute__((hot)); ANN void vm_remove(const VM* vm, const m_uint index)__attribute__((hot)); diff --git a/opt/fold.c b/opt/fold.c index ec60d6ef..937c9b37 100644 --- a/opt/fold.c +++ b/opt/fold.c @@ -2,9 +2,13 @@ #include "gwion_ast.h" #include "oo.h" #include "env.h" +#include "vm.h" +#include "instr.h" +#include "emit.h" #include "type.h" #include "optim.h" #include "constant.h" +#include "parse.h" ANN static void fold_exp(MemPool mp, const Exp_Binary* bin) { const Exp n = exp_self(bin)->next; @@ -34,21 +38,22 @@ describe_xxx_exp(float, m_float, float, fnum) CASE(mul, l, /, r) \ case op_div: DIV_BY_ZERO(l, / , r) break; -#define describe_fold_xxx(name, type, _l, _r, etype, opt) \ -ANN static m_bool fold_##name(MemPool mp, const Exp_Binary* bin) { \ - const union exp_primary_data *l = &bin->lhs->d.exp_primary.d; \ - const union exp_primary_data *r = &bin->rhs->d.exp_primary.d; \ - type ret = 0; \ - switch(bin->op) { \ - COMMON_CASE(l->_l, r->_r) \ - opt \ - default: \ - return GW_OK; \ - } \ - const Exp e = exp_self(bin); \ - fold_exp(mp, bin); \ - etype##_exp(e, ret); \ - return GW_OK; \ +#define describe_fold_xxx(name, type, _l, _r, etype, opt) \ +ANN static m_bool fold_##name(const Env env, const Exp_Binary* bin) { \ + MemPool mp = env->gwion->p; \ + const union exp_primary_data *l = &bin->lhs->d.exp_primary.d; \ + const union exp_primary_data *r = &bin->rhs->d.exp_primary.d; \ + type ret = 0; \ + switch(bin->op) { \ + COMMON_CASE(l->_l, r->_r) \ + opt \ + default: \ + return GW_OK; \ + } \ + const Exp e = exp_self(bin); \ + fold_exp(mp, bin); \ + etype##_exp(e, ret); \ + return GW_OK; \ } describe_fold_xxx(ii, m_int, num, num, int, case op_mod: DIV_BY_ZERO(l->num, % , r->num) break; @@ -57,17 +62,17 @@ describe_fold_xxx(ff, m_float, fnum, fnum, float,) describe_fold_xxx(if, m_float, num, fnum, float,) describe_fold_xxx(fi, m_float, fnum, num, float,) -m_bool constant_folding(MemPool mp, const Exp_Binary* bin) { +m_bool constant_folding(const Env env, const Exp_Binary* bin) { if(constant_int(bin->lhs)) { if(constant_int(bin->rhs)) - CHECK_BB(fold_ii(mp, bin)) + CHECK_BB(fold_ii(env, bin)) else if(constant_float(bin->rhs)) - CHECK_BB(fold_if(mp, bin)) + CHECK_BB(fold_if(env, bin)) } else if(constant_float(bin->lhs)) { if(constant_float(bin->rhs)) - CHECK_BB(fold_ff(mp, bin)) + CHECK_BB(fold_ff(env, bin)) else if(constant_int(bin->rhs)) - CHECK_BB(fold_fi(mp, bin)) + CHECK_BB(fold_fi(env, bin)) } return GW_OK; } diff --git a/opt/optim.c b/opt/optim.c index dc54aee7..004af0da 100644 --- a/opt/optim.c +++ b/opt/optim.c @@ -7,6 +7,6 @@ #include "optim.h" #include "constant.h" -m_bool optimize_const(MemPool mp, const Exp_Binary* bin) { - return constant_folding(mp, bin); +m_bool optimize_const(const Env env, const Exp_Binary* bin) { + return constant_folding(env, bin); } diff --git a/src/compile.c b/src/compile.c index b9fdeeeb..3f7c9d97 100644 --- a/src/compile.c +++ b/src/compile.c @@ -47,7 +47,7 @@ static void compiler_clean(MemPool p, const struct Compiler* c) { free_ast(p, c->ast); } -static m_bool compiler_open(struct Compiler* c) { +static m_bool _compiler_open(struct Compiler* c) { if(c->type == COMPILE_NAME) { m_str name = c->name; c->name = realpath(name, NULL); @@ -58,6 +58,16 @@ static m_bool compiler_open(struct Compiler* c) { return GW_OK; } +static inline m_bool compiler_open(struct Compiler* c) { + char name[strlen(c->name)]; + strcpy(name, c->name); + if(_compiler_open(c) < 0) { + gw_err("'%s': no such file\n", name); + return GW_ERROR; + } + return GW_OK; +} + static m_bool check(struct Gwion_* gwion, struct Compiler* c) { CHECK_BB(compiler_open(c)) struct ScannerArg_ arg = { c->name, c->file, gwion->st }; diff --git a/src/emit/emit.c b/src/emit/emit.c index a2a48242..2e32a673 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -22,6 +22,7 @@ #include "operator.h" #include "import.h" #include "switch.h" +#include "parser.h" #undef insert_symbol #define insert_symbol(a) insert_symbol(emit->env->gwion->st, (a)) @@ -225,9 +226,9 @@ ANN2(1,2) m_bool emit_instantiate_object(const Emitter emit, const Type type, Array_Sub array = arr; if(type->array_depth) { if(!array || array->depth < type->array_depth) { // from typeof xxx[]... - Exp base = new_exp_prim_int(emit->gwion->p, 0, 0), e = base; + Exp base = new_exp_prim_int(emit->gwion->p, 0, new_loc(emit->gwion->p, __LINE__)), e = base; for(m_uint i = (array ? array->depth : 0); i < type->array_depth; ++i) - e = (e->next = new_exp_prim_int(emit->gwion->p, 0, 0)); + e = (e->next = new_exp_prim_int(emit->gwion->p, 0, new_loc(emit->gwion->p, __LINE__))); if(array) { Exp array_base = array->exp; while(array_base->next) @@ -272,7 +273,8 @@ static const f_instr allocmember[] = { RegPushImm, RegPushImm2, RegPushImm3, Al static const f_instr allocword[] = { AllocWord, AllocWord2, AllocWord3, AllocWord4 }; ANN static inline Exp this_exp(const Emitter emit, const Type t, const loc_t pos) { - const Exp exp = new_exp_prim_id(emit->gwion->p, insert_symbol("this"), pos); + const Exp exp = new_exp_prim_id(emit->gwion->p, insert_symbol("this"), + loc_cpy(emit->gwion->p, pos)); exp->type = t; return exp; } @@ -286,7 +288,8 @@ ANN static inline Exp dot_this_exp(const Emitter emit, const Exp_Primary* prim, ANN static inline Exp dot_static_exp(const Emitter emit, const Exp_Primary* prim, const Type t) { const Symbol s = insert_symbol(t->name); - const Exp e = new_exp_prim_id(emit->gwion->p, s, exp_self(prim)->pos); + const Exp e = new_exp_prim_id(emit->gwion->p, s, + loc_cpy(emit->gwion->p, exp_self(prim)->pos)); const Value val = nspc_lookup_value1(t->nspc->parent, s); const Exp dot = new_exp_dot(emit->gwion->p, e, prim->d.var); dot->d.exp_dot.t_base = val->type; @@ -513,9 +516,12 @@ ANN static m_bool emit_exp_primary(const Emitter emit, const Exp_Primary* prim) ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const uint emit_var) { GWDEBUG_EXE const m_uint size = v->type->size; if(isa(v->type, t_class) < 0) { - const Instr instr = emit_kind(emit, size, emit_var, dotstatic); - instr->m_val = (m_uint)(v->owner->info->class_data + v->offset); - instr->m_val2 = size; + if(isa(v->type, t_union) < 0) { +printf("%s %lu %p·\n", v->name, v->offset, v->owner->info->class_data); + const Instr instr = emit_kind(emit, size, emit_var, dotstatic); + instr->m_val = (m_uint)(v->owner->info->class_data + v->offset); + instr->m_val2 = size; + } else exit(2); } else { const Instr instr = emit_add_instr(emit, RegPushImm); instr->m_val = (m_uint)v->type; @@ -534,11 +540,11 @@ ANN static m_bool decl_static(const Emitter emit, const Var_Decl var_decl, const return GW_OK; } -ANN static m_bool emit_exp_decl_static(const Emitter emit, const Var_Decl var_decl, const uint is_ref) { GWDEBUG_EXE +ANN static m_bool emit_exp_decl_static(const Emitter emit, const Var_Decl var_decl, const uint is_ref, const uint emit_addr) { GWDEBUG_EXE const Value value = var_decl->value; if(isa(value->type, t_object) > 0 && !is_ref) CHECK_BB(decl_static(emit, var_decl, 0)) - return emit_dot_static_data(emit, value, 1); + return emit_dot_static_data(emit, value, emit_addr); } ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Var_Decl var_decl, @@ -623,16 +629,15 @@ ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) { GWDE const uint var = exp_self(decl)->emit_var; if(GET_FLAG(decl->type, template)) CHECK_BB(emit_exp_decl_template(emit, decl)) - m_uint scope; const m_bool global = GET_FLAG(decl->td, global); - if(global) - scope = emit_push_global(emit); + const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit); do { +puts(s_name(list->self->xid)); const uint r = (uint)(GET_FLAG(list->self->value, ref) + ref); - if(!GET_FLAG(list->self->value, used)) - continue; +// if(!GET_FLAG(list->self->value, used)) +// continue; if(GET_FLAG(decl->td, static)) - CHECK_BB(emit_exp_decl_static(emit, list->self, r)) + CHECK_BB(emit_exp_decl_static(emit, list->self, r, var)) else if(!global) CHECK_BB(emit_exp_decl_non_static(emit, list->self, r, var)) else @@ -717,7 +722,7 @@ ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) { ANN static m_bool emit_exp_binary(const Emitter emit, const Exp_Binary* bin) { GWDEBUG_EXE const Exp lhs = bin->lhs; const Exp rhs = bin->rhs; - struct Op_Import opi = { .op=bin->op, .lhs=lhs->type, .rhs=rhs->type, .data = (uintptr_t)bin }; + struct Op_Import opi = { .op=bin->op, .lhs=lhs->type, .rhs=rhs->type, .pos=exp_self(bin)->pos, .data = (uintptr_t)bin }; CHECK_BB(emit_exp(emit, lhs, 1)) CHECK_BB(emit_exp(emit, rhs, 1)) return op_emit(emit, &opi); @@ -768,8 +773,7 @@ ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) { static inline m_bool push_func_code(const Emitter emit, const Func f) { if(GET_FLAG(f, template) && f->value_ref->owner_class) { const Instr instr = (Instr)vector_back(&emit->code->instr); -// assert(instr->execute == DotTmplVal); - assert(instr->opcode == DotTmplVal); + assert(instr->opcode == eDotTmplVal); size_t len = strlen(f->name); size_t sz = len - strlen(f->value_ref->owner_class->name); char c[sz + 1]; @@ -780,7 +784,7 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) { dt->overload = f->def->tmpl->base; dt->tl = tmpl_tl(emit->env, c); dt->base = f->def; - instr->opcode = OP_MAX; + instr->opcode = eOP_MAX; instr->m_val = (m_uint)dt; instr->m_val2 = strlen(c); instr->execute = DotTmpl; @@ -909,8 +913,8 @@ static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) #define SPORK_CODE_PREFIX "spork~code:%i" #define FORK_CODE_PREFIX "fork~code:%i" -static void push_spork_code(const Emitter emit, const m_str prefix, const int pos) { - char c[strlen(SPORK_FUNC_PREFIX) + num_digit(pos) + 1]; +static void push_spork_code(const Emitter emit, const m_str prefix, const loc_t pos) { + char c[strlen(SPORK_FUNC_PREFIX) + num_digit(pos->first_line) + 1]; sprintf(c, prefix, pos); emit_push_code(emit, c); } @@ -1112,6 +1116,11 @@ ANN static void emit_pop_stack(const Emitter emit, const m_uint index) { } ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) { + if(e->next) { + free_exp(emit->gwion->p, e->next); + e->next = NULL; + env_err(emit->env, e->pos, "expression after comma won't be executed"); + } CHECK_BO(emit_exp(emit, e, 0)) const f_instr instr_i = b ? BranchEqInt : BranchNeqInt; const f_instr instr_f = b ? BranchEqFloat : BranchNeqFloat; @@ -1204,7 +1213,7 @@ ANN static m_bool emit_stmt_auto(const Emitter emit, const Stmt_Auto stmt) { GWD emit_add_instr(emit, GWOP_EXCEPT); const Instr loop = emit_add_instr(emit, stmt->is_ptr ? AutoLoopPtr : AutoLoop); const Instr end = emit_add_instr(emit, BranchEqInt); - const m_uint offset = emit_local(emit, 2*SZ_INT, 0); + const m_uint offset = emit_local(emit, SZ_INT + stmt->v->type->size, 0); stmt->v->offset = offset + SZ_INT; CHECK_BB(emit_stmt(emit, stmt->body, 1)) const m_uint end_pc = emit_code_size(emit); @@ -1245,27 +1254,27 @@ ANN static m_bool emit_stmt_jump(const Emitter emit, const Stmt_Jump stmt) { GWD stmt->data.instr = emit_add_instr(emit, Goto); else { if(switch_inside(emit->env, stmt_self(stmt)->pos) && !strcmp(s_name(stmt->name), "default")) { - if(!strcmp(s_name(stmt->name), "default")) - vector_release(&stmt->data.v); +// if(!strcmp(s_name(stmt->name), "default")) +// vector_release(&stmt->data.v); return switch_default(emit->env, emit_code_size(emit), stmt_self(stmt)->pos); } if(!stmt->data.v.ptr) ERR_B(stmt_self(stmt)->pos, "illegal case") const m_uint size = vector_size(&stmt->data.v); if(!size) { - vector_release(&stmt->data.v); +// vector_release(&stmt->data.v); ERR_B(stmt_self(stmt)->pos, "label '%s' defined but not used.", s_name(stmt->name)) } LOOP_OPTIM for(m_uint i = size + 1; --i;) { const Stmt_Jump label = (Stmt_Jump)vector_at(&stmt->data.v, i - 1); if(!label->data.instr) { - vector_release(&stmt->data.v); +// vector_release(&stmt->data.v); ERR_B(stmt_self(label)->pos, "you are trying to use a upper label.") } label->data.instr->m_val = emit_code_size(emit); } - vector_release(&stmt->data.v); +// vector_release(&stmt->data.v); } return GW_OK; } @@ -1308,7 +1317,7 @@ ANN static m_bool emit_stmt_switch(const Emitter emit, const Stmt_Switch stmt) { Vector v = (Vector)(push[1]->m_val = (m_uint)switch_vec(emit->env)); push[0]->m_val = vector_size(v) * SZ_INT; } - switch_end(emit->env); + CHECK_BB(switch_end(emit->env, stmt->stmt->pos)) pop_vector(&emit->code->stack_break, emit_code_size(emit)); return GW_OK; } @@ -1388,10 +1397,14 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) { G stmt->value->type->nspc->info->offset = stmt->s; if(!stmt->value->type->p) stmt->value->type->p = mp_ini(emit->gwion->p, (uint32_t)stmt->value->type->size); - Type_Decl *type_decl = new_type_decl(emit->gwion->p, new_id_list(emit->gwion->p, stmt->xid, stmt_self(stmt)->pos), - emit->env->class_def ? ae_flag_member : 0); - type_decl->flag = stmt->flag;// ??? - const Var_Decl var_decl = new_var_decl(emit->gwion->p, stmt->xid, NULL, 0); + Type_Decl *type_decl = new_type_decl(emit->gwion->p, + new_id_list(emit->gwion->p, stmt->xid, loc_cpy(emit->gwion->p, loc_cpy(emit->gwion->p, stmt_self(stmt)->pos))), +// emit->env->class_def ? ae_flag_member : 0); + stmt->flag); +//if(emit->env->class_def && !GET_FLAG(stmt, static)) +//SET_FLAG(type_decl, member); +// type_decl->flag = stmt->flag;// ??? + const Var_Decl var_decl = new_var_decl(emit->gwion->p, stmt->xid, NULL, loc_cpy(emit->gwion->p, stmt_self(stmt)->pos)); const Var_Decl_List var_decl_list = new_var_decl_list(emit->gwion->p, var_decl, NULL); const Exp exp = new_exp_decl(emit->gwion->p, type_decl, var_decl_list); exp->d.exp_decl.type = stmt->value->type; @@ -1427,11 +1440,19 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) { G } while((l = l->next)); SET_FLAG(stmt->l->self->d.exp_decl.list->self->value, enum); } - emit_union_offset(stmt->l, stmt->o); - if(stmt->xid) { - const Instr instr = emit_add_instr(emit, RegPop); - instr->m_val = SZ_INT; + if(stmt->xid){ +// if(!emit->env->class_def) { + const Instr instr = emit_add_instr(emit, RegPop); + instr->m_val = !GET_FLAG(stmt, static) ? SZ_INT : SZ_INT*2; +/* + } else if(!GET_FLAG(stmt, static)) { + const Instr instr = emit_add_instr(emit, RegPop); + instr->m_val = SZ_INT; + printf("stmt->o %lu\n", stmt->o); + } +*/ } + emit_union_offset(stmt->l, stmt->o); if(stmt->xid || stmt->type_xid || global) emit_pop(emit, scope); return GW_OK; @@ -1526,6 +1547,7 @@ ANN static void emit_vararg_end(const Emitter emit, const m_uint offset) { GWDEB instr->m_val = offset; instr->m_val2 = emit->env->func->variadic->m_val2; emit->env->func->variadic->m_val2 = emit_code_size(emit); + SET_FLAG(emit->env->func, empty);// mark vararg func as complete } ANN static m_bool emit_vararg(const Emitter emit, const Exp_Dot* member) { GWDEBUG_EXE @@ -1569,14 +1591,9 @@ ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member, co func_i->m_val = (m_uint)(func->code ?: (VM_Code)func); return GW_OK; } - if(func->def->tmpl) { -//const Instr push = emit_add_instr(emit, RegPushImm); -//push->m_val = func; - const Instr instr = emit_add_instr(emit, DotTmplVal); -//printf("func %p\n", func); -// instr->m_val = func; -// instr->m_val2 = SZ_INT; - } else { + if(func->def->tmpl) + emit_add_instr(emit, DotTmplVal); + else { const Instr instr = emit_add_instr(emit, GET_FLAG(func, member) ? DotFunc : DotStaticFunc); instr->m_val = func->vt_index; } @@ -1594,11 +1611,13 @@ ANN static inline m_bool emit_member(const Emitter emit, const Value v, const ui ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member) { GWDEBUG_EXE if(is_special(member->t_base) > 0) return emit_exp_dot_special(emit, member); - if(isa(member->t_base, t_class) < 0) { + const Value value = find_value(actual_type(member->t_base), member->xid); + if(isa(member->t_base, t_class) < 0 && (GET_FLAG(value, member) || +(isa(exp_self(member)->type, t_function) > 0 && isa(exp_self(member)->type, t_fptr) < 0)) +) { CHECK_BB(emit_exp(emit, member->base, 0)) emit_add_instr(emit, GWOP_EXCEPT); } - const Value value = find_value(actual_type(member->t_base), member->xid); if(isa(exp_self(member)->type, t_function) > 0 && isa(exp_self(member)->type, t_fptr) < 0) return emit_member_func(emit, member, value->d.func_ref); return (GET_FLAG(value, member) ? emit_member : emit_dot_static_import_data) (emit, value, exp_self(member)->emit_var); @@ -1692,8 +1711,28 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { G emit_push_scope(emit); emit->env->func = func; CHECK_BB(emit_func_def_body(emit, func_def)) - if(GET_FLAG(func_def, variadic) && !emit->env->func->variadic) - ERR_B(func_def->pos, "invalid variadic use") +// if(GET_FLAG(func_def, variadic) && !emit->env->func->variadic) + if(GET_FLAG(func_def, variadic)) { + if(!emit->env->func->variadic) + ERR_B(func_def->pos, "invalid variadic use") + if(!GET_FLAG(func, empty)) + ERR_B(func_def->pos, "invalid variadic use") +//printf("opcode %p %p %p\n", emit->env->func->variadic->execute, VarargTop, VarargEnd); + +/* + if(emit->env->func->variadic->execute == VarargIni || + emit->env->func->variadic->execute == VarargTop +) { +//assert(emit->env->func->variadic->execute == VarargTop); +//free_code(emit->gwion->p, emit->code); +// emit_func_def_code(emit, func); +// REM_REF(func->code, emit->gwion); +// emit->env->func = former; +// emit_pop_code(emit); + ERR_B(func_def->pos, "invalid variadic use") + } +*/ + } emit_func_def_return(emit); emit_func_def_code(emit, func); emit->env->func = former; @@ -1761,19 +1800,23 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def class_def) return GW_OK; } -ANN static void emit_free_code(MemPool p, Code* code) { - LOOP_OPTIM - for(m_uint j = vector_size(&code->instr) + 1; --j;) - mp_free(p, Instr, (Instr)vector_at(&code->instr, j - 1)); - free_code(p, code); +ANN static void emit_free_code(const Emitter emit, Code* code) { +// LOOP_OPTIM +// for(m_uint j = vector_size(&code->instr) + 1; --j;) { +// mp_free(p, Instr, (Instr)vector_at(&code->instr, j - 1)); +if(vector_size(&code->instr)) + free_code_instr(&code->instr, emit->gwion); +//vector_release(&code->instr); +// } + free_code(emit->gwion->p, code); } ANN static void emit_free_stack(const Emitter emit) { GWDEBUG_EXE LOOP_OPTIM for(m_uint i = vector_size(&emit->stack) + 1; --i;) - emit_free_code(emit->gwion->p, (Code*)vector_at(&emit->stack, i - 1)); + emit_free_code(emit, (Code*)vector_at(&emit->stack, i - 1)); vector_clear(&emit->stack); - emit_free_code(emit->gwion->p, emit->code); + emit_free_code(emit, emit->code); } ANN static inline m_bool emit_ast_inner(const Emitter emit, Ast ast) { GWDEBUG_EXE diff --git a/src/emit/escape.c b/src/emit/escape.c index 98f8de4e..c171c14a 100644 --- a/src/emit/escape.c +++ b/src/emit/escape.c @@ -24,7 +24,10 @@ char* escape_table(void) { } static int get_escape(const Emitter emit, const char c, const loc_t pos) { - return emit->escape[(int)c] ?: err_msg(pos, "unrecognized escape sequence '\\%c'", c); + if(emit->escape[(int)c]) + return emit->escape[(int)c]; + env_err(emit->env, pos, "unrecognized escape sequence '\\%c'", c); + return GW_ERROR; } m_bool escape_str(const Emitter emit, const m_str base, const loc_t pos) { @@ -33,8 +36,10 @@ m_bool escape_str(const Emitter emit, const m_str base, const loc_t pos) { while(*str_lit) { if(*str_lit == '\\') { ++str_lit; - if(*str_lit == '\0') - ERR_B(pos, "invalid: string ends with escape charactor '\\'") + if(*str_lit == '\0') { + env_err(emit->env, pos, "invalid: string ends with escape charactor '\\'"); + return GW_ERROR; + } const unsigned char c = *(str_lit); const unsigned char c2 = *(str_lit+1); if(c >= '0' && c <= '7') { @@ -45,8 +50,10 @@ m_bool escape_str(const Emitter emit, const m_str base, const loc_t pos) { if(c2 >= '0' && c2 <= '7' && c3 >= '0' && c3 <= '7') { *str++ = (char)((c-'0') * 64 + (c2-'0') * 8 + (c3-'0')); str_lit += 2; - } else - ERR_B(pos, "malformed octal escape sequence '\\%c%c%c'", c, c2, c3) + } else { + env_err(emit->env, pos, "malformed octal escape sequence '\\%c%c%c'", c, c2, c3); + return GW_ERROR; + } } } else if(c == 'x') { ++str_lit; @@ -55,8 +62,10 @@ m_bool escape_str(const Emitter emit, const m_str base, const loc_t pos) { if(c1 >= '0' && c1 <= 'F' && c3 >= '0' && c3 <= 'F') { *str++ = (char)((c1-'0') * 16 + (c3-'0')); ++str_lit; - } else - ERR_B(pos, "malformed hex escape sequence '\\%c%c'", c1, c3) + } else { + env_err(emit->env, pos, "malformed hex escape sequence '\\%c%c'", c1, c3); + return GW_ERROR; + } } else CHECK_BB((*str++ = (char)get_escape(emit, (char)c, pos))) } diff --git a/src/gwion.c b/src/gwion.c index 2300232c..a81912c2 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -14,6 +14,7 @@ #include "arg.h" #include "gwion.h" #include "compile.h" +#include "object.h" // fork_clean ANN m_bool gwion_audio(const Gwion gwion) { Driver* di = gwion->vm->bbq; @@ -45,7 +46,7 @@ ANN static inline void gwion_compile(const Gwion gwion, const Vector v) { #include "shreduler_private.h" ANN VM* gwion_cpy(const VM* src) { const Gwion gwion = mp_alloc(src->gwion->p, Gwion); - gwion->vm = new_vm(src->gwion->p); + gwion->vm = new_vm(src->gwion->p, 0); gwion->vm->gwion = gwion; gwion->vm->bbq->si = soundinfo_cpy(src->gwion->p, src->bbq->si); gwion->emit = src->gwion->emit; @@ -59,7 +60,7 @@ ANN VM* gwion_cpy(const VM* src) { ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) { gwion->p = mempool_ini((sizeof(VM_Shred) + SIZEOF_REG + SIZEOF_MEM) / SZ_INT); gwion->st = new_symbol_table(gwion->p, 65347); - gwion->vm = new_vm(gwion->p); + gwion->vm = new_vm(gwion->p, 1); gwion->emit = new_emitter(); gwion->env = new_env(gwion->p); gwion->emit->env = gwion->env; @@ -90,6 +91,10 @@ ANN void gwion_end(const Gwion gwion) { const VM_Code code = new_vm_code(gwion->p, NULL, 0, ae_flag_builtin, "in code dtor"); gwion->vm->cleaner_shred = new_vm_shred(gwion->p, code); vm_add_shred(gwion->vm, gwion->vm->cleaner_shred); + MUTEX_LOCK(gwion->vm->shreduler->mutex); + if(gwion->child.ptr) + fork_clean(gwion->vm, &gwion->child); + MUTEX_UNLOCK(gwion->vm->shreduler->mutex); free_env(gwion->env); free_vm_shred(gwion->vm->cleaner_shred); free_emitter(gwion->emit); @@ -100,19 +105,15 @@ ANN void gwion_end(const Gwion gwion) { mempool_end(gwion->p); } -ANN void env_err(const Env env, const loc_t pos, const m_str fmt, ...) { - gw_err("in file: '%s'\n", env->name); +ANN void env_err(const Env env, const struct YYLTYPE* pos, const m_str fmt, ...) { + loc_err(pos, env->name); if(env->class_def) gw_err("in class: '%s'\n", env->class_def->name); if(env->func) gw_err("in function: '%s'\n", env->func->name); - if(pos) - fprintf(stderr, "line: %u\t", pos); - else - fprintf(stderr, "\t"); va_list arg; va_start(arg, fmt); vfprintf(stderr, fmt, arg); va_end(arg); fprintf(stderr, "\n"); -} \ No newline at end of file +} diff --git a/src/lib/array.c b/src/lib/array.c index dc6e349c..e98bd44e 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -13,6 +13,7 @@ #include "emit.h" #include "import.h" #include "operator.h" +#include "parse.h" struct M_Vector_ { m_bit* ptr; diff --git a/src/lib/engine.c b/src/lib/engine.c index 6773a708..2f1e71c1 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -16,6 +16,7 @@ #include "gwion.h" #include "operator.h" #include "engine.h" +#include "parser.h" static FREEARG(freearg_switchini) { free_vector(((Gwion)gwion)->p, (Vector)instr->m_val); @@ -97,6 +98,7 @@ ANN m_bool type_engine_init(VM* vm, const Vector plug_dirs) { struct Gwi_ gwi; memset(&gwi, 0, sizeof(struct Gwi_)); gwi.gwion = vm->gwion; + gwi.loc = new_loc(vm->gwion->p, 0); CHECK_BB(import_core_libs(&gwi)) vm->gwion->env->name = "[imported]"; for(m_uint i = 0; i < vector_size(plug_dirs); ++i) { @@ -104,5 +106,6 @@ ANN m_bool type_engine_init(VM* vm, const Vector plug_dirs) { if(import && import(&gwi) < 0) env_reset(gwi.gwion->env); } + free_loc(vm->gwion->p, gwi.loc); return GW_OK; } \ No newline at end of file diff --git a/src/lib/func.c b/src/lib/func.c index 588a8f91..15037e01 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -27,6 +27,8 @@ static INSTR(LambdaAssign) { GWDEBUG_EXE static OP_CHECK(opck_func_call) { Exp_Binary* bin = (Exp_Binary*)data; + if(bin->rhs->exp_type == ae_exp_decl) + ERR_N(bin->rhs->pos, "calling fptr decl, this is forbidden.") Exp_Call call = { .func=bin->rhs, .args=bin->lhs }; Exp e = exp_self(bin); e->exp_type = ae_exp_call; @@ -37,7 +39,9 @@ static OP_CHECK(opck_func_call) { static OP_EMIT(opem_func_assign) { Exp_Binary* bin = (Exp_Binary*)data; emit_add_instr(emit, int_r_assign); - if(bin->lhs->type != t_lambda && GET_FLAG(bin->rhs->type->d.func, member)) { + if(bin->lhs->type != t_lambda && GET_FLAG(bin->rhs->type->d.func, member) + && !emit->env->class_def +) { const Instr instr = emit_add_instr(emit, LambdaAssign); instr->m_val = SZ_INT; } @@ -71,7 +75,8 @@ ANN2(1,3,4) m_bool check_lambda(const Env env, const Type owner, } if(base || arg) ERR_B(exp_self(l)->pos, "argument number does not match for lambda") - l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, def->base->td, l->name, l->args), l->code, def->flag, def->pos); + l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, def->base->td, l->name, l->args), l->code, def->flag, + loc_cpy(env->gwion->p, def->pos)); const m_bool ret = traverse_func_def(env, l->def); arg = l->args; while(arg) { diff --git a/src/lib/import.c b/src/lib/import.c index 823801e8..45036d06 100644 --- a/src/lib/import.c +++ b/src/lib/import.c @@ -25,16 +25,19 @@ #undef ERR_O #define ERR_O(a, b, ...) { env_err(gwi->gwion->env, (a), (b), ## __VA_ARGS__); return NULL; } +#include "parser.h" struct Path { m_str path, curr; m_uint len; + YYLTYPE loc; }; -ANN static ID_List templater_def(SymTable *st, const Templater* templater) { +ANN static ID_List templater_def(SymTable *st, const Gwi gwi) { + const Templater* templater = &gwi->templater; ID_List list[templater->n]; - list[0] = new_id_list(st->p, insert_symbol(st, templater->list[0]), 0); + list[0] = new_id_list(st->p, insert_symbol(st, templater->list[0]), loc_cpy(gwi->gwion->p, gwi->loc)); for(m_uint i = 1; i < templater->n; i++) { - list[i] = new_id_list(st->p, insert_symbol(st, templater->list[i]), 0); + list[i] = new_id_list(st->p, insert_symbol(st, templater->list[i]), loc_cpy(gwi->gwion->p, gwi->loc)); list[i - 1]->next = list[i]; } return list[0]; @@ -76,7 +79,7 @@ ANN static void dl_func_func_arg(DL_Func* a, const restrict m_str t, const restr ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_str n) { if(gwi->func.narg == DLARG_MAX - 1) - ERR_B(0, "too many arguments for function '%s'.", gwi->func.name) + ERR_B(gwi->loc, "too many arguments for function '%s'.", gwi->func.name) dl_func_func_arg(&gwi->func, t, n); return GW_OK; } @@ -89,7 +92,8 @@ ANN static m_bool check_illegal(char* curr, const char c, const m_uint i) { return GW_OK; } -ANN static m_bool name_valid(Env env, const m_str a) { +ANN static m_bool name_valid(const Gwi gwi, const m_str a) { + const Env env = gwi->gwion->env; const m_uint len = strlen(a); m_uint lvl = 0; for(m_uint i = 0; i < len; i++) { @@ -103,20 +107,20 @@ ANN static m_bool name_valid(Env env, const m_str a) { } if(c == ',') { if(!lvl) { - env_err(env, 0, "illegal use of ',' outside of templating in name '%s'.", a); + env_err(env, gwi->loc, "illegal use of ',' outside of templating in name '%s'.", a); return GW_ERROR; } continue; } if(c == '>') { if(!lvl) { - env_err(env, 0, "illegal templating in name '%s'.", a); + env_err(env, gwi->loc, "illegal templating in name '%s'.", a); return GW_ERROR; } lvl--; continue; } - env_err(env, 0, "illegal character '%c' in name '%s'.", c, a); + env_err(env, gwi->loc, "illegal character '%c' in name '%s'.", c, a); return GW_ERROR; } return !lvl ? 1 : -1; @@ -131,22 +135,22 @@ ANN static void path_valid_inner(const m_str curr) { } } -ANN static m_bool path_valid(const Env env,ID_List* list, const struct Path* p) { +ANN static m_bool path_valid(const Env env, ID_List* list, const struct Path* p) { char last = '\0'; for(m_uint i = p->len + 1; --i;) { const char c = p->path[i - 1]; if(c != '.' && check_illegal(p->curr, c, i) < 0) { - env_err(env, 0, "illegal character '%c' in path '%s'.", c, p->path); + env_err(env, &p->loc, "illegal character '%c' in path '%s'.", c, p->path); return GW_ERROR; } if(c == '.' || i == 1) { if((i != 1 && last != '.' && last != '\0') || (i == 1 && c != '.')) { path_valid_inner(p->curr); - *list = prepend_id_list(env->gwion->st->p, insert_symbol(env->gwion->st, p->curr), *list, 0); + *list = prepend_id_list(env->gwion->st->p, insert_symbol(env->gwion->st, p->curr), *list, loc_cpy(env->gwion->p, &p->loc)); memset(p->curr, 0, p->len + 1); } else { - env_err(env, 0, "path '%s' must not ini or end with '.'.", p->path); + env_err(env, &p->loc, "path '%s' must not ini or end with '.'.", p->path); return GW_ERROR; } } @@ -160,7 +164,7 @@ ANN /* static */ ID_List str2list(const Env env, const m_str path, m_uint* array ID_List list = NULL; m_uint depth = 0; char curr[len + 1]; - struct Path p = { path, curr, len }; + struct Path p = { path, curr, len, { 1,1,1,1} }; memset(curr, 0, len + 1); while(p.len > 2 && path[p.len - 1] == ']' && path[p.len - 2] == '[') { @@ -196,7 +200,7 @@ ANN2(1,2) Type gwi_mk_type(const Gwi gwi NUSED, const m_str name, const m_uint s ANN m_int gwi_add_type(const Gwi gwi, const Type type) { if(type->name[0] != '@') - CHECK_BB(name_valid(gwi->gwion->env, type->name)); + CHECK_BB(name_valid(gwi, type->name)); env_add_type(gwi->gwion->env, type); return (m_int)type->xid; } @@ -221,10 +225,10 @@ ANN2(1,2) static void import_class_ini(const Env env, const Type type, ANN2(1,2) m_int gwi_class_ini(const Gwi gwi, const Type type, const f_xtor pre_ctor, const f_xtor dtor) { if(type->nspc) - ERR_B(0, "during import: class '%s' already imported.", type->name) + ERR_B(gwi->loc, "during import: class '%s' already imported.", type->name) if(gwi->templater.n) { - const ID_List types = templater_def(gwi->gwion->st,&gwi->templater); - type->def = new_class_def(gwi->gwion->p, 0, insert_symbol(gwi->gwion->st, type->name), NULL, NULL, 0); + const ID_List types = templater_def(gwi->gwion->st, gwi); + type->def = new_class_def(gwi->gwion->p, 0, insert_symbol(gwi->gwion->st, type->name), NULL, NULL, loc_cpy(gwi->gwion->p, gwi->loc)); type->def->tmpl = new_tmpl_class(gwi->gwion->p, types, -1); type->def->base.type = type; SET_FLAG(type, template); @@ -237,13 +241,13 @@ ANN2(1,2) m_int gwi_class_ini(const Gwi gwi, const Type type, const f_xtor pre_c ANN m_int gwi_class_ext(const Gwi gwi, Type_Decl* td) { if(!gwi->gwion->env->class_def) - ERR_B(0, "gwi_class_ext invoked before gwi_class_ini") + ERR_B(gwi->loc, "gwi_class_ext invoked before gwi_class_ini") const VM_Code ctor = gwi->gwion->env->class_def->nspc->pre_ctor; if(gwi->gwion->env->class_def->parent || (gwi->gwion->env->class_def->def && gwi->gwion->env->class_def->def->base.ext)) - ERR_B(0, "class extend already set") + ERR_B(gwi->loc, "class extend already set") if(td->array && !td->array->exp) - ERR_B(0, "class extend array can't be empty") + ERR_B(gwi->loc, "class extend array can't be empty") if(!gwi->gwion->env->class_def->def) { const Type t = known_type(gwi->gwion->env, td); CHECK_OB(t) @@ -270,7 +274,7 @@ ANN m_int gwi_class_ext(const Gwi gwi, Type_Decl* td) { ANN m_int gwi_class_end(const Gwi gwi) { if(!gwi->gwion->env->class_def) - ERR_B(0, "import: too many class_end called.") + ERR_B(gwi->loc, "import: too many class_end called.") const Type t = gwi->gwion->env->class_def; if(t->nspc && t->nspc->info->offset) t->p = mp_ini(gwi->gwion->p, (uint32_t)t->nspc->info->offset); @@ -310,7 +314,7 @@ ANN m_int gwi_item_ini(const Gwi gwi, const restrict m_str type, const restrict DL_Var* v = &gwi->var; memset(v, 0, sizeof(DL_Var)); if(!(v->t.xid = str2list(gwi->gwion->env, type, &v->array_depth))) - ERR_B(0, "\t...\tduring var import '%s.%s'.", + ERR_B(gwi->loc, "\t...\tduring var import '%s.%s'.", gwi->gwion->env->class_def->name, name) v->var.xid = insert_symbol(gwi->gwion->st, name); return GW_OK; @@ -332,7 +336,7 @@ ANN2(1) m_int gwi_item_end(const Gwi gwi, const ae_flag flag, const m_uint* addr v->var.addr = (void*)addr; if(gwi->gwion->env->class_def && GET_FLAG(gwi->gwion->env->class_def, template)) { Type_Decl *type_decl = new_type_decl(gwi->gwion->p, v->t.xid, flag); - const Var_Decl var_decl = new_var_decl(gwi->gwion->p, v->var.xid, v->var.array, 0); + const Var_Decl var_decl = new_var_decl(gwi->gwion->p, v->var.xid, v->var.array, loc_cpy(gwi->gwion->p, gwi->loc)); const Var_Decl_List var_decl_list = new_var_decl_list(gwi->gwion->p, var_decl, NULL); const Exp exp = new_exp_decl(gwi->gwion->p, type_decl, var_decl_list); const Stmt stmt = new_stmt_exp(gwi->gwion->p, ae_stmt_exp, exp); @@ -343,6 +347,7 @@ ANN2(1) m_int gwi_item_end(const Gwi gwi, const ae_flag flag, const m_uint* addr gwi_body(gwi, body); return GW_OK; } + v->exp.pos = gwi->loc; CHECK_BB(traverse_decl(gwi->gwion->env, &v->exp.d.exp_decl)) SET_FLAG(v->var.value, builtin); dl_var_release(gwi->gwion->p, v); @@ -393,7 +398,8 @@ ANN Type_Decl* str2decl(const Env env, const m_str s, m_uint *depth) { return td; } -ANN static Arg_List make_dll_arg_list(const Env env, DL_Func * dl_fun) { +ANN static Arg_List make_dll_arg_list(const Gwi gwi, DL_Func * dl_fun) { + const Env env = gwi->gwion->env; Arg_List arg_list = NULL; for(m_uint i = dl_fun->narg + 1; --i; ) { m_uint array_depth = 0, array_depth2 = 0; @@ -405,7 +411,7 @@ ANN static Arg_List make_dll_arg_list(const Env env, DL_Func * dl_fun) { if(!(type_decl = str2decl(env, arg->type, &array_depth))) { if(arg_list) free_arg_list(env->gwion->p, arg_list); - env_err(env, 0, "\t...\tat argument '%i'", i + 1); + env_err(env, gwi->loc, "\t...\tat argument '%i'", i + 1); return NULL; } if((type_path2 = str2list(env, arg->name, &array_depth2))) @@ -414,17 +420,18 @@ ANN static Arg_List make_dll_arg_list(const Env env, DL_Func * dl_fun) { free_type_decl(env->gwion->p, type_decl); if(arg_list) free_arg_list(env->gwion->p, arg_list); - env_err(env, 0, "array subscript specified incorrectly for built-in module"); + env_err(env, gwi->loc, "array subscript specified incorrectly for built-in module"); return NULL; } array_sub = make_dll_arg_list_array(env->gwion->p, array_sub, &array_depth, array_depth2); - var_decl = new_var_decl(env->gwion->p, insert_symbol(env->gwion->st, arg->name), array_sub, 0); + var_decl = new_var_decl(env->gwion->p, insert_symbol(env->gwion->st, arg->name), array_sub, loc_cpy(gwi->gwion->p, gwi->loc)); arg_list = new_arg_list(env->gwion->p, type_decl, var_decl, arg_list); } return arg_list; } -ANN static Func_Def make_dll_as_fun(const Env env, DL_Func * dl_fun, ae_flag flag) { +ANN static Func_Def make_dll_as_fun(const Gwi gwi, DL_Func * dl_fun, ae_flag flag) { + const Env env = gwi->gwion->env; Func_Def func_def = NULL; ID_List type_path = NULL; Type_Decl* type_decl = NULL; @@ -435,7 +442,8 @@ ANN static Func_Def make_dll_as_fun(const Env env, DL_Func * dl_fun, ae_flag fla flag |= ae_flag_builtin; if(!(type_path = str2list(env, dl_fun->type, &array_depth)) || !(type_decl = new_type_decl(env->gwion->p, type_path, 0))) { - env_err(env, 0, "\t...\tduring @ function import '%s' (type).", dl_fun->name); + if(type_path)free_id_list(env->gwion->p, type_path); + env_err(env, gwi->loc, "\t...\tduring @ function import '%s' (type).", dl_fun->name); return NULL; } if(array_depth) { @@ -445,23 +453,21 @@ ANN static Func_Def make_dll_as_fun(const Env env, DL_Func * dl_fun, ae_flag fla type_decl = add_type_decl_array(type_decl, array_sub); } name = dl_fun->name; - arg_list = make_dll_arg_list(env, dl_fun); - func_def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, type_decl, insert_symbol(env->gwion->st, name), arg_list), NULL, flag, 0); + arg_list = make_dll_arg_list(gwi, dl_fun); + func_def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, type_decl, insert_symbol(env->gwion->st, name), arg_list), + NULL, flag, loc_cpy(gwi->gwion->p, gwi->loc)); func_def->d.dl_func_ptr = (void*)(m_uint)dl_fun->addr; return func_def; } -ANN static Func_Def import_fun(const Env env, DL_Func * mfun, const ae_flag flag) { - CHECK_BO(name_valid(env, mfun->name)); - return make_dll_as_fun(env, mfun, flag); -} - ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag) { - Func_Def def = import_fun(gwi->gwion->env, &gwi->func, flag); + CHECK_BB(name_valid(gwi, gwi->func.name)); + Func_Def def = make_dll_as_fun(gwi, &gwi->func, flag); +// Func_Def def = import_fun(gwi->gwion->env, &gwi->func, flag); CHECK_OB(def) if(gwi->templater.n) { - def = new_func_def(gwi->gwion->p, new_func_base(gwi->gwion->p, NULL, NULL, NULL), NULL, 0, 0); - const ID_List list = templater_def(gwi->gwion->st, &gwi->templater); + def = new_func_def(gwi->gwion->p, new_func_base(gwi->gwion->p, NULL, NULL, NULL), NULL, 0, loc_cpy(gwi->gwion->p, gwi->loc)); + const ID_List list = templater_def(gwi->gwion->st, gwi); def->tmpl = new_tmpl_list(gwi->gwion->p, list, -1); SET_FLAG(def, template); } @@ -487,13 +493,14 @@ static Type get_type(const Env env, const m_str str) { return t ? (depth ? array_type(env, t, depth) : t) : NULL; } -ANN2(1,2) static int import_op(const Env env, const DL_Oper* op, +ANN2(1,2) static int import_op(const Gwi gwi, const DL_Oper* op, const f_instr f) { + const Env env = gwi->gwion->env; const Type lhs = op->lhs ? get_type(env, op->lhs) : NULL; const Type rhs = op->rhs ? get_type(env, op->rhs) : NULL; const Type ret = get_type(env, op->ret); const struct Op_Import opi = { lhs, rhs, ret, - op->ck, op->em, (uintptr_t)f, 0, op->op, op->mut }; + op->ck, op->em, (uintptr_t)f, gwi->loc, op->op, op->mut }; return env_add_op(env, &opi); } @@ -523,7 +530,7 @@ ANN void gwi_oper_mut(const Gwi gwi, const m_bool mut) { ANN m_int gwi_oper_end(const Gwi gwi, const Operator op, const f_instr f) { gwi->oper.op = op; - const m_bool ret = import_op(gwi->gwion->env, &gwi->oper, f); + const m_bool ret = import_op(gwi, &gwi->oper, f); gwi->oper.ck = NULL; gwi->oper.em = NULL; return ret; @@ -534,15 +541,16 @@ ANN m_int gwi_fptr_ini(const Gwi gwi, const restrict m_str type, const restrict return GW_OK; } -ANN static Stmt import_fptr(const Env env, DL_Func* dl_fun, ae_flag flag) { +ANN static Stmt import_fptr(const Gwi gwi, DL_Func* dl_fun, ae_flag flag) { + const Env env = gwi->gwion->env; m_uint array_depth; ID_List type_path; Type_Decl* type_decl = NULL; - const Arg_List args = make_dll_arg_list(env, dl_fun); + const Arg_List args = make_dll_arg_list(gwi, dl_fun); flag |= ae_flag_builtin; if(!(type_path = str2list(env, dl_fun->type, &array_depth)) || !(type_decl = new_type_decl(env->gwion->p, type_path, 0))) { - env_err(env, 0, "\t...\tduring fptr import '%s' (type).", + env_err(env, gwi->loc, "\t...\tduring fptr import '%s' (type).", dl_fun->name); return NULL; } @@ -551,19 +559,20 @@ ANN static Stmt import_fptr(const Env env, DL_Func* dl_fun, ae_flag flag) { } ANN Type gwi_fptr_end(const Gwi gwi, const ae_flag flag) { - const Stmt stmt = import_fptr(gwi->gwion->env, &gwi->func, flag); + const Stmt stmt = import_fptr(gwi, &gwi->func, flag); CHECK_BO(traverse_stmt_fptr(gwi->gwion->env, &stmt->d.stmt_fptr)) if(gwi->gwion->env->class_def) SET_FLAG(stmt->d.stmt_fptr.base->func->def, builtin); else SET_FLAG(stmt->d.stmt_fptr.base->func, builtin); const Type t = stmt->d.stmt_fptr.type; - ADD_REF(t); +// ADD_REF(t); free_stmt(gwi->gwion->p, stmt); return t; } -ANN static Exp make_exp(const Env env, const m_str type, const m_str name) { +ANN static Exp make_exp(const Gwi gwi, const m_str type, const m_str name) { + const Env env = gwi->gwion->env; Type_Decl *type_decl; ID_List id_list; m_uint array_depth; @@ -575,7 +584,7 @@ ANN static Exp make_exp(const Env env, const m_str type, const m_str name) { } type_decl = new_type_decl(env->gwion->p, id_list, 0); const Var_Decl var_decl = new_var_decl(env->gwion->p, - insert_symbol(env->gwion->st, name), array, 0); + insert_symbol(env->gwion->st, name), array, loc_cpy(env->gwion->p, gwi->loc)); const Var_Decl_List var_decl_list = new_var_decl_list(env->gwion->p, var_decl, NULL); return new_exp_decl(env->gwion->p, type_decl, var_decl_list); } @@ -587,11 +596,11 @@ ANN2(1) m_int gwi_union_ini(const Gwi gwi, const m_str name) { } ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, const restrict m_str name) { - const Exp exp = make_exp(gwi->gwion->env, type, name); + const Exp exp = make_exp(gwi, type, name); CHECK_OB(exp); const Type t = type_decl_resolve(gwi->gwion->env, exp->d.exp_decl.td); if(!t) - ERR_B(0, "type '%s' unknown in union declaration.", type) + ERR_B(gwi->loc, "type '%s' unknown in union declaration.", type) if(isa(t, t_object) > 0) SET_FLAG(exp->d.exp_decl.td, ref); gwi->union_data.list = new_decl_list(gwi->gwion->p, exp, gwi->union_data.list); @@ -600,8 +609,8 @@ ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, const restrict ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) { if(!gwi->union_data.list) - ERR_O(0, "union is empty"); - const Stmt stmt = new_stmt_union(gwi->gwion->p, gwi->union_data.list, 0); + ERR_O(gwi->loc, "union is empty"); + const Stmt stmt = new_stmt_union(gwi->gwion->p, gwi->union_data.list, loc_cpy(gwi->gwion->p, gwi->loc)); stmt->d.stmt_union.flag = flag; CHECK_BO(traverse_stmt_union(gwi->gwion->env, &stmt->d.stmt_union)) emit_union_offset(stmt->d.stmt_union.l, stmt->d.stmt_union.o); @@ -623,7 +632,7 @@ ANN2(1) m_int gwi_enum_ini(const Gwi gwi, const m_str type) { } ANN m_int gwi_enum_add(const Gwi gwi, const m_str name, const m_uint i) { - const ID_List list = new_id_list(gwi->gwion->p, insert_symbol(gwi->gwion->st, name), 0); + const ID_List list = new_id_list(gwi->gwion->p, insert_symbol(gwi->gwion->st, name), loc_cpy(gwi->gwion->p, gwi->loc)); DL_Enum* d = &gwi->enum_data; ALLOC_PTR(gwi->gwion->p, addr, m_int, i); vector_add(&gwi->enum_data.addr, (vtype)addr); diff --git a/src/lib/instr.c b/src/lib/instr.c index ed8ed670..53420788 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -70,7 +70,7 @@ ANN static Func_Def from_base(const Env env, const struct dottmpl_ *dt, const Ty CHECK_OO(v) const Func_Def base = v->d.func_ref->def; const Func_Def def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, base->base->td, insert_symbol(env->gwion->st, v->name), - base->base->args), base->d.code, base->flag, base->pos); + base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->p, base->pos)); def->tmpl = new_tmpl_list(env->gwion->p, base->tmpl->list, dt->overload); SET_FLAG(def, template); return def; diff --git a/src/lib/object.c b/src/lib/object.c index 8d971c50..ff421025 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -121,8 +121,10 @@ static OP_CHECK(at_object) { return t_null; if(bin->rhs->exp_type == ae_exp_decl) SET_FLAG(bin->rhs->d.exp_decl.td, ref); - if(l != t_null && isa(l, r) < 0) - ERR_N(exp_self(bin)->pos, "'%s' @=> '%s': not allowed", l->name, r->name) + if(l != t_null && isa(l, r) < 0) { + env_err(env, exp_self(bin)->pos, "'%s' @=> '%s': not allowed", l->name, r->name); + return t_null; + } bin->rhs->emit_var = 1; return r; } diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 8d0dc292..28934e67 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -9,6 +9,7 @@ #include "object.h" #include "import.h" #include "emit.h" +#include "parse.h" static inline m_str access(ae_Exp_Meta meta) { return meta == ae_meta_value ? "non-mutable" : "protected"; diff --git a/src/lib/prim.c b/src/lib/prim.c index eb28ceee..3ce66da9 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -12,6 +12,7 @@ #include "emit.h" #include "operator.h" #include "driver.h" +#include "parse.h" #define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func) @@ -233,6 +234,8 @@ static GWION_IMPORT(time) { _CHECK_OP(chuck, rassign, Time_Advance) CHECK_BB(gwi_oper_ini(gwi, "@now", "@now", NULL)) _CHECK_OP(chuck, chuck_now, NULL) + CHECK_BB(gwi_oper_ini(gwi, NULL, "@now", NULL)) + CHECK_BB(gwi_oper_end(gwi, op_not, NULL)) CHECK_BB(gwi_oper_ini(gwi, "time", "time", "int")) CHECK_BB(gwi_oper_end(gwi, op_gt, float_gt)) CHECK_BB(gwi_oper_end(gwi, op_ge, float_ge)) diff --git a/src/lib/ptr.c b/src/lib/ptr.c index 95a4298f..2b677e9c 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -19,8 +19,10 @@ static OP_CHECK(opck_ptr_assign) { Type t = bin->lhs->type; do { if(!strcmp(t->name, get_type_name(env, bin->rhs->type->name, 1))) { - if(bin->lhs->meta != ae_meta_var) - ERR_N(0, "left side operand is constant") + if(bin->lhs->meta != ae_meta_var) { + env_err(env, exp_self(bin)->pos, "left side operand is constant"); + return t_null; + } bin->lhs->emit_var = 1; return bin->lhs->type; } @@ -44,8 +46,10 @@ static OP_CHECK(opck_implicit_ptr) { const struct Implicit* imp = (struct Implicit*)data; const Exp e = (Exp)imp->e; if(!strcmp(get_type_name(env, imp->t->name, 1), e->type->name)) { - if(e->meta == ae_meta_value) - ERR_N(0, "can't cast constant to Ptr"); + if(e->meta == ae_meta_value) { + env_err(env, 0, "can't cast constant to Ptr"); + return t_null; + } e->cast_to = imp->t; e->emit_var = 1; return imp->t; @@ -57,8 +61,10 @@ static INSTR(instr_ptr_deref) { GWDEBUG_EXE const M_Object o = *(M_Object*)REG(-SZ_INT); if(instr->m_val2) memcpy(REG(-SZ_INT), o->data, SZ_INT); - else - memcpy(REG(-SZ_INT), *(m_bit**)o->data, instr->m_val); + else { + shred->reg -= SZ_INT - instr->m_val; + memcpy(REG(-instr->m_val), *(m_bit**)o->data, instr->m_val); + } } static OP_EMIT(opem_ptr_deref) { diff --git a/src/lib/shred.c b/src/lib/shred.c index 6fc2af16..a404adff 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -13,10 +13,12 @@ #include "shreduler_private.h" #include "gwion.h" -static m_int o_fork_thread, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize, o_fork_retval; +static m_int o_fork_thread, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize, o_fork_retval, + o_fork_orig; #define FORK_THREAD(o) *(THREAD_TYPE*)(o->data + o_fork_thread) #define FORK_RETSIZE(o) *(m_int*)(o->data + o_fork_retsize) #define FORK_RETVAL(o) (o->data + o_fork_retval) +#define FORK_ORIG(o) (*(VM**)((o)->data + o_fork_orig)) M_Object new_shred(const VM_Shred shred, m_bool is_spork) { const M_Object obj = new_object(shred->info->mp, NULL, is_spork ? t_shred : t_fork); @@ -55,11 +57,14 @@ static MFUN(shred_yield) { static SFUN(vm_shred_from_id) { const m_int index = *(m_int*)MEM(0); - const VM_Shred s = (VM_Shred)vector_at(&shred->tick->shreduler->shreds, (vtype)index); - if(s) - *(M_Object*)RETURN = s->info->me; - else - *(m_uint*)RETURN = 0; +// TODO vector_size_safe() + if(index <= 0 && (m_uint)index < vector_size(&shred->tick->shreduler->shreds)) { + const VM_Shred s = (VM_Shred)vector_at(&shred->tick->shreduler->shreds, (vtype)index); + if(s) + *(M_Object*)RETURN = s->info->me; + else + *(m_uint*)RETURN = 0; + } } static MFUN(shred_args) { @@ -117,6 +122,7 @@ static DTOR(fork_dtor) { static MFUN(fork_join) { MUTEX_LOCK(ME(o)->tick->shreduler->mutex); MUTEX_LOCK(shred->tick->shreduler->mutex); + release(o, shred); if(*(m_int*)(o->data + o_fork_done)) { MUTEX_UNLOCK(shred->tick->shreduler->mutex); MUTEX_UNLOCK(ME(o)->tick->shreduler->mutex); @@ -155,15 +161,39 @@ static ANN void* fork_run(void* data) { } while(vm->bbq->is_running); fork_retval(me); MUTEX_LOCK(vm->shreduler->mutex); +// MUTEX_LOCK(FORK_ORIG(me)->shreduler->mutex); + vector_rem2(&FORK_ORIG(me)->gwion->child, (vtype)me); +// MUTEX_UNLOCK(FORK_ORIG(me)->shreduler->mutex); *(m_int*)(me->data + o_fork_done) = 1; broadcast(*(M_Object*)(me->data + o_fork_ev)); MUTEX_UNLOCK(vm->shreduler->mutex); THREAD_RETURN(NULL); } -void fork_launch(const M_Object o, const m_uint sz) { +ANN void fork_clean(const VM *vm, const Vector v) { + for(m_uint i = 0; i < vector_size(v); ++i) { + const M_Object o = (M_Object)vector_at(v, i); + THREAD_JOIN(FORK_THREAD(o)); + release(o, vm->cleaner_shred); + } + vector_release(v); +} + +void fork_launch(const VM* vm, const M_Object o, const m_uint sz) { + ++o->ref; ++o->ref; +// Gwion gwion = ME(o)->info->vm->gwion; +// if(!gwion->child.ptr) +// vector_init(&gwion->child); +// vector_add(&gwion->child, (vtype)o); +// o->ref += 2; + if(!vm->gwion->child.ptr) { + vector_init(&vm->gwion->child); + } + vector_add(&vm->gwion->child, (vtype)o); + FORK_ORIG(o) = (VM*)vm; FORK_RETSIZE(o) = sz; +//printf("sz %lu\n", vector_size(&gwion->child)); THREAD_CREATE(FORK_THREAD(o), fork_run, o); } @@ -241,6 +271,8 @@ GWION_IMPORT(shred) { CHECK_BB((o_fork_ev = gwi_item_end(gwi, ae_flag_const, NULL))) gwi_item_ini(gwi, "int", "retsize"); CHECK_BB((o_fork_retsize = gwi_item_end(gwi, ae_flag_const, NULL))) + gwi_item_ini(gwi, "int", "@orig"); + CHECK_BB((o_fork_orig = gwi_item_end(gwi, ae_flag_const, NULL))) o_fork_retval = t_fork->nspc->info->offset; CHECK_BB(gwi_union_ini(gwi, NULL)) CHECK_BB(gwi_union_add(gwi, "int", "i")) diff --git a/src/oo/env_utils.c b/src/oo/env_utils.c index 6e86a951..27155e5f 100644 --- a/src/oo/env_utils.c +++ b/src/oo/env_utils.c @@ -59,14 +59,16 @@ ANN Type find_type(const Env env, ID_List path) { path = path->next; while(path) { const Symbol xid = path->xid; - Type t = nspc_lookup_type1(nspc, xid); - while(!t && type && type->parent) { - t = nspc_lookup_type1(type->parent->nspc, xid); // was lookup2 - type = type->parent; + if(nspc) { + Type t = nspc_lookup_type1(nspc, xid); + while(!t && type && type->parent && type->parent) { + t = nspc_lookup_type1(type->parent->nspc, xid); // was lookup2 + type = type->parent; + } + if(!t) + ERR_O(path->pos, "...(cannot find class '%s' in nspc '%s')", s_name(xid), nspc->name) + type = t; } - if(!t) - ERR_O(path->pos, "...(cannot find class '%s' in nspc '%s')", s_name(xid), nspc->name) - type = t; nspc = type->nspc; path = path->next; } @@ -75,7 +77,10 @@ ANN Type find_type(const Env env, ID_List path) { ANN m_bool already_defined(const Env env, const Symbol s, const loc_t pos) { const Value v = nspc_lookup_value0(env->curr, s); - return v ? err_msg(pos, - "'%s' already declared as variable of type '%s'.", s_name(s), v->type->name) : GW_OK; + if(!v) + return GW_OK; + env_err(env, pos, + "'%s' already declared as variable of type '%s'.", s_name(s), v->type->name); + return GW_ERROR; } diff --git a/src/oo/switch.c b/src/oo/switch.c index ed5bb366..169b0316 100644 --- a/src/oo/switch.c +++ b/src/oo/switch.c @@ -11,6 +11,8 @@ #include "type.h" #include "context.h" #include "nspc.h" +#include "parse.h" +#include "switch.h" static inline void _scope_add(Scope s, Switch sw) { vector_add((Vector)(void*)s, (vtype)sw); } static inline vtype _scope_pop(Scope s) { return vector_pop((Vector)(void*)s); } @@ -26,8 +28,8 @@ static Switch new_switch(MemPool p) { } ANN static void free_switch(MemPool p, const Switch sw) { -// if(!sw->ok) -// free_map(sw->cases); + if(!sw->ok) + free_map(p, sw->cases); free_vector(p, sw->vec); // only for dynamic vector_release(&sw->exp); mp_free(p, Switch, sw); @@ -46,6 +48,7 @@ ANN static Switch new_swinfo(const Env env, const Stmt_Switch stmt) { info->f = env->func; const Switch sw = new_switch(env->gwion->p); map_set(&env->scope->swi.map, (vtype)info, (vtype)sw); + sw->depth = env->scope->depth + 2; return sw; } @@ -69,6 +72,14 @@ ANN m_bool switch_add(const Env env, const Stmt_Switch stmt) { return GW_OK; } +ANN m_bool switch_decl(const Env env, const loc_t pos) { + const Switch sw = (Switch)(VLEN(&env->scope->swi.map) ? + VVAL(&env->scope->swi.map, VLEN(&env->scope->swi.map) - 1): 0); + if(sw && sw->depth == env->scope->depth) + ERR_B(pos, "Declaration in switch is prohibited.") + return GW_OK; +} + ANN void switch_get(const Env env, const Stmt_Switch stmt) { const struct SwInfo_ info = { stmt, env->class_def, env->func }; const Switch sw = swinfo_get(env, &info); @@ -80,7 +91,8 @@ void switch_reset(const Env env) { struct SwInfo_ *info = (struct SwInfo_ *)VKEY(&env->scope->swi.map, i - 1); mp_free(env->gwion->p, SwInfo, info); Switch sw = (Switch)VVAL(&env->scope->swi.map, i - 1); - free_map(env->gwion->p, sw->cases); +//if(sw->cases) +// free_map(env->gwion->p, sw->cases); free_switch(env->gwion->p, sw); } _scope_clear(&env->scope->swi); @@ -112,6 +124,7 @@ ANN m_bool switch_dup(const Env env, const m_int value, const loc_t pos) { const Switch sw = (Switch)_scope_back(&env->scope->swi); if(map_get(sw->cases, (vtype)value)) ERR_B(pos, "duplicated cases value %i", value) + sw->ok = 1; return GW_OK; } @@ -153,14 +166,18 @@ ANN m_uint switch_idx(const Env env) { return sw->default_case_index; } -ANN void switch_pop(const Env env) { +ANN m_bool switch_pop(const Env env) { _scope_pop(&env->scope->swi); + return GW_OK; } -ANN void switch_end(const Env env) { +ANN m_bool switch_end(const Env env, const loc_t pos) { const Switch sw = (Switch)_scope_pop(&env->scope->swi); const vtype index = VKEY(&env->scope->swi.map, VLEN(&env->scope->swi.map) - 1); + sw->ok = 1; + if(!VLEN(sw->cases) && !VLEN(&sw->exp)) + ERR_B(pos, "switch statement with no cases.") map_remove(&env->scope->swi.map, index); free_switch(env->gwion->p, sw); -// return sw->ok = 1; + return GW_OK; } diff --git a/src/oo/type.c b/src/oo/type.c index dc9efe32..e6979bb1 100644 --- a/src/oo/type.c +++ b/src/oo/type.c @@ -49,9 +49,11 @@ ANN Type find_common_anc(const restrict Type lhs, const restrict Type rhs) { #define describe_find(name, t) \ ANN t find_##name(const Type type, const Symbol xid) { \ + if(type->nspc) { \ const t val = nspc_lookup_##name##0(type->nspc, xid); \ if(val) \ return val; \ + } \ return type->parent ? find_##name(type->parent, xid) : NULL; \ } describe_find(value, Value) diff --git a/src/parse/check.c b/src/parse/check.c index 95d39887..b2e62da8 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -46,7 +46,12 @@ ANN static inline void decl_##a(const Nspc nspc, const Value v) { \ nspc->info->b += v->type->size; \ } describe_check_decl(member, offset) -describe_check_decl(static, class_data_size) +//describe_check_decl(static, class_data_size) +ANN static inline void decl_static(const Nspc nspc, const Value v) { \ + SET_FLAG(v, static); + v->offset = nspc->info->class_data_size; + nspc->info->class_data_size += v->type->size; +} ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) { const Value v = var->value; @@ -80,9 +85,9 @@ ANN Type check_td(const Env env, Type_Decl *td) { td->xid = str2list(env, t->name, &depth); if(depth) { - Exp base = new_exp_prim_int(env->gwion->p, 0, 0), e = base; + Exp base = new_exp_prim_int(env->gwion->p, 0, new_loc(env->gwion->p, __LINE__)), e = base; for(m_uint i = 0; i < depth - 1; ++i) { - e = (e->next = new_exp_prim_int(env->gwion->p, 0, 0)); + e = (e->next = new_exp_prim_int(env->gwion->p, 0, new_loc(env->gwion->p, __LINE__))); } td->array = new_array_sub(env->gwion->p, base); } @@ -91,7 +96,7 @@ ANN Type check_td(const Env env, Type_Decl *td) { ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE Var_Decl_List list = decl->list; - + CHECK_BO(switch_decl(env, exp_self(decl)->pos)) if(!decl->td->xid) { const Type t = check_td(env, decl->td); CHECK_OO(t) @@ -102,15 +107,15 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE if(decl->td->xid->xid == insert_symbol("auto")) { // should be better CHECK_BO(scan1_exp(env, exp_self(decl))) CHECK_BO(scan2_exp(env, exp_self(decl))) + if(decl->type == t_auto) + ERR_O(td_pos(decl->td), "can't infer type."); } if(GET_FLAG(decl->type , template)) { const Type t = typedef_base(decl->type); CHECK_BO(traverse_template(env, t->def)) } - m_uint scope; const m_bool global = GET_FLAG(decl->td, global); - if(global) - scope = env_push_global(env); + const m_uint scope = !global ? env->scope->depth : env_push_global(env); do { const Var_Decl var = list->self; const Value v = var->value; @@ -330,7 +335,7 @@ ANN static Type_List mk_type_list(const Env env, const Type type) { } ID_List id = NULL; for(m_uint i = vector_size(&v) + 1; --i;) - id = prepend_id_list(env->gwion->p, (Symbol)vector_at(&v, i - 1), id, 0); + id = prepend_id_list(env->gwion->p, (Symbol)vector_at(&v, i - 1), id, new_loc(env->gwion->p, __LINE__)); vector_release(&v); assert(id); Type_Decl* td = new_type_decl(env->gwion->p, id, 0); @@ -433,7 +438,7 @@ ANN static Func _find_template_match(const Env env, const Value v, const Exp_Cal continue; base = value->d.func_ref->def; def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, base->base->td, insert_symbol(v->name), - base->base->args), base->d.code, base->flag, base->pos); + base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->p, base->pos)); def->tmpl = new_tmpl_list(env->gwion->p, base->tmpl->list, (m_int)i); SET_FLAG(def, template); } @@ -581,7 +586,8 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) { } if(arg || e) ERR_O(exp_self(exp)->pos, "argument number does not match for lambda") - l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, NULL, l->name, l->args), l->code, 0, exp_self(exp)->pos); + l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, NULL, l->name, l->args), + l->code, 0, loc_cpy(env->gwion->p, exp_self(exp)->pos)); CHECK_BO(traverse_func_def(env, l->def)) if(env->class_def) SET_FLAG(l->def, member); @@ -858,7 +864,7 @@ stmt_func_xxx(loop, Stmt_Loop,, !(!check_exp(env, stmt->cond) || check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1) stmt_func_xxx(switch, Stmt_Switch,, !(!check_exp(env, stmt->val) || cond_type(env, stmt->val) < 0 || !switch_add(env, stmt) || - check_breaks(env, stmt_self(stmt), stmt->stmt) < 0 || !switch_pop(env)) ? 1 : -1) + check_breaks(env, stmt_self(stmt), stmt->stmt) < 0 || switch_pop(env) < 0) ? 1 : -1) stmt_func_xxx(auto, Stmt_Auto,, do_stmt_auto(env, stmt)) ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) { GWDEBUG_EXE @@ -896,6 +902,7 @@ describe_check_stmt_stack(breaks, break) ANN Value case_value(const Exp exp); ANN static m_bool check_stmt_case(const Env env, const Stmt_Exp stmt) { GWDEBUG_EXE + CHECK_BB(switch_inside(env, stmt_self(stmt)->pos)); const Type t = check_exp(env, stmt->val); CHECK_OB(t); if(isa(t, t_int) < 0) @@ -920,13 +927,8 @@ ANN static m_bool check_stmt_jump(const Env env, const Stmt_Jump stmt) { GWDEBUG if(!m) ERR_B(stmt_self(stmt)->pos, "label '%s' used but not defined", s_name(stmt->name)) const Stmt_Jump ref = (Stmt_Jump)map_get(m, (vtype)stmt->name); - if(!ref) { - for(m_uint i = 0; i < map_size(m); ++i) { - const Stmt_Jump s = (Stmt_Jump)map_at(m, i); - vector_release(&s->data.v); - } + if(!ref) ERR_B(stmt_self(stmt)->pos, "label '%s' used but not defined", s_name(stmt->name)) - } vector_add(&ref->data.v, (vtype)stmt); return GW_OK; } diff --git a/src/parse/did_you_mean.c b/src/parse/did_you_mean.c index 5be923d8..e936ec4b 100644 --- a/src/parse/did_you_mean.c +++ b/src/parse/did_you_mean.c @@ -52,7 +52,7 @@ ANN static void ressembles(const Vector v, const Nspc nspc, const char* name) { ANN void did_you_mean_nspc(Nspc nspc, const char* name) { struct Vector_ v; vector_init(&v); - do ressembles(&v, nspc, name); + do ressembles(&v, nspc, name); while((nspc = nspc->parent)); for(m_uint i = 0; i < vector_size(&v); ++i) gw_err("\t(did you mean '%s'?)\n", (m_str)vector_at(&v, i)); @@ -64,7 +64,7 @@ ANN void did_you_mean_type(Type type, const char* name) { struct Vector_ v; vector_init(&v); do ressembles(&v, t->nspc, name); - while((t = t->parent)); + while((t = t->parent) && t->nspc); for(m_uint i = 0; i < vector_size(&v); ++i) gw_err("\t(did you mean '%s'?)\n", (m_str)vector_at(&v, i)); did_you_mean_nspc(type->nspc, name); diff --git a/src/parse/func.c b/src/parse/func.c index 130592bc..3ad395ed 100644 --- a/src/parse/func.c +++ b/src/parse/func.c @@ -12,6 +12,8 @@ ANN static void free_func(Func a, Gwion gwion) { if(GET_FLAG(a, template)) { free_tmpl_list(gwion->p, a->def->tmpl); + free_func_base(gwion->p, a->def->base); + free_loc(gwion->p, a->def->pos); mp_free(gwion->p, Func_Def, a->def); } if(a->code) diff --git a/src/parse/operator.c b/src/parse/operator.c index bfc20339..d8ce2f38 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -85,10 +85,12 @@ ANN m_bool add_op(const Gwion gwion, const Nspc nspc, const struct Op_Import* op if(!n->info->op_map.ptr) continue; const Vector v = (Vector)map_get(&n->info->op_map, (vtype)opi->op); - if(v && (mo = operator_find(v, opi->lhs, opi->rhs))) - ERR_B(opi->pos, "operator '%s', for type '%s' and '%s' already imported", + if(v && (mo = operator_find(v, opi->lhs, opi->rhs))) { + env_err(gwion->env, opi->pos, "operator '%s', for type '%s' and '%s' already imported", op2str(opi->op), opi->lhs ? opi->lhs->name : NULL, - opi->rhs ? opi->rhs->name : NULL) + opi->rhs ? opi->rhs->name : NULL); + return GW_ERROR; + } } while((n = n->parent)); Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op); if(!v) { @@ -170,7 +172,7 @@ ANN Type op_check(const Env env, struct Op_Import* opi) { nspc = nspc->parent; } while(nspc); if(opi->op == op_cast || (ret != t_null && opi->op != op_impl)) - err_msg(opi->pos, "%s %s %s: no match found for operator", + env_err(env, opi->pos, "%s %s %s: no match found for operator", type_name(opi->lhs), op2str(opi->op), type_name(opi->rhs)); return NULL; } @@ -186,8 +188,8 @@ ANN m_bool operator_set_func(const struct Op_Import* opi) { ANN static m_bool handle_instr(const Emitter emit, const M_Operator* mo) { if(mo->func) { - const Instr instr = emit_add_instr(emit, RegPushImm); - instr->m_val = (m_uint)mo->func->code; + const Instr instr = emit_add_instr(emit, mo->func->code ? RegPushImm : PushStaticCode); + instr->m_val = ((m_uint)mo->func->code ?:(m_uint)mo->func); return emit_exp_call1(emit, mo->func); } emit_add_instr(emit, mo->instr); diff --git a/src/parse/scan0.c b/src/parse/scan0.c index d91216bc..1ef5fc73 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -23,7 +23,7 @@ ANN static Value mk_class(const Env env, const Type base) { } ANN static inline m_bool scan0_defined(const Env env, const Symbol s, const loc_t pos) { - if(nspc_lookup_type1(env->curr, s)) + if(nspc_lookup_type0(env->curr, s)) ERR_B(pos, "type '%s' already defined", s_name(s)); return already_defined(env, s, pos); } @@ -43,7 +43,7 @@ ANN m_bool scan0_stmt_fptr(const Env env, const Stmt_Fptr stmt) { GWDEBUG_EXE return GW_OK; } -ANN static m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { GWDEBUG_EXE +ANN /*static */ m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { GWDEBUG_EXE CHECK_BB(env_access(env, stmt->ext->flag, stmt_self(stmt)->pos)) const Type base = known_type(env, stmt->ext); CHECK_OB(base) @@ -61,7 +61,8 @@ ANN static m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { GWDEBUG SET_FLAG(t, empty); } else { const ae_flag flag = base->def ? base->def->flag : 0; - const Class_Def def = new_class_def(env->gwion->p, flag, stmt->xid, stmt->ext, NULL, stmt->ext->xid->pos); + const Class_Def def = new_class_def(env->gwion->p, flag, stmt->xid, stmt->ext, NULL, + loc_cpy(env->gwion->p, td_pos(stmt->ext))); CHECK_BB(scan0_class_def(env, def)) stmt->type = def->base.type; } @@ -107,7 +108,7 @@ ANN static Type union_type(const Env env, const Nspc nspc, const Symbol s, const return t; } -ANN static m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { GWDEBUG_EXE +ANN /* static */m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { GWDEBUG_EXE CHECK_BB(env_storage(env, stmt->flag, stmt_self(stmt)->pos)) if(stmt->xid) { CHECK_BB(scan0_defined(env, stmt->xid, stmt_self(stmt)->pos)) @@ -120,19 +121,33 @@ ANN static m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { GWDEB stmt->value->owner = nspc; nspc_add_value(nspc, stmt->xid, stmt->value); SET_FLAG(stmt->value, checked | stmt->flag); - if(env->class_def && !GET_FLAG(stmt, static)) + if(env->class_def && !GET_FLAG(stmt, static)) { SET_FLAG(stmt->value, member); + SET_FLAG(stmt, member); + } if(!stmt->type_xid) SET_FLAG(t, op); } else if(stmt->type_xid) { const Nspc nspc = !GET_FLAG(stmt, global) ? env->curr : env->global_nspc; stmt->type = union_type(env, nspc, stmt->type_xid, 1); + } else { + const Nspc nspc = !GET_FLAG(stmt, global) ? + env->curr : env->global_nspc; + const Type t = union_type(env, nspc, insert_symbol("union"), 1); + stmt->value = new_value(env->gwion->p, t, "union"); + stmt->value->owner_class = env->class_def; + stmt->value->owner = nspc; + nspc_add_value(nspc, stmt->xid, stmt->value); + SET_FLAG(stmt->value, checked | stmt->flag); + } return GW_OK; } -ANN static m_bool scan0_Stmt(const Env env, const Stmt stmt) { GWDEBUG_EXE +ANN static m_bool scan0_stmt_switch(const Env env, const Stmt_Switch stmt); +ANN static m_bool scan0_stmt_code(const Env env, const Stmt_Code stmt); +ANN static m_bool scan0_stmt(const Env env, const Stmt stmt) { GWDEBUG_EXE if(stmt->stmt_type == ae_stmt_fptr) return scan0_stmt_fptr(env, &stmt->d.stmt_fptr); if(stmt->stmt_type == ae_stmt_type) @@ -141,11 +156,24 @@ ANN static m_bool scan0_Stmt(const Env env, const Stmt stmt) { GWDEBUG_EXE return scan0_stmt_enum(env, &stmt->d.stmt_enum); if(stmt->stmt_type == ae_stmt_union) return scan0_stmt_union(env, &stmt->d.stmt_union); + if(stmt->stmt_type == ae_stmt_code) + return scan0_stmt_code(env, &stmt->d.stmt_code); + if(stmt->stmt_type == ae_stmt_switch) + return scan0_stmt_switch(env, &stmt->d.stmt_switch); return GW_OK; } -ANN static m_bool scan0_Stmt_List(const Env env, Stmt_List l) { GWDEBUG_EXE - do CHECK_BB(scan0_Stmt(env, l->stmt)) +ANN static m_bool scan0_stmt_list(const Env env, Stmt_List l); +ANN static m_bool scan0_stmt_switch(const Env env, const Stmt_Switch stmt) { +// CHECK_BB(scan0_exp(env, stmt->val)) + return scan0_stmt(env, stmt->stmt); +} +ANN static m_bool scan0_stmt_code(const Env env, const Stmt_Code stmt) { GWDEBUG_EXE + return stmt->stmt_list ? scan0_stmt_list(env, stmt->stmt_list) : GW_OK; +} + +ANN static m_bool scan0_stmt_list(const Env env, Stmt_List l) { GWDEBUG_EXE + do CHECK_BB(scan0_stmt(env, l->stmt)) while((l = l->next)); return GW_OK; } @@ -179,11 +207,17 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def class_def) { return t; } +ANN static m_bool scan0_func_def(const Env env, const Func_Def def) { + return def->d.code ? scan0_stmt(env, def->d.code) : GW_OK; +} + ANN static m_bool scan0_section(const Env env, const Section* section) { GWDEBUG_EXE if(section->section_type == ae_section_stmt) - return scan0_Stmt_List(env, section->d.stmt_list); + return scan0_stmt_list(env, section->d.stmt_list); if(section->section_type == ae_section_class) return scan0_class_def(env, section->d.class_def); + if(section->section_type == ae_section_func) + return scan0_func_def(env, section->d.func_def); return GW_OK; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 1e0b36a5..d7e85abc 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -8,8 +8,7 @@ #include "optim.h" #include "vm.h" #include "parse.h" - -//#define FAKE_FUNC ((Func)1) +#include "traverse.h" ANN m_bool scan0_class_def(const Env env, const Class_Def class_def); ANN /* static */ m_bool scan1_exp(const Env env, Exp exp); @@ -17,16 +16,16 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list); ANN m_bool scan1_class_def(const Env env, const Class_Def class_def); ANN static m_bool scan1_stmt(const Env env, Stmt stmt); -ANN static Type void_type(const Env env, const Type_Decl* td, const loc_t pos) { +ANN static Type void_type(const Env env, const Type_Decl* td) { const Type t = known_type(env, td); CHECK_OO(t) if(t->size) return t; - ERR_O(pos, "cannot declare variables of size '0' (i.e. 'void')...") + ERR_O(td_pos(td), "cannot declare variables of size '0' (i.e. 'void')...") } ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) { - const Type t = void_type(env, decl->td, exp_self(decl)->pos); + const Type t = void_type(env, decl->td); CHECK_OO(t); if(decl->td->xid && decl->td->xid->xid == insert_symbol("auto") && decl->type) return decl->type; @@ -49,27 +48,28 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) { return t; } -ANN m_bool scan1_exp_decl(const Env env, Exp_Decl* decl) { GWDEBUG_EXE +ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos)) Var_Decl_List list = decl->list; ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl); CHECK_OB(decl->type) const m_bool global = GET_FLAG(decl->td, global); - m_uint scope = !global ? env->scope->depth : env_push_global(env); + const m_uint scope = !global ? env->scope->depth : env_push_global(env); const Nspc nspc = !global ? env->curr : env->global_nspc; - if(global) - scope = env_push_global(env); do { Type t = decl->type; const Var_Decl var = list->self; const Value former = nspc_lookup_value0(env->curr, var->xid); CHECK_BB(isres(env, var->xid, exp_self(decl)->pos)) - if(!decl->td->exp && decl->td->xid->xid != insert_symbol("auto") && - former && (!env->class_def || // cuold be better - (!GET_FLAG(env->class_def, template) || !GET_FLAG(env->class_def, scan1)))) + if(former && !decl->td->exp && +/*!(decl->td->xid->xid == insert_symbol("auto") && former->type != t_auto) &&*/ +//(decl->td->xid->xid == insert_symbol("auto") && former->type != t_auto) && +//(!env->class_def || +// (!GET_FLAG(env->class_def, template) || !GET_FLAG(env->class_def, scan1)))) + (!env->class_def || !(GET_FLAG(env->class_def, template) || GET_FLAG(env->class_def, scan1)))) ERR_B(var->pos, "variable %s has already been defined in the same scope...", s_name(var->xid)) - if(var->array && decl->type != t_undefined) { + if(var->array && decl->type != t_undefined && decl->type != t_auto) { if(var->array->exp) { if(GET_FLAG(decl->td, ref)) ERR_B(td_pos(decl->td), "ref array must not have array expression.\n" @@ -90,7 +90,7 @@ ANN m_bool scan1_exp_decl(const Env env, Exp_Decl* decl) { GWDEBUG_EXE v->owner = !env->func ? env->curr : NULL; v->owner_class = env->scope->depth ? NULL : env->class_def; } while((list = list->next)); - decl->type = decl->list->self->value->type; + ((Exp_Decl*)decl)->type = decl->list->self->value->type; if(global) env_pop(env, scope); return GW_OK; @@ -120,9 +120,11 @@ ANN static inline m_bool scan1_exp_cast(const Env env, const Exp_Cast* cast) { G ANN static m_bool scan1_exp_post(const Env env, const Exp_Postfix* post) { GWDEBUG_EXE CHECK_BB(scan1_exp(env, post->exp)) - return post->exp->meta == ae_meta_var ? 1 : - err_msg(post->exp->pos, "post operator '%s' cannot be used" - " on non-mutable data-type...", op2str(post->op)); + if(post->exp->meta == ae_meta_var) + return GW_OK; + env_err(env, post->exp->pos, "post operator '%s' cannot be used" + " on non-mutable data-type...", op2str(post->op)); + return GW_ERROR; } ANN static m_bool scan1_exp_call(const Env env, const Exp_Call* exp_call) { GWDEBUG_EXE @@ -167,7 +169,8 @@ describe_ret_nspc(auto, Stmt_Auto,, !(scan1_exp(env, stmt->exp) < 0 || scan1_stmt(env, stmt->body) < 0) ? 1 : -1) describe_ret_nspc(loop, Stmt_Loop,, !(scan1_exp(env, stmt->cond) < 0 || scan1_stmt(env, stmt->body) < 0) ? 1 : -1) -describe_ret_nspc(switch, Stmt_Switch,, scan1_exp(env, stmt->val)) +describe_ret_nspc(switch, Stmt_Switch,, !(scan1_exp(env, stmt->val) < 0 || + scan1_stmt(env, stmt->stmt) < 0) ? 1 : -1) describe_ret_nspc(if, Stmt_If,, !(scan1_exp(env, stmt->cond) < 0 || scan1_stmt(env, stmt->if_body) < 0 || (stmt->else_body && scan1_stmt(env, stmt->else_body) < 0)) ? 1 : -1) @@ -188,6 +191,8 @@ ANN static inline m_bool scan1_stmt_case(const Env env, const Stmt_Exp stmt) { G } ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum stmt) { GWDEBUG_EXE + if(!stmt->t) + CHECK_BB(scan0_stmt_enum(env, stmt)) ID_List list = stmt->list; do { CHECK_BB(already_defined(env, list->xid, stmt_self(stmt)->pos)) @@ -211,21 +216,27 @@ ANN static m_bool scan1_args(const Env env, Arg_List list) { GWDEBUG_EXE if(var->xid) CHECK_BB(isres(env, var->xid, var->pos)) if(list->td) - CHECK_OB((list->type = void_type(env, list->td, var->pos))) + CHECK_OB((list->type = void_type(env, list->td))) } while((list = list->next)); return GW_OK; } -ANN m_bool scan1_stmt_fptr(const Env env, const Stmt_Fptr ptr) { GWDEBUG_EXE - CHECK_OB((ptr->base->ret_type = known_type(env, ptr->base->td))) - return ptr->base->args ? scan1_args(env, ptr->base->args) : GW_OK; +ANN m_bool scan1_stmt_fptr(const Env env, const Stmt_Fptr stmt) { GWDEBUG_EXE + if(!stmt->type) + CHECK_BB(scan0_stmt_fptr(env, stmt)) + CHECK_OB((stmt->base->ret_type = known_type(env, stmt->base->td))) + return stmt->base->args ? scan1_args(env, stmt->base->args) : GW_OK; } ANN static inline m_bool scan1_stmt_type(const Env env, const Stmt_Type stmt) { GWDEBUG_EXE + if(!stmt->type) + CHECK_BB(scan0_stmt_type(env, stmt)) return stmt->type->def ? scan1_class_def(env, stmt->type->def) : 1; } ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) { GWDEBUG_EXE + if(!stmt->value) + CHECK_BB(scan0_stmt_union(env, stmt)) Decl_List l = stmt->l; const m_uint scope = union_push(env, stmt); if(stmt->xid || stmt->type_xid) { @@ -235,7 +246,9 @@ ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) { GWDEBUG_EXE do { const Exp_Decl decl = l->self->d.exp_decl; SET_FLAG(decl.td, checked | stmt->flag); - if(GET_FLAG(stmt, static)) + if(GET_FLAG(stmt, member)) + SET_FLAG(decl.td, member); + else if(GET_FLAG(stmt, static)) SET_FLAG(decl.td, static); CHECK_BB(scan1_exp(env, l->self)) } while((l = l->next)); @@ -335,6 +348,8 @@ ANN static m_bool scan1_class_body(const Env env, const Class_Def class_def) { } ANN m_bool scan1_class_def(const Env env, const Class_Def class_def) { GWDEBUG_EXE + if(!class_def->base.type) + CHECK_BB(scan0_class_def(env, class_def)) if(tmpl_class_base(class_def->tmpl)) return GW_OK; if(class_def->base.ext) diff --git a/src/parse/scan2.c b/src/parse/scan2.c index ca8e30c8..6de500ea 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -32,10 +32,8 @@ ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE const Type type = decl->type; if(GET_FLAG(type, template) && !GET_FLAG(type, scan2)) CHECK_BB(scan2_exp_decl_template(env, decl)) - m_uint scope; const m_bool global = GET_FLAG(decl->td, global); - if(global) - scope = env_push_global(env); + const m_uint scope = !global ? env->scope->depth : env_push_global(env); do { const Var_Decl var = list->self; const Array_Sub array = var->array; @@ -51,7 +49,7 @@ ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE ANN static Value arg_value(MemPool p, const Arg_List list) { const Var_Decl var = list->var_decl; if(!var->value) { - const Value v = new_value(p, list->type, s_name(var->xid)); + const Value v = new_value(p, list->type, var->xid ? s_name(var->xid) : (m_str)__func__); if(list->td) v->flag = list->td->flag | ae_flag_arg; return v; @@ -91,7 +89,7 @@ ANN static Value scan2_func_assign(const Env env, const Func_Def d, ANN m_bool scan2_stmt_fptr(const Env env, const Stmt_Fptr ptr) { GWDEBUG_EXE const Func_Def def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, ptr->base->td, ptr->base->xid, ptr->base->args), - NULL,ptr->base->td->flag, stmt_self(ptr)->pos); + NULL,ptr->base->td->flag, loc_cpy(env->gwion->p, stmt_self(ptr)->pos)); def->base->ret_type = ptr->base->ret_type; ptr->base->func = new_func(env->gwion->p, s_name(ptr->base->xid), def); ptr->value->d.func_ref = ptr->base->func; @@ -265,11 +263,8 @@ ANN static Map scan2_label_map(const Env env) { GWDEBUG_EXE ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) { GWDEBUG_EXE if(stmt->is_label) { const Map m = scan2_label_map(env); - if(map_get(m, (vtype)stmt->name)) { - const Stmt_Jump l = (Stmt_Jump)map_get(m, (vtype)stmt->name); - vector_release(&l->data.v); + if(map_get(m, (vtype)stmt->name)) ERR_B(stmt_self(stmt)->pos, "label '%s' already defined", s_name(stmt->name)) - } map_set(m, (vtype)stmt->name, (vtype)stmt); vector_init(&stmt->data.v); } @@ -307,7 +302,7 @@ ANN static m_bool scan2_stmt_list(const Env env, Stmt_List list) { GWDEBUG_EXE ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) { GWDEBUG_EXE const m_bool base = tmpl_list_base(f->tmpl); const m_bool tmpl = GET_FLAG(overload, template); - if(isa(overload->type, t_function) < 0) + if(isa(overload->type, t_function) < 0 || isa(overload->type, t_fptr) > 0) ERR_B(f->pos, "function name '%s' is already used by another value", overload->name) if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f, template))) ERR_B(f->pos, "must overload template function with template") @@ -344,8 +339,12 @@ ANN2(1,2) static Value func_value(const Env env, const Func f, ADD_REF(v); nspc_add_value(env->curr, f->def->base->xid, v); } else /* if(!GET_FLAG(f->def, template)) */ { +// f->next = overload->d.func_ref->next; +if(overload->d.func_ref) { f->next = overload->d.func_ref->next; overload->d.func_ref->next = f; +} else + overload->d.func_ref = f; } return v; } diff --git a/src/parse/template.c b/src/parse/template.c index 424fa2d2..565aeed3 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -25,10 +25,10 @@ ANEW ANN static Vector get_types(const Env env, Type t) { } ANEW ANN static ID_List id_list_copy(MemPool p, ID_List src) { - const ID_List list = new_id_list(p, src->xid, src->pos); + const ID_List list = new_id_list(p, src->xid, loc_cpy(p, src->pos)); ID_List tmp = list; while((src = src->next)) - tmp = (tmp->next = new_id_list(p, src->xid, src->pos)); + tmp = (tmp->next = new_id_list(p, src->xid, loc_cpy(p, src->pos))); return list; } @@ -116,7 +116,8 @@ ANN m_bool template_match(ID_List base, Type_List call) { ANN static Class_Def template_class(const Env env, const Class_Def def, const Type_List call) { const Symbol name = template_id(env, def, call); const Type t = nspc_lookup_type1(env->curr, name); - return t ? t->def : new_class_def(env->gwion->p, def->flag, name, def->base.ext, def->body, def->pos); + return t ? t->def : new_class_def(env->gwion->p, def->flag, name, def->base.ext, def->body, + loc_cpy(env->gwion->p, def->pos)); } ANN m_bool template_push_types(const Env env, ID_List base, Type_List tl) { diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index b93a72a6..5e2e59b7 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -76,7 +76,7 @@ ANEW ANN m_str tl2str(const Env env, Type_List tl) { ANN static inline void* type_unknown(const Env env, const ID_List id) { char path[id_list_len(id)]; type_path(path, id); - err_msg(id->pos, "unknown type '%s'", path); + env_err(env, id->pos, "unknown type '%s'", path); did_you_mean_nspc(env->curr, s_name(id->xid)); return NULL; } diff --git a/src/vm/driver.c b/src/vm/driver.c index b91a1a4e..37b095b6 100644 --- a/src/vm/driver.c +++ b/src/vm/driver.c @@ -14,7 +14,7 @@ ANN Driver* new_driver(MemPool p) { Driver* di = (Driver*)mp_alloc(p, BBQ); di->func = dummy_driver; - di->run = vm_run; +// di->run = vm_run; di->driver = (DriverData*)mp_alloc(p, DriverData); di->is_running = 1; return di; diff --git a/src/vm/shreduler.c b/src/vm/shreduler.c index 89646740..c63be569 100644 --- a/src/vm/shreduler.c +++ b/src/vm/shreduler.c @@ -45,8 +45,10 @@ ANN static void unwind(const VM_Shred shred) { const m_bit exec = (m_bit)((Instr)vector_back(code->instr))->opcode; if(exec == eFuncReturn) { code = *(VM_Code*)(shred->mem - SZ_INT*3); +if(!code)break; REM_REF(code, shred->info->vm->gwion); shred->mem -= *(m_uint*)(shred->mem - SZ_INT); +// shred->mem -= *(m_uint*)(shred->mem - SZ_INT*4); } else break; } } @@ -54,12 +56,13 @@ ANN static void unwind(const VM_Shred shred) { ANN static void shreduler_child(const Vector v) { for(m_uint i = vector_size(v) + 1; --i;) { const VM_Shred child = (VM_Shred)vector_at(v, i - 1); - unwind(child); +// unwind(child); shreduler_remove(child->info->vm->shreduler, child, 1); } } ANN static void shreduler_erase(const Shreduler s, struct ShredTick_ *tk) { + unwind(tk->self); if(tk->parent) shreduler_parent(tk->self, &tk->parent->child); if(tk->child.ptr) @@ -82,7 +85,7 @@ ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool er tk->prev = tk->next = NULL; if(erase) { shreduler_erase(s, tk); - _release(out->info->me, out); + /*shred_*/release(out->info->me, out); } MUTEX_UNLOCK(s->mutex); } diff --git a/src/vm/vm.c b/src/vm/vm.c index b1753ef1..8da46b8c 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -49,18 +49,6 @@ uint32_t gw_rand(uint32_t s[2]) { return ret; } -VM* new_vm(MemPool p) { - VM* vm = (VM*)mp_alloc(p, VM); - vector_init(&vm->ugen); - vm->bbq = new_driver(p); - vm->shreduler = (Shreduler)mp_alloc(p, Shreduler); - vector_init(&vm->shreduler->shreds); - MUTEX_SETUP(vm->shreduler->mutex); - vm->shreduler->bbq = vm->bbq; - gw_seed(vm->rand, (uint64_t)time(NULL)); - return vm; -} - void vm_remove(const VM* vm, const m_uint index) { const Vector v = (Vector)&vm->shreduler->shreds; LOOP_OPTIM @@ -76,8 +64,8 @@ ANN void free_vm(VM* vm) { vector_release(&vm->ugen); if(vm->bbq) free_driver(vm->bbq, vm); - mp_free(vm->gwion->p, Shreduler, vm->shreduler); MUTEX_CLEANUP(vm->shreduler->mutex); + mp_free(vm->gwion->p, Shreduler, vm->shreduler); mp_free(vm->gwion->p, VM, vm); } @@ -165,7 +153,7 @@ ANN static inline VM_Shred init_fork_shred(const VM_Shred shred, const Instr ins DISPATCH(); #define INT_OP(op, ...) OP(m_int, SZ_INT, op, __VA_ARGS__) -#define FLOAT_OP(op) OP(m_float, SZ_FLOAT, op) +#define FLOAT_OP(op, ...) OP(m_float, SZ_FLOAT, op, __VA_ARGS__) #define LOGICAL(t, sz0, sz, op)\ reg -= sz0;\ @@ -235,9 +223,28 @@ __attribute__((hot)) (m_int)(*(m_float*)(reg-SZ_INT))); \ DISPATCH() + +#define STRINGIFY_NX(a) #a +#define STRINGIFY(a) STRINGIFY_NX(a) +#define PPCAT_NX(A, B) A ## B +#define PPCAT(A, B) PPCAT_NX(A, B) + +#if defined(__clang__) +#define COMPILER clang +#define UNINITIALIZED "-Wuninitialized") +#elif defined(__GNUC__) || defined(__GNUG__) +#define COMPILER GCC +#define UNINITIALIZED "-Wmaybe-uninitialized") +#endif + +#define PRAGMA_PUSH() \ +_Pragma(STRINGIFY(COMPILER diagnostic push)) \ +_Pragma(STRINGIFY(COMPILER diagnostic ignored UNINITIALIZED) +#define PRAGMA_POP() _Pragma(STRINGIFY(COMPILER diagnostic pop)) \ + __attribute__ ((optimize("-O2"))) ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] -static const void* dispatch[] = { + static const void* dispatch[] = { &®setimm, &®pushimm, &®pushfloat, &®pushother, &®pushaddr, &®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr, @@ -291,6 +298,8 @@ static const void* dispatch[] = { register m_bit next; while((shred = shreduler_get(s))) { register VM_Code code = shred->code; +//if(!code->instr) +// exit(2); register m_uint* ip = code->instr->ptr + OFFSET; register size_t pc = shred->pc; @@ -448,8 +457,10 @@ intrassign: intradd: INT_R(+) intrsub: INT_R(-) intrmul: INT_R(*) -intrdiv: INT_R(/, TEST0(m_int, -SZ_INT)) -intrmod: INT_R(%, TEST0(m_int, -SZ_INT)) +//intrdiv: INT_R(/, TEST0(m_int, -SZ_INT)) +//intrmod: INT_R(%, TEST0(m_int, -SZ_INT)) +intrdiv: INT_R(/, TEST0(m_int, SZ_INT)) +intrmod: INT_R(%, TEST0(m_int, SZ_INT)) intrsl: INT_R(<<) intrsr: INT_R(>>) intrsand: INT_R(&) @@ -536,7 +547,7 @@ firassign: firadd: FI_R(+) firsub: FI_R(-) firmul: FI_R(*) -firdiv: FI_R(/, TEST0(m_int, -SZ_INT)) +firdiv: FI_R(/, TEST0(m_float, SZ_INT)) itof: reg -= SZ_INT - SZ_FLOAT; @@ -559,8 +570,10 @@ timeadv: setcode: a.code = *(VM_Code*)(reg-SZ_INT); funcptr: +PRAGMA_PUSH() if(!GET_FLAG((VM_Code)a.code, builtin)) goto funcusr; +PRAGMA_POP() funcmember: reg -= SZ_INT; a.code = *(VM_Code*)reg; @@ -592,7 +605,9 @@ overflow: if(overflow_(mem, shred)) Except(shred, "StackOverflow"); next: +PRAGMA_PUSH() goto *dispatch[next]; +PRAGMA_POP() funcusrend: ip = (code = a.code)->instr->ptr + OFFSET; pc = 0; @@ -623,7 +638,7 @@ sporkexp: *(m_uint*)(a.child->mem + i) = *(m_uint*)(mem+i); DISPATCH() forkend: - fork_launch(a.child->info->me, instr->m_val2); + fork_launch(vm, a.child->info->me, instr->m_val2); sporkend: *(M_Object*)(reg-SZ_INT) = a.child->info->me; DISPATCH() @@ -749,15 +764,18 @@ staticfloat: DISPATCH() staticother: // LOOP_OPTIM - for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT) - *(m_uint*)(reg+i) = *(m_uint*)((m_bit*)instr->m_val + i); +// for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT) +// *(m_uint*)(reg+i) = *(m_uint*)((m_bit*)instr->m_val + i); + memcpy(reg, (m_bit*)instr->m_val, instr->m_val2); reg += instr->m_val2; DISPATCH() dotfunc: assert(a.obj); reg += SZ_INT; dotstaticfunc: +PRAGMA_PUSH() *(VM_Code*)(reg-SZ_INT) = ((Func)vector_at(a.obj->vtable, instr->m_val))->code; +PRAGMA_POP() DISPATCH() staticcode: instr->m_val = (m_uint)(a.code = (*(VM_Code*)reg = ((Func)instr->m_val)->code)); @@ -797,8 +815,22 @@ DISPATCH() } while(s->curr); MUTEX_UNLOCK(s->mutex); } - if(!vm->bbq->is_running) - return; - if(vector_size(&vm->ugen)) - vm_ugen_init(vm); -} \ No newline at end of file +} + +static void vm_run_audio(const VM *vm) { + vm_run(vm); + vm_ugen_init(vm); +} + +VM* new_vm(MemPool p, const m_bool audio) { + VM* vm = (VM*)mp_alloc(p, VM); + vector_init(&vm->ugen); + vm->bbq = new_driver(p); + vm->bbq->run = audio ? vm_run_audio : vm_run; + vm->shreduler = (Shreduler)mp_alloc(p, Shreduler); + vector_init(&vm->shreduler->shreds); + MUTEX_SETUP(vm->shreduler->mutex); + vm->shreduler->bbq = vm->bbq; + gw_seed(vm->rand, (uint64_t)time(NULL)); + return vm; +} diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index e59f28c4..8db52b6f 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -14,7 +14,7 @@ #include "gwion.h" #include "import.h" -ANN static void free_code_instr(const Vector v, const Gwion gwion) { +ANN /*static*/ void free_code_instr(const Vector v, const Gwion gwion) { for(m_uint i = vector_size(v) + 1; --i;) { const Instr instr = (Instr)vector_at(v, i - 1); const f_freearg f = (f_freearg)(map_get(&gwion->freearg, instr->opcode) ?: @@ -23,14 +23,18 @@ ANN static void free_code_instr(const Vector v, const Gwion gwion) { f(instr, gwion); mp_free(gwion->p, Instr, instr); } - free_vector(gwion->p, v); +// free_vector(gwion->p, v); } +ANN static void _free_code_instr(const Vector v, const Gwion gwion) { + free_code_instr(v, gwion); + free_vector(gwion->p, v); +} ANN static void free_vm_code(VM_Code a, Gwion gwion) { if(a->memoize) memoize_end(gwion->p, a->memoize); if(!GET_FLAG(a, builtin)) - free_code_instr(a->instr, gwion); + _free_code_instr(a->instr, gwion); xfree(a->name); mp_free(gwion->p , VM_Code, a); } diff --git a/tests/import/Makefile b/tests/import/Makefile index 561da2f7..f6253570 100644 --- a/tests/import/Makefile +++ b/tests/import/Makefile @@ -3,7 +3,7 @@ CC ?= gcc SRC = ${NAME}.c OBJ = $(SRC:.c=.o) -CFLAGS = -std=c99 $(../../gwion -k 2>&1 | grep CFLAGS) ${INC} ${CICFLAGS} +CFLAGS = -std=c99 $(../../gwion -k 2>&1 | grep CFLAGS | sed 's/CFLAGS: //') ${INC} ${CICFLAGS} -Wall -Wextra LDFLAGS = $(../../gwion -k 2>&1 | grep LDFLAGS) # os specific diff --git a/tests/import/array.c b/tests/import/array.c index a256dda6..43ba2ad8 100644 --- a/tests/import/array.c +++ b/tests/import/array.c @@ -12,7 +12,7 @@ MFUN(test_mfun){} GWION_IMPORT(array_test) { Type t_invalid_var_name; - CHECK_BB((t_invalid_var_name = gwi_mk_type(gwi, "invalid_var_name", SZ_INT, t_object))) + CHECK_OB((t_invalid_var_name = gwi_mk_type(gwi, "invalid_var_name", SZ_INT, t_object))) CHECK_BB(gwi_class_ini(gwi, t_invalid_var_name, NULL, NULL)) CHECK_BB(gwi_item_ini(gwi,"int[]", "int_array")) CHECK_BB(gwi_item_end(gwi, 0, NULL)) // import array var diff --git a/tests/import/class_template.c b/tests/import/class_template.c index 0a6a26de..f1ab7f5d 100644 --- a/tests/import/class_template.c +++ b/tests/import/class_template.c @@ -23,10 +23,6 @@ static CTOR(class_template_ctor) { /**(M_Object*)(o->data + SZ_INT) = new_array(t2->size, 0, t2->array_depth);*/ } -static MFUN(class_template_set) { - -} - GWION_IMPORT(class_template) { Type t_class_template; const m_str list[2] = { "A", "B" }; diff --git a/tests/import/enum.c b/tests/import/enum.c index 8618b58c..c50129bf 100644 --- a/tests/import/enum.c +++ b/tests/import/enum.c @@ -62,7 +62,7 @@ GWION_IMPORT(enum_test) { CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM7", 7)) CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM8", 8)) CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM9", 9)) - CHECK_BB(gwi_enum_end(gwi)) + CHECK_OB(gwi_enum_end(gwi)) CHECK_OB(gwi_class_end(gwi)) return GW_OK; diff --git a/tests/import/extend_array.c b/tests/import/extend_array.c index 7e124090..e72c24f2 100644 --- a/tests/import/extend_array.c +++ b/tests/import/extend_array.c @@ -16,8 +16,8 @@ GWION_IMPORT(extend_array_test) { Type t_array_ext; CHECK_OB((t_array_ext = gwi_mk_type(gwi, "ArrayExt", SZ_INT, NULL))) CHECK_BB(gwi_class_ini(gwi, t_array_ext, NULL, NULL)) - Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "float"), 0), 0); - Exp e = new_exp_prim_int(gwi->gwion->st->p, 1, 0); + Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "float"), GWI_LOC), 0); + Exp e = new_exp_prim_int(gwi->gwion->st->p, 1, GWI_LOC); Array_Sub array = new_array_sub(gwi->gwion->st->p, e); add_type_decl_array(td, array); CHECK_BB(gwi_class_ext(gwi, td)) diff --git a/tests/import/extend_event.c b/tests/import/extend_event.c index dc38469a..2f2cb06f 100644 --- a/tests/import/extend_event.c +++ b/tests/import/extend_event.c @@ -18,7 +18,7 @@ GWION_IMPORT(extend_event_test) { Type t_ev ; CHECK_OB((t_ev = gwi_mk_type(gwi, "Ev", SZ_INT , NULL))) CHECK_BB(gwi_class_ini(gwi, t_ev, ev_ctor, NULL)) - Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "Event"), 0), 0); + Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "Event"), GWI_LOC), 0); CHECK_BB(gwi_class_ext(gwi, td)) CHECK_BB(gwi_class_end(gwi)) return GW_OK; diff --git a/tests/import/extend_pair.c b/tests/import/extend_pair.c index 801841cd..33dfae1e 100644 --- a/tests/import/extend_pair.c +++ b/tests/import/extend_pair.c @@ -19,9 +19,9 @@ GWION_IMPORT(extend_pair_test) { CHECK_BB(gwi_tmpl_ini(gwi, 2, types)) CHECK_BB(gwi_class_ini(gwi, t_pair_ext, NULL, NULL)) CHECK_BB(gwi_tmpl_end(gwi)) - Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "Pair"), 0), 0); - Type_Decl* td0 = new_type_decl(gwi->gwion->st->p ,new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "A"), 0), 0); - Type_Decl* td1 = new_type_decl(gwi->gwion->st->p ,new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "B"), 0), 0); + Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "Pair"), GWI_LOC), 0); + Type_Decl* td0 = new_type_decl(gwi->gwion->st->p ,new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "A"), GWI_LOC), 0); + Type_Decl* td1 = new_type_decl(gwi->gwion->st->p ,new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "B"), GWI_LOC), 0); Type_List tl1 = new_type_list(gwi->gwion->st->p, td1, NULL); Type_List tl0 = new_type_list(gwi->gwion->st->p,td0, tl1); td->types = tl0; diff --git a/tests/import/invalid_type1.c b/tests/import/invalid_type1.c index 99bed3f1..b9e72bde 100644 --- a/tests/import/invalid_type1.c +++ b/tests/import/invalid_type1.c @@ -8,7 +8,6 @@ #include "instr.h" #include "import.h" -static MFUN(test_mfun){} GWION_IMPORT(invalid_type1_test) { Type t_invalid_var_type; CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", diff --git a/tests/import/invalid_type2.c b/tests/import/invalid_type2.c index b2242ecb..1dc5c8e2 100644 --- a/tests/import/invalid_type2.c +++ b/tests/import/invalid_type2.c @@ -8,7 +8,6 @@ #include "instr.h" #include "import.h" -static MFUN(test_mfun){} GWION_IMPORT(invalid_type2_test) { Type t_invalid_var_type ; CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", diff --git a/tests/import/invalid_type3.c b/tests/import/invalid_type3.c index f8e8c9fb..2a207d20 100644 --- a/tests/import/invalid_type3.c +++ b/tests/import/invalid_type3.c @@ -9,7 +9,6 @@ #include "instr.h" #include "import.h" -static MFUN(test_mfun){} GWION_IMPORT(invalid_type3_test) { Type t_invalid_var_type ; CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, ".invalid_var_type", diff --git a/tests/import/no_import.c b/tests/import/no_import.c index 9a10bead..39ff84dc 100644 --- a/tests/import/no_import.c +++ b/tests/import/no_import.c @@ -7,6 +7,3 @@ #include "object.h" #include "instr.h" #include "import.h" - - -static MFUN(test_mfun){} diff --git a/util b/util index c09b4ef1..d225ae77 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit c09b4ef1af52812816a0cb2fde12e0d81ccc3b06 +Subproject commit d225ae77804624fbfd1d904a1dd028e392139f62