From 281b317c5a7516dc1cfccf79cad36aa477a59ac3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Sat, 29 May 2021 14:13:31 +0200 Subject: [PATCH] Update libcmdapp --- ast | 2 +- fmt | 2 +- libcmdapp | 2 +- src/parse/check.c | 115 +---------------------------------- src/parse/check_traits.c | 127 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 117 deletions(-) create mode 100644 src/parse/check_traits.c diff --git a/ast b/ast index aa209a79..f0007dce 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit aa209a7911f18d117fd133e1c52fbc2c6ddb181b +Subproject commit f0007dceb4ce87d3c1882fa385be805fa1c21b62 diff --git a/fmt b/fmt index d58f01e7..14d746b2 160000 --- a/fmt +++ b/fmt @@ -1 +1 @@ -Subproject commit d58f01e7f844cab87613a8084dee3e69d1582cac +Subproject commit 14d746b2d31b99395d8035c8450353afc059eac5 diff --git a/libcmdapp b/libcmdapp index 4c97e4ed..84f5a692 160000 --- a/libcmdapp +++ b/libcmdapp @@ -1 +1 @@ -Subproject commit 4c97e4ed96a958d75c2657f8744c7e86e8a66a30 +Subproject commit 84f5a69293c50e66f9edb584a71e6526c8b66646 diff --git a/src/parse/check.c b/src/parse/check.c index c9c88ef8..5a2ff50e 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1667,120 +1667,7 @@ if(isa(dlist->self->value->type, env->gwion->type[et_compound]) > 0) return false; } -ANN static bool request_var(const Env env, const Type t, const Value request) { - const Value value = nspc_lookup_value0(t->nspc, insert_symbol(request->name)); - if(!value) { - gwerr_basic("missing requested variable", NULL, NULL, - request->from->filename, request->from->loc, 0); - return false; - } - bool error = true; - if(isa(value->type, request->type) < 0) { - gwerr_basic("invalid variable type", NULL, NULL, - value->from->filename, value->from->loc, 0); - // can we point to the type decl? - error = false; - } - if(GET_FLAG(value, const) && !GET_FLAG(request, const)) { - gwerr_basic("variable differs in {/}constness{0}", NULL, NULL, - value->from->filename, value->from->loc, 0); - // can we point to the flag? - error = false; - } - if(error) - return true; - gwerr_secondary("from requested variable", request->from->filename, request->from->loc); - return error; -} - -ANN static bool check_trait_variables(const Env env, const Type t, const Trait trait) { - bool error = false; - for(m_uint i = 0; i < vector_size(&trait->requested_values); i++) { - const Value request = (Value)vector_at(&trait->requested_values, i); - if(!request_var(env, t, request)) - error = true; - } - return error; -} - -ANN static bool request_fun(const Env env, const Type t, const Func_Def request) { - const Value v = nspc_lookup_value0(t->nspc, request->base->xid); -if(v) { - if(isa(v->type, env->gwion->type[et_function]) < 0 || is_fptr(env->gwion, v->type)) { - gwerr_basic("is not a function", NULL, NULL, - v->from->filename, v->from->loc, 0); - return false; - } - Func f = v->d.func_ref; - do { - if(compat_func(f->def, request) > 0) { - if(!GET_FLAG(f->def->base, abstract)) - return true; - } - } while ((f = f->next)); -} - if(!GET_FLAG(request->base, abstract)){ - const m_uint scope = env_push_type(env, t); - const Func_Def cpy = cpy_func_def(env->gwion->mp, request); - const m_bool ret = traverse_func_def(env, cpy); - env_pop(env, scope); - if(ret > 0){ - Section *section = new_section_func_def(env->gwion->mp, cpy); - const Ast ast = new_ast(env->gwion->mp, section, NULL); - Ast last = t->info->cdef->body; - while(last->next) - last = last->next; - last->next = ast; - return true; - } else - free_func_def(env->gwion->mp, cpy); - } - if(!v) { - gwerr_basic("missing requested function", NULL, NULL, - env->name, request->base->pos, 0); - return false; - } - return true; -} - -ANN static bool check_trait_functions(const Env env, const Type t, const Trait trait) { - bool error = false; - for(m_uint i = 0; i < vector_size(&trait->requested_funcs); i++) { - const Func_Def request = (Func_Def)vector_at(&trait->requested_funcs, i); - if(!request_fun(env, t, request)) - error = true; - } - return error; -} - -ANN2(1,2,3) static inline bool trait_nodup(Type t, const Symbol trait, ID_List list) { - bool nodup = true; - do { - while(list) { - if(trait == list->xid) -// return false; - nodup = false; - list = list->next; - } - } while ((t = t->info->parent)); - return nodup; -} - -ANN static bool check_trait_requests(const Env env, const Type t, const ID_List list) { - const Trait trait = nspc_lookup_trait1(env->curr, list->xid); - if(!trait_nodup(t, list->xid, list->next)) { - gwerr_secondary("duplicated trait", trait->filename, trait->loc); - return false; - } - const bool value_error = check_trait_variables(env, t, trait); - const bool funcs_error = check_trait_functions(env, t, trait); - if(!value_error && !funcs_error) - return true; - const Value request = (Value)vector_front(&trait->requested_values); - gwerr_secondary("from trait", request->from->filename, trait->loc); - return false; -} - +ANN bool check_trait_requests(const Env env, const Type t, const ID_List list); ANN static m_bool _check_class_def(const Env env, const Class_Def cdef) { const Type t = cdef->base.type; if(cdef->base.ext) diff --git a/src/parse/check_traits.c b/src/parse/check_traits.c new file mode 100644 index 00000000..b830a970 --- /dev/null +++ b/src/parse/check_traits.c @@ -0,0 +1,127 @@ +#include +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" +#include "vm.h" +#include "instr.h" +#include "traverse.h" +#include "template.h" +#include "gwion.h" +#include "object.h" +#include "operator.h" +#include "import.h" +#include "parse.h" + +ANN static bool request_var(const Env env, const Type t, const Value request) { + const Value value = nspc_lookup_value0(t->nspc, insert_symbol(request->name)); + if(!value) { + gwerr_basic("missing requested variable", NULL, NULL, + request->from->filename, request->from->loc, 0); + return false; + } + bool error = true; + if(isa(value->type, request->type) < 0) { + gwerr_basic("invalid variable type", NULL, NULL, + value->from->filename, value->from->loc, 0); + // can we point to the type decl? + error = false; + } + if(GET_FLAG(value, const) && !GET_FLAG(request, const)) { + gwerr_basic("variable differs in {/}constness{0}", NULL, NULL, + value->from->filename, value->from->loc, 0); + // can we point to the flag? + error = false; + } + if(error) + return true; + gwerr_secondary("from requested variable", request->from->filename, request->from->loc); + return error; +} + +ANN static bool check_trait_variables(const Env env, const Type t, const Trait trait) { + bool error = false; + for(m_uint i = 0; i < vector_size(&trait->requested_values); i++) { + const Value request = (Value)vector_at(&trait->requested_values, i); + if(!request_var(env, t, request)) + error = true; + } + return error; +} + +ANN static bool request_fun(const Env env, const Type t, const Func_Def request) { + const Value v = nspc_lookup_value0(t->nspc, request->base->xid); +if(v) { + if(isa(v->type, env->gwion->type[et_function]) < 0 || is_fptr(env->gwion, v->type)) { + gwerr_basic("is not a function", NULL, NULL, + v->from->filename, v->from->loc, 0); + return false; + } + Func f = v->d.func_ref; + do { + if(compat_func(f->def, request) > 0) { + if(!GET_FLAG(f->def->base, abstract)) + return true; + } + } while ((f = f->next)); +} + if(!GET_FLAG(request->base, abstract)){ + const m_uint scope = env_push_type(env, t); + const Func_Def cpy = cpy_func_def(env->gwion->mp, request); + const m_bool ret = traverse_func_def(env, cpy); + env_pop(env, scope); + if(ret > 0){ + Section *section = new_section_func_def(env->gwion->mp, cpy); + const Ast ast = new_ast(env->gwion->mp, section, NULL); + Ast last = t->info->cdef->body; + while(last->next) + last = last->next; + last->next = ast; + return true; + } else + free_func_def(env->gwion->mp, cpy); + } + if(!v) { + gwerr_basic("missing requested function", NULL, NULL, + env->name, request->base->pos, 0); + return false; + } + return true; +} + +ANN static bool check_trait_functions(const Env env, const Type t, const Trait trait) { + bool error = false; + for(m_uint i = 0; i < vector_size(&trait->requested_funcs); i++) { + const Func_Def request = (Func_Def)vector_at(&trait->requested_funcs, i); + if(!request_fun(env, t, request)) + error = true; + } + return error; +} + +ANN2(1,2,3) static inline bool trait_nodup(Type t, const Symbol trait, ID_List list) { + bool nodup = true; + do { + while(list) { + if(trait == list->xid) + nodup = false; + list = list->next; + } + } while ((t = t->info->parent)); + return nodup; +} + +ANN bool check_trait_requests(const Env env, const Type t, const ID_List list) { + const Trait trait = nspc_lookup_trait1(env->curr, list->xid); + if(!trait_nodup(t, list->xid, list->next)) { + gwerr_secondary("duplicated trait", trait->filename, trait->loc); + return false; + } + const bool value_error = check_trait_variables(env, t, trait); + const bool funcs_error = check_trait_functions(env, t, trait); + if(!value_error && !funcs_error) + return true; + const Value request = (Value)vector_front(&trait->requested_values); + gwerr_secondary("from trait", request->from->filename, trait->loc); + return false; +} + -- 2.43.0