78548: Subject: [PATCH 11/17] vbscript: Added parser support for string literals
buildbot at kegel.com
buildbot at kegel.com
Thu Sep 8 09:59:39 CDT 2011
This is an experimental automated build and test service.
Please feel free to ignore this email while we work the kinks out.
The Buildbot has detected a failed build on builder runtests-heaptest while building Wine.
Full details are available at: http://buildbot.kegel.com/builders/runtests-heaptest/builds/43 (though maybe not for long, as I'm still reinstalling the buildbot periodically while experimenting)
BUILD FAILED: failed shell_3
For more info about this message, see http://wiki.winehq.org/BuildBot
-------------- next part --------------
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 01/17] vbscript: Store call identifier as BSTR
Message-Id: <4E68BAFF.10705 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:54:23 +0200
---
dlls/vbscript/Makefile.in | 1 +
dlls/vbscript/compile.c | 47
++++++++++++++++++++++++++++++++++++++++++--
dlls/vbscript/vbscript.h | 10 +++++++-
3 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/dlls/vbscript/Makefile.in b/dlls/vbscript/Makefile.in
index 9e27dd4..cd7e18d 100644
--- a/dlls/vbscript/Makefile.in
+++ b/dlls/vbscript/Makefile.in
@@ -1,4 +1,5 @@
MODULE = vbscript.dll
+IMPORTS = oleaut32
C_SRCS = \
compile.c \
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index d57abcf..49d933b 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -59,15 +59,45 @@ static unsigned push_instr(compile_ctx_t *ctx, vbsop_t op)
return ctx->instr_cnt++;
}
-static HRESULT push_instr_str(compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg)
+static BSTR alloc_bstr_arg(compile_ctx_t *ctx, const WCHAR *str)
+{
+ if(!ctx->code->bstr_pool_size) {
+ ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR));
+ if(!ctx->code->bstr_pool)
+ return NULL;
+ ctx->code->bstr_pool_size = 8;
+ }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
+ BSTR *new_pool;
+
+ new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
+ if(!new_pool)
+ return NULL;
+
+ ctx->code->bstr_pool = new_pool;
+ ctx->code->bstr_pool_size *= 2;
+ }
+
+ ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
+ if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
+ return NULL;
+
+ return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
+}
+
+static HRESULT push_instr_bstr(compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg)
{
unsigned instr;
+ BSTR bstr;
+
+ bstr = alloc_bstr_arg(ctx, arg);
+ if(!bstr)
+ return E_OUTOFMEMORY;
instr = push_instr(ctx, op);
if(instr == -1)
return E_OUTOFMEMORY;
- instr_ptr(ctx, instr)->arg1.str = arg;
+ instr_ptr(ctx, instr)->arg1.bstr = bstr;
return S_OK;
}
@@ -84,7 +114,7 @@ static HRESULT compile_member_expression(compile_ctx_t *ctx, member_expression_t
FIXME("obj_expr not implemented\n");
hres = E_NOTIMPL;
}else {
- hres = push_instr_str(ctx, OP_icallv, expr->identifier);
+ hres = push_instr_bstr(ctx, OP_icallv, expr->identifier);
}
return hres;
@@ -130,7 +160,14 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
void release_vbscode(vbscode_t *code)
{
+ unsigned i;
+
list_remove(&code->entry);
+
+ for(i=0; i < code->bstr_cnt; i++)
+ SysFreeString(code->bstr_pool[i]);
+
+ heap_free(code->bstr_pool);
heap_free(code->source);
heap_free(code->instrs);
heap_free(code);
@@ -159,6 +196,10 @@ static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source)
ctx->instr_cnt = 0;
ctx->instr_size = 32;
+ ret->bstr_pool = NULL;
+ ret->bstr_pool_size = 0;
+ ret->bstr_cnt = 0;
+
ret->global_code.code_ctx = ret;
list_init(&ret->entry);
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index bca630a..9942ac7 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -64,11 +64,12 @@ HRESULT init_global(script_ctx_t*);
typedef enum {
ARG_NONE = 0,
- ARG_STR
+ ARG_STR,
+ ARG_BSTR
} instr_arg_type_t;
#define OP_LIST \
- X(icallv, 1, ARG_STR, 0) \
+ X(icallv, 1, ARG_BSTR, 0) \
X(ret, 0, 0, 0)
typedef enum {
@@ -80,6 +81,7 @@ OP_LIST
typedef union {
const WCHAR *str;
+ BSTR bstr;
} instr_arg_t;
typedef struct {
@@ -100,6 +102,10 @@ struct _vbscode_t {
BOOL global_executed;
function_t global_code;
+ BSTR *bstr_pool;
+ unsigned bstr_pool_size;
+ unsigned bstr_cnt;
+
struct list entry;
};
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 02/17] vbscript: Added intep_icallv implementation
Message-Id: <4E68BB0D.2000707 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:54:37 +0200
---
dlls/vbscript/interp.c | 67
+++++++++++++++++++++++++++++++++++++++--
dlls/vbscript/vbdisp.c | 43 ++++++++++++++++++++++++++
dlls/vbscript/vbscript.h | 8 ++++-
dlls/vbscript/vbscript_main.c | 2 +
4 files changed, 115 insertions(+), 5 deletions(-)
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 3ff6bbd..b309397 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -28,15 +28,75 @@ WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
typedef struct {
vbscode_t *code;
instr_t *instr;
+ script_ctx_t *script;
} exec_ctx_t;
-
typedef HRESULT (*instr_func_t)(exec_ctx_t*);
+typedef enum {
+ REF_NONE,
+ REF_DISP
+} ref_type_t;
+
+typedef struct {
+ ref_type_t type;
+ union {
+ struct {
+ IDispatch *disp;
+ DISPID id;
+ } d;
+ } u;
+} ref_t;
+
+static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, ref_t *ref)
+{
+ named_item_t *item;
+ DISPID id;
+ HRESULT hres;
+
+ LIST_FOR_EACH_ENTRY(item, &ctx->script->named_items, named_item_t, entry) {
+ if(item->flags & SCRIPTITEM_GLOBALMEMBERS) {
+ hres = disp_get_id(item->disp, name, &id);
+ if(SUCCEEDED(hres)) {
+ ref->type = REF_DISP;
+ ref->u.d.disp = item->disp;
+ ref->u.d.id = id;
+ return S_OK;
+ }
+ }
+ }
+
+ FIXME("create if no option explicit\n");
+
+ ref->type = REF_NONE;
+ return S_OK;
+}
+
static HRESULT interp_icallv(exec_ctx_t *ctx)
{
- FIXME("\n");
- return E_NOTIMPL;
+ BSTR identifier = ctx->instr->arg1.bstr;
+ DISPPARAMS dp = {0};
+ ref_t ref;
+ HRESULT hres;
+
+ TRACE("\n");
+
+ hres = lookup_identifier(ctx, identifier, &ref);
+ if(FAILED(hres))
+ return hres;
+
+ switch(ref.type) {
+ case REF_DISP:
+ hres = disp_call(ctx->script, ref.u.d.disp, ref.u.d.id, &dp, NULL);
+ if(FAILED(hres))
+ return hres;
+ break;
+ default:
+ FIXME("%s not found\n", debugstr_w(identifier));
+ return DISP_E_UNKNOWNNAME;
+ }
+
+ return S_OK;
}
static HRESULT interp_ret(exec_ctx_t *ctx)
@@ -67,6 +127,7 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func)
exec.code = func->code_ctx;
exec.instr = exec.code->instrs + func->code_off;
+ exec.script = ctx;
while(exec.instr) {
op = exec.instr->op;
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 3c81789..c115199 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -203,3 +203,46 @@ HRESULT init_global(script_ctx_t *ctx)
{
return create_vbdisp(&ctx->script_obj);
}
+
+HRESULT disp_get_id(IDispatch *disp, BSTR name, DISPID *id)
+{
+ IDispatchEx *dispex;
+ HRESULT hres;
+
+ if(disp->lpVtbl == (IDispatchVtbl*)&DispatchExVtbl)
+ FIXME("properly handle builtin objects\n");
+
+ hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+ if(FAILED(hres)) {
+ TRACE("unsing IDispatch\n");
+ return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
+ }
+
+ hres = IDispatchEx_GetDispID(dispex, name, fdexNameCaseInsensitive, id);
+ IDispatchEx_Release(dispex);
+ return hres;
+}
+
+HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, DISPPARAMS *dp, VARIANT *retv)
+{
+ const WORD flags = DISPATCH_METHOD|(retv ? DISPATCH_PROPERTYGET : 0);
+ IDispatchEx *dispex;
+ EXCEPINFO ei;
+ HRESULT hres;
+
+ memset(&ei, 0, sizeof(ei));
+ if(retv)
+ V_VT(retv) = VT_EMPTY;
+
+ hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+ if(FAILED(hres)) {
+ UINT err = 0;
+
+ TRACE("using IDispatch\n");
+ return IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, dp, retv, &ei, &err);
+ }
+
+ hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, dp, retv, &ei, NULL /* CALLER_FIXME */);
+ IDispatchEx_Release(dispex);
+ return hres;
+}
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 9942ac7..8aca01c 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -33,6 +33,7 @@
typedef struct _function_t function_t;
typedef struct _vbscode_t vbscode_t;
+typedef struct _script_ctx_t script_ctx_t;
typedef struct named_item_t {
IDispatch *disp;
@@ -48,7 +49,10 @@ typedef struct {
LONG ref;
} vbdisp_t;
-typedef struct {
+HRESULT disp_get_id(IDispatch*,BSTR,DISPID*);
+HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*);
+
+struct _script_ctx_t {
IActiveScriptSite *site;
LCID lcid;
@@ -58,7 +62,7 @@ typedef struct {
struct list code_list;
struct list named_items;
-} script_ctx_t;
+};
HRESULT init_global(script_ctx_t*);
diff --git a/dlls/vbscript/vbscript_main.c b/dlls/vbscript/vbscript_main.c
index fc31aed..9d74026 100644
--- a/dlls/vbscript/vbscript_main.c
+++ b/dlls/vbscript/vbscript_main.c
@@ -27,6 +27,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+
static HINSTANCE vbscript_hinstance;
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 03/17] vbscript: Added simple call test
Message-Id: <4E68BB1B.8010500 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:54:51 +0200
---
dlls/vbscript/tests/run.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c
index d61b81f..4f70224 100644
--- a/dlls/vbscript/tests/run.c
+++ b/dlls/vbscript/tests/run.c
@@ -463,6 +463,12 @@ static void run_tests(void)
parse_script_a("");
parse_script_a("' empty ;");
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ parse_script_a("reportSuccess");
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
}
static BOOL check_vbscript(void)
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 04/17] vbscript: Added support for a few more characters in lexer
Message-Id: <4E68BB32.60706 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:55:14 +0200
---
dlls/vbscript/lex.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c
index d481e6a..d41c582 100644
--- a/dlls/vbscript/lex.c
+++ b/dlls/vbscript/lex.c
@@ -76,6 +76,18 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
else
ctx->ptr = ctx->end;
return tNL;
+ case '(':
+ case ')':
+ case ',':
+ case '=':
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '^':
+ case '\\':
+ case '.':
+ return *ctx->ptr++;
default:
FIXME("Unhandled char %c in %s\n", *ctx->ptr, debugstr_w(ctx->ptr));
}
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 05/17] vbscript: Better function call parsing
Message-Id: <4E68BB47.9080909 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:55:35 +0200
---
dlls/vbscript/parser.y | 16 ++++++++++++++--
dlls/vbscript/tests/run.c | 6 ++++++
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 5fb6bd2..d5c7d40 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -39,6 +39,8 @@ static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,co
static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
+#define CHECK_ERROR if(((parser_ctx_t*)ctx)->hres != S_OK) YYABORT
+
%}
%pure_parser
@@ -47,6 +49,7 @@ static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
%union {
const WCHAR *string;
statement_t *statement;
+ expression_t *expression;
member_expression_t *member;
}
@@ -55,6 +58,7 @@ static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
%type <statement> Statement StatementNl
%type <member> MemberExpression
+%type <expression> Arguments_opt ArgumentList_opt
%%
@@ -69,12 +73,20 @@ StatementNl
: Statement tNL { $$ = $1; }
Statement
- : MemberExpression /* FIXME: Arguments_opt */ { $$ = new_call_statement(ctx, $1); }
+ : MemberExpression Arguments_opt { $1->args = $2; $$ = new_call_statement(ctx, $1); CHECK_ERROR; }
MemberExpression
- : tIdentifier { $$ = new_member_expression(ctx, NULL, $1); }
+ : tIdentifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
/* FIXME: MemberExpressionArgs '.' tIdentifier */
+Arguments_opt
+ : /* empty */ { $$ = NULL; }
+ | '(' ArgumentList_opt ')' { $$ = $2; }
+
+ArgumentList_opt
+ : /* empty */ { $$ = NULL; }
+ /* | ArgumentList { $$ = $1; } */
+
%%
static int parser_error(const char *str)
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c
index 4f70224..9b1abd4 100644
--- a/dlls/vbscript/tests/run.c
+++ b/dlls/vbscript/tests/run.c
@@ -469,6 +469,12 @@ static void run_tests(void)
parse_script_a("reportSuccess");
CHECK_CALLED(global_success_d);
CHECK_CALLED(global_success_i);
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ parse_script_a("reportSuccess()");
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
}
static BOOL check_vbscript(void)
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 06/17] vbscript: Added support for call keyword in lexer
Message-Id: <4E68BB57.2070804 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:55:51 +0200
---
dlls/vbscript/lex.c | 58
++++++++++++++++++++++++++++++++++++++++++++++-
dlls/vbscript/parser.y | 1 +
2 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c
index d41c582..af01220 100644
--- a/dlls/vbscript/lex.c
+++ b/dlls/vbscript/lex.c
@@ -26,11 +26,61 @@
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
+static const WCHAR callW[] = {'c','a','l','l',0};
+
+static const struct {
+ const WCHAR *word;
+ int token;
+} keywords[] = {
+ {callW, tCALL}
+};
+
static inline BOOL is_identifier_char(WCHAR c)
{
return isalnumW(c) || c == '_';
}
+static int check_keyword(parser_ctx_t *ctx, const WCHAR *word)
+{
+ const WCHAR *p1 = ctx->ptr;
+ const WCHAR *p2 = word;
+ WCHAR c;
+
+ while(p1 < ctx->end && *p2) {
+ c = tolowerW(*p1);
+ if(c != *p2)
+ return c - *p2;
+ p1++;
+ p2++;
+ }
+
+ if(*p2 || (p1 < ctx->end && is_identifier_char(*p1)))
+ return 1;
+
+ ctx->ptr = p1;
+ return 0;
+}
+
+static int check_keywords(parser_ctx_t *ctx)
+{
+ int min = 0, max = sizeof(keywords)/sizeof(keywords[0])-1, r, i;
+
+ while(min <= max) {
+ i = (min+max)/2;
+
+ r = check_keyword(ctx, keywords[i].word);
+ if(!r)
+ return keywords[i].token;
+
+ if(r > 0)
+ min = i+1;
+ else
+ max = i-1;
+ }
+
+ return 0;
+}
+
static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
{
const WCHAR *ptr = ctx->ptr++;
@@ -62,8 +112,12 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
c = *ctx->ptr;
- if(isalphaW(c))
- return parse_identifier(ctx, lval);
+ if(isalphaW(c)) {
+ int ret = check_keywords(ctx);
+ if(!ret)
+ return parse_identifier(ctx, lval);
+ return ret;
+ }
switch(c) {
case '\n':
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index d5c7d40..447aa12 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -54,6 +54,7 @@ static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
}
%token tEOF tNL blah
+%token tCALL
%token <string> tIdentifier
%type <statement> Statement StatementNl
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 07/17] vbscript: Added Call statement implementation
Message-Id: <4E68BB65.2020507 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:56:05 +0200
---
dlls/vbscript/parser.y | 3 ++-
dlls/vbscript/tests/run.c | 6 ++++++
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 447aa12..caf6f49 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -74,7 +74,8 @@ StatementNl
: Statement tNL { $$ = $1; }
Statement
- : MemberExpression Arguments_opt { $1->args = $2; $$ = new_call_statement(ctx, $1); CHECK_ERROR; }
+ : MemberExpression Arguments_opt { $1->args = $2; $$ = new_call_statement(ctx, $1); CHECK_ERROR; }
+ | tCALL MemberExpression Arguments_opt { $2->args = $3; $$ = new_call_statement(ctx, $2); CHECK_ERROR; }
MemberExpression
: tIdentifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c
index 9b1abd4..6f1a967 100644
--- a/dlls/vbscript/tests/run.c
+++ b/dlls/vbscript/tests/run.c
@@ -475,6 +475,12 @@ static void run_tests(void)
parse_script_a("reportSuccess()");
CHECK_CALLED(global_success_d);
CHECK_CALLED(global_success_i);
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ parse_script_a("Call reportSuccess");
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
}
static BOOL check_vbscript(void)
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 08/17] vbscript: Added more keywords to lexer
Message-Id: <4E68BB72.4070008 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:56:18 +0200
---
dlls/vbscript/lex.c | 98
+++++++++++++++++++++++++++++++++++++++++++++++-
dlls/vbscript/parser.y | 15 ++++++-
2 files changed, 110 insertions(+), 3 deletions(-)
diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c
index af01220..04ade1e 100644
--- a/dlls/vbscript/lex.c
+++ b/dlls/vbscript/lex.c
@@ -26,13 +26,109 @@
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
+static const WCHAR andW[] = {'a','n','d',0};
+static const WCHAR byrefW[] = {'b','y','r','e','f',0};
+static const WCHAR byvalW[] = {'b','y','v','a','l',0};
static const WCHAR callW[] = {'c','a','l','l',0};
+static const WCHAR classW[] = {'c','l','a','s','s',0};
+static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
+static const WCHAR dimW[] = {'d','i','m',0};
+static const WCHAR doW[] = {'d','o',0};
+static const WCHAR elseW[] = {'e','l','s','e',0};
+static const WCHAR elseifW[] = {'e','l','s','e','i','f',0};
+static const WCHAR emptyW[] = {'e','m','p','t','y',0};
+static const WCHAR endW[] = {'e','n','d',0};
+static const WCHAR eqvW[] = {'e','q','v',0};
+static const WCHAR errorW[] = {'e','r','r','o','r',0};
+static const WCHAR exitW[] = {'e','x','i','t',0};
+static const WCHAR explicitW[] = {'e','x','p','l','i','c','i','t',0};
+static const WCHAR falseW[] = {'f','a','l','s','e',0};
+static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
+static const WCHAR getW[] = {'g','e','t',0};
+static const WCHAR gotoW[] = {'g','o','t','o',0};
+static const WCHAR ifW[] = {'i','f',0};
+static const WCHAR impW[] = {'i','m','p',0};
+static const WCHAR isW[] = {'i','s',0};
+static const WCHAR letW[] = {'l','e','t',0};
+static const WCHAR loopW[] = {'l','o','o','p',0};
+static const WCHAR meW[] = {'m','e',0};
+static const WCHAR modW[] = {'m','o','d',0};
+static const WCHAR newW[] = {'n','e','w',0};
+static const WCHAR nextW[] = {'n','e','x','t',0};
+static const WCHAR notW[] = {'n','o','t',0};
+static const WCHAR nothingW[] = {'n','o','t','h','i','n','g',0};
+static const WCHAR nullW[] = {'n','u','l','l',0};
+static const WCHAR onW[] = {'o','n',0};
+static const WCHAR optionW[] = {'o','p','t','i','o','n',0};
+static const WCHAR orW[] = {'o','r',0};
+static const WCHAR privateW[] = {'p','r','i','v','a','t','e',0};
+static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
+static const WCHAR publicW[] = {'p','u','b','l','i','c',0};
+static const WCHAR remW[] = {'r','e','m',0};
+static const WCHAR resumeW[] = {'r','e','s','u','m','e',0};
+static const WCHAR setW[] = {'s','e','t',0};
+static const WCHAR stopW[] = {'s','t','o','p',0};
+static const WCHAR subW[] = {'s','u','b',0};
+static const WCHAR thenW[] = {'t','h','e','n',0};
+static const WCHAR trueW[] = {'t','r','u','e',0};
+static const WCHAR untilW[] = {'u','n','t','i','l',0};
+static const WCHAR wendW[] = {'w','e','n','d',0};
+static const WCHAR whileW[] = {'w','h','i','l','e',0};
+static const WCHAR xorW[] = {'x','o','r',0};
static const struct {
const WCHAR *word;
int token;
} keywords[] = {
- {callW, tCALL}
+ {andW, tAND},
+ {byrefW, tBYREF},
+ {byvalW, tBYVAL},
+ {callW, tCALL},
+ {classW, tCLASS},
+ {defaultW, tDEFAULT},
+ {dimW, tDIM},
+ {doW, tDO},
+ {elseW, tELSE},
+ {elseifW, tELSEIF},
+ {emptyW, tEMPTY},
+ {endW, tEND},
+ {eqvW, tEQV},
+ {errorW, tERROR},
+ {exitW, tEXIT},
+ {explicitW, tEXPLICIT},
+ {falseW, tFALSE},
+ {functionW, tFUNCTION},
+ {getW, tGET},
+ {gotoW, tGOTO},
+ {ifW, tIF},
+ {impW, tIMP},
+ {isW, tIS},
+ {letW, tLET},
+ {loopW, tLOOP},
+ {meW, tME},
+ {modW, tMOD},
+ {newW, tNEW},
+ {nextW, tNEXT},
+ {notW, tNOT},
+ {nothingW, tNOTHING},
+ {nullW, tNULL},
+ {onW, tON},
+ {optionW, tOPTION},
+ {orW, tOR},
+ {privateW, tPRIVATE},
+ {propertyW, tPROPERTY},
+ {publicW, tPUBLIC},
+ {remW, tREM},
+ {resumeW, tRESUME},
+ {setW, tSET},
+ {stopW, tSTOP},
+ {subW, tSUB},
+ {thenW, tTHEN},
+ {trueW, tTRUE},
+ {untilW, tUNTIL},
+ {wendW, tWEND},
+ {whileW, tWHILE},
+ {xorW, tXOR}
};
static inline BOOL is_identifier_char(WCHAR c)
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index caf6f49..2fe9bdb 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -53,8 +53,19 @@ static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
member_expression_t *member;
}
-%token tEOF tNL blah
-%token tCALL
+%token tEOF tNL tREM
+%token tTRUE tFALSE
+%token tNOT tAND tOR tXOR tEQV tIMP tNEQ
+%token tIS tLTEQ tGTEQ tMOD
+%token tCALL tDIM tSUB tFUNCTION tPROPERTY tGET tLET
+%token tIF tELSE tELSEIF tEND tTHEN tEXIT
+%token tWHILE tWEND tDO tLOOP tUNTIL
+%token tBYREF tBYVAL
+%token tOPTION tEXPLICIT
+%token tSTOP
+%token tNOTHING tEMPTY tNULL
+%token tCLASS tSET tNEW tPUBLIC tPRIVATE tDEFAULT tME
+%token tERROR tNEXT tON tRESUME tGOTO
%token <string> tIdentifier
%type <statement> Statement StatementNl
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 09/17] vbscript: Added bool literals parsing support
Message-Id: <4E68BB84.8010809 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:56:36 +0200
---
dlls/vbscript/parse.h | 6 ++++++
dlls/vbscript/parser.y | 30 ++++++++++++++++++++++++++++--
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index 7c9ab26..df337d2 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -17,6 +17,7 @@
*/
typedef enum {
+ EXPR_BOOL,
EXPR_MEMBER
} expression_type_t;
@@ -27,6 +28,11 @@ typedef struct _expression_t {
typedef struct {
expression_t expr;
+ VARIANT_BOOL value;
+} bool_expression_t;
+
+typedef struct {
+ expression_t expr;
expression_t *obj_expr;
const WCHAR *identifier;
expression_t *args;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 2fe9bdb..3761b13 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -35,6 +35,8 @@ static void parse_complete(parser_ctx_t*);
static void source_add_statement(parser_ctx_t*,statement_t*);
+static expression_t *new_bool_expression(parser_ctx_t*,VARIANT_BOOL);
+
static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,const WCHAR*);
static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
@@ -69,8 +71,9 @@ static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
%token <string> tIdentifier
%type <statement> Statement StatementNl
+%type <expression> Expression LiteralExpression
%type <member> MemberExpression
-%type <expression> Arguments_opt ArgumentList_opt
+%type <expression> Arguments_opt ArgumentList_opt ArgumentList
%%
@@ -98,7 +101,18 @@ Arguments_opt
ArgumentList_opt
: /* empty */ { $$ = NULL; }
- /* | ArgumentList { $$ = $1; } */
+ | ArgumentList { $$ = $1; }
+
+ArgumentList
+ : Expression { $$ = $1; }
+ | Expression ',' ArgumentList { $1->next = $3; $$ = $1; }
+
+Expression
+ : LiteralExpression /* FIXME */ { $$ = $1; }
+
+LiteralExpression
+ : tTRUE { $$ = new_bool_expression(ctx, VARIANT_TRUE); CHECK_ERROR; }
+ | tFALSE { $$ = new_bool_expression(ctx, VARIANT_FALSE); CHECK_ERROR; }
%%
@@ -135,6 +149,18 @@ static void *new_expression(parser_ctx_t *ctx, expression_type_t type, unsigned
return expr;
}
+static expression_t *new_bool_expression(parser_ctx_t *ctx, VARIANT_BOOL value)
+{
+ bool_expression_t *expr;
+
+ expr = new_expression(ctx, EXPR_BOOL, sizeof(*expr));
+ if(!expr)
+ return NULL;
+
+ expr->value = value;
+ return &expr->expr;
+}
+
static member_expression_t *new_member_expression(parser_ctx_t *ctx, expression_t *obj_expr, const WCHAR *identifier)
{
member_expression_t *expr;
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 10/17] vbscript: Added lexer support for string literals
Message-Id: <4E68BB90.1010709 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:56:48 +0200
---
dlls/vbscript/lex.c | 45
+++++++++++++++++++++++++++++++++++++++++++++
dlls/vbscript/parser.y | 2 +-
2 files changed, 46 insertions(+), 1 deletions(-)
diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c
index 04ade1e..2fd51bc 100644
--- a/dlls/vbscript/lex.c
+++ b/dlls/vbscript/lex.c
@@ -197,6 +197,49 @@ static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
return tIdentifier;
}
+static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret)
+{
+ const WCHAR *ptr = ++ctx->ptr;
+ WCHAR *rptr;
+ int len = 0;
+
+ while(ctx->ptr < ctx->end) {
+ if(*ctx->ptr == '\n') {
+ FIXME("newline inside string literal\n");
+ return 0;
+ }
+
+ if(*ctx->ptr == '"') {
+ if(ctx->ptr[1] != '"')
+ break;
+ len--;
+ ctx->ptr++;
+ }
+ ctx->ptr++;
+ }
+
+ if(ctx->ptr == ctx->end) {
+ FIXME("unterminated string literal\n");
+ return 0;
+ }
+
+ len += ctx->ptr-ptr;
+
+ *ret = rptr = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
+ if(!rptr)
+ return 0;
+
+ while(ptr < ctx->ptr) {
+ if(*ptr == '"')
+ ptr++;
+ *rptr++ = *ptr++;
+ }
+
+ *rptr = 0;
+ ctx->ptr++;
+ return tString;
+}
+
static int parse_next_token(void *lval, parser_ctx_t *ctx)
{
WCHAR c;
@@ -238,6 +281,8 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
case '\\':
case '.':
return *ctx->ptr++;
+ case '"':
+ return parse_string_literal(ctx, lval);
default:
FIXME("Unhandled char %c in %s\n", *ctx->ptr, debugstr_w(ctx->ptr));
}
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 3761b13..06a0eb3 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -68,7 +68,7 @@ static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
%token tNOTHING tEMPTY tNULL
%token tCLASS tSET tNEW tPUBLIC tPRIVATE tDEFAULT tME
%token tERROR tNEXT tON tRESUME tGOTO
-%token <string> tIdentifier
+%token <string> tIdentifier tString
%type <statement> Statement StatementNl
%type <expression> Expression LiteralExpression
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 11/17] vbscript: Added parser support for string literals
Message-Id: <4E68BB9A.3040807 at codeweavers.com>
Date: Thu, 08 Sep 2011 14:56:58 +0200
---
dlls/vbscript/parse.h | 8 +++++++-
dlls/vbscript/parser.y | 14 ++++++++++++++
2 files changed, 21 insertions(+), 1 deletions(-)
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index df337d2..a0c7f2c 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -18,7 +18,8 @@
typedef enum {
EXPR_BOOL,
- EXPR_MEMBER
+ EXPR_MEMBER,
+ EXPR_STRING
} expression_type_t;
typedef struct _expression_t {
@@ -33,6 +34,11 @@ typedef struct {
typedef struct {
expression_t expr;
+ const WCHAR *value;
+} string_expression_t;
+
+typedef struct {
+ expression_t expr;
expression_t *obj_expr;
const WCHAR *identifier;
expression_t *args;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 06a0eb3..2d50565 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -36,6 +36,7 @@ static void parse_complete(parser_ctx_t*);
static void source_add_statement(parser_ctx_t*,statement_t*);
static expression_t *new_bool_expression(parser_ctx_t*,VARIANT_BOOL);
+static expression_t *new_string_expression(parser_ctx_t*,const WCHAR*);
static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,const WCHAR*);
@@ -113,6 +114,7 @@ Expression
LiteralExpression
: tTRUE { $$ = new_bool_expression(ctx, VARIANT_TRUE); CHECK_ERROR; }
| tFALSE { $$ = new_bool_expression(ctx, VARIANT_FALSE); CHECK_ERROR; }
+ | tString { $$ = new_string_expression(ctx, $1); CHECK_ERROR; }
%%
@@ -161,6 +163,18 @@ static expression_t *new_bool_expression(parser_ctx_t *ctx, VARIANT_BOOL value)
return &expr->expr;
}
+static expression_t *new_string_expression(parser_ctx_t *ctx, const WCHAR *value)
+{
+ string_expression_t *expr;
+
+ expr = new_expression(ctx, EXPR_STRING, sizeof(*expr));
+ if(!expr)
+ return NULL;
+
+ expr->value = value;
+ return &expr->expr;
+}
+
static member_expression_t *new_member_expression(parser_ctx_t *ctx, expression_t *obj_expr, const WCHAR *identifier)
{
member_expression_t *expr;
More information about the wine-tests-results
mailing list