return S_OK;
}
+static HRESULT push_instr_uint(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
+{
+ unsigned ret;
+
+ ret = push_instr(ctx, op);
+ if(ret == -1)
+ return E_OUTOFMEMORY;
+
+ instr_ptr(ctx, ret)->arg1.uint = arg;
+ return S_OK;
+}
+
static HRESULT push_instr_addr(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
{
unsigned ret;
return S_OK;
}
+static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat)
+{
+ unsigned step_instr, instr;
+ BSTR identifier;
+ HRESULT hres;
+
+ identifier = alloc_bstr_arg(ctx, stat->identifier);
+ if(!identifier)
+ return E_OUTOFMEMORY;
+
+ hres = compile_expression(ctx, stat->from_expr);
+ if(FAILED(hres))
+ return hres;
+
+ instr = push_instr(ctx, OP_assign_ident);
+ if(instr == -1)
+ return E_OUTOFMEMORY;
+ instr_ptr(ctx, instr)->arg1.bstr = identifier;
+
+ hres = compile_expression(ctx, stat->to_expr);
+ if(FAILED(hres))
+ return hres;
+
+ if(push_instr(ctx, OP_val) == -1)
+ return E_OUTOFMEMORY;
+
+ if(stat->step_expr) {
+ hres = compile_expression(ctx, stat->step_expr);
+ if(FAILED(hres))
+ return hres;
+
+ if(push_instr(ctx, OP_val) == -1)
+ return E_OUTOFMEMORY;
+ }else {
+ hres = push_instr_int(ctx, OP_short, 1);
+ if(FAILED(hres))
+ return hres;
+ }
+
+ step_instr = push_instr(ctx, OP_step);
+ if(step_instr == -1)
+ return E_OUTOFMEMORY;
+ instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
+
+ hres = compile_statement(ctx, stat->body);
+ if(FAILED(hres))
+ return hres;
+
+ instr = push_instr(ctx, OP_incc);
+ if(instr == -1)
+ return E_OUTOFMEMORY;
+ instr_ptr(ctx, instr)->arg1.bstr = identifier;
+
+ hres = push_instr_addr(ctx, OP_jmp, step_instr);
+ if(FAILED(hres))
+ return hres;
+
+ instr_ptr(ctx, step_instr)->arg1.uint = ctx->instr_cnt;
+
+ return push_instr_uint(ctx, OP_pop, 2);
+}
+
static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
{
HRESULT hres;
case STAT_EXITSUB:
hres = compile_exitsub_statement(ctx);
break;
+ case STAT_FORTO:
+ hres = compile_forto_statement(ctx, (forto_statement_t*)stat);
+ break;
case STAT_FUNC:
hres = compile_function_statement(ctx, (function_statement_t*)stat);
break;
return add_dynamic_var(ctx, arg, TRUE, val.v, val.owned);
}
+static HRESULT interp_val(exec_ctx_t *ctx)
+{
+ FIXME("\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT interp_pop(exec_ctx_t *ctx)
+{
+ const unsigned n = ctx->instr->arg1.uint;
+
+ TRACE("%u\n", n);
+
+ stack_popn(ctx, n);
+ return S_OK;
+}
+
static HRESULT interp_new(exec_ctx_t *ctx)
{
const WCHAR *arg = ctx->instr->arg1.bstr;
return stack_push(ctx, &v);
}
+static HRESULT interp_step(exec_ctx_t *ctx)
+{
+ const BSTR ident = ctx->instr->arg2.bstr;
+ FIXME("%s\n", debugstr_w(ident));
+ return E_NOTIMPL;
+}
+
static HRESULT interp_jmp(exec_ctx_t *ctx)
{
const unsigned arg = ctx->instr->arg1.uint;
return stack_push(ctx, &v);
}
+static HRESULT interp_incc(exec_ctx_t *ctx)
+{
+ const BSTR ident = ctx->instr->arg1.bstr;
+ FIXME("%s\n", debugstr_w(ident));
+ return E_NOTIMPL;
+}
+
static const instr_func_t op_funcs[] = {
#define X(x,n,a,b) interp_ ## x,
OP_LIST
X(icallv, 1, ARG_BSTR, ARG_UINT) \
X(idiv, 1, 0, 0) \
X(imp, 1, 0, 0) \
+ X(incc, 1, ARG_BSTR, 0) \
X(is, 1, 0, 0) \
X(jmp, 0, ARG_ADDR, 0) \
X(jmp_false, 0, ARG_ADDR, 0) \
X(nothing, 1, 0, 0) \
X(null, 1, 0, 0) \
X(or, 1, 0, 0) \
+ X(pop, 1, ARG_UINT, 0) \
X(ret, 0, 0, 0) \
X(set_ident, 1, ARG_BSTR, 0) \
X(set_member, 1, ARG_BSTR, 0) \
X(short, 1, ARG_INT, 0) \
+ X(step, 0, ARG_ADDR, ARG_BSTR) \
X(stop, 1, 0, 0) \
X(string, 1, ARG_STR, 0) \
X(sub, 1, 0, 0) \
+ X(val, 1, 0, 0) \
X(xor, 1, 0, 0)
typedef enum {