78895: Subject: [PATCH 03/19] vbscript: Added set statement parser/compiler implementation

buildbot at kegel.com buildbot at kegel.com
Thu Sep 15 07:44:25 CDT 2011


This is an experimental automated build and test service.
Please feel free to ignore this email while we work the kinks out.

For more info about this message, see http://wiki.winehq.org/BuildBot

The Buildbot has detected a failed build on builder runtests-default while building Wine.
Full details are available at: http://buildbot.kegel.com/builders/runtests-default/builds/89 (though maybe not for long, as I'm still reinstalling the buildbot periodically while experimenting)
BUILD FAILED: failed shell_3

Errors:
action.c:4792: Test failed: The 'Spooler' service does not exist
make: *** [action.ok] Error 1

-------------- next part --------------
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 01/19] vbscript: Added class parser implementation
Message-Id: <4E71ECAF.6080705 at codeweavers.com>
Date: Thu, 15 Sep 2011 14:16:47 +0200

---
  dlls/vbscript/parse.h        |    6 ++++++
  dlls/vbscript/parser.y       |   32 +++++++++++++++++++++++++++++++-
  dlls/vbscript/tests/lang.vbs |    3 +++
  3 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index 7e1124c..67fa221 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -142,6 +142,11 @@ typedef struct _function_statement_t {
     function_decl_t *func_decl;
 } function_statement_t;
 
+typedef struct _class_decl_t {
+    const WCHAR *name;
+    struct _class_decl_t *next;
+} class_decl_t;
+
 typedef struct _elseif_decl_t {
     expression_t *expr;
     statement_t *stat;
@@ -170,6 +175,7 @@ typedef struct {
 
     statement_t *stats;
     statement_t *stats_tail;
+    class_decl_t *class_decls;
 
     vbsheap_t heap;
 } parser_ctx_t;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index a6281d6..6d8a674 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -34,6 +34,7 @@ static int parser_error(const char*);
  static void parse_complete(parser_ctx_t*,BOOL);
 
 static void source_add_statement(parser_ctx_t*,statement_t*);
+static void source_add_class(parser_ctx_t*,class_decl_t*);
 
 static void *new_expression(parser_ctx_t*,expression_type_t,size_t);
 static expression_t *new_bool_expression(parser_ctx_t*,VARIANT_BOOL);
@@ -56,6 +57,7 @@ static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,dim_decl_t*);
 static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
 static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,arg_decl_t*,statement_t*);
 static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
+static class_decl_t *new_class_decl(parser_ctx_t*);
 
 #define CHECK_ERROR if(((parser_ctx_t*)ctx)->hres != S_OK) YYABORT
 
@@ -73,6 +75,7 @@ static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
     dim_decl_t *dim_decl;
     function_decl_t *func_decl;
     arg_decl_t *arg_decl;
+    class_decl_t *class_decl;
     LONG lng;
     BOOL bool;
     double dbl;
@@ -105,6 +108,7 @@ static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
 %type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
 %type <func_decl> FunctionDecl
 %type <elseif> ElseIfs_opt ElseIfs ElseIf
+%type <class_decl> ClassDeclaration ClassBody
 %type <dim_decl> DimDeclList
 
 %%
@@ -118,7 +122,8 @@ OptionExplicit_opt
 
 SourceElements
     : /* empty */
-    | SourceElements StatementNl    { source_add_statement(ctx, $2); }
+    | SourceElements StatementNl            { source_add_statement(ctx, $2); }
+    | SourceElements ClassDeclaration       { source_add_class(ctx, $2); }
 
 StatementsNl_opt
     : /* empty */                           { $$ = NULL; }
@@ -268,6 +273,12 @@ LiteralExpression
 PrimaryExpression
     : '(' Expression ')'            { $$ = $2; }
 
+ClassDeclaration
+    : tCLASS tIdentifier tNL ClassBody tEND tCLASS tNL      { $4->name = $2; $$ = $4; }
+
+ClassBody
+    : /* empty */                               { $$ = new_class_decl(ctx); }
+
 FunctionDecl
     : /* Storage_opt */ tSUB tIdentifier ArgumentsDecl_opt tNL StatementsNl_opt tEND tSUB
                                     { $$ = new_function_decl(ctx, $2, FUNC_SUB, $3, $5); CHECK_ERROR; }
@@ -304,6 +315,12 @@ static void source_add_statement(parser_ctx_t *ctx, statement_t *stat)
     }
 }
 
+static void source_add_class(parser_ctx_t *ctx, class_decl_t *class_decl)
+{
+    class_decl->next = ctx->class_decls;
+    ctx->class_decls = class_decl;
+}
+
 static void parse_complete(parser_ctx_t *ctx, BOOL option_explicit)
 {
     ctx->parse_complete = TRUE;
@@ -545,6 +562,18 @@ static statement_t *new_function_statement(parser_ctx_t *ctx, function_decl_t *d
     return &stat->stat;
 }
 
+static class_decl_t *new_class_decl(parser_ctx_t *ctx)
+{
+    class_decl_t *class_decl;
+
+    class_decl = parser_alloc(ctx, sizeof(*class_decl));
+    if(!class_decl)
+        return NULL;
+
+    class_decl->next = NULL;
+    return class_decl;
+}
+
 void *parser_alloc(parser_ctx_t *ctx, size_t size)
 {
     void *ret;
@@ -568,6 +597,7 @@ HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code)
     ctx->last_token = tNL;
     ctx->last_nl = 0;
     ctx->stats = ctx->stats_tail = NULL;
+    ctx->class_decls = NULL;
     ctx->option_explicit = FALSE;
 
     parser_parse(ctx);
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index b9b5c57..a338e76 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -355,4 +355,7 @@ x = false
 ok SetVal(x, true), "SetVal returned false?"
 Call ok(x, "x is not set to true by SetVal?")
 
+Class EmptyClass
+End Class
+
 reportSuccess()

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 02/19] vbscript: Added class compiler implementation
Message-Id: <4E71ECCD.3010208 at codeweavers.com>
Date: Thu, 15 Sep 2011 14:17:17 +0200

---
  dlls/vbscript/compile.c  |   75 
++++++++++++++++++++++++++++++++++++++++++++++
  dlls/vbscript/vbscript.h |    7 ++++
  2 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index f74f5fe..21c8588 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -47,6 +47,8 @@ typedef struct {
     function_t *func;
     function_t *funcs;
     function_decl_t *func_decls;
+
+    class_desc_t *classes;
 } compile_ctx_t;
 
 static HRESULT compile_expression(compile_ctx_t*,expression_t*);
@@ -779,8 +781,44 @@ static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, functi
     return S_OK;
 }
 
+static BOOL lookup_class_name(compile_ctx_t *ctx, const WCHAR *name)
+{
+    class_desc_t *iter;
+
+    for(iter = ctx->classes; iter; iter = iter->next) {
+        if(!strcmpiW(iter->name, name))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
+{
+    class_desc_t *class_desc;
+
+    if(lookup_dim_decls(ctx, class_decl->name) || lookup_funcs_name(ctx, class_decl->name)
+            || lookup_class_name(ctx, class_decl->name)) {
+        FIXME("%s: redefinition\n", debugstr_w(class_decl->name));
+        return E_FAIL;
+    }
+
+    class_desc = compiler_alloc(ctx->code, sizeof(*class_desc));
+    if(!class_desc)
+        return E_OUTOFMEMORY;
+
+    class_desc->name = compiler_alloc_string(ctx->code, class_decl->name);
+    if(!class_desc->name)
+        return E_OUTOFMEMORY;
+
+    class_desc->next = ctx->classes;
+    ctx->classes = class_desc;
+    return S_OK;
+}
+
 static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier)
 {
+    class_desc_t *class;
     dynamic_var_t *var;
     function_t *func;
 
@@ -794,11 +832,17 @@ static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifi
             return TRUE;
     }
 
+    for(class = script->classes; class; class = class->next) {
+        if(!strcmpiW(class->name, identifier))
+            return TRUE;
+    }
+
     return FALSE;
 }
 
 static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script)
 {
+    class_desc_t *class;
     dynamic_var_t *var;
     function_t *func;
 
@@ -816,6 +860,13 @@ static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script)
         }
     }
 
+    for(class = ctx->classes; class; class = class->next) {
+        if(lookup_script_identifier(script, class->name)) {
+            FIXME("%s: redefined\n", debugstr_w(class->name));
+            return E_FAIL;
+        }
+    }
+
     return S_OK;
 }
 
@@ -891,6 +942,7 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
 {
     function_t *new_func;
     function_decl_t *func_decl;
+    class_decl_t *class_decl;
     compile_ctx_t ctx;
     vbscode_t *code;
     HRESULT hres;
@@ -907,6 +959,7 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
     ctx.func_decls = NULL;
     ctx.global_vars = NULL;
     ctx.dim_decls = NULL;
+    ctx.classes = NULL;
     ctx.labels = NULL;
     ctx.labels_cnt = ctx.labels_size = 0;
 
@@ -927,6 +980,14 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
         ctx.funcs = new_func;
     }
 
+    for(class_decl = ctx.parser.class_decls; class_decl; class_decl = class_decl->next) {
+        hres = compile_class(&ctx, class_decl);
+        if(FAILED(hres)) {
+            release_compiler(&ctx);
+            return hres;
+        }
+    }
+
     hres = check_script_collisions(&ctx, script);
     if(FAILED(hres)) {
         release_compiler(&ctx);
@@ -949,6 +1010,20 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
         script->global_funcs = ctx.funcs;
     }
 
+    if(ctx.classes) {
+        class_desc_t *class = ctx.classes;
+
+        while(1) {
+            class->ctx = script;
+            if(!class->next)
+                break;
+            class = class->next;
+        }
+
+        class->next = script->classes;
+        script->classes = ctx.classes;
+    }
+
     if(TRACE_ON(vbscript_disas))
         dump_code(&ctx);
 
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 5f1d6ce..9ad3bb6 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -55,6 +55,12 @@ typedef struct named_item_t {
     struct list entry;
 } named_item_t;
 
+typedef struct _class_desc_t {
+    const WCHAR *name;
+    script_ctx_t *ctx;
+    struct _class_desc_t *next;
+} class_desc_t;
+
 typedef struct {
     IDispatchEx IDispatchEx_iface;
 
@@ -98,6 +104,7 @@ struct _script_ctx_t {
 
     dynamic_var_t *global_vars;
     function_t *global_funcs;
+    class_desc_t *classes;
 
     struct list code_list;
     struct list named_items;

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 03/19] vbscript: Added set statement parser/compiler implementation
Message-Id: <4E71ECE2.8050309 at codeweavers.com>
Date: Thu, 15 Sep 2011 14:17:38 +0200

---
  dlls/vbscript/compile.c  |   11 +++++++----
  dlls/vbscript/interp.c   |   14 ++++++++++++++
  dlls/vbscript/parse.h    |    3 ++-
  dlls/vbscript/parser.y   |   16 ++++++++++++++++
  dlls/vbscript/vbscript.h |    2 ++
  5 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 21c8588..d1720cf 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -475,7 +475,7 @@ static HRESULT compile_if_statement(compile_ctx_t *ctx, if_statement_t *stat)
     return S_OK;
 }
 
-static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat)
+static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
 {
     HRESULT hres;
 
@@ -493,9 +493,9 @@ static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *
         if(FAILED(hres))
             return hres;
 
-        hres = push_instr_bstr(ctx, OP_assign_member, stat->member_expr->identifier);
+        hres = push_instr_bstr(ctx, is_set ? OP_set_member : OP_assign_member, stat->member_expr->identifier);
     }else {
-        hres = push_instr_bstr(ctx, OP_assign_ident, stat->member_expr->identifier);
+        hres = push_instr_bstr(ctx, is_set ? OP_set_ident : OP_assign_ident, stat->member_expr->identifier);
     }
 
     return hres;
@@ -585,7 +585,7 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
     while(stat) {
         switch(stat->type) {
         case STAT_ASSIGN:
-            hres = compile_assign_statement(ctx, (assign_statement_t*)stat);
+            hres = compile_assign_statement(ctx, (assign_statement_t*)stat, FALSE);
             break;
         case STAT_CALL:
             hres = compile_member_expression(ctx, ((call_statement_t*)stat)->expr, FALSE);
@@ -605,6 +605,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
         case STAT_IF:
             hres = compile_if_statement(ctx, (if_statement_t*)stat);
             break;
+        case STAT_SET:
+            hres = compile_assign_statement(ctx, (assign_statement_t*)stat, TRUE);
+            break;
         default:
             FIXME("Unimplemented statement type %d\n", stat->type);
             hres = E_NOTIMPL;
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 2a50667..e61ed7a 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -385,6 +385,13 @@ static HRESULT interp_assign_ident(exec_ctx_t *ctx)
     return assign_ident(ctx, arg, v.v, v.owned);
 }
 
+static HRESULT interp_set_ident(exec_ctx_t *ctx)
+{
+    const BSTR arg = ctx->instr->arg1.bstr;
+    FIXME("%s\n", debugstr_w(arg));
+    return E_NOTIMPL;
+}
+
 static HRESULT interp_assign_member(exec_ctx_t *ctx)
 {
     BSTR identifier = ctx->instr->arg1.bstr;
@@ -419,6 +426,13 @@ static HRESULT interp_assign_member(exec_ctx_t *ctx)
     return hres;
 }
 
+static HRESULT interp_set_member(exec_ctx_t *ctx)
+{
+    BSTR identifier = ctx->instr->arg1.bstr;
+    FIXME("%s\n", debugstr_w(identifier));
+    return E_NOTIMPL;
+}
+
 static HRESULT interp_jmp(exec_ctx_t *ctx)
 {
     const unsigned arg = ctx->instr->arg1.uint;
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index 67fa221..76f8775 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -94,7 +94,8 @@ typedef enum {
     STAT_EXITFUNC,
     STAT_EXITSUB,
     STAT_FUNC,
-    STAT_IF
+    STAT_IF,
+    STAT_SET
 } statement_type_t;
 
 typedef struct _statement_t {
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 6d8a674..2e0140e 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -49,6 +49,7 @@ static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,co
 static void *new_statement(parser_ctx_t*,statement_type_t,size_t);
 static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
 static statement_t *new_assign_statement(parser_ctx_t*,member_expression_t*,expression_t*);
+static statement_t *new_set_statement(parser_ctx_t*,member_expression_t*,expression_t*);
 static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*);
 static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
 static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
@@ -146,6 +147,8 @@ Statement
     | FunctionDecl                          { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
     | tEXIT tFUNCTION                       { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; }
     | tEXIT tSUB                            { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; }
+    | tSET MemberExpression Arguments_opt '=' Expression
+                                            { $2->args = $3; $$ = new_set_statement(ctx, $2, $5); CHECK_ERROR; }
 
 MemberExpression
     : tIdentifier                           { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
@@ -465,6 +468,19 @@ static statement_t *new_assign_statement(parser_ctx_t *ctx, member_expression_t
     return &stat->stat;
 }
 
+static statement_t *new_set_statement(parser_ctx_t *ctx, member_expression_t *left, expression_t *right)
+{
+    assign_statement_t *stat;
+
+    stat = new_statement(ctx, STAT_SET, sizeof(*stat));
+    if(!stat)
+        return NULL;
+
+    stat->member_expr = left;
+    stat->value_expr = right;
+    return &stat->stat;
+}
+
 static dim_decl_t *new_dim_decl(parser_ctx_t *ctx, const WCHAR *name, dim_decl_t *next)
 {
     dim_decl_t *decl;
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 9ad3bb6..9655978 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -150,6 +150,8 @@ typedef enum {
     X(null,           1, 0,           0)          \
     X(or,             1, 0,           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(string,         1, ARG_STR,     0)          \
     X(sub,            1, 0,           0)          \



More information about the wine-tests-results mailing list