afl: gwion-fuzz
+gwcdoc:
+ @+LDFLAGS="-L../fmt/ -lgwfmt" CFLAGS="-I../fmt/include -DGWION_DOC" ${MAKE} PRG=gwcdoc all
+
gwion-fuzz:
@touch src/parse/{scan*.c,check.c} src/emit/emit.c src/main.c
@+PRG=gwion-fuzz CC=afl-clang-fast CFLAGS=-D__FUZZING__ ${MAKE}
#ifndef __GWI
#define __GWI
+#ifdef GWION_DOC
+#include "lint.h"
+#define gwiheader(a,...) do { lint_nl(a->lint); lint_indent(a->lint); lint(a->lint, "{-}#!+ {/}%s{0}\n", __VA_ARGS__); } while(0)
+#define gwidoc(a,...) do { lint_nl(a->lint); lint_indent(a->lint); lint(a->lint, "{-}#!- {/}%s{0}\n", __VA_ARGS__); } while(0)
+#define gwinote(a,...) do { lint_indent(a->lint); lint(a->lint, "{-}#!- {/}%s{0}\n", __VA_ARGS__); } while(0)
+#else
+#define gwiheader(a,...)
+#define gwidoc(a,...)
+#define gwinote(a,...)
+#endif
struct Gwi_ {
struct Gwion_ *const gwion;
Ast body;
struct ImportCK *ck;
struct OperCK *oper; // _misc
struct Vector_ effects;
- uint tmpls;
loc_t loc;
+#ifdef GWION_DOC
+ Lint *lint;
+#endif
+ uint tmpls;
};
#include "import/internals.h"
ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) {
CHECK_BO(emit_exp_pop_next(emit, e));
emit_exp_addref1(emit, e, -exp_size(e));
- struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"),
+ struct Op_Import opi = { .op=insert_symbol(b ? "@conditional" : "@unconditional"),
.rhs=e->type, .pos=e->pos, .data=(uintptr_t)e };
CHECK_BO(op_emit(emit, &opi));
return (Instr)vector_back(&emit->code->instr);
gwi->tmpls++;
add_template(gwi->gwion->env, t);
}
+#ifdef GWION_DOC
+ lint_indent(gwi->lint);
+ gwi->lint->indent++;
+ lint_class_def(gwi->lint, t->info->cdef);
+#endif
return t;
}
}
ANN m_int gwi_class_end(const Gwi gwi) {
+#ifdef GWION_DOC
+ gwi->lint->indent--;
+ lint_rbrace(gwi->lint);
+ lint_nl(gwi->lint);
+#endif
if(!gwi->gwion->env->class_def)
GWI_ERR_B(_("import: too many class_end called."))
nspc_allocdata(gwi->gwion->mp, gwi->gwion->env->class_def->nspc);
gwi->ck->tmpl = NULL;
const m_bool ret = traverse_enum_def(gwion->env, edef);
import_enum_end(gwi, &edef->values);
+#ifdef GWION_DOC
+ lint_indent(gwi->lint);
+ lint_enum_def(gwi->lint, edef);
+#endif
const Type t = ret > 0 ? edef->t : NULL;
if(edef->values.ptr)
vector_release(&edef->values);
ANEW ANN static Func_Def import_fdef(const Gwi gwi, ImportCK *ck) {
Func_Base* base = gwi_func_base(gwi, ck);
const Func_Def fdef = new_func_def(gwi->gwion->mp, base, NULL);
+#ifdef GWION_DOC
+ lint_indent(gwi->lint);
+ lint_func_def(gwi->lint, fdef);
+#endif
if(gwi->effects.ptr) {
vector_init(&fdef->base->effects);
vector_copy2(&gwi->effects, &fdef->base->effects);
CHECK_BO(ck_ok(gwi, ck_fdef));
DECL_OO(const Fptr_Def, fptr, = import_fptr(gwi));
fptr->base->flag |= flag;
+#ifdef GWION_DOC
+ lint_indent(gwi->lint);
+ lint_fptr_def(gwi->lint, fptr);
+#endif
if(safe_tflag(gwi->gwion->env->class_def, tflag_tmpl)/* && !fptr->base->tmpl*/) {
section_fptr(gwi, fptr);
ck_end(gwi);
}
ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi)) {
- const m_str name = gwion->env->name;
- OperCK oper = {};
- struct Gwi_ gwi = { .gwion=gwion, .oper=&oper };
- const m_bool ret = f(&gwi);
- if(ret < 0)
- gwi_reset(&gwi);
- gwion->env->name = name;
- return ret;
+ const m_str name = gwion->env->name;
+ OperCK oper = {};
+ struct Gwi_ gwi = { .gwion=gwion, .oper=&oper };
+#ifdef GWION_DOC
+ struct LintState ls = { .builtin=true };
+ Lint linter = { .mp=gwion->mp, .ls=&ls };
+ lint(&linter, "{-}#!+ %s{0}\n", name);
+ gwi.lint = &linter;
+#endif
+ const m_bool ret = f(&gwi);
+ if(ret < 0)
+ gwi_reset(&gwi);
+ gwion->env->name = name;
+ return ret;
}
CHECK_BB(ck_ok(gwi, ck_item));
const Env env = gwi->gwion->env;
gwi->ck->exp->d.exp_decl.td->flag = flag;
+#ifdef GWION_DOC
+ lint_indent(gwi->lint);
+ lint_exp(gwi->lint, gwi->ck->exp);
+ lint_sc(gwi->lint);
+ lint_nl(gwi->lint);
+#endif
if(env->class_def && tflag(env->class_def, tflag_tmpl))
return gwi_item_tmpl(gwi);
CHECK_BB(traverse_exp(env, gwi->ck->exp));
}
ANN m_int gwi_oper_end(const Gwi gwi, const m_str op, const f_instr f) {
+#ifdef GWION_DOC
+ lint_indent(gwi->lint);
+ lint(gwi->lint, "{+C}operator{0} ");
+ if(gwi->oper->lhs && !gwi->oper->rhs) {
+ lint(gwi->lint, "{+}%s{0}", gwi->oper->lhs != (m_str)1 ? gwi->oper->lhs : "@Any");
+ lint_space(gwi->lint);
+ }
+ if(gwi->oper->ret) {
+ lint(gwi->lint, "{+}%s{0}", gwi->oper->ret != (m_str)1 ? gwi->oper->ret : "@Any");
+ lint_space(gwi->lint);
+ }
+ lint(gwi->lint, "{/}%s{0}", op);
+ lint_lparen(gwi->lint);
+ if(gwi->oper->lhs && gwi->oper->rhs) {
+ lint(gwi->lint, "{+}%s{0}", gwi->oper->lhs != (m_str)1 ? gwi->oper->lhs : "@Any");
+ lint(gwi->lint, ",");
+ lint_space(gwi->lint);
+ }
+ if(gwi->oper->rhs)
+ lint(gwi->lint, "{+}%s{0}", gwi->oper->rhs != (m_str)1 ? gwi->oper->rhs : "@Any");
+ lint_rparen(gwi->lint);
+ lint_sc(gwi->lint);
+ lint_nl(gwi->lint);
+#endif
gwi->oper->sym = insert_symbol(gwi->gwion->st, op);
const m_bool ret = import_op(gwi, gwi->oper, f);
gwi->oper->ck = NULL;
ANN m_int gwi_oper_cond(const Gwi gwi, const m_str type,
const f_instr f1, const f_instr f2) {
GWI_BB(gwi_oper_ini(gwi, NULL, type, "bool"))
- GWI_BB(gwi_oper_end(gwi, "@conditionnal", f1))
- GWI_BB(gwi_oper_end(gwi, "@unconditionnal", f2))
+ GWI_BB(gwi_oper_end(gwi, "@conditional", f1))
+ GWI_BB(gwi_oper_end(gwi, "@unconditional", f2))
return GW_OK;
}
}
ANN void gwi_specialid(const Gwi gwi, const m_str id, const SpecialId spid) {
+#ifdef GWION_DOC
+ lint(gwi->lint, "{+C}specialid{0} %s{/}%s{0};\n",
+ spid->is_const ? "{+G}const{0} " : "",
+ id);
+#endif
struct SpecialId_ *a = mp_calloc(gwi->gwion->mp, SpecialId);
memcpy(a, spid, sizeof(struct SpecialId_));
map_set(&gwi->gwion->data->id, (vtype)insert_symbol(gwi->gwion->st, id), (vtype)a);
gwi->ck->td = NULL;
gwi->ck->tmpl = NULL;
const m_bool ret = traverse_type_def(gwi->gwion->env, tdef);
+#ifdef GWION_DOC
+ lint_indent(gwi->lint);
+ lint_type_def(gwi->lint, tdef);
+#endif
const Type t = tdef->type;
set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
free_type_def(gwi->gwion->mp, tdef);
}
ANN2(1,2) Type gwi_mk_type(const Gwi gwi, const m_str name, const m_uint size, const m_str parent_name) {
+#ifdef GWION_DOC
+ lint_indent(gwi->lint);
+ lint(gwi->lint, "{+C}primitive{0} {+}%s{0}", name);
+ if(parent_name)
+ lint(gwi->lint, " {+C}extends{0} {+}%s{0}", parent_name);
+ lint_sc(gwi->lint);
+ lint_nl(gwi->lint);
+#endif
CHECK_OO(gwi_str2sym(gwi, name));
const Type parent = get_parent(gwi, parent_name);
const Type t = new_type(gwi->gwion->mp, name, parent);
// set_vflag(udef->value, vflag_builtin);
// const M_Object o = new_object(gwi->gwion->mp, NULL, udef->value->type);
// udef->value->d.ptr = (m_uint*)o;
+#ifdef GWION_DOC
+ lint_indent(gwi->lint);
+ lint_union_def(gwi->lint, udef);
+#endif
return udef->type;
}
}
ANN static m_bool import_core_libs(const Gwi gwi) {
+ gwidoc(gwi, "one type to rule them all.");
const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL);
set_tflag(t_class, tflag_infer);
GWI_BB(gwi_set_global_type(gwi, t_class, et_class))
GWI_BB(gwi_gack(gwi, t_class, gack_class))
+ gwidoc(gwi, "this type is infered.");
const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
set_tflag(t_auto, tflag_infer);
GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto))
+
+ gwidoc(gwi, "a void type.");
const Type t_void = gwi_mk_type(gwi, "void", 0, NULL);
GWI_BB(gwi_gack(gwi, t_void, gack_void))
GWI_BB(gwi_set_global_type(gwi, t_void, et_void))
+
+ gwidoc(gwi, "a type for *pretty print*.");
const Type t_gack = gwi_mk_type(gwi, "@Gack", SZ_INT, NULL);
GWI_BB(gwi_gack(gwi, t_gack, gack_gack))
GWI_BB(gwi_set_global_type(gwi, t_gack, et_gack))
+
+ gwidoc(gwi, "integer type.");
const Type t_int = gwi_mk_type(gwi, "int", SZ_INT, NULL);
GWI_BB(gwi_gack(gwi, t_int, gack_int))
GWI_BB(gwi_set_global_type(gwi, t_int, et_int))
+
+ gwidoc(gwi, "character type.");
const Type t_char = gwi_mk_type(gwi, "char", SZ_INT, "int");
GWI_BB(gwi_gack(gwi, t_char, gack_char))
GWI_BB(gwi_set_global_type(gwi, t_char, et_char))
+
+ gwidoc(gwi, "float type.");
const Type t_float = gwi_mk_type(gwi, "float", SZ_FLOAT, NULL);
GWI_BB(gwi_gack(gwi, t_float, gack_float))
GWI_BB(gwi_set_global_type(gwi, t_float, et_float))
+
+ gwidoc(gwi, "represent duration.");
const Type t_dur = gwi_mk_type(gwi, "dur", SZ_FLOAT, NULL);
GWI_BB(gwi_gack(gwi, t_dur, gack_float))
GWI_BB(gwi_add_type(gwi, t_dur))
+
+ gwidoc(gwi, "represent time.");
const Type t_time = gwi_mk_type(gwi, "time", SZ_FLOAT, NULL);
GWI_BB(gwi_gack(gwi, t_time, gack_float))
GWI_BB(gwi_add_type(gwi, t_time))
+
+ gwidoc(gwi, "internal time for `{/}now{0}{-}`.");
const Type t_now = gwi_mk_type(gwi, "@now", SZ_FLOAT, "time");
GWI_BB(gwi_add_type(gwi, t_now))
struct SpecialId_ spid = { .type=t_now, .exec=RegPushNow, .is_const=1 };
gwi_specialid(gwi, "now", &spid);
+ gwidoc(gwi, "internal predicate representation.");
struct SpecialId_ predicate = { .type=t_void, .exec=PredicateCheck, .is_const=1 };
gwi_specialid(gwi, "@predicate", &predicate);
+ gwidoc(gwi, "internal base of all objects and structures.");
const Type t_compound = gwi_mk_type(gwi, "@Compound", SZ_INT, NULL);
GWI_BB(gwi_gack(gwi, t_compound, gack_compound))
GWI_BB(gwi_set_global_type(gwi, t_compound, et_compound))
GWI_BB(import_object(gwi))
GWI_BB(import_prim(gwi))
+ gwidoc(gwi, "the base of all functions.");
const Type t_function = gwi_mk_type(gwi, "@function", SZ_INT, NULL);
GWI_BB(gwi_gack(gwi, t_function, gack_function))
GWI_BB(gwi_set_global_type(gwi, t_function, et_function))
+
+ gwidoc(gwi, "the base of function pointers.");
const Type t_fptr = gwi_mk_type(gwi, "@func_ptr", SZ_INT, "@function");
GWI_BB(gwi_gack(gwi, t_fptr, gack_fptr))
GWI_BB(gwi_set_global_type(gwi, t_fptr, et_fptr))
+
+ gwidoc(gwi, "the base of decayed operators.");
const Type t_op = gwi_mk_type(gwi, "@op", SZ_INT, "@function");
GWI_BB(gwi_set_global_type(gwi, t_op, et_op))
const Type t_lambda = gwi_mk_type(gwi, "@lambda", SZ_INT, "@function");
set_tflag(t_lambda, tflag_infer);
GWI_BB(gwi_set_global_type(gwi, t_lambda, et_lambda))
+ gwidoc(gwi, "type for internal pointer data.");
GWI_BB(gwi_typedef_ini(gwi, "int", "@internal"))
GWI_BB(gwi_typedef_end(gwi, ae_flag_none))
GWI_BB(import_modules(gwi))
GWI_BB(import_ref(gwi))
+ gwidoc(gwi, "Operators class types.");
GWI_BB(gwi_oper_ini(gwi, "@Class", "@Class", "int"))
GWI_BB(gwi_oper_end(gwi, "==", int_eq))
GWI_BB(gwi_oper_end(gwi, "!=", int_neq))
GWI_BB(gwi_oper_end(gwi, "<=", instr_class_le))
GWI_BB(gwi_oper_end(gwi, "<", instr_class_lt))
+ gwidoc(gwi, "internal constructor operator.");
GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_basic_ctor))
GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
+ gwidoc(gwi, "allow member access.");
GWI_BB(gwi_oper_ini(gwi, "@Compound", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_object_dot))
GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
+ gwidoc(gwi, "allow static access.");
GWI_BB(gwi_oper_ini(gwi, "@Class", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_object_dot))
GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
if(bin->rhs->exp_type == ae_exp_decl)
SET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
exp_setvar(bin->rhs, 1);
- CHECK_BN(isa(bin->lhs->type , bin->rhs->type));
+ CHECK_BO(isa(bin->lhs->type , bin->rhs->type));
return bin->rhs->type;
}
}
GWION_IMPORT(ref) {
+ gwidoc(gwi, "Ref: take a reference from a variable.");
+ gwinote(gwi, "used just as the variable it reference.");
+ gwinote(gwi, "can only be used as argument.");
+ gwinote(gwi, "and cannot be returned.");
const Type t_foreach = gwi_struct_ini(gwi, "Ref:[A]");
set_tflag(t_foreach, tflag_infer);
- GWI_BB(gwi_item_ini(gwi, "@internal", "val"))
- GWI_BB(gwi_item_end(gwi, ae_flag_none, num, 0))
+
+ gwinote(gwi, "a pointer to the referenced variable.");
+ GWI_BB(gwi_item_ini(gwi, "@internal", "val"))
+ GWI_BB(gwi_item_end(gwi, ae_flag_none, num, 0))
+
GWI_BB(gwi_struct_end(gwi))
+
+ gwidoc(gwi, "internal `Ref` type creation.");
GWI_BB(gwi_oper_ini(gwi, "Ref", NULL, NULL))
GWI_BB(gwi_oper_add(gwi, opck_ref_scan))
GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
ANN static Type _flow(const Env env, const Exp e, const m_bool b) {
DECL_OO(const Type, type, = check_exp(env, e));
- struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"),
+ struct Op_Import opi = { .op=insert_symbol(b ? "@conditional" : "@unconditional"),
.rhs=type, .pos=e->pos, .data=(uintptr_t)e };
return op_check(env, &opi);
}
opi->op =fdef->base->xid;
const m_str str = s_name(fdef->base->xid);
const uint is_unary = fbflag(fdef->base, fbflag_unary) +
- (!strcmp(str, "@conditionnal") || !strcmp(str, "@unconditionnal"));
+ (!strcmp(str, "@conditional") || !strcmp(str, "@unconditional"));
const Arg_List args = fdef->base->args;
opi->lhs = is_unary ? NULL :
args ? args->var_decl->value->type : NULL;
const Instr push = emit_add_instr(emit, mo->func->code ? RegPushImm : SetFunc);
push->m_val = ((m_uint)mo->func->code ?:(m_uint)mo->func);
CHECK_BB(emit_exp_call1(emit, mo->func));
- if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@conditionnal"))
+ if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@conditional"))
emit_add_instr(emit, BranchEqInt);
- else if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@unconditionnal"))
+ else if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@unconditional"))
emit_add_instr(emit, BranchNeqInt);
return GW_OK;
}
return class_internal(env, base);
if(op == insert_symbol("@implicit"))
return scan_internal_arg(env, base);
- if(op == insert_symbol("@conditionnal") ||
- op == insert_symbol("@unconditionnal"))
+ if(op == insert_symbol("@conditional") ||
+ op == insert_symbol("@unconditional"))
return scan_internal_int(env, base);
return GW_OK;
}
plug->imp = 1;
CHECK_BB(dependencies(gwion, plug));
const m_uint scope = env_push_global(gwion->env);
+ const m_str name = gwion->env->name;
+ gwion->env->name = iname;
const m_bool ret = gwi_run(gwion, imp);
+ gwion->env->name = name;
env_pop(gwion->env, scope);
return ret;
}
10 => var int i;
}
-operator int @conditionnal (C c) {
+operator int @conditional (C c) {
<<< __func__ >>>;
--c.i;
return c.i;
#! [contains] must return
-operator Object @conditionnal (int i) {}
+operator Object @conditional (int i) { return new Object; }
10 => var int i;
}
-operator int @unconditionnal (C c) {
+operator int @unconditional (C c) {
<<< __func__ >>>;
--c.i;
return !c.i;