-Subproject commit 3047b71b37f6f2416d9374da8875a7d17da0ad65
+Subproject commit 2c9e91d5b289259b22c78a2b75b34b3c4111dbc6
#! write members
<<< 12 => c.i >>>;
<<< 1.2 => c.f >>>;
-<<< null @=> c.o >>>;
+++ /dev/null
-fun void test(Object o) { <<< o >>>; }
-<<< new Object == null , " ", null => test >>>;
<<< "success" >>>;
}
-#!operator int plusplus(null d, int i){}
var int i;
var Object o;
<<< o, " ", i >>>;
#! write members
<<< 12 => C.i >>>;
<<< 1.2 => C.f >>>;
-<<< null @=> C.o >>>;
var string s;
"CamelCase" => s;
<<< "test" => s >>>;
-<<< null @=> s >>>; #!test me
+++ /dev/null
-union
-{
- int i;
- Object o;
-};
-<<< i, " ", o >>>;
}
}
test(1);
-test(1, 2.3, null);
+test(1, 2.3, new Object);
ANN m_uint emit_local(const Emitter emit, const Type t);
ANN Instr emit_exp_spork(const Emitter, const Exp_Unary*);
ANN m_bool emit_exp(const Emitter, const Exp);
-ANN static inline void emit_except(const Emitter emit, const Type t) {
- if(!GET_FLAG(t, nonnull))
- emit_add_instr(emit, GWOP_EXCEPT);
-}
ANN static inline Instr emit_gc(const Emitter emit, const m_int offset) {
const Instr gc = emit_add_instr(emit, GcAdd);
gc->m_val = offset;
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, Type_Decl*);
-__attribute__((returns_nonnull))
-ANN Type special_type(const Env, const Type, const uint);
-#define nonnul_type(a, b) special_type(a, (b), 0);
-#define force_type(a, b) special_type(a, (b), 1);
ANN Type prim_ref(const Env env, const Type t, const Type_Decl* td);
ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos);
ANN m_bool env_storage(const Env env, ae_flag flag, const loc_t pos);
tflag_dtor = 1 << 15,
tflag_tmpl = 1 << 16,
tflag_typedef = 1 << 17,
- tflag_nonnull = 1 << 18,
- tflag_force = 1 << 19,
} __attribute__((packed));
struct Type_ {
return t; // unreachable
}
-__attribute__((returns_nonnull))
-ANN Type unflag_type(const Type t);
__attribute__((returns_nonnull))
ANN Type get_type(const Type t);
-ANN static inline int is_special(const Type t) {
- return tflag(t, tflag_nonnull) || tflag(t, tflag_force);
-}
typedef enum {
et_void, et_int, et_bool, et_char, et_float,
- et_null, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack,
+ et_error, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack,
et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_undefined, et_auto,
MAX_TYPE
} type_enum;
#define __OPERATOR
#define OP_ANY_TYPE (Type)1
-#define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return env->gwion->type[et_null]; }
-#define DECL_ON(decl, f, exp) decl f exp; { if(!f) return env->gwion->type[et_null]; }
-#define DECL_BN(decl, f, exp) decl f exp; { if(f < 0) return env->gwion->type[et_null]; }
-#define DECL_NN(decl, f, exp) decl f exp; { if(f == env->gwion->type[et_null]) return env->gwion->type[et_null]; }
-#define CHECK_ON(f) { if(!f) return env->gwion->type[et_null]; }
-#define CHECK_NB(f) { if(f == env->gwion->type[et_null]) return GW_ERROR; }
-#define CHECK_NO(f) { if(f == env->gwion->type[et_null]) return NULL; }
-#define CHECK_BN(f) { if(f < 0) return env->gwion->type[et_null]; }
-#define CHECK_NN(f) { if(f == env->gwion->type[et_null]) return env->gwion->type[et_null]; }
+#define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return env->gwion->type[et_error]; }
+#define DECL_ON(decl, f, exp) decl f exp; { if(!f) return env->gwion->type[et_error]; }
+#define DECL_BN(decl, f, exp) decl f exp; { if(f < 0) return env->gwion->type[et_error]; }
+#define DECL_NN(decl, f, exp) decl f exp; { if(f == env->gwion->type[et_error]) return env->gwion->type[et_error]; }
+#define CHECK_ON(f) { if(!f) return env->gwion->type[et_error]; }
+#define CHECK_NB(f) { if(f == env->gwion->type[et_error]) return GW_ERROR; }
+#define CHECK_NO(f) { if(f == env->gwion->type[et_error]) return NULL; }
+#define CHECK_BN(f) { if(f < 0) return env->gwion->type[et_error]; }
+#define CHECK_NN(f) { if(f == env->gwion->type[et_error]) return env->gwion->type[et_error]; }
typedef Type (*opck)(const Env, void*, m_bool*);
typedef struct Instr_* (*opem)(const Emitter, void*);
keyword_private="private"
keyword_const="const"
keyword_ref="ref"
-keyword_nonnull="nonnull"
keyword_if="if"
keyword_else="else"
keyword_break="break"
ANN void emit_ext_ctor(const Emitter emit, const Type t);
ANN static inline void maybe_ctor(const Emitter emit, const Type t) {
- if(!is_special(t) && tflag(t, tflag_ctor))
+ if(tflag(t, tflag_ctor))
emit_ext_ctor(emit, t);
}
regseti(emit, (m_uint)e->info->type);
interp_size(emit, e->info->type);
const m_bool isobj = isa(e->info->type, emit->gwion->type[et_object]) > 0;
- if(isobj && !tflag(e->info->type, tflag_force))
+ if(isobj && e->exp_type != ae_exp_cast)
emit_add_instr(emit, GackType);
const Instr instr = emit_add_instr(emit, Gack);
instr->m_val = emit_code_offset(emit);
CHECK_BB(emit_exp_decl_non_static(emit, decl, list->self, ref, var))
else
CHECK_BB(emit_exp_decl_global(emit, list->self, ref, var))
+ if(!var && !GET_FLAG(decl->td, optionnal) && (GET_FLAG(decl->td, ref) || is_fptr(emit->gwion, list->self->value->type)))
+ ERR_B(list->self->pos, "kljlkj")
} while((list = list->next));
return GW_OK;
}
ANN static Instr get_prelude(const Emitter emit, const Func f) {
const Type t = actual_type(emit->gwion, f->value_ref->type);
if(is_fptr(emit->gwion, t)) {
- emit_except(emit, t);
if(f->def->base->tmpl)
tmpl_prelude(emit, f);
}
emit_exp_addref1(emit, e, -exp_size(e));
struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"),
.rhs=e->info->type, .pos=e->pos, .data=(uintptr_t)e, .op_type=op_exp };
- const Instr instr = op_emit(emit, &opi);
- assert(instr != (Instr)GW_OK);
- return instr;
+ return op_emit(emit, &opi);
}
#define emit_flow(emit,b) _flow(emit, b, 1)
Exp exp = e;
do {
CHECK_BB(emit_exp_func[exp->exp_type](emit, &exp->d))
- if(exp_getnonnull(exp))
- emit_except(emit, exp->info->type);
if(exp->info->cast_to)
CHECK_BB(emit_implicit_cast(emit, exp, exp->info->cast_to))
} while((exp = exp->next));
emit_local(emit, emit->gwion->type[et_int]);
stmt->v->from->offset = offset + SZ_INT;
const m_uint ini_pc = emit_code_size(emit);
- emit_except(emit, stmt->exp->info->type);
const Instr loop = emit_add_instr(emit, stmt->is_ptr ? AutoLoopPtr : AutoLoop);
const Instr end = emit_add_instr(emit, BranchEqInt);
const m_bool ret = scoped_stmt(emit, stmt->body, 1);
#include "object.h"
ANN static inline m_bool freeable(const Type a) {
- return !(tflag(a, tflag_force) || tflag(a, tflag_nonnull)) && (tflag(a, tflag_tmpl) ||GET_FLAG(a, global));
+ return tflag(a, tflag_tmpl) ||GET_FLAG(a, global);
}
ANN void free_type(const Type a, struct Gwion_ *const gwion) {
+++ /dev/null
-#include "gwion_util.h"
-#include "gwion_ast.h"
-#include "gwion_env.h"
-#include "vm.h"
-#include "gwion.h"
-
-static m_str const special_name[] = { "^nonnull", "^force" };
-#define SPECIAL_LEN strlen(special_name[0]) + strlen(special_name[1])
-static const enum tflag special_flag[] = { tflag_nonnull, tflag_force };
-
-typedef struct {
- const Type type;
- Symbol name;
- enum tflag flag;
- uint st_type;
-} SpecialType;
-
-
-ANN static Type specialtype_create(const Env env, const SpecialType *s) {
- const Type t = type_copy(env->gwion->mp, s->type);
- if(t->nspc)
- nspc_addref(t->nspc);
- t->name = s_name(s->name);
- t->flag = s->type->flag;
- t->tflag |= s->type->tflag | s->flag;
- t->info->parent = unflag_type(s->type);
- nspc_add_type_front(s->type->info->owner, s->name, t);
- mk_class(env, t);
- return t;
-}
-
-static inline int get_flag(const Type t, const enum tflag flag) {
- return (t->tflag & flag) == flag;
-}
-
-
-ANN static void specialtype_flag(SpecialType *s, m_str c, const uint i) {
- const enum tflag flag = special_flag[i];
- if(i == s->st_type || get_flag(s->type, flag)) {
- strcat(c, special_name[i]);
- s->flag |= flag;
- }
-}
-
-ANN static void specialtype_init(SymTable *st, SpecialType *s) {
- const size_t sz = strlen(s->type->name);
- char c[sz + SPECIAL_LEN + 1];
- strcpy(c, s->type->name);
- m_str flagged = strchr(c, '^');
- if(flagged)
- *flagged = '\0';
- specialtype_flag(s, c, 0);
- specialtype_flag(s, c, 1);
- s->name = insert_symbol(st, c);
-}
-
-ANN Type special_type(const Env env, const Type t, const uint st_type) {
- SpecialType s = { .type=t, .st_type=st_type };
- specialtype_init(env->gwion->st, &s);
- return nspc_lookup_type1(t->info->owner, s.name) ?:
- specialtype_create(env, &s);
-}
}
ANN Type_Decl* str2decl(const Gwion gwion, const m_str str, const loc_t pos) {
- const ae_flag flag = strncmp(str, "nonnull ", 8) ? ae_flag_none : ae_flag_nonnull;
struct td_checker tdc = { .str=str, .pos=pos };
- if(flag == ae_flag_nonnull)
- tdc.str += 8;
DECL_OO(Type_Decl *, td, = _str2decl(gwion, &tdc))
if(*tdc.str) {
free_type_decl(gwion->mp, td);
GWION_ERR_O(pos, "excedental character '%c'", *tdc.str);
}
- td->flag |= flag;
return td;
}
}
static DTOR(array_dtor) {
- const Type t = unflag_type(o->type_ref);
+ const Type t = o->type_ref;
if(*(void**)(o->data + SZ_INT))
xfree(*(void**)(o->data + SZ_INT));
struct M_Vector_* a = ARRAY(o);
const M_Vector v = ARRAY(o);
if(index < 0 || (m_uint)index >= ARRAY_LEN(v))
return;
- const Type t = unflag_type(o->type_ref);
+ const Type t = o->type_ref;
if(t->nspc->info->class_data_size)
(*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v));
m_vector_rem(v, (vtype)index);
static OP_CHECK(opck_array_at) {
const Exp_Binary* bin = (Exp_Binary*)data;
- if(opck_const_rhs(env, data, mut) == env->gwion->type[et_null])
- return env->gwion->type[et_null];
- if(bin->lhs->info->type != env->gwion->type[et_null]) {
+ if(opck_const_rhs(env, data, mut) == env->gwion->type[et_error])
+ return env->gwion->type[et_error];
+ if(bin->lhs->info->type != env->gwion->type[et_error]) {
ARRAY_OPCK(bin->lhs, bin->rhs, exp_self(bin)->pos)
if(bin->lhs->info->type->array_depth != bin->rhs->info->type->array_depth)
ERR_N(exp_self(bin)->pos, _("array depths do not match."))
ANN static Type check_array_shift(const Env env,
const Exp a, const Exp b, const m_str str, const loc_t pos) {
- if(a->info->type == env->gwion->type[et_null] &&
+ if(a->info->type == env->gwion->type[et_error] &&
b->info->type->array_depth > 1)
return a->info->type;
ARRAY_OPCK(a, b, pos)
r = r->info->parent;
if(get_depth(cast->exp->info->type) == get_depth(exp_self(cast)->info->type) && isa(l->info->base_type, r->info->base_type) > 0)
return l;
- return env->gwion->type[et_null];
+ return env->gwion->type[et_error];
}
static OP_CHECK(opck_array_slice) {
const Exp e = (Exp)data;
exp_setmeta(exp_self(e), 1);
- exp_setnonnull(e->d.exp_slice.base, 1);
return e->d.exp_slice.base->info->type;
}
ANN static void array_loop(const Emitter emit, const m_uint depth) {
const Instr pre_pop = emit_add_instr(emit, RegPop);
pre_pop->m_val = depth * SZ_INT;
- emit_add_instr(emit, GWOP_EXCEPT);
for(m_uint i = 0; i < depth - 1; ++i) {
const Instr access = emit_add_instr(emit, ArrayAccess);
access->m_val = i * SZ_INT;
const Instr get = emit_add_instr(emit, ArrayGet);
get->m_val = i * SZ_INT;
get->m_val2 = -SZ_INT;
- emit_add_instr(emit, GWOP_EXCEPT);
}
const Instr post_pop = emit_add_instr(emit, RegPop);
post_pop->m_val = SZ_INT;
info->array = next;
return (Instr)(m_uint)(exp ? emit_array_access(emit, info) : GW_ERROR);
}
-OP_EMIT(opem_at_object);
+
GWION_IMPORT(array) {
const Type t_array = gwi_class_ini(gwi, "@Array", NULL);
gwi->gwion->type[et_array] = t_array;
GWI_BB(gwi_class_end(gwi))
GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL))
GWI_BB(gwi_oper_add(gwi, opck_array_at))
- GWI_BB(gwi_oper_emi(gwi, opem_at_object))
- GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
- GWI_BB(gwi_oper_ini(gwi, "@null", "@Array", NULL))
- GWI_BB(gwi_oper_add(gwi, opck_array_at))
GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
- GWI_BB(gwi_oper_ini(gwi, "nonnull @Array", (m_str)OP_ANY_TYPE, NULL))
+ GWI_BB(gwi_oper_ini(gwi, "@Array", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_array_sl))
GWI_BB(gwi_oper_emi(gwi, opem_array_sl))
GWI_BB(gwi_oper_end(gwi, "<<", NULL))
- GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "nonnull @Array", NULL))
+ GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@Array", NULL))
GWI_BB(gwi_oper_add(gwi, opck_array_sr))
GWI_BB(gwi_oper_emi(gwi, opem_array_sr))
GWI_BB(gwi_oper_end(gwi, ">>", NULL))
GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL))
GWI_BB(gwi_oper_add(gwi, opck_array_cast))
GWI_BB(gwi_oper_end(gwi, "$", NULL))
- GWI_BB(gwi_oper_ini(gwi, "int", "nonnull @Array", "int"))
+ GWI_BB(gwi_oper_ini(gwi, "int", "@Array", "int"))
GWI_BB(gwi_oper_add(gwi, opck_array_slice))
GWI_BB(gwi_oper_emi(gwi, opem_array_slice))
GWI_BB(gwi_oper_end(gwi, "@slice", NULL))
POP_REG(shred, SZ_INT - instr->m_val);
memcpy(REG(-instr->m_val), o->data + SZ_INT, instr->m_val);
}
-
+MFUN(union_is);
static OP_EMIT(opem_dot_union) {
Exp_Dot *dot = (Exp_Dot*)data;
CHECK_BO(emit_exp(emit, dot->base))
+ if(isa(exp_self(dot)->info->type, emit->gwion->type[et_function]) > 0) {
+ const Func f = (Func)vector_at(&dot->t_base->nspc->info->vtable, 0);
+ const Instr instr = emit_add_instr(emit, RegPushImm);
+ instr->m_val = (m_uint)f->code;
+ return instr;
+ }
const uint emit_var = exp_getvar(exp_self(dot));
const Value v = nspc_lookup_value0(dot->t_base->nspc, dot->xid);
const Instr instr = emit_add_instr(emit, !emit_var ? UnionGet : UnionSet);
GWI_BB(gwi_func_ini(gwi, "void", "broadcast"))
GWI_BB(gwi_func_end(gwi, event_broadcast, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
- GWI_BB(gwi_oper_ini(gwi, "nonnull Event", "@now", "int"))
+ GWI_BB(gwi_oper_ini(gwi, "Event", "@now", "int"))
GWI_BB(gwi_oper_end(gwi, "=>", EventWait))
return GW_OK;
}
struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
const m_str name = dt->name;
const M_Object o = *(M_Object*)REG(-SZ_INT);
- Type t = !tflag(o->type_ref, tflag_nonnull) ? o->type_ref : o->type_ref->info->parent;
+ Type t = o->type_ref;
do {
const Emitter emit = shred->info->vm->gwion->emit;
emit->env->name = "runtime";
e->exp_type = ae_exp_call;
memcpy(&e->d.exp_call, &call, sizeof(Exp_Call));
++*mut;
- return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_null];
+ return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error];
}
static inline void fptr_instr(const Emitter emit, const Func f, const m_uint i) {
ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
if(isa(info->exp->info->type, env->gwion->type[et_lambda]) < 0) {
- m_bool nonnull = tflag(info->exp->info->type, tflag_nonnull);
CHECK_BB(fptr_check(env, info))
- DECL_OB(const Type, t, = fptr_type(env, info))
- info->exp->info->type = !nonnull ? t : nonnul_type(env, t);
+ CHECK_OB((info->exp->info->type = fptr_type(env, info)))
return GW_OK;
}
Exp_Lambda *l = &info->exp->d.exp_lambda;
const Exp_Binary* bin = (Exp_Binary*)data;
// we'll only deal with auto fptr declaration
if(bin->rhs->exp_type != ae_exp_decl && bin->rhs->d.exp_decl.td->xid != insert_symbol("auto"))
- return env->gwion->type[et_null];
+ return env->gwion->type[et_error];
// create a matching signature
// TODO: we could check first if there a matching existing one
Func_Base *const fbase = cpy_func_base(env->gwion->mp, bin->lhs->info->type->info->func->def->base);
type_remref(t, env->gwion);
bin->rhs->d.exp_decl.list->self->value->type = bin->rhs->info->type = bin->rhs->d.exp_decl.type = t;
exp_setvar(bin->rhs, 1);
- return ret > 0 ? t : env->gwion->type[et_null];
+ return ret > 0 ? t : env->gwion->type[et_error];
}
static OP_CHECK(opck_fptr_at) {
return bin->rhs->info->type;
}
-static OP_CHECK(opck_null_fptr_at) {
- Exp_Binary* bin = (Exp_Binary*)data;
- CHECK_NN(opck_const_rhs(env, bin, mut))
- exp_setvar(bin->rhs, 1);
- return bin->rhs->info->type;
-}
-
static OP_CHECK(opck_fptr_cast) {
Exp_Cast* cast = (Exp_Cast*)data;
const Type t = exp_self(cast)->info->type;
dup->m_val = -SZ_INT;
}
-static int is_member(const Type from, const Type to) {
- return vflag(from->info->func->value_ref, vflag_member) &&
- !(tflag(from, tflag_nonnull) || tflag(to, tflag_nonnull));
+static inline int is_member(const Type from) {
+ return vflag(from->info->func->value_ref, vflag_member);
}
static OP_EMIT(opem_fptr_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
if(exp_self(cast)->info->type->info->func->def->base->tmpl)
fptr_instr(emit, cast->exp->info->type->info->func, 1);
- if(is_member(cast->exp->info->type, exp_self(cast)->info->type))
+ if(is_member(cast->exp->info->type))
member_fptr(emit);
return (Instr)GW_OK;
}
static OP_EMIT(opem_fptr_impl) {
struct Implicit *impl = (struct Implicit*)data;
- if(is_member(impl->e->info->type, impl->t))
+ if(is_member(impl->e->info->type))
member_fptr(emit);
if(impl->t->info->func->def->base->tmpl)
fptr_instr(emit, ((Exp)impl->e)->info->type->info->func, 1);
if(t == env->gwion->type[et_void])
return env->gwion->type[et_fork];
char c[21 + strlen(t->name)];
- sprintf(c, "nonnull TypedFork:[%s]", t->name);
+ sprintf(c, "TypedFork:[%s]", t->name);
const Type fork = env->gwion->type[et_fork];
UNSET_FLAG(fork, final);
const Type typed = str2type(env->gwion, "TypedFork", exp_self(unary)->pos);
GWI_BB(gwi_oper_add(gwi, opck_fptr_impl))
GWI_BB(gwi_oper_emi(gwi, opem_fptr_impl))
GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
- GWI_BB(gwi_oper_ini(gwi, "@null", "@func_ptr", NULL))
- GWI_BB(gwi_oper_add(gwi, opck_null_fptr_at))
- GWI_BB(gwi_oper_emi(gwi, opem_func_assign))
- GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
- GWI_BB(gwi_oper_add(gwi, opck_fptr_cast))
- GWI_BB(gwi_oper_emi(gwi, opem_fptr_cast))
- GWI_BB(gwi_oper_end(gwi, "$", NULL))
- GWI_BB(gwi_oper_add(gwi, opck_fptr_impl))
- GWI_BB(gwi_oper_emi(gwi, opem_fptr_impl))
- GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_spork))
GWI_BB(gwi_oper_emi(gwi, opem_spork))
+++ /dev/null
-#require Std
-#require Math
-#require Modules
-
-enum Pitch { C, D, E, F, G, A, B }
-
-class MusicObject {
- fun UGen update() {}
- fun UGen onStart() {}
- fun UGen onEnd() {}
-}
-
-var SinOsc osc;
-
-class MyTone extends MusicObject {
- var float freq;
-
- fun UGen onStart() {
- freq => osc.freq;
- return osc => dac;
- }
-
- fun UGen onEnd() {
- return osc =< dac;
- }
-}
-
-fun MyTone tone(float freq) {
- var MyTone t;
- 660 => t.freq;
- return t;
-}
-
-class Note extends MusicObject {
- var Pitch pitch;
- var int accidental;
- var int octave;
-
-
- fun int toMidi() {
- var int p;
-
- match (pitch) {
- case C: 0 => p;
- case D: 2 => p;
- case E: 4 => p;
- case F: 5 => p;
- case G: 7 => p;
- case A: 9 => p;
- case B: 11 => p;
- }
-
- return p + (12 * (octave+1)) + accidental;
- }
-
- fun UGen onStart() {
- toMidi() => Std.mtof => osc.freq;
- return osc => dac;
- }
-
- fun UGen onEnd() {
- osc =< dac;
- }
-}
-
-fun Note note(Pitch pitch, int accidental, int octave) {
- var Note n;
- A => n.pitch;
- 0 => n.accidental;
- 4 => n.octave;
- return n;
-}
-
-class Coord {
- var dur start;
- var dur end;
-}
-
-fun Coord coord(dur start, dur end) {
- const Coord c;
- start => c.start;
- end => c.end;
- return c;
-}
-
-class TLEvent {
- fun dur getStart() {}
- fun void doIt() {}
-}
-
-class StartTLEvent extends TLEvent {
- var dur start;
- var MusicObject obj;
- fun dur getStart() { return start; }
- fun void doIt() {
- obj.onStart();
- }
-}
-
-fun StartTLEvent startevent(dur start, MusicObject obj) {
- const StartTLEvent evt;
- start => evt.start;
- obj @=> evt.obj;
- return evt;
-}
-
-class EndTLEvent extends TLEvent {
- var dur start;
- var MusicObject obj;
- fun dur getStart() { return start; }
- fun void doIt() {
- obj.onEnd();
- }
-}
-
-fun EndTLEvent endevent(dur start, MusicObject obj) {
- const EndTLEvent evt;
- start => evt.start;
- obj @=> evt.obj;
- return evt;
-}
-
-class DTimeline {
- var TLEvent events[0];
-
- fun void add(TLEvent event) {
- for (0 => var int i; i < events.size(); ++i) {
- if (event.getStart() < events[i].getStart()) {
- for (events.size()-1 => var int j; j >= i; --j) {
- events[j-1] @=> const TLEvent temp;
- events[j] @=> events[j-1];
- temp @=> events[j];
- }
- return;
- }
- }
- events << event;
- }
-
- fun void perform() {
- 0::second => var dur current;
- foreach(evt:events) {
- evt.getStart() - current => now;
- evt.getStart() => current;
- evt.doIt();
- }
- }
-}
-
-class Frame {
- var int test;
- var Coord coord;
- var MusicObject objs[0];
-}
-
-class Timeline {
- const Frame frames[0];
-
- fun void add(Coord c, MusicObject obj) {
- var Frame toAdd;
- for (0 => var int i; i < frames.size(); ++i) {
- if ((c.start >= frames[i].coord.start) && (c.start <= frames[i].coord.start)
- && (c.end >= frames[i].coord.end) && (c.end <= frames[i].coord.end)) {
- frames[i].objs << obj;
- return;
- }
- }
- var Coord c2;
- c.start => c2.start;
- c.end => c2.end;
- toAdd.objs << obj;
- c2 @=> toAdd.coord;
- frames << toAdd;
- }
-
- fun DTimeline toDTimeline() {
- var DTimeline theTL;
- foreach(frame:frames) {
- foreach(obj:frame.objs) {
- theTL.add(startevent(frame.coord.start, obj));
- theTL.add(endevent(frame.coord.end, obj));
- }
- }
- return theTL;
- }
-
- fun void perform() {
- this.toDTimeline().perform();
- }
-}
-
-var Timeline t;
-t.add(coord(0::second, 2::second), note(A,0,4));
-t.add(coord(2::second,4::second), note(C,1,5));
-<<< t.frames[0].objs.size() >>>;
-t.perform();
MemPool p = shred->info->mp;
Type t = o->type_ref;
do {
- if(!t->nspc || is_special(t) || tflag(t, tflag_udef))
+ if(!t->nspc || isa(t, shred->info->vm->gwion->type[et_union]) > 0)
continue;
struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
Value v;
if(env->func && !vflag(env->func->value_ref, vflag_member))
ERR_O(exp_self(prim)->pos, _("keyword 'this' cannot be used inside static functions..."))
if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack"))
- return force_type(env, get_gack(env->class_def->info->parent)); // get_gack ?
+ return get_gack(env->class_def->info->parent); // get_gack ?
return env->class_def;
}
describe_logical(Eq, ==)
describe_logical(Neq, !=)
-static inline m_bool nonnull_check(const Type l, const Type r) {
- return !tflag(l, tflag_nonnull) && tflag(r, tflag_nonnull);
-}
-
-ANN static inline Type check_nonnull(const Env env, const Type l, const Type r,
- const m_str action, const loc_t pos) {
- if(tflag(r, tflag_nonnull)) {
- if(isa(l, env->gwion->type[et_null]) > 0)
- ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
- if(isa(l, unflag_type(r)) < 0)
- ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
- return r->info->parent;
- }
- if(l != env->gwion->type[et_null] && isa(l, r) < 0)
- ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
- return r;
-}
static OP_CHECK(at_object) {
const Exp_Binary* bin = (Exp_Binary*)data;
- const Type l = bin->lhs->info->type;
- const Type r = bin->rhs->info->type;
- if(opck_rassign(env, data, mut) == env->gwion->type[et_null])
- return env->gwion->type[et_null];
- if(check_nonnull(env, l, r, "assign", exp_self(bin)->pos) == env->gwion->type[et_null])
- return env->gwion->type[et_null];
+ if(opck_rassign(env, data, mut) == env->gwion->type[et_error])
+ return env->gwion->type[et_error];
if(bin->rhs->exp_type == ae_exp_decl)
SET_FLAG(bin->rhs->d.exp_decl.td, ref);
exp_setvar(bin->rhs, 1);
- return r;
-}
-
-/*static*/ OP_EMIT(opem_at_object) {
- const Exp_Binary* bin = (Exp_Binary*)data;
- const Type l = bin->lhs->info->type;
- const Type r = bin->rhs->info->type;
- if(nonnull_check(l, r)) {
- const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
- instr->m_val = SZ_INT;
- }
- return emit_add_instr(emit, ObjectAssign);
+ CHECK_BO(isa(bin->lhs->info->type , bin->rhs->info->type))
+ return bin->rhs->info->type;
}
static OP_CHECK(opck_object_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
- const Type l = cast->exp->info->type;
- const Type r = exp_self(cast)->info->type;
- if(check_nonnull(env, l, r, "cast", exp_self(cast)->pos) == env->gwion->type[et_null])
- return env->gwion->type[et_null];
- return force_type(env, r);
-}
-
-static OP_EMIT(opem_object_cast) {
- const Exp_Cast* cast = (Exp_Cast*)data;
- const Type l = cast->exp->info->type;
- const Type r = exp_self(cast)->info->type;
- if(nonnull_check(l, r))
- emit_add_instr(emit, GWOP_EXCEPT);
- return (Instr)GW_OK;
+ const Type to = known_type(env, cast->td);
+ if(isa(cast->exp->info->type, to) < 0) {
+ if(isa(to, cast->exp->info->type) > 0)
+ ERR_N(exp_self(cast)->pos, _("can't upcast '%s' to '%s'"), cast->exp->info->type->name, to->name)
+ ERR_N(exp_self(cast)->pos, _("can't cast '%s' to '%s'"), cast->exp->info->type->name, to->name)
+ }
+ return exp_self(cast)->info->type;
}
static OP_CHECK(opck_implicit_null2obj) {
const struct Implicit* imp = (struct Implicit*)data;
- const Type l = imp->e->info->type;
- const Type r = imp->t;
- if(check_nonnull(env, l, r, "implicitly cast", imp->e->pos) == env->gwion->type[et_null])
- return env->gwion->type[et_null];
return imp->t;
}
static OP_EMIT(opem_implicit_null2obj) {
- const struct Implicit* imp = (struct Implicit*)data;
- const Type l = imp->e->info->type;
- const Type r = imp->t;
- if(nonnull_check(l, r))
- emit_add_instr(emit, GWOP_EXCEPT);
return (Instr)GW_OK;
}
-static OP_CHECK(opck_object_not) {
- const Exp_Unary* unary = (Exp_Unary*)data;
- const Type t = unary->exp->info->type;
- if(tflag(t, tflag_nonnull))
- ERR_N(unary->exp->pos, "expression is known to be nonnull");
- return unary->exp->info->type;
-}
-
ANN /*static*/ Type scan_class(const Env env, const Type t, const Type_Decl * td);
static Type opck_object_scan(const Env env, const struct TemplateScan *ts) {
if(ts->td->types)
- return scan_class(env, ts->t, ts->td) ?: env->gwion->type[et_null];
+ return scan_class(env, ts->t, ts->td) ?: env->gwion->type[et_error];
ERR_N(td_pos(ts->td), _("you must provide template types for type '%s'"), ts->t->name)
}
if(f->def->base->tmpl)
emit_add_instr(emit, DotTmplVal);
else
- if(is_class(emit->gwion, member->t_base) || tflag(member->base->info->type, tflag_force)) {
+ if(is_class(emit->gwion, member->t_base) || member->base->exp_type == ae_exp_cast) {
const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : SetFunc);
func_i->m_val = (m_uint)f->code ?: (m_uint)f;
return;
_("class '%s' has no member '%s'"), the_base->name, str);
if(member->t_base->nspc)
did_you_mean_type(the_base, str);
- return env->gwion->type[et_null];
+ return env->gwion->type[et_error];
}
CHECK_BN(not_from_owner_class(env, the_base, value, exp_self(member)->pos))
if(!env->class_def || isa(env->class_def, value->from->owner_class) < 0) {
!is_fptr(emit->gwion, exp_self(member)->info->type)))) {
if(!tflag(t_base, tflag_struct))
CHECK_BO(emit_exp(emit, member->base))
- if(isa(member->t_base, emit->env->gwion->type[et_object]) > 0)
- emit_except(emit, member->t_base);
}
if(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->info->type))
emit_member_func(emit, member);
ANN static OP_EMIT(opem_option_not) {
Exp_Unary *unary = (Exp_Unary*)data;
const Instr pop = emit_add_instr(emit, RegPop);
- pop->m_val = unary->exp->info->type->nspc->info->offset - sizeof(uint16_t)*2;
- const Instr set = emit_add_instr(emit, Reg2Reg);
- set->m_val = -sizeof(uint16_t)*2;
- set->m_val2 = unary->exp->info->type->nspc->info->offset - sizeof(uint16_t)*2;
+ pop->m_val = unary->exp->info->type->size - SZ_INT;
return emit_add_instr(emit, IntNot);
}
ANN static OP_EMIT(opem_option_cond) {
Exp exp = (Exp)data;
- const Instr set = emit_add_instr(emit, Reg2Reg);
- set->m_val = -exp->info->type->size;
- set->m_val2 = -sizeof(uint16_t)*2;
- const Instr pop2 = emit_add_instr(emit, RegPop);
- pop2->m_val = exp->info->type->nspc->info->offset - sizeof(uint16_t)*2;
- const Instr instr = emit_add_instr(emit, BranchEqInt);
- return instr;
+ const Instr pop = emit_add_instr(emit, RegPop);
+ pop->m_val = exp->info->type->size - SZ_INT;
+ return emit_add_instr(emit, BranchEqInt);
}
ANN static OP_EMIT(opem_option_uncond) {
Exp exp = (Exp)data;
- const Instr set = emit_add_instr(emit, Reg2Reg);
- set->m_val = -exp->info->type->size;
- set->m_val2 = -sizeof(uint16_t)*2;
- const Instr pop2 = emit_add_instr(emit, RegPop);
- pop2->m_val = exp->info->type->size - sizeof(uint16_t)*2;
- const Instr instr = emit_add_instr(emit, BranchNeqInt);
- return instr;
+ const Instr pop = emit_add_instr(emit, RegPop);
+ pop->m_val = exp->info->type->size - SZ_INT;
+ return emit_add_instr(emit, BranchNeqInt);
}
.op=insert_symbol(env->gwion->st, "@=>"), .pos=info->td->pos };
CHECK_BB(add_op(env->gwion, &opi1))
const struct Op_Func opfunc2 = { .ck=opck_option_setn, .em=opem_option_setn };
- struct Op_Import opi2 = { .lhs=env->gwion->type[et_null], .rhs=udef->type, .ret=udef->type, .func=&opfunc2,
+ struct Op_Import opi2 = { .lhs=env->gwion->type[et_error], .rhs=udef->type, .ret=udef->type, .func=&opfunc2,
.op=insert_symbol(env->gwion->st, "@=>"), .pos=info->td->pos };
CHECK_BB(add_op(env->gwion, &opi2))
const struct Op_Func opfunc3 = { .em=opem_option_not };
struct tmpl_info info = { .base=t, .td=td, .list=t->info->cdef->base.tmpl->list };
const Type exists = tmpl_exists(env, &info);
if(exists)
- return exists != env->gwion->type[et_null] ? exists : NULL;
+ return exists != env->gwion->type[et_error] ? exists : NULL;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
.scope=env->scope->depth, .flag=tflag_scan0 };
+// CHECK_BO(envset_push(&es, t->info->owner_class, t->info->ctx ? t->info->ctx->nspc : env->curr))
+//const Nspc former = env->curr;
+//if(env->class_def)
+//const Type cdef = env->class_def;
CHECK_BO(envset_push(&es, t->info->owner_class, t->info->ctx ? t->info->ctx->nspc : env->curr))
+// CHECK_BO(envset_push(&es, t->info->owner_class, t->info->owner))
+/*{
+nspc_push_type(env->gwion->mp, env->curr);
+ Type_List tl = td->types;
+ do {
+ nspc_add_type(env->curr, tl->td->xid, nspc_lookup_type0(former, tl->td->xid));
+ } while((tl = tl->next));
+}*/
const Type ret = _scan_class(env, &info);
+//nspc_pop_type(env->gwion->mp, env->curr);
if(es.run)
envset_pop(&es, t->info->owner_class);
return ret;
}
GWION_IMPORT(object_op) {
- const Type t_null = gwi_mk_type(gwi, "@null", SZ_INT, NULL);
- gwi->gwion->type[et_null] = t_null;
- GWI_BB(gwi_set_global_type(gwi, t_null, et_null))
+ const Type t_error = gwi_mk_type(gwi, "@error", 0, NULL);
+ gwi->gwion->type[et_error] = t_error;
+ GWI_BB(gwi_set_global_type(gwi, t_error, et_error))
GWI_BB(gwi_oper_cond(gwi, "Object", BranchEqInt, BranchNeqInt))
GWI_BB(gwi_oper_ini(gwi, "Object", "Object", NULL))
GWI_BB(gwi_oper_add(gwi, at_object))
- GWI_BB(gwi_oper_emi(gwi, opem_at_object))
- GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
- GWI_BB(gwi_oper_ini(gwi, "@null", "Object", NULL))
- GWI_BB(gwi_oper_add(gwi, at_object))
- GWI_BB(gwi_oper_emi(gwi, opem_at_object))
- GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
+ GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
GWI_BB(gwi_oper_ini(gwi, "Object", "Object", "int"))
GWI_BB(gwi_oper_end(gwi, "==", EqObject))
GWI_BB(gwi_oper_end(gwi, "!=", NeqObject))
GWI_BB(gwi_oper_add(gwi, opck_object_cast))
- GWI_BB(gwi_oper_emi(gwi, opem_object_cast))
GWI_BB(gwi_oper_end(gwi, "$", NULL))
GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj))
GWI_BB(gwi_oper_emi(gwi, opem_implicit_null2obj))
GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
- GWI_BB(gwi_oper_ini(gwi, "@null", "Object", NULL))
- GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj))
- GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
- GWI_BB(gwi_oper_ini(gwi, "@null", "Object", NULL))
- GWI_BB(gwi_oper_add(gwi, opck_object_cast))
- GWI_BB(gwi_oper_emi(gwi, opem_object_cast))
- GWI_BB(gwi_oper_end(gwi, "$", NULL))
- GWI_BB(gwi_oper_ini(gwi, NULL, "Object", "bool"))
- GWI_BB(gwi_oper_add(gwi, opck_unary_meta2)) // this is suspicious
- GWI_BB(gwi_oper_add(gwi, opck_object_not))
- GWI_BB(gwi_oper_end(gwi, "!", IntNot))
GWI_BB(gwi_oper_ini(gwi, "@Compound", NULL, NULL))
GWI_BB(gwi_oper_add(gwi, opck_struct_scan))
GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
- gwi_item_ini(gwi, "@null", "null");
- gwi_item_end(gwi, 0, NULL);
return GW_OK;
}
OP_CHECK(opck_basic_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
return isa(cast->exp->info->type, exp_self(cast)->info->type) > 0 ?
- exp_self(cast)->info->type : env->gwion->type[et_null];
+ exp_self(cast)->info->type : env->gwion->type[et_error];
}
OP_CHECK(opck_usr_implicit) {
OP_CHECK(opck_rassign) {
const Exp_Binary* bin = (Exp_Binary*)data;
- if(opck_const_rhs(env, data, mut) == env->gwion->type[et_null])
- return env->gwion->type[et_null];
+ if(opck_const_rhs(env, data, mut) == env->gwion->type[et_error])
+ return env->gwion->type[et_error];
exp_setvar(bin->rhs, 1);
return bin->rhs->info->type;
}
}
static OP_CHECK(opck_implicit_f2i) {
- return env->gwion->type[et_null];
+ return env->gwion->type[et_error];
}
static OP_CHECK(opck_cast_i2f) {
exp_setvar(bin->rhs, 1);
Type t = bin->lhs->info->type;
do {
-// t = unflag_type(t);
Type u = bin->rhs->info->type;
do {
-// u = unflag_type(u);
const m_str str = get_type_name(env, u, 1);
if(str && !strcmp(t->name, str))
return bin->lhs->info->type; // use rhs?
} while((u = u->info->parent));
} while((t = t->info->parent));
- return env->gwion->type[et_null];
+ return env->gwion->type[et_error];
}
static INSTR(instr_ptr_assign) {
#include "gwi.h"
#include "gack.h"
-ANN static void push_string(const VM_Shred shred, const M_Object obj, const m_str c) {
- STRING(obj) = s_name(insert_symbol(shred->info->vm->gwion->st, c));
- *(M_Object*)REG(-SZ_INT) = (M_Object)obj;
- _release(obj, shred);
-}
-
#define describe_string_logical(name, action) \
static INSTR(String_##name) { \
POP_REG(shred, SZ_INT); \
describe_string_logical(eq, (lhs && rhs && STRING(lhs) == STRING(rhs)) || (!lhs && !rhs))
describe_string_logical(neq, !(lhs && rhs && STRING(lhs) == STRING(rhs)) || (!lhs && !rhs))
-static INSTR(String_Assign) {
- POP_REG(shred, SZ_INT);
- const M_Object lhs = *(M_Object*)REG(-SZ_INT);
- const M_Object rhs = *(M_Object*)REG(0);
- release(lhs, shred);
- push_string(shred, rhs, lhs ? STRING(lhs) : "");
-}
-
static CTOR(string_ctor) {
STRING(o) = "";
}
GWI_BB(gwi_func_end(gwi, string_findStart, ae_flag_none))
gwi_func_ini(gwi, "int", "find");
- gwi_func_arg(gwi, "nonnull string", "str");
+ gwi_func_arg(gwi, "string", "str");
GWI_BB(gwi_func_end(gwi, string_findStr, ae_flag_none))
gwi_func_ini(gwi, "int", "find");
- gwi_func_arg(gwi, "nonnull string", "str");
+ gwi_func_arg(gwi, "string", "str");
gwi_func_arg(gwi, "int", "pos");
GWI_BB(gwi_func_end(gwi, string_findStrStart, ae_flag_none))
GWI_BB(gwi_func_end(gwi, string_rfindStart, ae_flag_none))
gwi_func_ini(gwi, "int", "rfind");
- gwi_func_arg(gwi, "nonnull string", "str");
+ gwi_func_arg(gwi, "string", "str");
GWI_BB(gwi_func_end(gwi, string_rfindStr, ae_flag_none))
gwi_func_ini(gwi, "int", "rfind");
- gwi_func_arg(gwi, "nonnull string", "str");
+ gwi_func_arg(gwi, "string", "str");
gwi_func_arg(gwi, "int", "pos");
GWI_BB(gwi_func_end(gwi, string_rfindStrStart, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
- GWI_BB(gwi_oper_ini(gwi, "string", "nonnull string", "nonnull string"))
- GWI_BB(gwi_oper_add(gwi, opck_const_rhs))
- GWI_BB(gwi_oper_end(gwi, "=>", String_Assign))
-
GWI_BB(gwi_oper_ini(gwi, "string", "string", "bool"))
GWI_BB(gwi_oper_end(gwi, "==", String_eq))
GWI_BB(gwi_oper_end(gwi, "!=", String_neq))
- GWI_BB(gwi_oper_ini(gwi, "int", "nonnull string", "nonnull string"))
+ GWI_BB(gwi_oper_ini(gwi, "int", "string", "string"))
GWI_BB(gwi_oper_end(gwi, "@slice", StringSlice))
struct SpecialId_ spid = { .ck=check_funcpp, .exec=RegPushMe, .is_const=1 };
GWI_BB(gwi_func_end(gwi, ugen_get_last, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
- GWI_BB(gwi_oper_ini(gwi, "nonnull UGen", "nonnull UGen", "nonnull UGen"))
+ GWI_BB(gwi_oper_ini(gwi, "UGen", "UGen", "UGen"))
_CHECK_OP("=>", chuck_ugen, UgenConnect)
_CHECK_OP("=<", chuck_ugen, UgenDisconnect)
_CHECK_OP(":=>", chuck_ugen, TrigConnect)
_CHECK_OP(":=<", chuck_ugen, TrigDisconnect)
- GWI_BB(gwi_oper_ini(gwi, "nonnull UGen[]", "nonnull UGen[]", "nonnull UGen[]"))
+ GWI_BB(gwi_oper_ini(gwi, "UGen[]", "UGen[]", "UGen[]"))
_CHECK_OP("=>", chuck_ugen, UgenAAConnect)
_CHECK_OP("=<", chuck_ugen, UgenAADisconnect)
_CHECK_OP(":=>", chuck_ugen, TrigAAConnect)
_CHECK_OP(":=<", chuck_ugen, TrigAADisconnect)
- GWI_BB(gwi_oper_ini(gwi, "nonnull UGen", "nonnull UGen[]", "nonnull UGen[]"))
+ GWI_BB(gwi_oper_ini(gwi, "UGen", "UGen[]", "UGen[]"))
_CHECK_OP("=>", chuck_ugen, UgenUAConnect)
_CHECK_OP("=<", chuck_ugen, UgenUADisconnect)
_CHECK_OP(":=>", chuck_ugen, TrigUAConnect)
_CHECK_OP(":=<", chuck_ugen, TrigUADisconnect)
- GWI_BB(gwi_oper_ini(gwi, "nonnull UGen[]", "nonnull UGen", "nonnull UGen"))
+ GWI_BB(gwi_oper_ini(gwi, "UGen[]", "UGen", "UGen"))
_CHECK_OP("=>", chuck_ugen, UgenAUConnect)
_CHECK_OP("=<", chuck_ugen, UgenAUDisconnect)
_CHECK_OP(":=>", chuck_ugen, TrigAUConnect)
const Type t = (Type)instr->m_val,
u = (Type)vector_at(&arg->t, arg->i);
if(isa(u, t) > 0 ||
- (u == shred->info->vm->gwion->type[et_null] &&
+ (u == shred->info->vm->gwion->type[et_error] &&
isa(t, shred->info->vm->gwion->type[et_object]) > 0)) {
for(m_uint i = 0; i < t->size; i += SZ_INT)
*(m_uint*)REG(i - SZ_INT) = *(m_uint*)(arg->d + arg->o + i);
static ID_CHECK(idck_vararg) {
if(env->func && fbflag(env->func->def->base, fbflag_variadic))
- return nonnul_type(env, exp_self(prim)->info->type);
+ return exp_self(prim)->info->type;
ERR_O(exp_self(prim)->pos, _("'vararg' must be used inside variadic function"))
}
GWI_BB(gwi_class_end(gwi))
SET_FLAG(t_vararg, abstract | ae_flag_final);
gwi->gwion->type[et_vararg] = t_vararg;
- GWI_BB(gwi_oper_ini(gwi, "nonnull Vararg", (m_str)OP_ANY_TYPE, NULL))
+ GWI_BB(gwi_oper_ini(gwi, "Vararg", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_vararg_cast))
GWI_BB(gwi_oper_emi(gwi, opem_vararg_cast))
GWI_BB(gwi_oper_end(gwi, "$", NULL))
const Exp e = *exp;
DECL_OO(const Type, t, = check_exp(env, e))
CHECK_BO(inferable(env, t, (*exp)->pos))
- const Type force = force_type(env, t);
- return type_class(env->gwion, force);
+ return type_class(env->gwion, t);
}
ANN static Type check_prim_interp(const Env env, const Exp* exp) {
ANN m_bool func_check(const Env env, const Exp_Call *exp) {
CHECK_OB(check_exp(env, exp->func))
- const Type t = actual_type(env->gwion, unflag_type(exp->func->info->type));
+ const Type t = actual_type(env->gwion, exp->func->info->type);
struct Op_Import opi = { .op=insert_symbol("@func_check"),
.rhs=t, .pos=exp_self(exp)->pos, .data=(uintptr_t)exp, .op_type=op_exp };
CHECK_NB(op_check(env, &opi)) // doesn't really return NULL
- return exp_self(exp)->info->type != env->gwion->type[et_null] ?
+ return exp_self(exp)->info->type != env->gwion->type[et_error] ?
GW_OK : GW_ERROR;
}
ANN Type check_exp_call1(const Env env, const Exp_Call *exp) {
-// CHECK_OO(check_exp(env, exp->func))
CHECK_BO(func_check(env, exp))
const Type t = actual_type(env->gwion, exp->func->info->type);
if(isa(t, env->gwion->type[et_function]) < 0) {
ANN static Type check_exp_call(const Env env, Exp_Call* exp) {
if(exp->tmpl) {
CHECK_BO(func_check(env, exp))
- const Type t = actual_type(env->gwion, unflag_type(exp->func->info->type));
+ const Type t = actual_type(env->gwion, exp->func->info->type);
if(isa(t, env->gwion->type[et_function]) < 0)
return check_exp_call1(env, exp);
if(exp->args)
if(depth)
ptr = array_type(env, ptr, depth);
char c[15 + strlen(ptr->name)];
- sprintf(c, "nonnull Ptr:[%s]", ptr->name);
+ sprintf(c, "Ptr:[%s]", ptr->name);
ptr = str2type(env->gwion, c, stmt->exp->pos);
const Type base = get_type(ptr);
CHECK_BB(ensure_traverse(env, base))
return GW_OK;
}
+static OP_CHECK(opck_union_is) {
+ Exp_Call *call = (Exp_Call*)data;
+ Exp exp = call->args;
+ if(exp->exp_type != ae_exp_primary && exp->d.prim.prim_type != ae_prim_id)
+ ERR_N(exp->pos, "FFI variadic arguments must be of FFI type CHANGE ME");
+ const Value v = find_value(call->func->info->type->info->owner_class, exp->d.prim.d.var);
+ if(!v)
+ ERR_N(exp->pos, "'%s' has no member '%s'", call->func->info->type->info->owner_class, exp->d.prim.d.var);
+ exp->d.prim.prim_type = ae_prim_num;
+ exp->d.prim.d.num = v->from->offset;
+ return NULL;
+}
+
+/*static*/ MFUN(union_is) {
+ *(m_uint*)RETURN = *(m_uint*)MEM(SZ_INT) == *(m_uint*)o->data;
+}
+
ANN m_bool check_union_def(const Env env, const Union_Def udef) {
if(tmpl_base(udef->tmpl)) // there's a func for this
return GW_OK;
const m_uint scope = env_push_type(env, udef->type);
const m_bool ret = check_union_decl(env, udef);
+
+ Type_Decl *td = new_type_decl(env->gwion->mp, insert_symbol("bool"), loc_cpy(env->gwion->mp, udef->pos));
+// Type_Decl *arg_td = new_type_decl(env->gwion->mp, insert_symbol(), loc_cpy(env->gwion->mp, udef->pos));
+ Type_Decl *arg_td = new_type_decl(env->gwion->mp, insert_symbol("int"), loc_cpy(env->gwion->mp, udef->pos));;
+ Var_Decl var = new_var_decl(env->gwion->mp, insert_symbol("arg"), NULL, loc_cpy(env->gwion->mp, udef->pos));
+ Arg_List args = new_arg_list(env->gwion->mp, arg_td, var, NULL);
+ Func_Base *fb = new_func_base(env->gwion->mp, td, insert_symbol("is"), args, ae_flag_none);
+ Func_Def fdef = new_func_def(env->gwion->mp, fb, NULL, loc_cpy(env->gwion->mp, udef->pos));
+ CHECK_BB(traverse_func_def(env, fdef)) // use ret
+ builtin_func(env->gwion->mp, fb->func, union_is);
+
+ const m_uint oscope = env_push(env, udef->type->info->owner_class, udef->type->info->owner);
+ const struct Op_Func opfunc = { .ck=opck_union_is };
+ const struct Op_Import opi = { .rhs=fb->func->value_ref->type,
+ .func=&opfunc, .data=(uintptr_t)fb->func, .pos=udef->pos, .op=insert_symbol("@func_check") };
+ CHECK_BB(add_op(env->gwion, &opi))
+ env_pop(env, oscope);
+// set_vflag(fb->func->value_ref, vflag_builtin);
+
env_pop(env, scope);
set_tflag(udef->type, tflag_check);
return ret;
static m_bool op_match(const restrict Type t, const restrict Type mo) {
if(t == OP_ANY_TYPE || mo == OP_ANY_TYPE)
return GW_OK;
- if(t && mo)
- return unflag_type(t) == unflag_type(mo);
return t == mo;
}
exp_self((union exp_data*)opi->data)->info->nspc = nspc;
}
-ANN static inline void set_nonnull(const Type t, const Exp exp) {
- if(t != OP_ANY_TYPE && tflag(t, tflag_nonnull))
- exp_setnonnull(exp, 1);
-}
-
-ANN static void nn_implicit(const M_Operator *mo, const struct Op_Import *opi) {
- const struct Implicit *a = (struct Implicit*)opi->data;
- set_nonnull(mo->lhs, a->e);
-}
-
-ANN static void nn_exp(const M_Operator *mo, const struct Op_Import *opi) {
- const Exp a = (Exp)opi->data;
- set_nonnull(mo->rhs, a); // rhs ???
-}
-
-ANN static void nn_dot(const M_Operator *mo, const struct Op_Import *opi) {
- const Exp_Dot *a = (Exp_Dot*)opi->data;
- set_nonnull(mo->lhs, a->base);
-}
-
-ANN static void nn_array(const M_Operator *mo, const struct Op_Import *opi) {
- const Array_Sub a = (Array_Sub)opi->data;
- set_nonnull(mo->lhs, a->exp);
-}
-
-ANN static void nn_binary(const M_Operator *mo, const struct Op_Import *opi) {
- const Exp_Binary *a = (Exp_Binary*)opi->data;
- set_nonnull(mo->lhs, a->lhs);
- set_nonnull(mo->rhs, a->rhs);
-}
-
-ANN static void nn_cast(const M_Operator *mo, const struct Op_Import *opi) {
- const Exp_Cast *a = (Exp_Cast*)opi->data;
- set_nonnull(mo->lhs, a->exp);
-}
-
-ANN static void nn_postfix(const M_Operator *mo, const struct Op_Import *opi) {
- const Exp_Postfix *a = (Exp_Postfix*)opi->data;
- set_nonnull(mo->lhs, a->exp);
-}
-
-ANN static void nn_unary(const M_Operator *mo, const struct Op_Import *opi) {
- const Exp_Unary *a = (Exp_Unary*)opi->data;
- set_nonnull(mo->rhs, a->exp);
-}
-
-ANN static void nn_scan(const M_Operator *mo NUSED, const struct Op_Import *opi NUSED) {
-}
-
-typedef void (*nn_f)(const M_Operator *mo, const struct Op_Import *opi);
-static const nn_f nn_func[] = {
- nn_implicit, nn_exp, nn_dot, nn_array,
- nn_binary, nn_cast, nn_postfix, nn_unary, nn_scan
-};
-
-ANN static void opi_nonnull(const M_Operator *mo, const struct Op_Import *opi) {
- nn_func[opi->op_type](mo, opi);
-}
-
ANN static Type op_check_inner(struct OpChecker* ock) {
Type t, r = ock->opi->rhs;
do {
const M_Operator* mo;
const Vector v = (Vector)map_get(ock->map, (vtype)ock->opi->op);
if(v && (mo = operator_find(v, ock->opi->lhs, r))) {
- opi_nonnull(mo, ock->opi);
if((mo->ck && (t = mo->ck(ock->env, (void*)ock->opi->data, &ock->mut))))
return t;
else
struct OpChecker ock = { env, &nspc->info->op_map, &opi2, 0 };
const Type ret = op_check_inner(&ock);
if(ret) {
- if(ret == env->gwion->type[et_null])
+ if(ret == env->gwion->type[et_error])
break;
if(!ock.mut)
set_nspc(&opi2, nspc);
CHECK_BB(ensure_scan1(env, parent))
if(type_ref(parent))
ERR_B(pos, _("can't use ref type in class extend"))
- if(tflag(parent, tflag_nonnull))
- ERR_B(pos, _("can't use nonnull type in class extend"))
return GW_OK;
}
return ret;
}
-__attribute__((returns_nonnull))
-ANN Type unflag_type(const Type t) {
- const Type type = !tflag(t, tflag_nonnull) ? t : t->info->parent;
- return !tflag(type, tflag_force) ? type : type->info->parent;
-}
-
__attribute__((returns_nonnull))
ANN Type get_type(const Type t) {
const Type type = !t->array_depth ? t : array_base(t);
- return unflag_type(type);
+ return type;
}
ANN m_bool scanx_cdef(const Env env, void* opt, const Type base,
#include "traverse.h"
#include "parse.h"
+ANN static Type option(const Env env, Type_Decl* td) {
+ struct Type_List_ tl = { .td=td };
+ Type_Decl option_td = { .xid=insert_symbol("Option"), .types=&tl };
+ UNSET_FLAG(td, optionnal);
+ const Type ret = known_type(env, &option_td);
+ SET_FLAG(td, optionnal);
+ return ret;
+}
ANN static Type resolve(const Env env, Type_Decl* td) {
DECL_OO(const Type, base, = find_type(env, td))
ERR_O(td_pos(td), _("type '%s' is invalid"), base->name)
DECL_OO(const Type, t, = scan_type(env, base, td))
const Type ret = !td->array ? t : array_type(env, t, td->array->depth);
- if(GET_FLAG(td, nonnull)) {
- if(isa(ret, env->gwion->type[et_void]) > 0)
- ERR_O(td_pos(td), _("void types can't be nonnull."))
- if(isa(ret, env->gwion->type[et_object]) < 0 && isa(ret, env->gwion->type[et_fptr]) < 0)
- return ret;
- return nonnul_type(env, ret);
- }
- return ret;
+ return !GET_FLAG(td, optionnal) ? ret : option(env, td);
}
struct td_info {
+++ /dev/null
-#! [contains] NullTickException
-funcdef float ptr_t(float);
-var ptr_t ptr ~= var UsrUGen u;
+++ /dev/null
-class Tester
-{
- fun int assert_equal:[A](string description, A a, A b){ if(a == b) return 0; return 1; }
- fun int assert_not_equal:[A](string description, A a, A b){ if(a != b) return 0; return 1; }
-}
-
-var Tester t;
-var Object o;
-ref Object oref;
-"test" => var string s;
-#!<<< t.assert_equal("test", 1, 1) >>>;
-#!<<< t.assert_equal("test", 2, 1) >>>;
-<<< t.assert_equal(s, 1, 1) >>>;
-<<< t.assert_equal(s, 2, 1 + 1) >>>;
-<<< t.assert_equal(s, 2, 1) >>>;
-<<< t.assert_equal(s, o, o) >>>;
-<<< t.assert_equal(s, o, null) >>>;
-<<< t.assert_equal(s, null $ Object, null) >>>;
-<<< t.assert_equal(s, oref, null) >>>;
-<<< t.assert_not_equal(s, 1, 1) >>>;
-<<< t.assert_not_equal(s, 2, 1 + 1) >>>;
-<<< t.assert_not_equal(s, 2, 1) >>>;
-<<< t.assert_not_equal(s, o, o) >>>;
-<<< t.assert_not_equal(s, o, null) >>>;
-<<< t.assert_not_equal(s, null $ Object, null) >>>;
-<<< t.assert_not_equal(s, oref, null) >>>;
#! [contains] contains incompatible types
-[null, 1];
+[new Object, 1];
+++ /dev/null
-#! [contains] NullPtrException
-var int i[1][1];
-null @=> i[0];
-<<< i[0][0] >>>;
+++ /dev/null
-#! [contains] NullPtrException
-ref UGen u;
-adc => u;
+++ /dev/null
-#! [contains] NullPtrException
-class C
-{
- funcdef void test();
- var test t;
-}
-<<< var C c >>>;
-<<< c.t >>>;
-c.t();
+++ /dev/null
-#! [contains] NullPtrException
-class C
-{
- var int i;
-}
-
-ref C c;
-c.i;
+++ /dev/null
-#! [contains] NullPtrException
-ref Event e;
-e => now;
+++ /dev/null
-#! [contains] can't assign
-class C extends Event{}
-var Event e @=> var C o;
#! [contains] non-callable value
-null();
+1();
+++ /dev/null
-#! [contains] NullPtrException
-funcdef void Test();
-var Test test;
-test();
#! [contains] incompatible types
-maybe ? null : 1;
+maybe ? 2.1 : 1;
+++ /dev/null
-#! [contains] NullPtrException
-class C {
- funcdef void t_ptr();
-}
-var C.t_ptr ptr;
-ptr();
+++ /dev/null
-#! [contains] can't use nonnull type in class extend
-class C extends nonnull Object {
-
-}
+++ /dev/null
-#! [contains] expression is known to be nonnull
-nonnull Object o;
-<<< (!o) >>>;
+++ /dev/null
-#! [contains] NullPtrException
-var int i[];
-i[0];
+++ /dev/null
-#! [contains] NullPtrException
-var int i[][];
-i[0][0];
+++ /dev/null
-#! [contains] NullPtrException
-var int i[];
-foreach(a : i)
- <<< a >>>;
#! [contains] no match found for operator
var Object o;
-null +=> o;
+1 +=> o;
#! [contains] unknown_type
-union U
-{
+union U {
unknown_type unknown_variable;
-};
+}
#! [contains] Hello, interpolation! 1
1 => var int my;
-"Hello, interpolation! ${ my }" => var string s;
+"Hello, interpolation! ${ my }" @=> var string s;
<<< s >>>;
-new Object @=> nonnull Object o;
+new Object @=> var Object? o;
+++ /dev/null
-ref Object o;
-o $ nonnull Event;
+++ /dev/null
-ref Object o;
-o $ Object;
+++ /dev/null
-fun void test(nonnull Object o) { <<< o >>>; }
-
-ref Object o => test;
+++ /dev/null
-nonnull Object o @=> ref Object p;
+++ /dev/null
-nonnull Object o, p;
-o @=> p;
+++ /dev/null
-new nonnull Object @=> nonnull Object o;
+++ /dev/null
-(nonnull Object o) $ nonnull Object;
+++ /dev/null
-nonnull Object o;
+++ /dev/null
-new Object @=> nonnull ref Object o;
+++ /dev/null
-#! [contains] NullPtrException
-ref Object o;
-<<< o $ nonnull Object >>>;
+++ /dev/null
-#! [contains} NullPtrException
-fun void test(nonnull Object o) {
- <<< o >>>;
-}
-ref Object o => test;
+++ /dev/null
-#! [contains] NullPtrException
-ref Object ref_object;
-<<< ref_object $ nonnull Object >>>;
+++ /dev/null
-fun void test(nonnull Object o) { <<< o >>>; }
-nonnull Object o => test;
+++ /dev/null
-fun void test(nonnull Object o) { <<< o >>>; }
-nonnull Object o => test;
+++ /dev/null
-new Object @=> nonnull Object o;
+++ /dev/null
-new Object $ nonnull Object;
+++ /dev/null
-fun void test(nonnull Object o) { <<< o >>>; }
-new Object => test;
+++ /dev/null
-#! [contains] can't assign
-null @=> nonnull Object o;
+++ /dev/null
-#! [contains] can't cast
-null $ nonnull Object;
+++ /dev/null
-#! [contains] can't implicitly cast
-fun void test(nonnull Object o) { <<< o >>>; }
-null => test;
+++ /dev/null
-new Object @=> nonnull Object o;
+++ /dev/null
-#! [contains] NullPtrException
-ref Object o @=> nonnull Object p;
+++ /dev/null
-#! [contains] NullPtrException
-(ref Object o) $ nonnull Object;
+++ /dev/null
-#! [contains] NullPtrException
-fun void test(nonnull Object o) { <<< o >>>; }
-ref Object o => test;
+++ /dev/null
-#! [contains] NullPtrException
-ref Object a @=> nonnull Object o;
-<<< o >>>;
+++ /dev/null
-#! [contains] can't implicitly cast
-fun void test(nonnull Object o) { <<< o >>>; }
-
-null => test;
+++ /dev/null
-#! [contains] void types can't be nonnull
-nonnull void i;
<<< s0 != s0 >>>;
<<< s0 != s1 >>>;
-
-<<< null == s0 >>>;
-<<< null != s0 >>>;
-
-<<< s0 == null >>>;
-<<< s0 != null >>>;
-
-<<< null == null >>>;
-<<< null != null >>>;
+++ /dev/null
-funcdef void test_t:[A]();
-nonnull test_t t;
-t:[int]();
ev @=> ref Event e;
new Event @=> e;
ev @=> e;
-null @=> e;
-typedef int[2]Type;
-nonnull Type type;
+typedef int[2] Type;
+Type type;
<<<type>>>;
foreach(ref a : type);
fun void test(int i, ...) {}
-test(1, 2.3, null);
+test(1, 2.3, new Object);