Jacek Caban : vbscript: Added const statement compiler implementation.

Alexandre Julliard julliard at winehq.org
Wed Sep 21 13:35:15 CDT 2011


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep 21 14:03:38 2011 +0200

vbscript: Added const statement compiler implementation.

---

 dlls/vbscript/compile.c  |   78 ++++++++++++++++++++++++++++++++++++++++++++--
 dlls/vbscript/interp.c   |    7 ++++
 dlls/vbscript/vbscript.h |    1 +
 3 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 53b7f81..712d97d 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -46,6 +46,9 @@ typedef struct {
     dim_decl_t *dim_decls;
     dynamic_var_t *global_vars;
 
+    const_decl_t *const_decls;
+    const_decl_t *global_consts;
+
     function_t *func;
     function_t *funcs;
     function_decl_t *func_decls;
@@ -302,6 +305,26 @@ static inline void label_set_addr(compile_ctx_t *ctx, unsigned label)
     ctx->labels[label & ~LABEL_FLAG] = ctx->instr_cnt;
 }
 
+static expression_t *lookup_const_decls(compile_ctx_t *ctx, const WCHAR *name, BOOL lookup_global)
+{
+    const_decl_t *decl;
+
+    for(decl = ctx->const_decls; decl; decl = decl->next) {
+        if(!strcmpiW(decl->name, name))
+            return decl->value_expr;
+    }
+
+    if(!lookup_global)
+        return NULL;
+
+    for(decl = ctx->global_consts; decl; decl = decl->next) {
+        if(!strcmpiW(decl->name, name))
+            return decl->value_expr;
+    }
+
+    return NULL;
+}
+
 static HRESULT compile_args(compile_ctx_t *ctx, expression_t *args, unsigned *ret)
 {
     unsigned arg_cnt = 0;
@@ -325,6 +348,14 @@ static HRESULT compile_member_expression(compile_ctx_t *ctx, member_expression_t
     unsigned arg_cnt = 0;
     HRESULT hres;
 
+    if(ret_val && !expr->args) {
+        expression_t *const_expr;
+
+        const_expr = lookup_const_decls(ctx, expr->identifier, TRUE);
+        if(const_expr)
+            return compile_expression(ctx, const_expr);
+    }
+
     hres = compile_args(ctx, expr->args, &arg_cnt);
     if(FAILED(hres))
         return hres;
@@ -627,7 +658,8 @@ 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) || lookup_args_name(ctx, dim_decl->name)) {
+        if(lookup_dim_decls(ctx, dim_decl->name) || lookup_args_name(ctx, dim_decl->name)
+           || lookup_const_decls(ctx, dim_decl->name, FALSE)) {
             FIXME("dim %s name redefined\n", debugstr_w(dim_decl->name));
             return E_FAIL;
         }
@@ -643,6 +675,39 @@ static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
     return S_OK;
 }
 
+static HRESULT compile_const_statement(compile_ctx_t *ctx, const_statement_t *stat)
+{
+    const_decl_t *decl, *next_decl = stat->decls;
+
+    do {
+        decl = next_decl;
+
+        if(lookup_const_decls(ctx, decl->name, FALSE) || lookup_args_name(ctx, decl->name)
+                || lookup_dim_decls(ctx, decl->name)) {
+            FIXME("%s redefined\n", debugstr_w(decl->name));
+            return E_FAIL;
+        }
+
+        if(ctx->func->type == FUNC_GLOBAL) {
+            HRESULT hres;
+
+            hres = compile_expression(ctx, decl->value_expr);
+            if(FAILED(hres))
+                return hres;
+
+            hres = push_instr_bstr(ctx, OP_const, decl->name);
+            if(FAILED(hres))
+                return hres;
+        }
+
+        next_decl = decl->next;
+        decl->next = ctx->const_decls;
+        ctx->const_decls = decl;
+    } while(next_decl);
+
+    return S_OK;
+}
+
 static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement_t *stat)
 {
     if(ctx->func != &ctx->code->global_code) {
@@ -712,6 +777,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_CONST:
+            hres = compile_const_statement(ctx, (const_statement_t*)stat);
+            break;
         case STAT_DIM:
             hres = compile_dim_statement(ctx, (dim_statement_t*)stat);
             break;
@@ -815,6 +883,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
 
     ctx->func = func;
     ctx->dim_decls = NULL;
+    ctx->const_decls = NULL;
     hres = compile_statement(ctx, stat);
     ctx->func = NULL;
     if(FAILED(hres))
@@ -893,7 +962,7 @@ static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, functi
     function_t *func;
     HRESULT hres;
 
-    if(lookup_dim_decls(ctx, decl->name) || lookup_funcs_name(ctx, decl->name)) {
+    if(lookup_dim_decls(ctx, decl->name) || lookup_funcs_name(ctx, decl->name) || lookup_const_decls(ctx, decl->name, FALSE)) {
         FIXME("%s: redefinition\n", debugstr_w(decl->name));
         return E_FAIL;
     }
@@ -1019,7 +1088,7 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
     static const WCHAR class_terminateW[] = {'c','l','a','s','s','_','t','e','r','m','i','n','a','t','e',0};
 
     if(lookup_dim_decls(ctx, class_decl->name) || lookup_funcs_name(ctx, class_decl->name)
-            || lookup_class_name(ctx, class_decl->name)) {
+            || lookup_const_decls(ctx, class_decl->name, FALSE) || lookup_class_name(ctx, class_decl->name)) {
         FIXME("%s: redefinition\n", debugstr_w(class_decl->name));
         return E_FAIL;
     }
@@ -1247,6 +1316,7 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
     ctx.dim_decls = NULL;
     ctx.classes = NULL;
     ctx.labels = NULL;
+    ctx.global_consts = NULL;
     ctx.labels_cnt = ctx.labels_size = 0;
 
     hres = compile_func(&ctx, ctx.parser.stats, &ctx.code->global_code);
@@ -1255,6 +1325,8 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
         return hres;
     }
 
+    ctx.global_consts = ctx.const_decls;
+
     for(func_decl = ctx.func_decls; func_decl; func_decl = func_decl->next) {
         hres = create_function(&ctx, func_decl, &new_func);
         if(FAILED(hres)) {
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index aff7b91..232a582 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -644,6 +644,13 @@ static HRESULT interp_set_member(exec_ctx_t *ctx)
     return hres;
 }
 
+static HRESULT interp_const(exec_ctx_t *ctx)
+{
+    BSTR arg = ctx->instr->arg1.bstr;
+    FIXME("%s\n", debugstr_w(arg));
+    return E_NOTIMPL;
+}
+
 static HRESULT interp_new(exec_ctx_t *ctx)
 {
     const WCHAR *arg = ctx->instr->arg1.bstr;
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 5a968d1..73b0b86 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -184,6 +184,7 @@ typedef enum {
     X(assign_member,  1, ARG_BSTR,    0)          \
     X(bool,           1, ARG_INT,     0)          \
     X(concat,         1, 0,           0)          \
+    X(const,          1, ARG_BSTR,    0)          \
     X(div,            1, 0,           0)          \
     X(double,         1, ARG_DOUBLE,  0)          \
     X(empty,          1, 0,           0)          \




More information about the wine-cvs mailing list