]> Nishi Git Mirror - gwion.git/commitdiff
:art: Very crude commit to start with
authorfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 20 Oct 2019 23:55:25 +0000 (01:55 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 20 Oct 2019 23:55:25 +0000 (01:55 +0200)
src/emit/emit.c
src/lib/import.c
src/parse/check.c
src/parse/cpy_ast.c
src/parse/scan2.c
tests/import/func_tmpl.c [new file with mode: 0644]
tests/import/func_tmpl.gw [new file with mode: 0644]
tests/sh/import.sh

index 7e7ab4f91cf6afbdd7ac4ede63cf0ffd1cebc7aa..dc770fab729b262dde8120eb3f1a7a38ad9e1290 100644 (file)
@@ -321,7 +321,8 @@ ANN static m_bool emit_symbol_owned(const Emitter emit, const Exp_Primary* prim)
 
 ANN static m_bool emit_symbol_builtin(const Emitter emit, const Exp_Primary* prim) {
   const Value v = prim->value;
-  assert(!GET_FLAG(v, func));// regpushi(emit, (m_uint)v->d.func_ref);
+  if(GET_FLAG(v, func))
+    regpushi(emit, (m_uint)v->d.func_ref->def->d.dl_func_ptr);
   if(GET_FLAG(v, union)) {
     const m_uint size = v->type->size;
     const Instr instr = emit_kind(emit, size, exp_self(prim)->emit_var, dotstatic);
index f19215b29203501c4ede59bc96acf138d6da7aa8..27285ac7fa8322b989d9081365f3d25af7b8d6a4 100644 (file)
@@ -139,6 +139,61 @@ ANN static ID_List path_valid(const Env env, const m_str path, const loc_t pos)
   return list;
 }
 
+struct tmpl_checker {
+  const m_str str;
+  ID_List list;
+  const loc_t pos;
+};
+
+ANN static m_bool _tmpl_valid(const Gwion gwion, struct tmpl_checker *ck) {
+  m_str s = ck->str;
+  const size_t sz = strlen(s);
+  char c[sz + 1];
+  for(m_uint i = 0; i < sz; ++i) {
+    if(isalnum(s[i]) || s[i] == '_') {
+      c[i] = s[i];
+      continue;
+    }
+    if(s[i] == '~') {
+      if(!i || s[i+1] != '>')
+        break;
+      c[i] = '\0';
+      ck->list = new_id_list(gwion->mp, insert_symbol(gwion->st, c), ck->pos);
+      return GW_OK;
+    }
+    if(s[i] == ',') {
+      if(!i)break;
+      c[i] = '\0';
+      struct tmpl_checker _ck = { .str=ck->str + i + 1, .pos=ck->pos };
+      CHECK_BB(_tmpl_valid(gwion, &_ck))
+      ck->list->next = _ck.list;
+      return GW_OK;
+    }
+    break;
+  }
+  return GW_ERROR;
+}
+
+ANN static m_bool tmpl_check(const m_str str) {
+  if(str[0] != '<')
+    return 0; // TODO: make it GW_PASS
+  if(str[1] != '~')
+    return GW_ERROR;
+  return GW_OK;
+}
+
+ANN static ID_List tmpl_valid(const Gwi gwi, const m_str str) {
+  const m_bool ret = tmpl_check(str);
+  if(ret == GW_ERROR)
+    return (ID_List)GW_ERROR;
+  if(!ret)
+    return NULL;
+  struct tmpl_checker ck = { .str=str+2, .pos=gwi->loc };
+  if(_tmpl_valid(gwi->gwion, &ck) == GW_ERROR)
+    return (ID_List)GW_ERROR;
+  return ck.list;
+}
+
 ANN ID_List str2list(const Env env, const m_str path,
       m_uint* array_depth, const loc_t pos) {
   const m_uint sz = strlen(path);
@@ -469,12 +524,15 @@ ANN static Func_Def make_dll_as_fun(const Gwi gwi, DL_Func * dl_fun, ae_flag fla
   return func_def;
 }
 
-ANN static Func_Def template_fdef(const Gwi gwi) {
+ANN2(1) static Func_Def template_fdef(const Gwi gwi, const m_str name, const ID_List list) {
+  const Arg_List arg_list = make_dll_arg_list(gwi, &gwi->func);
+  m_uint depth;
+  Type_Decl *td = str2decl(gwi->gwion->env, gwi->func.type, &depth, gwi->loc);
   const Func_Def fdef = new_func_def(gwi->gwion->mp, new_func_base(gwi->gwion->mp,
-      NULL, NULL, NULL), NULL, 0, loc_cpy(gwi->gwion->mp, gwi->loc));
-  const ID_List list = templater_def(gwi->gwion->st, gwi);
+      td, insert_symbol(gwi->gwion->st, name), arg_list), NULL, ae_flag_builtin, loc_cpy(gwi->gwion->mp, gwi->loc));
   fdef->base->tmpl = new_tmpl(gwi->gwion->mp, list, -1);
-  SET_FLAG(fdef, template);
+  fdef->d.dl_func_ptr = (void*)(m_uint)gwi->func.addr;
+  SET_FLAG(fdef, template | ae_flag_builtin);
   return fdef;
 }
 
@@ -492,9 +550,13 @@ ANN static m_bool error_fdef(const Gwi gwi, const Func_Def fdef) {
 }
 
 ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag) {
-  CHECK_BB(name_valid(gwi, gwi->func.name));
-  DECL_OB(Func_Def, fdef, = !gwi->templater.n ?
-     make_dll_as_fun(gwi, &gwi->func, flag) : template_fdef(gwi))
+  const ID_List tmpl = tmpl_valid(gwi, gwi->func.name);
+  if(tmpl == (ID_List)GW_ERROR)
+    exit(16);
+  const m_str name = !tmpl ? gwi->func.name : strchr(gwi->func.name, '>') + 1;
+  CHECK_BB(name_valid(gwi, name));
+  DECL_OB(Func_Def, fdef, = !tmpl ?
+     make_dll_as_fun(gwi, &gwi->func, flag) : template_fdef(gwi, name, tmpl))
   if(gwi->gwion->env->class_def && GET_FLAG(gwi->gwion->env->class_def, template))
     return section_fdef(gwi, fdef);
   if(traverse_func_def(gwi->gwion->env, fdef) < 0)
@@ -572,7 +634,13 @@ ANN static Fptr_Def import_fptr(const Gwi gwi, DL_Func* dl_fun, ae_flag flag) {
   DECL_OO(ID_List, type_path, = str2list(env, dl_fun->type, &array_depth, gwi->loc))
   Type_Decl *type_decl = new_type_decl(env->gwion->mp, type_path);
   const Arg_List args = make_dll_arg_list(gwi, dl_fun);
-  Func_Base *base = new_func_base(env->gwion->mp, type_decl, insert_symbol(env->gwion->st, dl_fun->name), args);
+  const ID_List tmpl = tmpl_valid(gwi, gwi->func.name);
+  if(tmpl == (ID_List)GW_ERROR)
+    exit(16);
+  const m_str name = !tmpl ? gwi->func.name : strchr(gwi->func.name, '>') + 1;
+  Func_Base *base = new_func_base(env->gwion->mp, type_decl, insert_symbol(env->gwion->st, name), args);
+  if(tmpl)
+    base->tmpl = new_tmpl(gwi->gwion->mp, tmpl, -1);
   return new_fptr_def(env->gwion->mp, base, flag | ae_flag_builtin);
 }
 
index 0b208e4ecb5c3c53054ca26967ca75944f29a604..b4cc8fc7b174caa16c94cc8b8fcdd89313dca6f3 100644 (file)
@@ -594,6 +594,10 @@ CHECK_BO(check_call(env, exp))
         const Value value = template_get_ready(env, v, "template", i);
         if(!value)
           continue;
+        if(GET_FLAG(v, builtin)) {
+          SET_FLAG(value, builtin);
+          SET_FLAG(value->d.func_ref, builtin);
+        }
         const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
         SET_FLAG(fdef, template);
         fdef->base->tmpl->call = types;
index f881b055c736af3416fd8702b9e6c9dc7644f8b7..449af7a8260944cda14f8844863bee6e7f3029f1 100644 (file)
@@ -435,9 +435,11 @@ ANN static Stmt cpy_stmt(MemPool p, const Stmt src) {
 ANN Func_Def cpy_func_def(MemPool p, const Func_Def src) {
   Func_Def a = mp_calloc(p, Func_Def);
   a->base = cpy_func_base(p, src->base);
-  assert(!GET_FLAG(a, builtin));
-  if(src->d.code)
-    a->d.code = cpy_stmt(p, src->d.code);
+  if(!GET_FLAG(src, builtin)) {
+    if(src->d.code)
+      a->d.code = cpy_stmt(p, src->d.code);
+  } else
+    a->d.dl_func_ptr = src->d.dl_func_ptr;
   a->pos = loc_cpy(p, src->pos);
   a->flag = src->flag;
   return a;
index f9c1e2d82856a875e5964120cd1e010a6860e39e..a7c728fbd4cfee272207bb1cd9dc19042c79c525 100644 (file)
@@ -344,6 +344,13 @@ ANN2(1,2) static Value func_value(const Env env, const Func f,
   return v;
 }
 
+ANN static m_bool scan2_func_def_builtin(MemPool p, const Func func, const m_str name) {
+  SET_FLAG(func, builtin);
+  func->code = new_vm_code(p, NULL, func->def->stack_depth, func->flag, name);
+  func->code->native_func = (m_uint)func->def->d.dl_func_ptr;
+  return GW_OK;
+}
+
 ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const Value overload) {
   const m_str name = s_name(f->base->xid);
   const Func func = scan_new_func(env, f, name);
@@ -380,21 +387,20 @@ ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const
   } while(type && (type = type->e->parent) && (nspc = type->nspc));
   --i;
   const Symbol sym = func_symbol(env, env->curr->name, name, "template", i);
+puts(s_name(sym));
   nspc_add_value(env->curr, sym, value);
   if(!overload) {
-    func->vt_index = i;
+//    func->vt_index = i; // ?????
     ADD_REF(value)
     nspc_add_value(env->curr, f->base->xid, value);
     nspc_add_func(env->curr, f->base->xid, func);
   } else
     func->vt_index = ++overload->from->offset;
-  return GW_OK;
-}
-
-ANN static m_bool scan2_func_def_builtin(MemPool p, const Func func, const m_str name) {
-  SET_FLAG(func, builtin);
-  func->code = new_vm_code(p, NULL, func->def->stack_depth, func->flag, name);
-  func->code->native_func = (m_uint)func->def->d.dl_func_ptr;
+  if(GET_FLAG(f, builtin)) {
+    CHECK_BB(scan2_func_def_builtin(env->gwion->mp, func, func->name))
+    SET_FLAG(func, builtin);
+    SET_FLAG(value, builtin);
+  }
   return GW_OK;
 }
 
diff --git a/tests/import/func_tmpl.c b/tests/import/func_tmpl.c
new file mode 100644 (file)
index 0000000..fddf4d5
--- /dev/null
@@ -0,0 +1,24 @@
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "oo.h"
+#include "vm.h"
+#include "env.h"
+#include "type.h"
+#include "instr.h"
+#include "object.h"
+#include "gwion.h"
+#include "value.h"
+#include "operator.h"
+#include "import.h"
+#include "instr.h"
+
+static SFUN(func_tmpl_xfun) {
+  
+}
+
+GWION_IMPORT(func_tmpl) {
+  GWI_BB(gwi_func_ini(gwi, "void", "<~A~>test", func_tmpl_xfun))
+  GWI_BB(gwi_func_arg(gwi, "A", "i"))
+  GWI_BB(gwi_func_end(gwi, 0))
+  return GW_OK;
+}
diff --git a/tests/import/func_tmpl.gw b/tests/import/func_tmpl.gw
new file mode 100644 (file)
index 0000000..a963bb5
--- /dev/null
@@ -0,0 +1,2 @@
+test<~int~>(1);
+#!test(1);
index 6dd5eeba8985d23a70f2c97f8a6aa654acd87b41..e44592d8f40038871cd497ceba9ca36eae47a5e4 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-# [test] #55
+# [test] #56
 
 n=0
 [ "$1" ] && n="$1"