Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lint/check #101

Merged
merged 2 commits into from Dec 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/vararg.h
Expand Up @@ -5,5 +5,5 @@ struct Vararg_ {
m_bit* d; // d(ata)
m_uint o, i, s; // o(ffset), i(ndex), s(ize)
};

void free_vararg(struct Vararg_* arg);
#endif
29 changes: 11 additions & 18 deletions src/lib/vararg.c
Expand Up @@ -11,14 +11,19 @@
#include "import.h"
#include "vararg.h"

void free_vararg(struct Vararg_* arg) {
xfree(arg->d);
xfree(arg->k);
mp_free(Vararg, arg);
}

INSTR(VarargTop) { GWDEBUG_EXE
struct Vararg_* arg = *(struct Vararg_**)MEM(instr->m_val);
if(arg->d)
PUSH_REG(shred, SZ_INT)
else {
shred->pc = instr->m_val2 + 1;
mp_free(Vararg, arg);
return;
}
}

Expand All @@ -28,24 +33,15 @@ INSTR(VarargIni) { GWDEBUG_EXE
POP_REG(shred, instr->m_val)
arg->d = (m_bit*)xmalloc(instr->m_val);
memcpy(arg->d, shred->reg, instr->m_val);
} else {
if(*(m_uint*)instr->ptr)
POP_REG(shred, SZ_INT)
arg->d = NULL;
}
} else if(*(m_uint*)instr->ptr)
POP_REG(shred, SZ_INT)
const Vector kinds = (Vector)instr->m_val2;
if(kinds) {
arg->s = vector_size(kinds);
if(arg->s) {
if((arg->s = vector_size(kinds))) {
arg->k = (m_uint*)xcalloc(arg->s, SZ_INT);
memcpy(arg->k, kinds->ptr + OFFSET, arg->s * SZ_INT);
}
} else {
arg->s = 0;
arg->k = NULL;
}
arg->o = 0;
arg->i = 0;
*(struct Vararg_**)REG(0) = arg;
PUSH_REG(shred, SZ_INT);
}
Expand All @@ -56,11 +52,8 @@ INSTR(VarargEnd) { GWDEBUG_EXE
arg->o += arg->k[arg->i];
if(++arg->i < arg->s)
shred->pc = instr->m_val2;
else {
free(arg->d);
free(arg->k);
mp_free(Vararg, arg);
}
else
free_vararg(arg);
}

INSTR(VarargMember) { GWDEBUG_EXE
Expand Down
99 changes: 41 additions & 58 deletions src/parse/check.c
Expand Up @@ -272,13 +272,12 @@ ANN Type check_exp_array(const Env env, const Exp_Array* array) { GWDEBUG_EXE
CHECK_OO(t_base)
Exp e = array->array->exp;
CHECK_OO(check_exp(env, e))
m_uint depth = 0;
m_uint depth = 1;
do {
++depth;
if(isa(e->type, t_int) < 0)
ERR_O(e->pos, "array index %i must be of type 'int', not '%s'",
depth, e->type->name)
} while((e = e->next));
} while((e = e->next) && ++depth);
if(depth != array->array->depth)
ERR_O(array->self->pos, "invalid array acces expression.")

Expand Down Expand Up @@ -355,10 +354,9 @@ ANN2(1,2) static Func find_func_match_actual(const Env env, Func func, const Exp
return NULL;
}

ANN2(1, 2) static Func find_func_match(const Env env, const Func up, Exp args) {
ANN2(1, 2) static Func find_func_match(const Env env, const Func up, const Exp exp) {
Func func;
if(args && isa(args->type, t_void) > 0)
args = NULL;
const Exp args = (exp && isa(exp->type, t_void) < 0) ? exp : NULL;
if((func = find_func_match_actual(env, up, args, 0, 1)) ||
(func = find_func_match_actual(env, up, args, 1, 1)) ||
(func = find_func_match_actual(env, up, args, 0, 0)) ||
Expand All @@ -368,16 +366,14 @@ ANN2(1, 2) static Func find_func_match(const Env env, const Func up, Exp args) {
}

ANN static m_bool check_call(const Env env, const Exp_Call* exp) {
if(!check_exp(env, exp->func) || (exp->args && !check_exp(env, exp->args)))
return -1;
return 1;
CHECK_OB(check_exp(env, exp->func))
return exp->args ? !!check_exp(env, exp->args) : -1;
}

ANN static inline Value template_get_ready(const Env env, const Value v, const m_str tmpl,
const m_uint i) {
const Symbol sym = func_symbol(env->curr, v->name, tmpl, i);
ANN static inline Value template_get_ready(const Value v, const m_str tmpl, const m_uint i) {
const Symbol sym = func_symbol(v->owner, v->name, tmpl, i);
return v->owner_class ? find_value(v->owner_class, sym) :
nspc_lookup_value1(env->curr, sym);
nspc_lookup_value1(v->owner, sym);
}

ANN Func find_template_match(const Env env, const Value v, const Exp_Call* exp) {
Expand All @@ -390,7 +386,7 @@ ANN Func find_template_match(const Env env, const Value v, const Exp_Call* exp)
for(m_uint i = 0; i < v->offset + 1; ++i) {
Func_Def def = NULL;
Func_Def base = NULL;
Value value = template_get_ready(env, v, tmpl_name, i);
Value value = template_get_ready(v, tmpl_name, i);
if(value) {
if(env->func == value->d.func_ref) {
free(tmpl_name);
Expand All @@ -399,7 +395,7 @@ ANN Func find_template_match(const Env env, const Value v, const Exp_Call* exp)
}
base = def = value->d.func_ref->def;
} else {
if(!(value = template_get_ready(env, v, "template", i)))
if(!(value = template_get_ready(v, "template", i)))
continue;
base = value->d.func_ref->def;
def = new_func_def(base->td, insert_symbol(v->name),
Expand Down Expand Up @@ -437,32 +433,28 @@ ANN static void print_current_args(Exp e) {
gw_err(" \033[32m%s\033[0m", e->type->name);
if(e->type->array_depth)
REM_REF(e->type)
if(e->next)
gw_err(",");
} while((e = e->next));
} while((e = e->next) && gw_err(","));
gw_err("\n");
}

ANN static void print_arg(Arg_List e) {
do {
gw_err(" \033[32m%s\033[0m \033[1m%s\033[0m", e->type->name,
s_name(e->var_decl->xid));
if(e->next)
gw_err(",");
} while((e = e->next));
do gw_err(" \033[32m%s\033[0m \033[1m%s\033[0m", e->type->name,
s_name(e->var_decl->xid));
while((e = e->next) && gw_err(","));
}

ANN2(1) static void* function_alternative(const Type f, Exp args){
err_msg(args ? args->pos : 0, "argument type(s) do not match for function. should be :");
Func up = f->d.func;
do {
gw_err("(%s)\t", up->name);
const Arg_List e = up->def->arg_list;
gw_err("\t");
if(e)
print_arg(e);
else
gw_err("\033[32mvoid\033[0m");
gw_err(". (%s)\n%s", f->name, up->next ? "or :" : "");
gw_err("\n");
} while((up = up->next));
if(args)
print_current_args(args);
Expand Down Expand Up @@ -490,22 +482,19 @@ ANN static Func get_template_func(const Env env, const Exp_Call* func, const Exp
return f;
}
assert(func->self);
(void)err_msg(func->self->pos,
ERR_O(func->self->pos,
"function is template. automatic type guess not fully implemented yet.\n"
"\tplease provide template types. eg: '<type1, type2, ...>'");
return NULL;
"\tplease provide template types. eg: '<type1, type2, ...>'")
}

ANN2(1,2,4) static Type check_exp_call_template(const Env env, const Exp restrict call,
const restrict Exp args, const restrict Exp base) {
m_uint args_number = 0;
ID_List list;
const Value value = nspc_lookup_value1(call->type->owner, insert_symbol(call->type->name));
CHECK_OO(value)
const m_uint type_number = get_type_number(value->d.func_ref->def->tmpl->list);

list = value->d.func_ref->def->tmpl->list;
Type_List tl[type_number];
ID_List list = value->d.func_ref->def->tmpl->list;
while(list) {
Arg_List arg = value->d.func_ref->def->arg_list;
Exp template_arg = args;
Expand All @@ -528,7 +517,7 @@ ANN2(1,2,4) static Type check_exp_call_template(const Env env, const Exp restric
ERR_O(call->pos, "not able to guess types for template call.")
Tmpl_Call tmpl = { tl[0], NULL };
const Exp_Call tmp_func = { call, args, NULL, &tmpl, NULL };
Func func = get_template_func(env, &tmp_func, base, value);
const Func func = get_template_func(env, &tmp_func, base, value);
if(base->exp_type == ae_exp_call)
base->d.exp_call.m_func = func;
else if(base->exp_type == ae_exp_binary)
Expand Down Expand Up @@ -591,18 +580,16 @@ ANN static Type check_exp_post(const Env env, const Exp_Postfix* post) { GWDEBUG
OP_RET(post, "postfix");
}

ANN static Type check_exp_dur(const Env env, const Exp_Dur* dur) { GWDEBUG_EXE
const Type base = check_exp(env, dur->base);
CHECK_OO(base)
const Type unit = check_exp(env, dur->unit);
CHECK_OO(unit)
if(isa(base, t_int) < 0 && isa(base, t_float) < 0)
ERR_O(dur->base->pos, "invalid type '%s' in prefix of dur expression...\n"
" (must be of type 'int' or 'float')", base->name)
if(isa(unit, t_dur) < 0)
ERR_O(dur->unit->pos, "invalid type '%s' in postfix of dur expression...\n"
" (must be of type 'dur')", unit->name)
return unit;
ANN static Type check_exp_dur(const Env env, const Exp_Dur* exp) { GWDEBUG_EXE
CHECK_OO(check_exp(env, exp->base))
CHECK_OO(check_exp(env, exp->unit))
if(isa(exp->base->type, t_int) < 0 && isa(exp->base->type, t_float) < 0)
ERR_O(exp->base->pos, "invalid type '%s' in prefix of dur expression...\n"
" (must be of type 'int' or 'float')", exp->base->type->name)
if(isa(exp->unit->type, t_dur) < 0)
ERR_O(exp->unit->pos, "invalid type '%s' in postfix of dur expression...\n"
" (must be of type 'dur')", exp->base->type->name)
return exp->unit->type;
}

ANN static Type check_exp_call(const Env env, Exp_Call* exp) { GWDEBUG_EXE
Expand All @@ -623,19 +610,20 @@ ANN static Type check_exp_call(const Env env, Exp_Call* exp) { GWDEBUG_EXE
return check_exp_call1(env, exp->func, exp->args, exp->self);
}

ANN static inline m_bool check_exp_unary_spork1(const Env env, const Stmt code) {
RET_NSPC(check_stmt(env, code))
}

ANN Type check_exp_unary_spork(const Env env, const Stmt code) { GWDEBUG_EXE
++env->scope;
nspc_push_value(env->curr);
const m_bool ret = check_stmt(env, code);
nspc_pop_value(env->curr);
--env->scope;
return (ret > 0) ? t_shred : NULL;
CHECK_BO(check_exp_unary_spork1(env, code))
return t_shred;
}

ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) { GWDEBUG_EXE
struct Op_Import opi = { .op=unary->op, .rhs=unary->exp ? check_exp(env, unary->exp) : NULL,
.data=(uintptr_t)unary };
if(unary->exp && !opi.rhs)return NULL;
if(unary->exp && !opi.rhs)
return NULL;
OP_RET(unary, "unary")
}

Expand Down Expand Up @@ -735,9 +723,7 @@ ANN static m_bool check_flow(const Exp exp, const m_str orig) { GWDEBUG_EXE

ANN static m_bool check_breaks(const Env env, const Stmt a, const Stmt b) { GWDEBUG_EXE
vector_add(&env->breaks, (vtype)a);
nspc_push_value(env->curr);
const m_bool ret = check_stmt(env, b);
nspc_pop_value(env->curr);
RET_NSPC(check_stmt(env, b))
vector_pop(&env->breaks);
return ret;
}
Expand Down Expand Up @@ -1074,11 +1060,8 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE
ret = err_msg(f->td->xid->pos, "...in function '%s'", s_name(f->name));
if(variadic)
REM_REF(variadic)
if(GET_FLAG(f, builtin)) {
if(GET_FLAG(func, member) && GET_FLAG(func, ref))
f->stack_depth += SZ_INT;
if(GET_FLAG(f, builtin))
func->code->stack_depth = f->stack_depth;
}
else if(GET_FLAG(f, op))
operator_func(func);
nspc_pop_value(env->curr);
Expand Down
9 changes: 4 additions & 5 deletions src/parse/scan2.c
Expand Up @@ -41,10 +41,10 @@ ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE
env_push(env, NULL, env->global_nspc, &scope);
do {
const Var_Decl var = list->self;
nspc_add_value(env->curr, var->xid, var->value); // ???
const Array_Sub array = var->array;
if(array && array->exp)
CHECK_BB(scan2_exp(env, array->exp))
nspc_add_value(env->curr, var->xid, var->value); // ???
} while((list = list->next));
if(global)
env_pop(env, scope);
Expand Down Expand Up @@ -197,9 +197,7 @@ ANN2(1,2) static inline m_bool scan2_exp_call1(const Env env, const restrict Exp
}

ANN static inline m_bool scan2_exp_call(const Env env, const Exp_Call* exp_call) { GWDEBUG_EXE
if(!exp_call->tmpl) // avoid unused var
return scan2_exp_call1(env, exp_call->func, exp_call->args);
return scan2_exp(env, exp_call->func);
}

ANN static inline m_bool scan2_exp_dot(const Env env, const Exp_Dot* member) { GWDEBUG_EXE
Expand Down Expand Up @@ -369,8 +367,9 @@ ANN2(1, 2) static m_bool scan2_func_def_template (const Env env, const Func_Def

ANN static m_bool scan2_func_def_builtin(const Func func, const m_str name) { GWDEBUG_EXE
SET_FLAG(func, builtin);
func->code = new_vm_code(NULL, func->def->stack_depth,
GET_FLAG(func, member), name);
if(GET_FLAG(func->def, variadic))
func->def->stack_depth += SZ_INT;
func->code = new_vm_code(NULL, func->def->stack_depth, GET_FLAG(func, member), name);
SET_FLAG(func->code, builtin);
func->code->native_func = (m_uint)func->def->d.dl_func_ptr;
return 1;
Expand Down
8 changes: 7 additions & 1 deletion tests/test_plugins/variadic.c
Expand Up @@ -9,6 +9,10 @@
#include "import.h"
#include "vararg.h"

static MFUN(m_test) {
printf("%p\n", *(M_Object*)MEM(0));
}

static MFUN(m_variadic) {
M_Object str_obj = *(M_Object*)MEM(SZ_INT);
if(!str_obj)return;
Expand All @@ -29,7 +33,7 @@ static MFUN(m_variadic) {
arg->i++;
str++;
}
POP_REG(shred, SZ_INT);
free_vararg(arg);
}

GWION_IMPORT(variadic test) {
Expand All @@ -38,6 +42,8 @@ GWION_IMPORT(variadic test) {
CHECK_BB(gwi_func_ini(gwi, "void", "member", m_variadic))
CHECK_BB(gwi_func_arg(gwi, "string", "format"))
CHECK_BB(gwi_func_end(gwi, ae_flag_variadic))
CHECK_BB(gwi_func_ini(gwi, "void", "test", m_test))
CHECK_BB(gwi_func_end(gwi, 0))
CHECK_BB(gwi_class_end(gwi))
return 1;
}
11 changes: 8 additions & 3 deletions tests/test_plugins/variadic.gw
Expand Up @@ -2,7 +2,12 @@
Variadic v;
"iiii" => string format;
<<<v, " ", format $ Object>>>;
//v.member(format);
v.member(format, 1,2,3,4);
//v.member(1,2,3,4);
//v.member(1,2,3,4);
v.member(format, 1,2,3,4);
v.test();
v.member(format, 1,2,3,4);
v.member(format, 1,2,3,4);
v.test();
v.member(format, 1,2,3,4);
v.member(format, 1,2,3,4);
v.test();