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