Jacek Caban : vbscript: Added dim statement compiler implementation.

Alexandre Julliard julliard at winehq.org
Tue Sep 13 12:18:09 CDT 2011


Module: wine
Branch: master
Commit: d1c152756c3fd6461f4cab9d29cb993c2d0a30ed
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d1c152756c3fd6461f4cab9d29cb993c2d0a30ed

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Sep 13 11:36:47 2011 +0200

vbscript: Added dim statement compiler implementation.

---

 dlls/vbscript/compile.c      |  104 ++++++++++++++++++++++++++++++++++++++++++
 dlls/vbscript/tests/lang.vbs |    2 +
 dlls/vbscript/vbscript.h     |    8 +++
 3 files changed, 114 insertions(+), 0 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 877780d..9bdc31d 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -32,6 +32,9 @@ typedef struct {
     unsigned instr_cnt;
     unsigned instr_size;
     vbscode_t *code;
+
+    dim_decl_t *dim_decls;
+    dynamic_var_t *global_vars;
 } compile_ctx_t;
 
 static HRESULT compile_expression(compile_ctx_t*,expression_t*);
@@ -315,6 +318,38 @@ static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *
     return hres;
 }
 
+static BOOL lookup_dim_decls(compile_ctx_t *ctx, const WCHAR *name)
+{
+    dim_decl_t *dim_decl;
+
+    for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
+        if(!strcmpiW(dim_decl->name, name))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
+{
+    dim_decl_t *dim_decl = stat->dim_decls;
+
+    while(1) {
+        if(lookup_dim_decls(ctx, dim_decl->name)) {
+            FIXME("dim %s name redefined\n", debugstr_w(dim_decl->name));
+            return E_FAIL;
+        }
+
+        if(!dim_decl->next)
+            break;
+        dim_decl = dim_decl->next;
+    }
+
+    dim_decl->next = ctx->dim_decls;
+    ctx->dim_decls = stat->dim_decls;
+    return S_OK;
+}
+
 static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
 {
     HRESULT hres;
@@ -327,6 +362,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
         case STAT_CALL:
             hres = compile_member_expression(ctx, ((call_statement_t*)stat)->expr, FALSE);
             break;
+        case STAT_DIM:
+            hres = compile_dim_statement(ctx, (dim_statement_t*)stat);
+            break;
         default:
             FIXME("Unimplemented statement type %d\n", stat->type);
             hres = E_NOTIMPL;
@@ -353,6 +391,52 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
     if(push_instr(ctx, OP_ret) == -1)
         return E_OUTOFMEMORY;
 
+    if(ctx->dim_decls) {
+        dim_decl_t *dim_decl;
+        dynamic_var_t *new_var;
+
+        for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
+            new_var = compiler_alloc(ctx->code, sizeof(*new_var));
+            if(!new_var)
+                return E_OUTOFMEMORY;
+
+            new_var->name = compiler_alloc_string(ctx->code, dim_decl->name);
+            if(!new_var->name)
+                return E_OUTOFMEMORY;
+
+            V_VT(&new_var->v) = VT_EMPTY;
+
+            new_var->next = ctx->global_vars;
+            ctx->global_vars = new_var;
+        }
+    }
+
+    return S_OK;
+}
+
+static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier)
+{
+    dynamic_var_t *var;
+
+    for(var = script->global_vars; var; var = var->next) {
+        if(!strcmpiW(var->name, identifier))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script)
+{
+    dynamic_var_t *var;
+
+    for(var = ctx->global_vars; var; var = var->next) {
+        if(lookup_script_identifier(script, var->name)) {
+            FIXME("%s: redefined\n", debugstr_w(var->name));
+            return E_FAIL;
+        }
+    }
+
     return S_OK;
 }
 
@@ -422,12 +506,32 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
     if(!ctx.code)
         return E_OUTOFMEMORY;
 
+    ctx.global_vars = NULL;
+    ctx.dim_decls = NULL;
+
     hres = compile_func(&ctx, ctx.parser.stats, &ctx.code->global_code);
     if(FAILED(hres)) {
         release_vbscode(ctx.code);
         return hres;
     }
 
+    hres = check_script_collisions(&ctx, script);
+    if(FAILED(hres)) {
+        release_vbscode(ctx.code);
+        return hres;
+    }
+
+    if(ctx.global_vars) {
+        dynamic_var_t *var;
+
+        for(var = ctx.global_vars; var->next; var = var->next);
+
+        var->next = script->global_vars;
+        script->global_vars = ctx.global_vars;
+    }
+
+    parser_release(&ctx.parser);
+
     list_add_tail(&script->code_list, &ctx.code->entry);
     *ret = ctx.code;
     return S_OK;
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 2e81643..94dc3eb 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -18,6 +18,8 @@
 
 Option Explicit
 
+dim x, y
+
 call ok(true, "true is not true?")
 ok true, "true is not true?"
 call ok((true), "true is not true?")
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 226f0d2..734ce8a 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -65,6 +65,12 @@ HRESULT disp_get_id(IDispatch*,BSTR,DISPID*);
 HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*);
 HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*);
 
+typedef struct _dynamic_var_t {
+    struct _dynamic_var_t *next;
+    VARIANT v;
+    const WCHAR *name;
+} dynamic_var_t;
+
 struct _script_ctx_t {
     IActiveScriptSite *site;
     LCID lcid;
@@ -73,6 +79,8 @@ struct _script_ctx_t {
 
     vbdisp_t *script_obj;
 
+    dynamic_var_t *global_vars;
+
     struct list code_list;
     struct list named_items;
 };




More information about the wine-cvs mailing list