Skip to content

Commit

Permalink
Merge pull request #101 from fennecdjay/lint/check
Browse files Browse the repository at this point in the history
Lint/check
  • Loading branch information
fennecdjay committed Dec 11, 2018
2 parents 2532ca7 + e98b3bd commit f791231
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 86 deletions.
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();

0 comments on commit f791231

Please sign in to comment.