vbscript: Added for..to statement compiler implementation.
This commit is contained in:
parent
d935c21ccf
commit
8244e4c0c7
|
@ -169,6 +169,18 @@ static HRESULT push_instr_int(compile_ctx_t *ctx, vbsop_t op, LONG arg)
|
|||
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;
|
||||
|
@ -603,6 +615,68 @@ static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *
|
|||
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;
|
||||
|
@ -799,6 +873,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
|
|||
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;
|
||||
|
|
|
@ -682,6 +682,22 @@ static HRESULT interp_const(exec_ctx_t *ctx)
|
|||
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;
|
||||
|
@ -710,6 +726,13 @@ static HRESULT interp_new(exec_ctx_t *ctx)
|
|||
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;
|
||||
|
@ -1439,6 +1462,13 @@ static HRESULT interp_neg(exec_ctx_t *ctx)
|
|||
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
|
||||
|
|
|
@ -199,6 +199,7 @@ typedef enum {
|
|||
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) \
|
||||
|
@ -218,13 +219,16 @@ typedef enum {
|
|||
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 {
|
||||
|
|
Loading…
Reference in New Issue