-Subproject commit 5a1fda275fe41169cfe9edae73a7fd95811d24b8
+Subproject commit 853459cbbf4693c87febaa4be332818cf191a03b
ANEW ANN m_str tl2str(const Env, const Type_List); // in type_decl.c
ANN m_bool compat_func(const __restrict__ Func_Def, const __restrict__ Func_Def);
ANN Type known_type(const Env env, const Type_Decl*);
-ANN m_bool env_access(const Env env, const ae_flag flag);
-ANN m_bool env_storage(const Env env, ae_flag flag);
+ANN m_bool env_access(const Env env, const ae_flag flag, const uint pos);
+ANN m_bool env_storage(const Env env, ae_flag flag, const uint pos);
ANN void env_add_type(const Env, const Type);
ANN Type find_type(const Env, ID_List);
ANN m_bool already_defined(const Env env, const Symbol s, const uint pos);
ANN m_bool gwion_ini(const Gwion, struct Arg_*);
ANN VM* gwion_cpy(const VM*);
-ANN void gwion_run(const Gwion gwion);
-ANN void gwion_end(const Gwion gwion);
+ANN void gwion_run(const Gwion gwion);
+ANN void gwion_end(const Gwion gwion);
+ANN void gwion_err(const Gwion gwion, const uint pos, const m_str fmt, ...);
#endif
opck ck;
opem em;
uintptr_t data;
+ uint pos;
Operator op;
m_bool mut;
};
#include "gwion.h"
#define insert_symbol(a) insert_symbol(env->gwion->st, (a))
+#undef ERR_B
+#define ERR_B(a, b, ...) { gwion_err(env->gwion, (a), (b), ## __VA_ARGS__); return GW_ERROR; }
+#undef ERR_O
+#define ERR_O(a, b, ...) { gwion_err(env->gwion, (a), (b), ## __VA_ARGS__); return NULL; }
#define RET_NSPC(exp) \
++env->scope->depth; \
ANN Value find_value(const Type, const Symbol);
ANN Func find_func(const Type, const Symbol);
ANN m_bool isa(const Type, const Type) __attribute__((pure));
-ANN m_bool isres(const Symbol);
+ANN m_bool isres(const Env, const Symbol, const uint pos);
ANN Type array_type(const Env, const Type, const m_uint);
ANN Type find_common_anc(const Type, const Type) __attribute__((pure));
ANN m_uint id_list_len(ID_List);
#undef insert_symbol
#define insert_symbol(a) insert_symbol(emit->env->gwion->st, (a))
+#undef ERR_B
+#define ERR_B(a, b, ...) { gwion_err(emit->gwion, (a), (b), ## __VA_ARGS__); return GW_ERROR; }
+#undef ERR_O
+#define ERR_O(a, b, ...) { gwion_err(emit->gwion, (a), (b), ## __VA_ARGS__); return NULL; }
+
typedef struct Local_ {
m_uint size;
m_uint offset;
}
ANN static m_bool emit_vararg_start(const Emitter emit, const m_uint offset) { GWDEBUG_EXE
- if(emit->env->func->variadic)
- ERR_B(0, "vararg.start already used. this is an error")
emit->env->func->variadic = emit_add_instr(emit, VarargTop);
emit->env->func->variadic->m_val = offset;
emit->env->func->variadic->m_val2 = emit_code_size(emit);
return GW_OK;
}
-ANN static m_bool emit_vararg_end(const Emitter emit, const m_uint offset) { GWDEBUG_EXE
- if(!emit->env->func->variadic)
- ERR_B(0, "vararg.start not used before vararg.end. this is an error")
+ANN static void emit_vararg_end(const Emitter emit, const m_uint offset) { GWDEBUG_EXE
const Instr instr = emit_add_instr(emit, VarargEnd);
instr->m_val = offset;
instr->m_val2 = emit->env->func->variadic->m_val2;
emit->env->func->variadic->m_val2 = emit_code_size(emit);
- return GW_OK;
}
ANN static m_bool emit_vararg(const Emitter emit, const Exp_Dot* member) { GWDEBUG_EXE
offset += l->type->size;
l = l->next;
}
- if(!strcmp(str, "start"))
- return emit_vararg_start(emit, offset);
- if(!strcmp(str, "end"))
- return emit_vararg_end(emit, offset);
+ if(!strcmp(str, "start")) {
+ if(emit->env->func->variadic)
+ ERR_B(exp_self(member)->pos, "vararg.start already used. this is an error")
+ emit_vararg_start(emit, offset);
+ return GW_OK;
+ }
+ if(!strcmp(str, "end")) {
+ if(!emit->env->func->variadic)
+ ERR_B(exp_self(member)->pos, "vararg.start not used before vararg.end. this is an error")
+ emit_vararg_end(emit, offset);
+ return GW_OK;
+ }
const Instr instr = emit_add_instr(emit, VarargMember);
instr->m_val = offset;
instr->m_val2 = exp_self(member)->type->size;
emit->env->func = func;
CHECK_BB(emit_func_def_body(emit, func_def))
if(GET_FLAG(func_def, variadic) && !emit->env->func->variadic)
- ERR_B(func_def->base->td->xid->pos, "invalid variadic use")
+ ERR_B(func_def->pos, "invalid variadic use")
emit_func_def_return(emit);
emit_func_def_code(emit, func);
emit->env->func = former;
#include "oo.h"
#include "vm.h"
#include "env.h"
+#include "type.h"
+#include "func.h"
+#include "value.h"
#include "instr.h"
#include "emit.h"
#include "engine.h"
free_symbols(gwion->st);
mempool_end(gwion->p);
}
+
+ANN void gwion_err(const Gwion gwion, const uint pos, const m_str fmt, ...) {
+ const Env env = gwion->env;
+ gw_err("in file: '%s'\n", env->name);
+ if(env->class_def)
+ gw_err("in class: '%s'\n", env->class_def->name);
+ if(env->func) // problem with scan1 FAKE_FUNC
+ gw_err("in function: '%s'\n", env->func->name);
+ if(pos)
+ fprintf(stderr, "line: %u\t", pos);
+ else
+ fprintf(stderr, "\t");
+ va_list arg;
+ va_start(arg, fmt);
+ vfprintf(stderr, fmt, arg);
+ va_end(arg);
+ fprintf(stderr, "\n");
+}
\ No newline at end of file
Exp e = exp_self(bin);
e->exp_type = ae_exp_call;
memcpy(&e->d.exp_call, &call, sizeof(Exp_Call));
- return check_exp_call1(env, &e->d.exp_call);
+ return check_exp_call1(env, &e->d.exp_call) ?: t_null;
}
static OP_EMIT(opem_func_assign) {
}
if(base || arg)
ERR_B(exp_self(l)->pos, "argument number does not match for lambda")
- l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, def->base->td, l->name, l->args), l->code, def->flag);
+ l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, def->base->td, l->name, l->args), l->code, def->flag, def->pos);
const m_bool ret = traverse_func_def(env, l->def);
arg = l->args;
while(arg) {
}
name = dl_fun->name;
arg_list = make_dll_arg_list(env, dl_fun);
- func_def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, type_decl, insert_symbol(env->gwion->st, name), arg_list), NULL, flag);
+ func_def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, type_decl, insert_symbol(env->gwion->st, name), arg_list), NULL, flag, 0);
func_def->d.dl_func_ptr = (void*)(m_uint)dl_fun->addr;
return func_def;
}
Func_Def def = import_fun(gwi->gwion->env, &gwi->func, flag);
CHECK_OB(def)
if(gwi->templater.n) {
- def = new_func_def(gwi->gwion->p, new_func_base(gwi->gwion->p, NULL, NULL, NULL), NULL, 0);
+ def = new_func_def(gwi->gwion->p, new_func_base(gwi->gwion->p, NULL, NULL, NULL), NULL, 0, 0);
const ID_List list = templater_def(gwi->gwion->st, &gwi->templater);
def->tmpl = new_tmpl_list(gwi->gwion->p, list, -1);
SET_FLAG(def, template);
const Type rhs = op->rhs ? get_type(env, op->rhs) : NULL;
const Type ret = get_type(env, op->ret);
const struct Op_Import opi = { lhs, rhs, ret,
- op->ck, op->em, (uintptr_t)f, op->op, op->mut };
+ op->ck, op->em, (uintptr_t)f, 0, op->op, op->mut };
return env_add_op(env, &opi);
}
CHECK_OO(v)
const Func_Def base = v->d.func_ref->def;
const Func_Def def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, base->base->td, insert_symbol(env->gwion->st, v->name),
- base->base->args), base->d.code, base->flag);
+ base->base->args), base->d.code, base->flag, base->pos);
def->tmpl = new_tmpl_list(env->gwion->p, base->tmpl->list, dt->overload);
SET_FLAG(def, template);
return def;
#include "operator.h"
ANN void exception(const VM_Shred shred, const m_str c) {
- err_msg(0, "%s: shred[id=%" UINT_F ":%s], PC=[%" UINT_F "]",
+ gw_err("%s: shred[id=%" UINT_F ":%s], PC=[%" UINT_F "]",
c, shred->tick->xid, shred->info->name, shred->pc - 1);
vm_shred_exit(shred);
}
}
#define GET(a,b) ((a) & (b)) == (b)
-ANN m_bool env_access(const Env env, const ae_flag flag) {
+ANN m_bool env_access(const Env env, const ae_flag flag, const uint pos) {
if(env->scope->depth) {
if(GET(flag, ae_flag_global))
- ERR_B(0, "'global' can only be used at %s scope.",
+ ERR_B(pos, "'global' can only be used at %s scope.",
GET(flag, ae_flag_global) && !env->class_def ?
"file" : "class")
}
if((GET(flag, ae_flag_static) || GET(flag, ae_flag_private) ||
GET(flag, ae_flag_protect)) && (!env->class_def || env->scope->depth))
- ERR_B(0, "static/private/protect can only be used at class scope.")
+ ERR_B(pos, "static/private/protect can only be used at class scope.")
return GW_OK;
}
-ANN m_bool env_storage(const Env env, ae_flag flag) {
- CHECK_BB(env_access(env, flag))
+ANN m_bool env_storage(const Env env, ae_flag flag, const uint pos) {
+ CHECK_BB(env_access(env, flag, pos))
return !(env->class_def && GET(flag, ae_flag_global)) ? GW_OK :GW_ERROR;
}
#include "operator.h"
#include "switch.h"
-#define OP_RET(a, b)\
- const Type op_ret = op_check(env, &opi);\
- if(!op_ret)\
- ERR_O(exp_self(a)->pos, "in %s expression", b)\
- return op_ret;
-
ANN static Type check_exp(const Env env, Exp exp);
ANN static m_bool check_stmt_list(const Env env, Stmt_List list);
ANN m_bool check_class_def(const Env env, const Class_Def class_def);
return decl->type;
}
-ANN static m_bool prim_array_inner(const Type t, Type type, const Exp e) {
+ANN static m_bool prim_array_inner(const Env env, const Type t, Type type, const Exp e) {
const Type common = find_common_anc(t, type);
if(common)
return GW_OK;
e->cast_to = type;
return GW_OK;
}
- return err_msg(e->pos, "array init [...] contains incompatible types ...");
+ ERR_B(e->pos, "array init [...] contains incompatible types ...")
}
ANN static inline Type prim_array_match(const Env env, Exp e) {
const Type type = e->type;
- do CHECK_BO(prim_array_inner(e->type, type, e))
+ do CHECK_BO(prim_array_inner(env, e->type, type, e))
while((e = e->next));
return array_type(env, type->array_depth ? array_base(type) : type, type->array_depth + 1);
}
ANN static Type prim_id_non_res(const Env env, const Exp_Primary* primary) {
const Value v = check_non_res_value(env, primary);
if(!v || !GET_FLAG(v, checked)) {
- err_msg(exp_self(primary)->pos,
+ gwion_err(env->gwion, exp_self(primary)->pos,
"variable %s not legit at this point.", s_name(primary->d.var));
did_you_mean(env->gwion->st, s_name(primary->d.var));
return NULL;
}
if(implicit) {
const struct Implicit imp = { e, t };
- struct Op_Import opi = { .op=op_impl, .lhs=e->type, .rhs=t, .data=(m_uint)&imp };
+ struct Op_Import opi = { .op=op_impl, .lhs=e->type, .rhs=t, .data=(m_uint)&imp, .pos=e->pos };
return op_check(env, &opi) ? 1 : -1;
}
}
continue;
base = value->d.func_ref->def;
def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, base->base->td, insert_symbol(v->name),
- base->base->args), base->d.code, base->flag);
+ base->base->args), base->d.code, base->flag, base->pos);
def->tmpl = new_tmpl_list(env->gwion->p, base->tmpl->list, (m_int)i);
SET_FLAG(def, template);
}
t = t->parent;
}
assert(exp_self(exp));
- err_msg(exp_self(exp)->pos, "arguments do not match for template call");
- return NULL;
+ ERR_O(exp_self(exp)->pos, "arguments do not match for template call")
}
ANN static void print_current_args(Exp e) {
while((e = e->next) && gw_err(","));
}
-ANN2(1) static void* function_alternative(const Type f, const Exp args){
- err_msg(args ? args->pos : 0, "argument type(s) do not match for function. should be :");
+ANN2(1) static void* function_alternative(const Env env, const Type f, const Exp args, const uint pos){
+ gwion_err(env->gwion, pos, "argument type(s) do not match for function. should be :");
Func up = f->d.func;
do {
gw_err("(%s)\t", up->name);
}
if(arg || e)
ERR_O(exp_self(exp)->pos, "argument number does not match for lambda")
- l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, NULL, l->name, l->args), l->code, 0);
+ l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, NULL, l->name, l->args), l->code, 0, exp_self(exp)->pos);
CHECK_BO(traverse_func_def(env, l->def))
if(env->class_def)
SET_FLAG(l->def, member);
return check_exp_call_template(env, exp);
const Func func = find_func_match(env, exp->func->type->d.func, exp->args);
return (exp_self(exp)->d.exp_call.m_func = func) ?
- func->def->base->ret_type : function_alternative(exp->func->type, exp->args);
+ func->def->base->ret_type : function_alternative(env, exp->func->type, exp->args, exp_self(exp)->pos);
}
ANN static Type check_exp_binary(const Env env, const Exp_Binary* bin) { GWDEBUG_EXE
bin->rhs->type = bin->rhs->d.exp_decl.type = bin->lhs->type;
CHECK_OO(check_exp(env, bin->rhs))
struct Op_Import opi = { .op=bin->op, .lhs=bin->lhs->type,
- .rhs=bin->rhs->type, .data=(uintptr_t)bin };
- OP_RET(bin, "binary")
+ .rhs=bin->rhs->type, .data=(uintptr_t)bin, .pos=exp_self(bin)->pos };
+ return op_check(env, &opi);
}
ANN static Type check_exp_cast(const Env env, const Exp_Cast* cast) { GWDEBUG_EXE
const Type t = check_exp(env, cast->exp);
CHECK_OO(t)
CHECK_OO((exp_self(cast)->type = cast->td->xid ? known_type(env, cast->td) : check_td(env, cast->td)))
- struct Op_Import opi = { .op=op_cast, .lhs=t, .rhs=exp_self(cast)->type, .data=(uintptr_t)cast };
- OP_RET(cast, "cast")
+ struct Op_Import opi = { .op=op_cast, .lhs=t, .rhs=exp_self(cast)->type, .data=(uintptr_t)cast, .pos=exp_self(cast)->pos };
+ return op_check(env, &opi);
}
ANN static Type check_exp_post(const Env env, const Exp_Postfix* post) { GWDEBUG_EXE
- struct Op_Import opi = { .op=post->op, .lhs=check_exp(env, post->exp), .data=(uintptr_t)post };
+ struct Op_Import opi = { .op=post->op, .lhs=check_exp(env, post->exp), .data=(uintptr_t)post, .pos=exp_self(post)->pos };
CHECK_OO(opi.lhs)
- OP_RET(post, "postfix");
+ return op_check(env, &opi);
}
ANN static Type check_exp_call(const Env env, Exp_Call* exp) { GWDEBUG_EXE
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 };
+ .data=(uintptr_t)unary, .pos=exp_self(unary)->pos };
if(unary->exp && !opi.rhs)
return NULL;
- OP_RET(unary, "unary")
+ return op_check(env, &opi);
}
ANN static Type check_exp_if(const Env env, const Exp_If* exp_if) { GWDEBUG_EXE
return GW_OK;
}
-ANN static m_bool check_flow(const Exp exp, const m_str orig) { GWDEBUG_EXE
+ANN static m_bool check_flow(const Env env, const Exp exp, const m_str orig) { GWDEBUG_EXE
if(isa(exp->type, t_object) > 0 || isa(exp->type, t_int) > 0 || isa(exp->type, t_float) > 0 ||
isa(exp->type, t_dur) > 0 || isa(exp->type, t_time) > 0)
return GW_OK;
return GW_OK;
}
-ANN static inline m_bool for_empty(const Stmt_For stmt) {
+ANN static inline m_bool for_empty(const Env env, const Stmt_For stmt) {
if(!stmt->c2 || !stmt->c2->d.stmt_exp.val)
ERR_B(stmt_self(stmt)->pos, "empty for loop condition...",
"...(note: explicitly use 'true' if it's the intent)",
return check_conts(env, stmt_self(stmt), stmt->body);
}
-ANN static m_bool cond_type(const Exp e) {
+ANN static m_bool cond_type(const Env env, const Exp e) {
const Type t = e->type;
if(isa(t, t_int) > 0)
return GW_OK;
}
#define stmt_func_xxx(name, type, prolog, exp) describe_stmt_func(check, name, type, prolog, exp)
stmt_func_xxx(if, Stmt_If,, !(!check_exp(env, stmt->cond) ||
- check_flow(stmt->cond, "if") < 0 ||
+ check_flow(env, stmt->cond, "if") < 0 ||
check_stmt(env, stmt->if_body) < 0 ||
(stmt->else_body && check_stmt(env, stmt->else_body) < 0)) ? 1 : -1)
stmt_func_xxx(flow, Stmt_Flow,,
!(!check_exp(env, stmt->cond) ||
- check_flow(stmt->cond, stmt_self(stmt)->stmt_type == ae_stmt_while ? "while" : "until") < 0 ||
+ check_flow(env, stmt->cond, stmt_self(stmt)->stmt_type == ae_stmt_while ? "while" : "until") < 0 ||
check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
stmt_func_xxx(for, Stmt_For,, !(
- for_empty(stmt) < 0 ||
+ for_empty(env, stmt) < 0 ||
check_stmt(env, stmt->c1) < 0 ||
check_stmt(env, stmt->c2) < 0 ||
- check_flow(stmt->c2->d.stmt_exp.val, "for") < 0 ||
+ check_flow(env, stmt->c2->d.stmt_exp.val, "for") < 0 ||
(stmt->c3 && !check_exp(env, stmt->c3)) ||
check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
stmt_func_xxx(loop, Stmt_Loop,, !(!check_exp(env, stmt->cond) ||
- cond_type(stmt->cond) < 0 ||
+ cond_type(env, stmt->cond) < 0 ||
check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
stmt_func_xxx(switch, Stmt_Switch,, !(!check_exp(env, stmt->val) ||
- cond_type(stmt->val) < 0 || !switch_add(env, stmt) ||
+ cond_type(env, stmt->val) < 0 || !switch_add(env, stmt) ||
check_breaks(env, stmt_self(stmt), stmt->stmt) < 0 || !switch_pop(env)) ? 1 : -1)
stmt_func_xxx(auto, Stmt_Auto,, do_stmt_auto(env, stmt))
return GW_OK;
}
-ANN static m_bool check_signature_match(const Func_Def f, const Func parent) { GWDEBUG_EXE
+ANN static m_bool check_signature_match(const Env env, const Func_Def f, const Func parent) { GWDEBUG_EXE
if(GET_FLAG(parent->def, static) != GET_FLAG(f, static)) {
const m_str c_name = f->base->func->value_ref->owner_class->name;
const m_str p_name = parent->value_ref->owner_class->name;
const m_str f_name = s_name(f->base->xid);
- ERR_B(f->base->td->xid->pos,
+ ERR_B(td_pos(f->base->td),
"function '%s.%s' ressembles '%s.%s' but cannot override...\n"
"\t...(reason: '%s.%s' is declared as 'static')",
c_name, f_name, p_name, c_name,
Func parent_func = func;
do {
if(compat_func(f, parent_func->def) > 0) {
- CHECK_BB(check_signature_match(f, parent_func))
+ CHECK_BB(check_signature_match(env, f, parent_func))
if(!f->tmpl) {
f->base->func->vt_index = parent_func->vt_index;
vector_set(&env->curr->info->vtable, f->base->func->vt_index, (vtype)f->base->func);
for(m_uint j = i + 1; f1 && j <= v->offset; ++j) {
const Func f2 = get_overload(env, f, j);
if(f2 && compat_func(f1->def, f2->def) > 0)
- ERR_B(f2->def->base->td->xid->pos, "global function '%s' already defined"
+ ERR_B(td_pos(f2->def->base->td), "global function '%s' already defined"
" for those arguments", s_name(f->base->xid))
}
}
if(env->class_def && env->class_def->parent) {
const Value override = find_value(env->class_def->parent, f->base->xid);
if(override && override->owner_class && isa(override->type, t_function) < 0)
- ERR_B(f->base->td->xid->pos,
+ ERR_B(f->pos,
"function name '%s' conflicts with previously defined value...\n"
"\tfrom super class '%s'...",
s_name(f->base->xid), override->owner_class->name)
const Type l = is_unary ? NULL : a->type;
const Type r = is_unary ? a->type : a->next ? a->next->type : NULL;
const Operator op = name2op(s_name(f->def->base->xid));
- struct Op_Import opi = { .op=op, .lhs=l, .rhs=r, .data=(m_uint)f };
+ struct Op_Import opi = { .op=op, .lhs=l, .rhs=r, .data=(m_uint)f, .pos=f->def->pos };
operator_set_func(&opi);
}
if(ret > 0) {
const Value variadic = GET_FLAG(f, variadic) ? set_variadic(env) : NULL;
if(!GET_FLAG(f, builtin) && check_stmt_code(env, &f->d.code->d.stmt_code) < 0)
- ret = err_msg(f->base->td ? f->base->td->xid->pos : 0, "...in function '%s'",
- s_name(f->base->xid));
+ ret = GW_ERROR;
if(variadic)
REM_REF(variadic, env->gwion)
if(GET_FLAG(f, builtin))
}
ANN m_bool add_op(const Gwion gwion, const Nspc nspc, const struct Op_Import* opi) {
- Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
M_Operator* mo;
+ Nspc n = nspc;
+ do {
+ if(!n->info->op_map.ptr)
+ continue;
+ const Vector v = (Vector)map_get(&n->info->op_map, (vtype)opi->op);
+ if(v && (mo = operator_find(v, opi->lhs, opi->rhs)))
+ ERR_B(opi->pos, "operator '%s', for type '%s' and '%s' already imported",
+ op2str(opi->op), opi->lhs ? opi->lhs->name : NULL,
+ opi->rhs ? opi->rhs->name : NULL)
+ } while((n = n->parent));
+ Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
if(!v) {
v = new_vector(gwion->p);
map_set(&nspc->info->op_map, (vtype)opi->op, (vtype)v);
}
- if((mo = operator_find(v, opi->lhs, opi->rhs)))
- CHECK_BB((err_msg(0, "operator '%s', for type '%s' and '%s' already imported",
- op2str(opi->op), opi->lhs ? opi->lhs->name : NULL,
- opi->rhs ? opi->rhs->name : NULL)))
+// new mo
mo = mp_alloc(gwion->p, M_Operator);
mo->lhs = opi->lhs;
mo->rhs = opi->rhs;
mo->ck = opi->ck;
mo->em = opi->em;
mo->mut = opi->mut;
+// add
vector_add(v, (vtype)mo);
+// mo_type_ref
if(opi->lhs && opi->lhs != OP_ANY_TYPE)
ADD_REF(opi->lhs)
if(opi->rhs && opi->rhs != OP_ANY_TYPE)
}
ANN Type op_check(const Env env, struct Op_Import* opi) {
+ Type ret = NULL;
Nspc nspc = env->curr;
do {
if(nspc->info->op_map.ptr) {
Type l = opi->lhs;
do {
struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data };
- Type ret = op_check_inner(env, &nspc->info->op_map, &opi2);
+ ret = op_check_inner(env, &nspc->info->op_map, &opi2);
if(ret) {
if(ret == t_null)
break;
}
nspc = nspc->parent;
} while(nspc);
- if(opi->op != op_impl)
- (void)err_msg(0, "%s %s %s: no match found for operator",
+ if(opi->op == op_cast || (ret != t_null && opi->op != op_impl))
+ err_msg(opi->pos, "%s %s %s: no match found for operator",
type_name(opi->lhs), op2str(opi->op), type_name(opi->rhs));
-
return NULL;
}
}
ANN m_bool scan0_stmt_fptr(const Env env, const Stmt_Fptr stmt) { GWDEBUG_EXE
- CHECK_BB(env_access(env, stmt->base->td->flag))
- CHECK_BB(scan0_defined(env, stmt->base->xid, stmt->base->td->xid->pos));
+ CHECK_BB(env_access(env, stmt->base->td->flag, stmt_self(stmt)->pos))
+ CHECK_BB(scan0_defined(env, stmt->base->xid, td_pos(stmt->base->td)));
const m_str name = s_name(stmt->base->xid);
const Type t = new_type(env->gwion->p, t_fptr->xid, name, t_fptr);
t->owner = !(!env->class_def && GET_FLAG(stmt->base->td, global)) ?
}
ANN static m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { GWDEBUG_EXE
- CHECK_BB(env_access(env, stmt->ext->flag))
+ CHECK_BB(env_access(env, stmt->ext->flag, stmt_self(stmt)->pos))
const Type base = known_type(env, stmt->ext);
CHECK_OB(base)
CHECK_BB(scan0_defined(env, stmt->xid, stmt->ext->xid->pos))
}
ANN m_bool scan0_stmt_enum(const Env env, const Stmt_Enum stmt) { GWDEBUG_EXE
- CHECK_BB(env_storage(env, stmt->flag))
+ CHECK_BB(env_storage(env, stmt->flag, stmt_self(stmt)->pos))
if(stmt->xid) {
const Value v = nspc_lookup_value1(env->curr, stmt->xid);
if(v)
}
ANN static m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { GWDEBUG_EXE
- CHECK_BB(env_storage(env, stmt->flag))
+ CHECK_BB(env_storage(env, stmt->flag, stmt_self(stmt)->pos))
if(stmt->xid) {
CHECK_BB(scan0_defined(env, stmt->xid, stmt_self(stmt)->pos))
const Nspc nspc = !GET_FLAG(stmt, global) ?
}
ANN static m_bool scan0_class_def_pre(const Env env, const Class_Def class_def) { GWDEBUG_EXE
- CHECK_BB(env_storage(env, class_def->flag))
+ CHECK_BB(env_storage(env, class_def->flag, class_def->pos))
if(GET_FLAG(class_def, global)) {
vector_add(&env->scope->nspc_stack, (vtype)env->curr);
env->curr = env->global_nspc;
}
CHECK_BB(scan0_defined(env, class_def->base.xid, class_def->pos)) // test for type ?
- CHECK_BB(isres(class_def->base.xid))
+ CHECK_BB(isres(env, class_def->base.xid, class_def->pos))
return GW_OK;
}
#include "vm.h"
#include "parse.h"
-#define FAKE_FUNC ((Func)1)
+//#define FAKE_FUNC ((Func)1)
ANN m_bool scan0_class_def(const Env env, const Class_Def class_def);
ANN /* static */ m_bool scan1_exp(const Env env, Exp exp);
}
ANN m_bool scan1_exp_decl(const Env env, Exp_Decl* decl) { GWDEBUG_EXE
- CHECK_BB(env_storage(env, decl->td->flag))
+ CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
Var_Decl_List list = decl->list;
((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
CHECK_OB(decl->type)
Type t = decl->type;
const Var_Decl var = list->self;
const Value former = nspc_lookup_value0(env->curr, var->xid);
- CHECK_BB(isres(var->xid))
+ CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
if(!decl->td->exp && decl->td->xid->xid != insert_symbol("auto") &&
former && (!env->class_def || // cuold be better
(!GET_FLAG(env->class_def, template) || !GET_FLAG(env->class_def, scan1))))
do {
const Var_Decl var = list->var_decl;
if(var->xid)
- CHECK_BB(isres(var->xid))
+ CHECK_BB(isres(env, var->xid, var->pos))
if(list->td)
CHECK_OB((list->type = void_type(env, list->td, var->pos)))
} while((list = list->next));
}
ANN m_bool scan1_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE
- CHECK_BB(env_storage(env, f->flag))
+ if(f->base->td)
+ CHECK_BB(env_storage(env, f->flag, td_pos(f->base->td)))
if(tmpl_list_base(f->tmpl))
return GW_OK;
const Func former = env->func;
- env->func = FAKE_FUNC;
+ struct Func_ fake = { .name=s_name(f->base->xid) };
+ env->func = &fake;
++env->scope->depth;
if(GET_FLAG(f, dtor) && !env->class_def)
- ERR_B(f->base->td->xid->pos, "dtor must be in class def!!")
+ ERR_B(td_pos(f->base->td), "dtor must be in class def!!")
if(f->base->td)
CHECK_OB((f->base->ret_type = known_type(env, f->base->td)))
if(f->base->args)
DECL_SECTION_FUNC(scan1)
ANN static m_bool scan1_class_parent(const Env env, const Class_Def class_def) {
- const uint pos = class_def->base.ext->xid ? class_def->base.ext->xid->pos :
- class_def->base.ext->exp->pos;
+ const uint pos = td_pos(class_def->base.ext);
if(class_def->base.ext->array)
CHECK_BB(scan1_exp(env, class_def->base.ext->array->exp))
const Type parent = class_def->base.type->parent = known_type(env, class_def->base.ext);
}
ANN m_bool scan2_stmt_fptr(const Env env, const Stmt_Fptr ptr) { GWDEBUG_EXE
- const Func_Def def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, ptr->base->td, ptr->base->xid, ptr->base->args), NULL, ptr->base->td->flag);
+ const Func_Def def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, ptr->base->td, ptr->base->xid, ptr->base->args),
+ NULL,ptr->base->td->flag, stmt_self(ptr)->pos);
def->base->ret_type = ptr->base->ret_type;
ptr->base->func = new_func(env->gwion->p, s_name(ptr->base->xid), def);
ptr->value->d.func_ref = ptr->base->func;
}
-ANN static m_bool multi_decl(const Exp e, const Operator op) {
+ANN static m_bool multi_decl(const Env env, const Exp e, const Operator op) {
if(e->exp_type == ae_exp_decl) {
if(e->d.exp_decl.list->next)
ERR_B(e->pos, "cant '%s' from/to a multi-variable declaration.", op2str(op))
ANN static inline m_bool scan2_exp_binary(const Env env, const Exp_Binary* bin) { GWDEBUG_EXE
CHECK_BB(scan2_exp(env, bin->lhs))
CHECK_BB(scan2_exp(env, bin->rhs))
- CHECK_BB(multi_decl(bin->lhs, bin->op))
- return multi_decl(bin->rhs, bin->op);
+ CHECK_BB(multi_decl(env, bin->lhs, bin->op))
+ return multi_decl(env, bin->rhs, bin->op);
}
ANN static inline m_bool scan2_exp_cast(const Env env, const Exp_Cast* cast) { GWDEBUG_EXE
return GW_OK;
}
-ANN static m_bool scan2_func_def_overload(const Func_Def f, const Value overload) { GWDEBUG_EXE
+ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) { GWDEBUG_EXE
const m_bool base = tmpl_list_base(f->tmpl);
const m_bool tmpl = GET_FLAG(overload, template);
if(isa(overload->type, t_function) < 0)
- ERR_B(f->base->td->xid->pos, "function name '%s' is already used by another value", overload->name)
+ ERR_B(f->pos, "function name '%s' is already used by another value", overload->name)
if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f, template)))
- ERR_B(f->base->td->xid->pos, "must overload template function with template")
+ ERR_B(f->pos, "must overload template function with template")
return GW_OK;
}
f->base->args->var_decl->value->type;
const Type r = GET_FLAG(f, unary) ? f->base->args->var_decl->value->type :
f->base->args->next ? f->base->args->next->var_decl->value->type : NULL;
- struct Op_Import opi = { .op=op, .lhs=l, .rhs=r, .ret=f->base->ret_type };
+ struct Op_Import opi = { .op=op, .lhs=l, .rhs=r, .ret=f->base->ret_type, .pos=f->pos };
CHECK_BB(env_add_op(env, &opi))
if(env->class_def) {
if(env->class_def == l)
const Value overload = nspc_lookup_value0(env->curr, f->base->xid);
m_str func_name = s_name(f->base->xid);
if(overload)
- CHECK_BB(scan2_func_def_overload(f, overload))
+ CHECK_BB(scan2_func_def_overload(env, f, overload))
if(tmpl_list_base(f->tmpl))
return scan2_func_def_template(env, f, overload);
if(!f->tmpl) {
return NULL;
}
-ANN static Type prim_ref(const Type t, const Type_Decl* td) {
+ANN static inline Type prim_ref(const Env env, const Type t, const Type_Decl* td) {
if(GET_FLAG(td, ref) && isa(t, t_object) < 0 && isa(t, t_class) < 0)
ERR_O(td->xid->pos, "primitive types cannot be used as reference (@)...\n")
return t;
if(!td->xid)
return t_undefined;
const Type t = type_decl_resolve(env, td);
- return t ? prim_ref(t, td) : type_unknown(env, td->xid);
+ return t ? prim_ref(env, t, td) : type_unknown(env, td->xid);
}
#include "vm.h"
#include "parse.h"
-ANN m_bool isres(const Symbol xid) {
+ANN m_bool isres(const Env env, const Symbol xid, const uint pos) {
const m_str s = s_name(xid);
if(!strcmp(s, "this") || !strcmp(s, "vararg") || !name2op(s))
- ERR_B(0, "%s is reserved.", s_name(xid));
+ ERR_B(pos, "%s is reserved.", s_name(xid));
return GW_OK;
}
map_set(&pi->drv, (vtype)str(), (vtype)drv);
}
} else
- err_msg(0, "error in %s.", DLERROR());
+ gw_err("error in %s.", DLERROR());
}
ANN PlugInfo* new_plug(MemPool p, const Vector list) {
-// [contains] in function 'test'
+// [contains] in function:
function void test() { <<<b>>>; }
-Subproject commit 48ce5516794eb7deefa558bbb2229ff3f827ce74
+Subproject commit cb9e371b894ede91c4c0830e1ee494dd50483c02