]> Nishi Git Mirror - gwion.git/commitdiff
:art: Auto declarations
authorfennecdjay <astor.jeremie@wanadoo.fr>
Mon, 8 Apr 2019 19:01:20 +0000 (21:01 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Mon, 8 Apr 2019 19:01:20 +0000 (21:01 +0200)
ast
include/type.h
src/emit/emit.c
src/lib/engine.c
src/lib/instr.c
src/oo/type.c
src/parse/check.c
src/parse/scan1.c
src/vm/vm.c
tests/tree/auto_decl.gw [new file with mode: 0644]
tests/tree/decl_exp_array.gw [new file with mode: 0644]

diff --git a/ast b/ast
index be6de5a94edfab64aa61709c2a9ff3f1de5b9bff..5d45e48e6b8c5961f6aeb2d8ce437434e9dd5fe1 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit be6de5a94edfab64aa61709c2a9ff3f1de5b9bff
+Subproject commit 5d45e48e6b8c5961f6aeb2d8ce437434e9dd5fe1
index 228891f376ae19cf8df45dd4c1b75fade5191fbd..df3b0c97a48ad5b92e78e9bd5a1532def752022b 100644 (file)
@@ -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);
index 0eb218a0adee5f5169ead50e3d86bd6fbc0015d7..d503c7cc2d183df61d989fcd8d0c8ece2efc9714 100644 (file)
@@ -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;
index ff4608ab83316415a6ec27f5b7625a2a0fcef41e..c3f05af7e3068ec51272f3e6c4dbdb185342382d 100644 (file)
@@ -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))
index 8eb7cfbbcb36de2ae8ff467fcfee0735c5ad1ebb..957cdd681cd532a80f1e0f3db42a3062e5dc3931 100644 (file)
@@ -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);
 }
 
index 815604ec849211825866efbfeba4b4a5a5408efc..26c8c609864bc8aa8c43af99ba14f6a955e80446 100644 (file)
@@ -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);
index 4c509fbe0d74f007075109e42b3c180cfef164fb..12cdc22a60531f668042e7120e228d2f32bd9789 100644 (file)
@@ -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")
 }
 
index 44fe66f5d8bdfb7efdd5fa960871ba73b5b7ecbb..01a11933b511d676ced48f7f3be86aee3875eeca 100644 (file)
@@ -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);
index c85c41b5e21df7f7f0f1f904082a8aeec87b54e7..89be89fd1b6dd26ecb84f5709a26d55b4211f819 100644 (file)
@@ -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[] = {
     &&regsetimm,
     &&regpushimm, &&regpushfloat, &&regpushother, &&regpushaddr,
diff --git a/tests/tree/auto_decl.gw b/tests/tree/auto_decl.gw
new file mode 100644 (file)
index 0000000..e90c962
--- /dev/null
@@ -0,0 +1,2 @@
+<<<new float[3] @=> auto i>>>;
+<<<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 (file)
index 0000000..2a9d80a
--- /dev/null
@@ -0,0 +1,2 @@
+<<<~~ new int[2] ~~ i>>>;
+<<<i>>>;
\ No newline at end of file