# queries: ./path/to/local/query, your-org/your-repo/queries@main
- run: |
- git submodule update --init util ast
+ git submodule update --init util ast libcmdapp
make
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
uses: actions/checkout@v2
- name: Init submodules
- run: git submodule update --init util ast
+ run: git submodule update --init util ast libcmdapp
- name: Build Gwion
run: make
uses: actions/checkout@v2
- name: Init submodules
- run: git submodule update --init util ast
+ run: git submodule update --init util ast libcmdapp
- name: Download tool
run: |
- name: Build
run: |
export PATH=`pwd`/cov-analysis-linux64/bin:$PATH
- cov-build --dir cov-int make
+ cov-build --dir cov-int make
- name: Submit
run: |
uses: actions/checkout@v2
- name: SubModules
- run: git submodule update --init util ast
+ run: git submodule update --init util ast libcmdapp
- name: Build
run: make
uses: actions/checkout@v2
- name: Init submodules
- run: git submodule update --init util ast
+ run: git submodule update --init util ast libcmdapp
- name: Build
run: make
uses: actions/checkout@v2
- name: Init submodules
- run: git submodule update --init util ast
+ run: git submodule update --init util ast libcmdapp
- name: Build
run: make
uses: actions/checkout@v2
- name: SubModules
- run: git submodule update --init util ast
+ run: git submodule update --init util ast libcmdapp
- name: Build
run: make
uses: actions/checkout@v2
- name: Init submodules
- run: git submodule update --init util ast
+ run: git submodule update --init util ast libcmdapp
- name: Build
run: make
path = ast
url = https://github.com/Gwion/gwion-ast
active = true
+[submodule "libcmdapp"]
+ path = libcmdapp
+ url = https://github.com/euppal/libcmdapp
test_dir := $(filter-out $(test_ignore), $(test_dir_all))
test_dir += examples
+
+CFLAGS += -Iutil/include -Iast/include -Ilibcmdapp/src -D_GNU_SOURCE
+
ifeq (${DEBUG_STACK}, 1)
CFLAGS += -DDEBUG_STACK
endif
CFLAGS += -DGWION_BUILTIN
-GWLIBS = lib${PRG}.a ast/libgwion_ast.a util/libgwion_util.a
+GWLIBS = lib${PRG}.a ast/libgwion_ast.a util/libgwion_util.a libcmdapp/libcmdapp.a
_LDFLAGS = ${GWLIBS} ${LDFLAGS}
-all: options-show util/libgwion_util.a ast/libgwion_ast.a lib${PRG}.a src/main.o
+all: options-show ${GWLIBS} src/main.o
$(info link ${PRG})
@${CC} src/main.o -o ${PRG} ${_LDFLAGS} ${LIBS}
ast/libgwion_ast.a:
@+GWION_PACKAGE= ${MAKE} -s -C ast
+libcmdapp/libcmdapp.a:
+ @+${MAKE} -s -C libcmdapp static
+
ast: ast/libgwion_ast.a
@(info build ast)
# handle base options
PRG ?=gwion
PREFIX ?=/usr/local
-CFLAGS += -Iutil/include -Iast/include -D_GNU_SOURCE
# base plugin directories
GWPLUG_DIR ?= $(shell echo ~/.gwplug)
struct Vector_ config;
struct SoundInfo_ *si;
m_bool loop;
+ m_bool quit;
} Arg;
ANN void arg_release(Arg*);
opem em;
};
-enum op_type {
- op_implicit,
- op_exp,
- op_dot,
- op_array,
- op_binary,
- op_cast,
- op_postfix,
- op_unary,
- op_scan
-};
-
struct Op_Import {
Type lhs, rhs, ret;
const struct Op_Func *func;
uintptr_t data;
loc_t pos;
Symbol op;
- enum op_type op_type;
};
struct Implicit {
--- /dev/null
+Subproject commit 6d39da65b3eee1538c6fb4f4883b7f9072485050
#include "arg.h"
#include "pass.h"
#include "compile.h"
+#include "cmdapp.h"
#define GWIONRC ".gwionrc"
+enum {
+ CONFIG, PLUGIN, MODULE,
+ LOOP, PASS, STDIN,
+// sound options
+ DRIVER, SRATE, INPUT, OUTPUT,
+// pp options
+ DEFINE, UNDEF, INCLUDE,
+ NOPTIONS
+};
+
/* use before MemPool allocation */
ANN static inline void config_end(const Vector config) {
for(m_uint i = 0; i < vector_size(config); ++i) {
}
}
-static const char usage[] =
-"usage: Gwion <options>\n"
-" -h : this help\n"
-" -c <file> : load config\n"
-" -p <path> : add a plugin directory\n"
-" -s <number> : set samplerate\n"
-" -i <number> : set input channel number\n"
-" -o <number> : set output channel number\n"
-" -d <number> : set driver (and arguments)\n"
-" -l <number> : set loop mode\n"
-" -m <mod:args> : load module (and arguments)\n"
-" -g <mod:args> : set Gwion compiler passes order\n";
-
-ANN static void config_parse(const Gwion, Arg*, const m_str);
-
-#define ARG2INT(a) strtol(a, NULL, 10)
-
-ANN2(1) static inline void arg_set_pass(const Gwion gwion, const m_str str) {
- const Vector v = split_args(gwion->mp, str);
+ANN2(1) static inline void arg_set_pass(const Gwion gwion, const char *str) {
+ const Vector v = split_args(gwion->mp, (const m_str)str);
pass_set(gwion, v);
for(m_uint i = 0; i < vector_size(v); ++i)
free_mstr(gwion->mp, (m_str)vector_at(v, i));
free_vector(gwion->mp, v);
}
-ANN2(1) static void module_arg(const Map map, m_str str) {
+ANN2(1) static void module_arg(const Map map, const char *str) {
m_str val = strchr(str, '=');
if(val) {
*val = '\0';
map_set(map, (vtype)str, (vtype)val);
}
-ANN m_bool _arg_parse(const Gwion gwion, Arg* arg) {
- struct CArg *ca = &arg->arg;
- for(ca->idx = 1; ca->idx < ca->argc; ++ca->idx) {
- if(ca->argv[ca->idx][0] == '-') {
- m_str tmp;
- switch(ca->argv[ca->idx][1]) {
- case 'h':
- gw_err(usage);
- break;
- case 'c':
- CHECK_OB((tmp = option_argument(ca)))
- config_parse(gwion, arg, tmp);
- break;
- case 'p':
- CHECK_OB((tmp = option_argument(ca)))
- vector_add(&arg->lib, (vtype)tmp);
- break;
- case 'm':
- CHECK_OB((tmp = option_argument(ca)))
- module_arg(&arg->mod, tmp);
- break;
- case 'l':
- CHECK_OB((tmp = option_argument(ca)))
- arg->loop = (m_bool)ARG2INT(tmp) > 0 ? 1 : -1;
- break;
- case 'i':
- CHECK_OB((tmp = option_argument(ca)))
- arg->si->in = (uint8_t)ARG2INT(tmp);
- break;
- case 'o':
- CHECK_OB((tmp = option_argument(ca)))
- arg->si->out = (uint8_t)ARG2INT(tmp);
- break;
- case 's':
- CHECK_OB((tmp = option_argument(ca)))
- arg->si->sr = (uint32_t)ARG2INT(tmp);
- break;
- case 'd':
- CHECK_OB((tmp = option_argument(ca)))
- arg->si->arg = tmp;
- break;
- case 'g':
- CHECK_OB((tmp = option_argument(ca)))
- arg_set_pass(gwion, tmp);
- break;
- case '\0':
- vector_add(&arg->add, (vtype)ARG_STDIN);
- break;
- case 'D':
- CHECK_OB((tmp = option_argument(ca)))
- vector_add(&arg->add, (vtype)ARG_DEFINE);
- vector_add(&arg->add, (vtype)tmp);
- break;
- case 'U':
- CHECK_OB((tmp = option_argument(ca)))
- vector_add(&arg->add, (vtype)ARG_UNDEF);
- vector_add(&arg->add, (vtype)tmp);
- break;
- case 'I':
- CHECK_OB((tmp = option_argument(ca)))
- vector_add(&arg->add, (vtype)ARG_INCLUDE);
- vector_add(&arg->add, (vtype)tmp);
- break;
- default:
- gw_err(_("invalid arguments"));
- return GW_ERROR;
- }
- } else
-{
- vector_add(&arg->add, (vtype)ARG_FILE);
- vector_add(&arg->add, (vtype)ca->argv[ca->idx]);
+static void setup_options(cmdapp_t* app, cmdopt_t* opt) {
+ cmdapp_set(app,
+ 'c', "config",
+ CMDOPT_TAKESARG, NULL,
+ "parse a config file", &opt[CONFIG]
+ );
+ cmdapp_set(app,
+ 'p', "plugdir",
+ CMDOPT_TAKESARG, NULL,
+ "add ARG to the plugin search path", &opt[PLUGIN]
+ );
+ cmdapp_set(app,
+ 'm', "module",
+ CMDOPT_TAKESARG, NULL,
+ "activate module (and arguments)", &opt[MODULE]
+ );
+ cmdapp_set(app,
+ 'l', "loop",
+ CMDOPT_TAKESARG, NULL,
+ "set loop mode", &opt[LOOP]
+ );
+ cmdapp_set(app,
+ 'g', "passes",
+ CMDOPT_TAKESARG, NULL,
+ "set pass order", &opt[PASS]
+ );
+ cmdapp_set(app,
+ '\0', "stdin",
+ CMDOPT_OPTIONAL, NULL,
+ "read from stdin", &opt[STDIN]
+ );
+// sound options
+ cmdapp_set(app,
+ 'd', "driver",
+ CMDOPT_TAKESARG, NULL,
+ "set driver (and arguments)", &opt[DRIVER]
+ );
+ cmdapp_set(app,
+ 's', "samplerate",
+ CMDOPT_TAKESARG, NULL,
+ "set the samplerate", &opt[SRATE]
+ );
+ cmdapp_set(app,
+ 'i', "input",
+ CMDOPT_TAKESARG, NULL,
+ "number of input channel", &opt[INPUT]
+ );
+ cmdapp_set(app,
+ 'o', "output",
+ CMDOPT_TAKESARG, NULL,
+ "number of output channel", &opt[OUTPUT]
+ );
+ cmdapp_set(app,
+ 'D', "define",
+ CMDOPT_TAKESARG, NULL,
+ "define a macro", &opt[DEFINE]
+ );
+ cmdapp_set(app,
+ 'U', "undef",
+ CMDOPT_TAKESARG, NULL,
+ "undefine a macro", &opt[UNDEF]
+ );
+ cmdapp_set(app,
+ 'I', "include",
+ CMDOPT_TAKESARG, NULL,
+ "add ARG to include path", &opt[INCLUDE]
+ );
}
- }
- return GW_OK;
+
+static inline void add2arg(Arg *const arg, const char *data, const enum arg_type type) {
+ vector_add(&arg->add, type);
+ vector_add(&arg->add, (vtype)data);
}
ANN static void split_line(const m_str line, const Vector v) {
xfree(c);
}
-ANN static Vector get_config(const m_str name) {
+
+ANN static Vector get_config(const char *name) {
char *line = NULL;
size_t len = 0;
ssize_t nread;
return v;
}
-ANN static void config_parse(const Gwion gwion, Arg* arg, const m_str name) {
+struct ArgInternal {
+ const Gwion gwion;
+ Arg *arg;
+};
+
+ANN m_bool _arg_parse(struct ArgInternal* arg);
+
+ANN static void config_parse(struct ArgInternal* arg, const char *name) {
const Vector v = get_config(name);
if(v) {
- struct CArg ca = arg->arg;
- arg->arg.argc = vector_size(v);
- arg->arg.argv = (m_str*)(v->ptr + OFFSET);
- _arg_parse(gwion, arg);
- arg->arg = ca;
- vector_add(&arg->config, (vtype)v);
+ struct CArg ca = arg->arg->arg;
+ arg->arg->arg.argc = vector_size(v);
+ arg->arg->arg.argv = (m_str*)(v->ptr + OFFSET);
+ _arg_parse(arg);
+ arg->arg->arg = ca;
+ vector_add(&arg->arg->config, (vtype)v);
}
}
-ANN static void config_default(const Gwion gwion , Arg* arg) {
+#define ARG2INT(a) strtol(a, NULL, 10)
+
+static void myproc(void *data, cmdopt_t* option, const char* arg) {
+ struct ArgInternal *arg_int = data;
+ Arg *_arg = arg_int->arg;
+ if(arg) {
+ if(!_arg->arg.idx)
+ _arg->arg.idx++;
+ else
+ add2arg(_arg, arg, ARG_FILE);
+ } else {
+ switch(option->shorto) {
+ case 'p':
+ vector_add(&_arg->lib, (vtype)option->value);
+ break;
+ case 'm':
+ module_arg(&_arg->mod, option->value);
+ break;
+ case 'c':
+ config_parse(arg_int, option->value);
+ break;
+ case 'l':
+ _arg->loop = (m_bool)ARG2INT(option->value) > 0 ? 1 : -1;
+ break;
+ case 'g':
+ arg_set_pass(arg_int->gwion, option->value);
+ break;
+ case '\0':
+ vector_add(&_arg->add, (vtype)ARG_STDIN);
+ break;
+// sound options
+ case 's':
+ _arg->si->sr = (uint32_t)ARG2INT(option->value);
+ break;
+ case 'd':
+ _arg->si->arg = (m_str)option->value;
+ break;
+ case 'i':
+ _arg->si->in = (uint8_t)ARG2INT(option->value);
+ break;
+ case 'o':
+ _arg->si->out = (uint8_t)ARG2INT(option->value);
+ break;
+// pp options
+ case 'D':
+ add2arg(_arg, option->value, ARG_DEFINE);
+ break;
+ case 'U':
+ add2arg(_arg, option->value, ARG_UNDEF);
+ break;
+ case 'I':
+ add2arg(_arg, option->value, ARG_INCLUDE);
+ break;
+ }
+ }
+}
+
+ANN m_bool _arg_parse(struct ArgInternal *arg) {
+ cmdapp_t app;
+ const cmdapp_info_t info = {
+ .program = "gwion",
+ .synopses = NULL, // so it's automatic
+ .version = "N.A.",
+ .author = "Jérémie Astor",
+ .year = 2016,
+ .description = "Strongly timed musical programming language.",
+ .help_des_offset = 28,
+ .ver_extra =
+ "License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n"
+ };
+ struct CArg *ca = &arg->arg->arg;
+ cmdapp_init(&app, ca->argc, ca->argv, CMDAPP_MODE_SHORTARG, &info);
+ cmdapp_enable_procedure(&app, myproc, arg);
+ cmdopt_t opt[NOPTIONS];
+ setup_options(&app, opt);
+ if(cmdapp_run(&app) == EXIT_SUCCESS && cmdapp_should_exit(&app))
+ arg->arg->quit = 1;
+ cmdapp_destroy(&app);
+ return GW_OK;
+}
+
+ANN static void config_default(struct ArgInternal* arg) {
char* home = getenv("HOME");
char c[strlen(home) + strlen(GWIONRC) + 2];
sprintf(c, "%s/%s", home, GWIONRC);
- config_parse(gwion, arg, c);
+ config_parse(arg, c);
}
ANN m_bool arg_parse(const Gwion gwion, Arg* a) {
+ struct ArgInternal arg = { .gwion=gwion, .arg=a };
arg_init(a);
#ifdef __FUZZING
return;
#endif
- config_default(gwion, a);
- return _arg_parse(gwion, a);
+ config_default(&arg);
+ return _arg_parse(&arg);
}
const Exp e = range->start ?: range->end;
const Symbol sym = insert_symbol("@range");
struct Op_Import opi = { .op=sym, .rhs=e->type,
- .pos=e->pos, .data=(uintptr_t)prim_exp(data), .op_type=op_exp };
+ .pos=e->pos, .data=(uintptr_t)prim_exp(data) };
CHECK_BB(op_emit(emit, &opi))
emit_gc(emit, -SZ_INT);
return GW_OK;
}
// look mum no pos
struct Op_Import opi = { .op=insert_symbol("@array"), .lhs=info->array.exp->type, .rhs=info->array.type,
- .data=(uintptr_t)info, .op_type=op_array };
+ .data=(uintptr_t)info };
if(!info->is_var && (GET_FLAG(info->array.type, abstract) || type_ref(info->array.type))) {
const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
instr->m_val = -SZ_INT;
const Symbol sym = insert_symbol("@slice");
const Exp e = range->range->start ?: range->range->end;
struct Op_Import opi = { .op=sym, .lhs=e->type, .rhs=range->base->type,
- .pos=e->pos, .data=(uintptr_t)exp_self(range), .op_type=op_exp };
+ .pos=e->pos, .data=(uintptr_t)exp_self(range) };
return op_emit(emit, &opi);
}
CHECK_BB(emit_exp_call1(emit, t->info->func))
else {
struct Op_Import opi = { .op=insert_symbol("@ctor"), .rhs=t,
- .data=(uintptr_t)exp_call, .pos=exp_self(exp_call)->pos, .op_type=op_exp };
+ .data=(uintptr_t)exp_call, .pos=exp_self(exp_call)->pos };
CHECK_BB(op_emit(emit, &opi))
}
const Exp e = exp_self(exp_call);
// emit_exp_addref1(emit, lhs, -exp_size(lhs) - size);
// emit_exp_addref1(emit, rhs, -size);
struct Op_Import opi = { .op=bin->op, .lhs=lhs->type, .rhs=rhs->type,
- .pos=exp_self(bin)->pos, .data=(uintptr_t)bin, .op_type=op_binary };
+ .pos=exp_self(bin)->pos, .data=(uintptr_t)bin };
return op_emit(emit, &opi);
}
ANN static m_bool emit_exp_cast(const Emitter emit, const Exp_Cast* cast) {
// no pos ?
struct Op_Import opi = { .op=insert_symbol("$"), .lhs=cast->exp->type, .rhs=exp_self(cast)->type,
- .data=(uintptr_t)cast, .op_type=op_cast};
+ .data=(uintptr_t)cast };
CHECK_BB(emit_exp(emit, cast->exp))
(void)op_emit(emit, &opi);
return GW_OK;
ANN static m_bool emit_exp_post(const Emitter emit, const Exp_Postfix* post) {
// no pos ?
struct Op_Import opi = { .op=post->op, .lhs=post->exp->type,
- .data=(uintptr_t)post, .op_type=op_postfix };
+ .data=(uintptr_t)post };
CHECK_BB(emit_exp(emit, post->exp))
return op_emit(emit, &opi);
}
const Symbol sym = insert_symbol("==");
struct Exp_ exp = {};
struct Op_Import opi = { .op=sym, .lhs=arg->type, .rhs=arg->type,
- .pos=me->fdef->pos, .data=(uintptr_t)&exp.d, .op_type=op_binary };
+ .pos=me->fdef->pos, .data=(uintptr_t)&exp.d };
CHECK_BB(op_emit(emit, &opi))
const Instr instr = emit_add_instr(emit, BranchEqInt);
vector_add(&me->branch, (vtype)instr);
const Type base = actual_type(emit->gwion, t);
CHECK_BB(ensure_emit(emit, base))
// no pos ?
- struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary, .op_type=op_unary };
+ struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary };
if(unary->unary_type == unary_exp && unary->op != insert_symbol("spork") && unary->op != insert_symbol("fork")) {
CHECK_BB(emit_exp_pop_next(emit, unary->exp))
opi.rhs = unary->exp->type;
const struct Implicit imp = { from, to, from->pos };
// no pos
struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=from->type, .rhs=to,
- .data=(m_uint)&imp, .op_type=op_implicit };
+ .data=(m_uint)&imp };
return op_emit(emit, &opi);
}
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"),
- .rhs=e->type, .pos=e->pos, .data=(uintptr_t)e, .op_type=op_exp };
+ .rhs=e->type, .pos=e->pos, .data=(uintptr_t)e };
CHECK_BO(op_emit(emit, &opi))
return (Instr)vector_back(&emit->code->instr);
}
const Exp_Binary bin = { .lhs=base, .rhs=e, .op=op };
struct Exp_ ebin = { .d={.exp_binary=bin}, };
struct Op_Import opi = { .op=op, .lhs=base->type, .rhs=e->type,
- .data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos, .op_type=op_binary };
+ .data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos };
CHECK_BB(op_emit(emit, &opi))
const Instr instr = emit_add_instr(emit, BranchEqInt);
vector_add(v, (vtype)instr);
const Exp_Binary bin = { .lhs=base, .rhs=e, .op=insert_symbol("==") };
struct Exp_ ebin = { .d={.exp_binary=bin}, };
struct Op_Import opi = { .op=insert_symbol("=="), .lhs=base->type, .rhs=e->type,
- .data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos, .op_type=op_binary };
+ .data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos };
CHECK_BO(op_emit(emit, &opi))
const Instr instr = emit_add_instr(emit, BranchEqInt);
vector_add(vec, (vtype)instr);
ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member) {
struct Op_Import opi = { .op=insert_symbol("@dot"), .lhs=member->base->type,
- .rhs=exp_self(member)->type, .data=(uintptr_t)member, .pos=exp_self(member)->pos, .op_type=op_dot };
+ .rhs=exp_self(member)->type, .data=(uintptr_t)member, .pos=exp_self(member)->pos };
return op_emit(emit, &opi);
}
const size_t tdepth = depth + src->array_depth;
const Type base = tdepth > 1 ? array_type(env, src, tdepth-1) : src;
struct TemplateScan ts = { .t=base, /*.td=td*/ };
- struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=env->gwion->type[et_array], .data=(uintptr_t)&ts, .op_type=op_scan };
+ struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=env->gwion->type[et_array], .data=(uintptr_t)&ts };
return op_check(env, &opi);
}
pass_default(gwion);
arg->si = gwion->vm->bbq->si = new_soundinfo(gwion->mp);
CHECK_BB(arg_parse(gwion, arg))
- return gwion_ok(gwion, arg);
+ return !arg->quit ? gwion_ok(gwion, arg) : GW_ERROR;
}
ANN void gwion_run(const Gwion gwion) {
const Exp e, const Type t) {
struct Implicit imp = { .e=e, .t=t, .pos=e->pos };
struct Op_Import opi = { .op=sym, .lhs=e->type,
- .rhs=t, .data=(uintptr_t)&imp, .pos=e->pos, .op_type=op_implicit };
+ .rhs=t, .data=(uintptr_t)&imp, .pos=e->pos };
return op_check(env, &opi);
}
CHECK_BO(check_range(env, range))
const Exp e = range->start ?: range->end;
const Symbol sym = insert_symbol("@range");
- struct Op_Import opi = { .op=sym, .rhs=e->type, .pos=e->pos, .data=(uintptr_t)prim_exp(data), .op_type=op_exp };
+ struct Op_Import opi = { .op=sym, .rhs=e->type, .pos=e->pos, .data=(uintptr_t)prim_exp(data) };
return op_check(env, &opi);
}
ANN static Type check_dot(const Env env, const Exp_Dot *member) {
struct Op_Import opi = { .op=insert_symbol("@dot"), .lhs=member->base->type, .data=(uintptr_t)member,
- .pos=exp_self(member)->pos, .op_type=op_dot };
+ .pos=exp_self(member)->pos };
return op_check(env, &opi);
}
ANN Type check_array_access(const Env env, const Array_Sub array) {
const Symbol sym = insert_symbol("@array");
struct Op_Import opi = { .op=sym, .lhs=array->exp->type, .rhs=array->type,
- .pos=array->exp->pos, .data=(uintptr_t)array, .op_type=op_array };
+ .pos=array->exp->pos, .data=(uintptr_t)array };
return op_check(env, &opi);
}
const Symbol sym = insert_symbol("@slice");
const Exp e = range->range->start ?: range->range->end;
struct Op_Import opi = { .op=sym, .lhs=e->type, .rhs=range->base->type,
- .pos=e->pos, .data=(uintptr_t)exp_self(range), .op_type=op_exp };
+ .pos=e->pos, .data=(uintptr_t)exp_self(range) };
return op_check(env, &opi);
}
const Type t = actual_type(env->gwion, exp->func->type);
const Exp e = exp_self(exp);
struct Op_Import opi = { .op=insert_symbol("@func_check"),
- .rhs=t, .pos=e->pos, .data=(uintptr_t)e, .op_type=op_exp };
+ .rhs=t, .pos=e->pos, .data=(uintptr_t)e };
CHECK_NB(op_check(env, &opi)) // doesn't really return NULL
if(e->exp_type != ae_exp_call)
return 0;
const Type t = actual_type(env->gwion, exp->func->type);
if(isa(t, env->gwion->type[et_function]) < 0) { // use func flag?
struct Op_Import opi = { .op=insert_symbol("@ctor"), .rhs=actual_type(env->gwion, exp->func->type),
- .data=(uintptr_t)exp, .pos=exp_self(exp)->pos, .op_type=op_exp };
+ .data=(uintptr_t)exp, .pos=exp_self(exp)->pos };
const Type t = op_check(env, &opi);
return t;
}
if(is_auto)
bin->rhs->type = bin->lhs->type;
struct Op_Import opi = { .op=bin->op, .lhs=bin->lhs->type,
- .rhs=bin->rhs->type, .data=(uintptr_t)bin, .pos=exp_self(bin)->pos, .op_type=op_binary };
+ .rhs=bin->rhs->type, .data=(uintptr_t)bin, .pos=exp_self(bin)->pos };
exp_setuse(bin->lhs, 1);
exp_setuse(bin->rhs, 1);
const Type ret = op_check(env, &opi);
DECL_OO(const Type, t, = check_exp(env, cast->exp))
CHECK_OO((exp_self(cast)->type = known_type(env, cast->td)))
struct Op_Import opi = { .op=insert_symbol("$"), .lhs=t, .rhs=exp_self(cast)->type,
- .data=(uintptr_t)cast, .pos=exp_self(cast)->pos, .op_type=op_cast };
+ .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) {
struct Op_Import opi = { .op=post->op, .lhs=check_exp(env, post->exp),
- .data=(uintptr_t)post, .pos=exp_self(post)->pos, .op_type=op_postfix };
+ .data=(uintptr_t)post, .pos=exp_self(post)->pos };
CHECK_OO(opi.lhs)
exp_setuse(post->exp, 1);
const Type t = op_check(env, &opi);
exp_setuse(unary->exp, 1);
}
struct Op_Import opi = { .op=unary->op, .rhs=rhs,
- .data=(uintptr_t)unary, .pos=exp_self(unary)->pos, .op_type=op_unary };
+ .data=(uintptr_t)unary, .pos=exp_self(unary)->pos };
DECL_OO(const Type, ret, = op_check(env, &opi))
const Type t = actual_type(env->gwion, ret);
CHECK_BO(ensure_traverse(env, t))
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"),
- .rhs=type, .pos=e->pos, .data=(uintptr_t)e, .op_type=op_exp };
+ .rhs=type, .pos=e->pos, .data=(uintptr_t)e };
return op_check(env, &opi);
}
#define check_flow(emit,b) _flow(emit, b, 1)
Exp_Binary bin = { .lhs=base, .rhs=e, .op=op };
struct Exp_ ebin = { .d={.exp_binary=bin} };
struct Op_Import opi = { .op=op, .lhs=base->type, .rhs=e->type,
- .data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos, .op_type=op_binary };
+ .data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos };
CHECK_OB(op_check(env, &opi))
}
}
continue;
Type l = opi->lhs;
do {
- struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data, .op_type=opi->op_type };
+ struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data };
struct OpChecker ock = { env, &nspc->info->op_map, &opi2 };
const Type ret = op_check_inner(&ock, i);
if(ret) {
if(tflag(t, tflag_ntmpl) && !td->types)
return t;
struct TemplateScan ts = { .t=t, .td=td };
- struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td->pos, .op_type=op_scan };
+ struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td->pos };
return op_check(env, &opi);
} else if(td->types)
return maybe_func(env, t, td);