From 7ff872f6ce29f2e86390231a49e7c80c69971b75 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Mon, 21 Oct 2019 01:55:25 +0200 Subject: [PATCH] :art: Very crude commit to start with --- src/emit/emit.c | 3 +- src/lib/import.c | 84 +++++++++++++++++++++++++++++++++++---- src/parse/check.c | 4 ++ src/parse/cpy_ast.c | 8 ++-- src/parse/scan2.c | 22 ++++++---- tests/import/func_tmpl.c | 24 +++++++++++ tests/import/func_tmpl.gw | 2 + tests/sh/import.sh | 2 +- 8 files changed, 128 insertions(+), 21 deletions(-) create mode 100644 tests/import/func_tmpl.c create mode 100644 tests/import/func_tmpl.gw diff --git a/src/emit/emit.c b/src/emit/emit.c index 7e7ab4f9..dc770fab 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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); diff --git a/src/lib/import.c b/src/lib/import.c index f19215b2..27285ac7 100644 --- a/src/lib/import.c +++ b/src/lib/import.c @@ -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); } diff --git a/src/parse/check.c b/src/parse/check.c index 0b208e4e..b4cc8fc7 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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; diff --git a/src/parse/cpy_ast.c b/src/parse/cpy_ast.c index f881b055..449af7a8 100644 --- a/src/parse/cpy_ast.c +++ b/src/parse/cpy_ast.c @@ -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; diff --git a/src/parse/scan2.c b/src/parse/scan2.c index f9c1e2d8..a7c728fb 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -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 index 00000000..fddf4d50 --- /dev/null +++ b/tests/import/func_tmpl.c @@ -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 index 00000000..a963bb52 --- /dev/null +++ b/tests/import/func_tmpl.gw @@ -0,0 +1,2 @@ +test<~int~>(1); +#!test(1); diff --git a/tests/sh/import.sh b/tests/sh/import.sh index 6dd5eeba..e44592d8 100644 --- a/tests/sh/import.sh +++ b/tests/sh/import.sh @@ -1,5 +1,5 @@ #!/bin/bash -# [test] #55 +# [test] #56 n=0 [ "$1" ] && n="$1" -- 2.43.0