From: fennecdjay Date: Mon, 8 Apr 2019 19:01:20 +0000 (+0200) Subject: :art: Auto declarations X-Git-Tag: nightly~2544 X-Git-Url: http://10.11.0.4:5575/?a=commitdiff_plain;h=1f810fc4eae6129a24dc1b43dfc72c1dc1ba337c;p=gwion.git :art: Auto declarations --- diff --git a/ast b/ast index be6de5a9..5d45e48e 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit be6de5a94edfab64aa61709c2a9ff3f1de5b9bff +Subproject commit 5d45e48e6b8c5961f6aeb2d8ce437434e9dd5fe1 diff --git a/include/type.h b/include/type.h index 228891f3..df3b0c97 100644 --- a/include/type.h +++ b/include/type.h @@ -21,7 +21,7 @@ struct Type_ { Type t_void, t_int, t_bool, t_float, t_dur, t_time, t_now, t_complex, t_polar, t_vec3, t_vec4, t_null, t_object, t_shred, t_fork, t_event, t_ugen, t_string, t_ptr, t_array, t_gack, - t_function, t_fptr, t_vararg, t_lambda, t_class, t_union, t_undefined; + t_function, t_fptr, t_vararg, t_lambda, t_class, t_union, t_undefined, t_auto; ANN2(1,3) ANEW Type new_type(MemPool, const m_uint xid, const m_str name, const Type); ANEW ANN Type type_copy(MemPool, const Type type); diff --git a/src/emit/emit.c b/src/emit/emit.c index 0eb218a0..d503c7cc 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -219,11 +219,17 @@ ANN2(1,2) m_bool emit_instantiate_object(const Emitter emit, const Type type, const Array_Sub arr, const uint is_ref) { Array_Sub array = arr; if(type->array_depth) { - if(!array) { // from typeof xxx[]... + if(!array || array->depth < type->array_depth) { // from typeof xxx[]... Exp base = new_exp_prim_int(emit->gwion->p, 0, 0), e = base; - for(m_uint i = 0; i < type->array_depth; ++i) + 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)); - array = new_array_sub(emit->gwion->p, base); + if(array) { + Exp array_base = array->exp; + while(array_base->next) + array_base = array_base->next; + array_base->next = base; + } else + array = new_array_sub(emit->gwion->p, base); } assert(array->exp); ArrayInfo* info = emit_array_extend_inner(emit, type, array->exp); @@ -479,7 +485,6 @@ ANN static m_bool prim_gack(const Emitter emit, const Exp_Primary* primary) { offset += e->type->size; if(e->type != emit->env->class_def) ADD_REF(e->type); -puts(e->type->name); } while((e = e->next)); if(emit_exp(emit, exp, 0) < 0) { free_vector(emit->gwion->p, v); @@ -541,7 +546,6 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Var_Decl va const m_bool is_obj = isa(type, t_object) > 0; const uint emit_addr = ((is_ref && !array) || isa(type, t_object) < 0) ? emit_var : 1; -puts(v->type->name); if(is_obj && (is_array || !is_ref)) CHECK_BB(emit_instantiate_object(emit, type, array, is_ref)) f_instr *exec = (f_instr*)allocmember; @@ -555,8 +559,15 @@ puts(v->type->name); if(is_obj && (is_array || !is_ref)) { const Instr assign = emit_add_instr(emit, ObjectAssign); assign->m_val = emit_var; - if(is_array && !emit->env->scope->depth) + const size_t missing_depth = type->array_depth - (array ? array->depth : 0); + if((is_array || missing_depth) && !emit->env->scope->depth) ADD_REF(type) + if(missing_depth) { + const Instr push = emit_add_instr(emit, Reg2Reg); + push->m_val = -(1 + missing_depth) * SZ_INT; + const Instr instr = emit_add_instr(emit, RegPop); + instr->m_val = (missing_depth + 1) * SZ_INT; + } } return GW_OK; } @@ -606,7 +617,6 @@ ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) { GWDE Var_Decl_List list = decl->list; const uint ref = GET_FLAG(decl->td, ref) || type_ref(decl->type); 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; diff --git a/src/lib/engine.c b/src/lib/engine.c index ff4608ab..c3f05af7 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -37,6 +37,8 @@ ANN static m_bool import_core_libs(const Gwi gwi) { CHECK_OB((t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL))) // size = SZ_INT to enable declarations CHECK_OB((t_class = gwi_mk_type(gwi, "Class", SZ_INT, NULL))) CHECK_BB(gwi_add_type(gwi, t_class)) + CHECK_OB((t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL))) // size = SZ_INT to enable declarations + CHECK_BB(gwi_add_type(gwi, t_auto)) SET_FLAG(t_class, abstract); CHECK_OB((t_void = gwi_mk_type(gwi, "void", 0, NULL))) CHECK_BB(gwi_add_type(gwi, t_void)) diff --git a/src/lib/instr.c b/src/lib/instr.c index 8eb7cfbb..957cdd68 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -23,16 +23,7 @@ INSTR(DTOR_EOC) { GWDEBUG_EXE shred->info->mp = (MemPool)instr->m_val; const M_Object o = *(M_Object*)MEM(0); o->type_ref = o->type_ref->parent; -printf("'obj %p %p %s\n", o, shred->info->me, shred->info->me->type_ref->name); -//free_object( __release(o, shred); -//shreduler_remove(shred->tick->shreduler, shred, 0); -//vector_rem2(&shred->tick->shreduler->shreds, shred); -//++shred->info->me->ref; -//REM_REF(shred->code, shred->info->vm->gwion); -// _release(shred->info->me, shred); -// _release(shred->info->me, shred); -//free_vm_shred(shred); vm_shred_exit(shred); } diff --git a/src/oo/type.c b/src/oo/type.c index 815604ec..26c8c609 100644 --- a/src/oo/type.c +++ b/src/oo/type.c @@ -84,7 +84,7 @@ ANN Type array_type(const Env env, const Type base, const m_uint depth) { const Type t = new_type(env->gwion->p, t_array->xid, base->name, t_array); t->name = s_name(sym); t->size = SZ_INT; - t->array_depth = depth; + t->array_depth = depth + base->array_depth; t->d.base_type = base; t->nspc = t_array->nspc; ADD_REF(t->nspc); diff --git a/src/parse/check.c b/src/parse/check.c index 4c509fbe..12cdc22a 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -78,14 +78,21 @@ ANN Type check_td(const Env env, Type_Decl *td) { CHECK_BO(scan1_exp(env, td->exp)) CHECK_BO(scan2_exp(env, td->exp)) CHECK_OO(check_exp(env, td->exp)) -//assert(actual_type(td->exp->type)); -//printf("HERE %p %p %p\n", t_class, td->exp->type, td->exp->type->d.base_type); - if(!actual_type(td->exp->type) || (isa(td->exp->type, t_class) < 0 && actual_type(td->exp->type) == t_class)) + const Type t = actual_type(td->exp->type); + if(!t || (isa(td->exp->type, t_class) < 0 && t == t_class)) ERR_O(td->exp->pos, "Expression must be of type '%s', not '%s'\n" "maybe you meant typeof(Expression)", t_class->name, td->exp->type->name); m_uint depth; - td->xid = str2list(env->gwion->st, actual_type(td->exp->type)->name, &depth); - return actual_type(td->exp->type); + td->xid = str2list(env->gwion->st, t->name, &depth); + + if(depth) { + Exp base = new_exp_prim_int(env->gwion->p, 0, 0), e = base; + for(m_uint i = 0; i < depth - 1; ++i) { + e = (e->next = new_exp_prim_int(env->gwion->p, 0, 0)); + } + td->array = new_array_sub(env->gwion->p, base); + } + return t; } ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE @@ -98,6 +105,10 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE CHECK_BO(scan1_exp(env, exp_self(decl))) CHECK_BO(scan2_exp(env, exp_self(decl))) } + 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(GET_FLAG(decl->type , template)) { const Type t = typedef_base(decl->type); CHECK_BO(traverse_template(env, t->def)) @@ -121,8 +132,8 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE SET_FLAG(v, abstract); if(isa(decl->type, t_fptr) > 0) CHECK_BO(check_fptr_decl(env, var)) - SET_FLAG(v, checked | ae_flag_used); - nspc_add_value(env->curr, var->xid, v); + SET_FLAG(v, checked | ae_flag_used); + nspc_add_value(env->curr, var->xid, v); } while((list = list->next)); if(global) env_pop(env, scope); @@ -599,10 +610,12 @@ ANN Type check_exp_call1(const Env env, const Exp_Call *exp) { } ANN static Type check_exp_binary(const Env env, const Exp_Binary* bin) { GWDEBUG_EXE - struct Op_Import opi = { .op=bin->op, .lhs=check_exp(env, bin->lhs), - .rhs=check_exp(env, bin->rhs), .data=(uintptr_t)bin }; - CHECK_OO(opi.lhs) - CHECK_OO(opi.rhs) + CHECK_OO(check_exp(env, bin->lhs)) + if(bin->rhs->exp_type == ae_exp_decl && bin->rhs->d.exp_decl.type == t_auto) + bin->rhs->type = bin->rhs->d.exp_decl.type = bin->lhs->type; + CHECK_OO(check_exp(env, bin->rhs)) + struct Op_Import opi = { .op=bin->op, .lhs=bin->lhs->type, + .rhs=bin->rhs->type, .data=(uintptr_t)bin }; OP_RET(bin, "binary") } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 44fe66f5..01a11933 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -28,14 +28,14 @@ ANN static Type void_type(const Env env, const Type_Decl* td, const uint pos) { 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); CHECK_OO(t); + if(decl->td->xid && decl->td->xid->xid == insert_symbol("auto") && decl->type) + return decl->type; if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, ref)) ERR_O(exp_self(decl)->pos, "Type '%s' is abstract, declare as ref. (use @)", t->name) if(GET_FLAG(t, private) && t->owner != env->curr) ERR_O(exp_self(decl)->pos, "can't use private type %s", t->name) if(GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0)) ERR_O(exp_self(decl)->pos, "can't use protected type %s", t->name) -// if(GET_FLAG(decl->td, global) && env->class_def) -// ERR_O(exp_self(decl)->pos, "can't declare variable global inside class.") if(env->class_def) { if(!env->scope->depth) { if(!env->func && !GET_FLAG(decl->td, static)) @@ -64,11 +64,12 @@ ANN m_bool scan1_exp_decl(const Env env, Exp_Decl* decl) { GWDEBUG_EXE const Var_Decl var = list->self; const Value former = nspc_lookup_value0(env->curr, var->xid); CHECK_BB(isres(var->xid)) - if(!decl->td->exp && former && (!env->class_def || + 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)))) ERR_B(var->pos, "variable %s has already been defined in the same scope...", s_name(var->xid)) - if(var->array) { + if(var->array && decl->type != t_undefined) { if(var->array->exp) CHECK_BB(scan1_exp(env, var->array->exp)) t = array_type(env, decl->type, var->array->depth); diff --git a/src/vm/vm.c b/src/vm/vm.c index c85c41b5..89be89fd 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -244,7 +244,6 @@ __attribute__((hot)) __attribute__ ((optimize("-O2"))) ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] -//printf("here %p\n", vm->shreduler); static const void* dispatch[] = { &®setimm, &®pushimm, &®pushfloat, &®pushother, &®pushaddr, diff --git a/tests/tree/auto_decl.gw b/tests/tree/auto_decl.gw new file mode 100644 index 00000000..e90c9623 --- /dev/null +++ b/tests/tree/auto_decl.gw @@ -0,0 +1,2 @@ +<< auto i>>>; +<<>>; \ No newline at end of file diff --git a/tests/tree/decl_exp_array.gw b/tests/tree/decl_exp_array.gw new file mode 100644 index 00000000..2a9d80ae --- /dev/null +++ b/tests/tree/decl_exp_array.gw @@ -0,0 +1,2 @@ +<<<~~ new int[2] ~~ i>>>; +<<>>; \ No newline at end of file