-Subproject commit de339e926479367591c6dd16f63d331a4aedc797
+Subproject commit be6de5a94edfab64aa61709c2a9ff3f1de5b9bff
ANN m_bool type_engine_check_prog(const Env, const Ast);
ANN Func get_func(const Env, const Func_Def);
ANN m_bool traverse_func_template(const Env env, const Func_Def def, const Type_List types);
+ANN ID_List str2list(SymTable *st, const m_str path, m_uint* array_depth);
#endif
(_exp_func)prefix##_exp_decl, (_exp_func)prefix##_exp_binary, (_exp_func)prefix##_exp_unary, \
(_exp_func)prefix##_exp_primary, (_exp_func)prefix##_exp_cast, (_exp_func)prefix##_exp_post, \
(_exp_func)prefix##_exp_call, (_exp_func)prefix##_exp_array, (_exp_func)prefix##_exp_if, \
- (_exp_func)prefix##_exp_dot, (_exp_func)prefix##_exp_lambda \
+ (_exp_func)prefix##_exp_dot, (_exp_func)prefix##_exp_lambda, (_exp_func)prefix##_exp_typeof \
};
#define DECL_SECTION_FUNC(prefix) \
#define HANDLE_EXP_FUNC(prefix, type, ret) \
DECL_EXP_FUNC(prefix) \
-ANN static inline type prefix##_exp(const Env env, Exp exp) { GWDEBUG_EXE \
+ANN type prefix##_exp(const Env env, Exp exp) { GWDEBUG_EXE \
do CHECK_BB(exp_func[exp->exp_type](env, &exp->d)) \
while((exp = exp->next)); \
return ret; \
}
+ANN m_bool scan1_exp(const Env, Exp);
+ANN m_bool scan2_exp(const Env, Exp);
#define describe_stmt_func(prefix, name, type, prolog, exp) \
ANN static m_bool prefix##_stmt_##name(const Env env, const type stmt) { GWDEBUG_EXE \
Type t_void, t_int, t_bool, t_float, t_dur, t_time, t_now, t_complex, t_polar, t_vec3, t_vec4,
t_null, t_object, t_shred, t_fork, t_event, t_ugen, t_string, t_ptr, t_array, t_gack,
- t_function, t_fptr, t_vararg, t_lambda, t_class, t_union;
+ t_function, t_fptr, t_vararg, t_lambda, t_class, t_union, t_undefined;
ANN2(1,3) ANEW Type new_type(MemPool, const m_uint xid, const m_str name, const Type);
ANEW ANN Type type_copy(MemPool, const Type type);
offset += e->type->size;
if(e->type != emit->env->class_def)
ADD_REF(e->type);
+puts(e->type->name);
} while((e = e->next));
if(emit_exp(emit, exp, 0) < 0) {
free_vector(emit->gwion->p, v);
ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const uint emit_var) { GWDEBUG_EXE
const m_uint size = v->type->size;
- const Instr instr = emit_kind(emit, size, emit_var, dotstatic);
- instr->m_val = (m_uint)(v->owner_class->nspc->info->class_data + v->offset);
- instr->m_val2 = size;
+ if(isa(v->type, t_class) < 0) {
+ const Instr instr = emit_kind(emit, size, emit_var, dotstatic);
+ instr->m_val = (m_uint)(v->owner_class->nspc->info->class_data + v->offset);
+ instr->m_val2 = size;
+ } else {
+ const Instr instr = emit_add_instr(emit, RegPushImm);
+ instr->m_val = (m_uint)v->type;
+ }
return GW_OK;
}
const m_bool is_obj = isa(type, t_object) > 0;
const uint emit_addr = ((is_ref && !array) || isa(type, t_object) < 0) ?
emit_var : 1;
+puts(v->type->name);
if(is_obj && (is_array || !is_ref))
CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
f_instr *exec = (f_instr*)allocmember;
return GW_OK;
}
+ANN static m_bool emit_exp_typeof(const Emitter emit, const Exp_Typeof *exp) {
+ const Instr instr = emit_add_instr(emit, RegPushImm);
+ instr->m_val = (m_uint)exp->exp->type;
+ return GW_OK;
+}
+
DECL_EXP_FUNC(emit)
ANN2(1) static m_bool emit_exp(const Emitter emit, Exp exp, const m_bool ref) { GWDEBUG_EXE
}
ANN static m_bool import_core_libs(const Gwi gwi) {
- CHECK_OB((t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL)))
+ CHECK_OB((t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL))) // size = SZ_INT to enable declarations
+ CHECK_OB((t_class = gwi_mk_type(gwi, "Class", SZ_INT, NULL)))
+ CHECK_BB(gwi_add_type(gwi, t_class))
+ SET_FLAG(t_class, abstract);
CHECK_OB((t_void = gwi_mk_type(gwi, "void", 0, NULL)))
CHECK_BB(gwi_add_type(gwi, t_void))
CHECK_OB((t_null = gwi_mk_type(gwi, "@null", SZ_INT, NULL)))
print_object(type, *(M_Object*)(reg-offset));
else if(isa(type, t_function) > 0)
print_func(type, (reg-offset));
+ else if(type == t_class)
+ print_type(type);
else if(isa(type, t_class) > 0)
print_type(type->d.base_type);
else if(isa(type, t_void) > 0)
return GW_OK;
}
-ANN static ID_List str2list(SymTable *st, const m_str path, m_uint* array_depth) {
+ANN /* static */ ID_List str2list(SymTable *st, const m_str path, m_uint* array_depth) {
const m_uint len = strlen(path);
ID_List list = NULL;
m_uint depth = 0;
static OP_CHECK(opck_ptr_assign) {
const Exp_Binary* bin = (Exp_Binary*)data;
-Type t = bin->lhs->type;
-do {
- if(!strcmp(t->name, get_type_name(env, bin->rhs->type->name, 1))) {
- if(bin->lhs->meta != ae_meta_var)
- ERR_N(0, "left side operand is constant")
- bin->lhs->emit_var = 1;
- return bin->lhs->type;
- }
-} while((t = t->parent));
+ Type t = bin->lhs->type;
+ do {
+ if(!strcmp(t->name, get_type_name(env, bin->rhs->type->name, 1))) {
+ if(bin->lhs->meta != ae_meta_var)
+ ERR_N(0, "left side operand is constant")
+ bin->lhs->emit_var = 1;
+ return bin->lhs->type;
+ }
+ } while((t = t->parent));
return t_null;
}
return GW_OK;
}
+ANN Type check_td(const Env env, Type_Decl *td) {
+ CHECK_BO(scan1_exp(env, td->exp))
+ CHECK_BO(scan2_exp(env, td->exp))
+ CHECK_OO(check_exp(env, td->exp))
+//assert(actual_type(td->exp->type));
+//printf("HERE %p %p %p\n", t_class, td->exp->type, td->exp->type->d.base_type);
+ if(!actual_type(td->exp->type) || (isa(td->exp->type, t_class) < 0 && actual_type(td->exp->type) == t_class))
+ ERR_O(td->exp->pos, "Expression must be of type '%s', not '%s'\n"
+ "maybe you meant typeof(Expression)", t_class->name, td->exp->type->name);
+ m_uint depth;
+ td->xid = str2list(env->gwion->st, actual_type(td->exp->type)->name, &depth);
+ return actual_type(td->exp->type);
+}
+
ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE
Var_Decl_List list = decl->list;
+
+ if(!decl->td->xid) {
+ const Type t = check_td(env, decl->td);
+ CHECK_OO(t)
+ ((Exp_Decl*)decl)->type = NULL;
+ CHECK_BO(scan1_exp(env, exp_self(decl)))
+ CHECK_BO(scan2_exp(env, exp_self(decl)))
+ }
if(GET_FLAG(decl->type , template)) {
const Type t = typedef_base(decl->type);
CHECK_BO(traverse_template(env, t->def))
if(global)
scope = env_push_global(env);
do {
- if(!env->class_def && !GET_FLAG(list->self->value, builtin) &&
- !GET_FLAG(list->self->value, used)) {
- err_msg(list->self->pos, "unused variable '%s'",
- list->self->value->name);
- continue;
- }
const Var_Decl var = list->self;
const Value v = var->value;
if(env->class_def && !env->scope->depth && env->class_def->parent)
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 = known_type(env, cast->td)))
+ 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")
}
ANN static Type check_exp_lambda(const Env env NUSED,
const Exp_If* exp_if NUSED) { return t_lambda; }
+ANN static Type check_exp_typeof(const Env env, const Exp_Typeof *exp) {
+ const Type t = check_exp(env, exp->exp);
+ CHECK_OO(t)
+ const Value v = nspc_lookup_value1(t->owner, insert_symbol(t->name));
+ CHECK_OO(v)
+ return v->type;
+}
+
static const _type_func exp_func[] = {
(_type_func)check_exp_decl, (_type_func)check_exp_binary, (_type_func)check_exp_unary,
(_type_func)check_exp_primary, (_type_func)check_exp_cast, (_type_func)check_exp_post,
(_type_func)check_exp_call, (_type_func)check_exp_array, (_type_func)check_exp_if,
- (_type_func)check_exp_dot, (_type_func)check_exp_lambda
+ (_type_func)check_exp_dot, (_type_func)check_exp_lambda, (_type_func)check_exp_typeof
};
ANN static inline Type check_exp(const Env env, const Exp exp) { GWDEBUG_EXE
do {
const Var_Decl decl = arg_list->var_decl;
const Value v = decl->value;
+ if(arg_list->td && !arg_list->td->xid)
+ arg_list->type = v->type = check_td(env, arg_list->td);
if(isa(v->type, t_object) > 0 || isa(v->type, t_function) > 0)
UNSET_FLAG(env->func, pure);
CHECK_BB(already_defined(env, decl->xid, decl->pos))
m_bool ret = GW_OK;
if(tmpl_list_base(f->tmpl))
return env->class_def ? check_parent_match(env, f) : 1;
+ if(f->base->td && !f->base->td->xid) {
+ f->base->ret_type = check_td(env, f->base->td);
+ return traverse_func_def(env, f);
+ }
CHECK_BB(check_func_def_override(env, f))
if(env->class_def)
CHECK_BB(check_parent_match(env, f))
ANN m_bool check_class_def(const Env env, const Class_Def class_def) { GWDEBUG_EXE
if(tmpl_class_base(class_def->tmpl))
return GW_OK;
+ if(class_def->base.type->parent == t_undefined) {
+ class_def->base.type->parent = check_td(env, class_def->base.ext);
+ return traverse_class_def(env, class_def);
+ }
const Type the_class = class_def->base.type;
if(class_def->base.ext)
CHECK_BB(check_class_parent(env, class_def))
#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 /* static */ m_bool scan1_exp(const Env env, Exp exp);
ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
ANN m_bool scan1_class_def(const Env env, const Class_Def class_def);
ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
const Var_Decl var = list->self;
const Value former = nspc_lookup_value0(env->curr, var->xid);
CHECK_BB(isres(var->xid))
- if(former && (!env->class_def ||
+ if(!decl->td->exp && former && (!env->class_def ||
(!GET_FLAG(env->class_def, template) || !GET_FLAG(env->class_def, scan1))))
ERR_B(var->pos, "variable %s has already been defined in the same scope...",
s_name(var->xid))
SET_FLAG(v, ref);
if(!env->func && !env->scope->depth && !env->class_def)
SET_FLAG(v, global);
+ v->type = t;
v->d.ptr = var->addr;
v->owner = !env->func ? env->curr : NULL;
v->owner_class = env->scope->depth ? NULL : env->class_def;
return scan1_exp(env, exp_if->else_exp);
}
-ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary * unary) {
+ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary *unary) {
if((unary->op == op_spork || unary->op == op_fork) && unary->code)
return scan1_stmt(env, unary->code);
return unary->exp ? scan1_exp(env, unary->exp) : GW_OK;
}
+ANN static inline m_bool scan1_exp_typeof(const restrict Env env, const Exp_Typeof *exp) {
+ return scan1_exp(env, exp->exp);
+}
+
#define scan1_exp_lambda dummy_func
HANDLE_EXP_FUNC(scan1, m_bool, 1)
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;
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);
CHECK_OB(parent)
+ if(parent == t_undefined)
+ return GW_OK;
if(parent == class_def->base.type)
- ERR_B(class_def->base.ext->xid->pos, "class '%s' cannot extend itself",
+ ERR_B(pos, "class '%s' cannot extend itself",
class_def->base.type->name);
if(isa(class_def->base.type->parent, t_object) < 0)
- ERR_B(class_def->base.ext->xid->pos, "cannot extend primitive type '%s'",
+ ERR_B(pos, "cannot extend primitive type '%s'",
class_def->base.type->parent->name)
if(!GET_FLAG(parent, scan1) && parent->def)
CHECK_BB(scan1_class_def(env, parent->def))
if(type_ref(parent))
- ERR_B(class_def->base.ext->xid->pos, "can't use ref type in class extend")
+ ERR_B(pos, "can't use ref type in class extend")
return GW_OK;
}
#include "nspc.h"
#include "operator.h"
-ANN static m_bool scan2_exp(const Env, const Exp);
+ANN /* static */ m_bool scan2_exp(const Env, const Exp);
ANN static m_bool scan2_stmt(const Env, const Stmt);
ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
extern ANN m_bool scan1_class_def(const Env, const Class_Def);
return GW_OK;
}
+ANN static inline m_bool scan2_exp_typeof(const restrict Env env, const Exp_Typeof *exp) {
+ return scan2_exp(env, exp->exp);
+}
+
#define scan2_exp_lambda dummy_func
HANDLE_EXP_FUNC(scan2, m_bool, 1)
f->stack_depth += SZ_INT;
if(GET_FLAG(func->def, variadic))
f->stack_depth += SZ_INT;
- f->base->ret_type = type_decl_resolve(env, f->base->td);
+ f->base->ret_type = known_type(env, f->base->td);
return (f->base->args && f->base->args->type) ? scan2_args(env, f) : GW_OK;
}
}
}
ANN static Type prim_ref(const Type t, const Type_Decl* td) {
- if(GET_FLAG(td, ref) && isa(t, t_object) < 0)
+ 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;
}
ANN Type known_type(const Env env, const Type_Decl* td) {
+ 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);
}
--- /dev/null
+~~ 1 + 2 ~~ i;
\ No newline at end of file
+++ /dev/null
-// [contains] unused variable
-int i;