vbscript: Added for..to statement compiler implementation.
authorJacek Caban <jacek@codeweavers.com>
Thu, 22 Sep 2011 12:23:10 +0000 (14:23 +0200)
committerAlexandre Julliard <julliard@winehq.org>
Thu, 22 Sep 2011 14:33:08 +0000 (16:33 +0200)
dlls/vbscript/compile.c
dlls/vbscript/interp.c
dlls/vbscript/vbscript.h

index 9cfe45b6b4c0b8808e9a25bbd280f4f7f8eb7d0f..1f1f0410f5f4f3f4974f5d0c0f4c412e8364936b 100644 (file)
@@ -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;
index c2ffd98e62a1e66e69355728563d3fba92e3d1dc..1327c173c8132dcd84b9d18f09d38f63a10635f0 100644 (file)
@@ -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
index bd55719364d199d573cf5da30de57d8630c52ff5..4b0a569f56c7385a7c202afc7ca740ad9ece3537 100644 (file)
@@ -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 {