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;
|
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)
|
static HRESULT push_instr_addr(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
|
||||||
{
|
{
|
||||||
unsigned ret;
|
unsigned ret;
|
||||||
|
@ -603,6 +615,68 @@ static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *
|
||||||
return S_OK;
|
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)
|
static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
@ -799,6 +873,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
|
||||||
case STAT_EXITSUB:
|
case STAT_EXITSUB:
|
||||||
hres = compile_exitsub_statement(ctx);
|
hres = compile_exitsub_statement(ctx);
|
||||||
break;
|
break;
|
||||||
|
case STAT_FORTO:
|
||||||
|
hres = compile_forto_statement(ctx, (forto_statement_t*)stat);
|
||||||
|
break;
|
||||||
case STAT_FUNC:
|
case STAT_FUNC:
|
||||||
hres = compile_function_statement(ctx, (function_statement_t*)stat);
|
hres = compile_function_statement(ctx, (function_statement_t*)stat);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -682,6 +682,22 @@ static HRESULT interp_const(exec_ctx_t *ctx)
|
||||||
return add_dynamic_var(ctx, arg, TRUE, val.v, val.owned);
|
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)
|
static HRESULT interp_new(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
const WCHAR *arg = ctx->instr->arg1.bstr;
|
const WCHAR *arg = ctx->instr->arg1.bstr;
|
||||||
|
@ -710,6 +726,13 @@ static HRESULT interp_new(exec_ctx_t *ctx)
|
||||||
return stack_push(ctx, &v);
|
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)
|
static HRESULT interp_jmp(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
const unsigned arg = ctx->instr->arg1.uint;
|
const unsigned arg = ctx->instr->arg1.uint;
|
||||||
|
@ -1439,6 +1462,13 @@ static HRESULT interp_neg(exec_ctx_t *ctx)
|
||||||
return stack_push(ctx, &v);
|
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[] = {
|
static const instr_func_t op_funcs[] = {
|
||||||
#define X(x,n,a,b) interp_ ## x,
|
#define X(x,n,a,b) interp_ ## x,
|
||||||
OP_LIST
|
OP_LIST
|
||||||
|
|
|
@ -199,6 +199,7 @@ typedef enum {
|
||||||
X(icallv, 1, ARG_BSTR, ARG_UINT) \
|
X(icallv, 1, ARG_BSTR, ARG_UINT) \
|
||||||
X(idiv, 1, 0, 0) \
|
X(idiv, 1, 0, 0) \
|
||||||
X(imp, 1, 0, 0) \
|
X(imp, 1, 0, 0) \
|
||||||
|
X(incc, 1, ARG_BSTR, 0) \
|
||||||
X(is, 1, 0, 0) \
|
X(is, 1, 0, 0) \
|
||||||
X(jmp, 0, ARG_ADDR, 0) \
|
X(jmp, 0, ARG_ADDR, 0) \
|
||||||
X(jmp_false, 0, ARG_ADDR, 0) \
|
X(jmp_false, 0, ARG_ADDR, 0) \
|
||||||
|
@ -218,13 +219,16 @@ typedef enum {
|
||||||
X(nothing, 1, 0, 0) \
|
X(nothing, 1, 0, 0) \
|
||||||
X(null, 1, 0, 0) \
|
X(null, 1, 0, 0) \
|
||||||
X(or, 1, 0, 0) \
|
X(or, 1, 0, 0) \
|
||||||
|
X(pop, 1, ARG_UINT, 0) \
|
||||||
X(ret, 0, 0, 0) \
|
X(ret, 0, 0, 0) \
|
||||||
X(set_ident, 1, ARG_BSTR, 0) \
|
X(set_ident, 1, ARG_BSTR, 0) \
|
||||||
X(set_member, 1, ARG_BSTR, 0) \
|
X(set_member, 1, ARG_BSTR, 0) \
|
||||||
X(short, 1, ARG_INT, 0) \
|
X(short, 1, ARG_INT, 0) \
|
||||||
|
X(step, 0, ARG_ADDR, ARG_BSTR) \
|
||||||
X(stop, 1, 0, 0) \
|
X(stop, 1, 0, 0) \
|
||||||
X(string, 1, ARG_STR, 0) \
|
X(string, 1, ARG_STR, 0) \
|
||||||
X(sub, 1, 0, 0) \
|
X(sub, 1, 0, 0) \
|
||||||
|
X(val, 1, 0, 0) \
|
||||||
X(xor, 1, 0, 0)
|
X(xor, 1, 0, 0)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
Loading…
Reference in New Issue