vbscript: Added for..to statement compiler implementation.

This commit is contained in:
Jacek Caban 2011-09-22 14:23:10 +02:00 committed by Alexandre Julliard
parent d935c21ccf
commit 8244e4c0c7
3 changed files with 111 additions and 0 deletions

View File

@ -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;

View File

@ -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

View File

@ -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 {