diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 9cfe45b6b4c..1f1f0410f5f 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -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; diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index c2ffd98e62a..1327c173c81 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -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 diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index bd55719364d..4b0a569f56c 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -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 {