Jacek Caban : jscript: Added parser support for regular expressions.

Alexandre Julliard julliard at winehq.org
Tue Sep 16 06:54:21 CDT 2008


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Sep 15 20:38:18 2008 +0200

jscript: Added parser support for regular expressions.

---

 dlls/jscript/engine.h  |    9 +++++++++
 dlls/jscript/jscript.h |    1 +
 dlls/jscript/lex.c     |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/jscript/parser.y  |    8 +++++++-
 dlls/jscript/regexp.c  |   42 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 105 insertions(+), 1 deletions(-)

diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 57a68c2..0d75716 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -18,6 +18,11 @@
 
 typedef struct _source_elements_t source_elements_t;
 
+typedef struct _obj_literal_t {
+    DispatchEx *obj;
+    struct _obj_literal_t *next;
+} obj_literal_t;
+
 typedef struct _parser_ctx_t {
     LONG ref;
 
@@ -33,6 +38,8 @@ typedef struct _parser_ctx_t {
     jsheap_t tmp_heap;
     jsheap_t heap;
 
+    obj_literal_t *obj_literals;
+
     struct _parser_ctx_t *next;
 } parser_ctx_t;
 
@@ -105,6 +112,8 @@ typedef struct {
     } u;
 } literal_t;
 
+literal_t *parse_regexp(parser_ctx_t*);
+
 typedef struct _variable_declaration_t {
     const WCHAR *identifier;
     expression_t *expr;
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index a3c5c0a..ec42011 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -116,6 +116,7 @@ HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,DWORD,DispatchEx*
 HRESULT create_object(script_ctx_t*,DispatchEx*,DispatchEx**);
 HRESULT create_math(script_ctx_t*,DispatchEx**);
 HRESULT create_array(script_ctx_t*,DWORD,DispatchEx**);
+HRESULT create_regexp_str(script_ctx_t*,const WCHAR*,DWORD,const WCHAR*,DWORD,DispatchEx**);
 
 HRESULT to_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
 HRESULT to_boolean(VARIANT*,VARIANT_BOOL*);
diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c
index 8ae15d3..0aea118 100644
--- a/dlls/jscript/lex.c
+++ b/dlls/jscript/lex.c
@@ -684,3 +684,49 @@ int parser_lex(void *lval, parser_ctx_t *ctx)
     WARN("unexpected char '%c' %d\n", *ctx->ptr, *ctx->ptr);
     return 0;
 }
+
+static void add_object_literal(parser_ctx_t *ctx, DispatchEx *obj)
+{
+    obj_literal_t *literal = parser_alloc(ctx, sizeof(obj_literal_t));
+
+    literal->obj = obj;
+    literal->next = ctx->obj_literals;
+    ctx->obj_literals = literal;
+}
+
+literal_t *parse_regexp(parser_ctx_t *ctx)
+{
+    const WCHAR *re, *flags;
+    DispatchEx *regexp;
+    literal_t *ret;
+    DWORD re_len;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    re = ctx->ptr;
+    while(ctx->ptr < ctx->end && (*ctx->ptr != '/' || *(ctx->ptr-1) == '\\'))
+        ctx->ptr++;
+
+    if(ctx->ptr == ctx->end) {
+        WARN("unexpected end of file\n");
+        return NULL;
+    }
+
+    re_len = ctx->ptr-re;
+
+    flags = ++ctx->ptr;
+    while(ctx->ptr < ctx->end && isalnumW(*ctx->ptr))
+        ctx->ptr++;
+
+    hres = create_regexp_str(ctx->script, re, re_len, flags, ctx->ptr-flags, &regexp);
+    if(FAILED(hres))
+        return NULL;
+
+    add_object_literal(ctx, regexp);
+
+    ret = parser_alloc(ctx, sizeof(literal_t));
+    ret->vt = VT_DISPATCH;
+    ret->u.disp = (IDispatch*)_IDispatchEx_(regexp);
+    return ret;
+}
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y
index cc4ee7b..ec5f4bd 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -775,7 +775,8 @@ Literal
         | BooleanLiteral        { $$ = $1; }
         | tNumericLiteral       { $$ = $1; }
         | tStringLiteral        { $$ = new_string_literal(ctx, $1); }
-        | '/'                   { FIXME("RegExp literal\n"); YYABORT; }
+        | '/'                   { $$ = parse_regexp(ctx);
+                                  if(!$$) YYABORT; }
 
 /* ECMA-262 3rd Edition    7.8.2 */
 BooleanLiteral
@@ -1509,9 +1510,14 @@ static void program_parsed(parser_ctx_t *ctx, source_elements_t *source)
 
 void parser_release(parser_ctx_t *ctx)
 {
+    obj_literal_t *iter;
+
     if(--ctx->ref)
         return;
 
+    for(iter = ctx->obj_literals; iter; iter = iter->next)
+        jsdisp_release(iter->obj);
+
     jsheap_free(&ctx->heap);
     heap_free(ctx);
 }
diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c
index 88f7c3b..7c352ef 100644
--- a/dlls/jscript/regexp.c
+++ b/dlls/jscript/regexp.c
@@ -22,6 +22,11 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
 
+#define JSREG_FOLD      0x01    /* fold uppercase to lowercase */
+#define JSREG_GLOB      0x02    /* global exec, creates array of matches */
+#define JSREG_MULTILINE 0x04    /* treat ^ and $ as begin and end of line */
+#define JSREG_STICKY    0x08    /* only match starting at lastIndex */
+
 typedef struct {
     DispatchEx dispex;
 } RegExpInstance;
@@ -174,6 +179,12 @@ static HRESULT alloc_regexp(script_ctx_t *ctx, BOOL use_constr, RegExpInstance *
     return S_OK;
 }
 
+static HRESULT create_regexp(script_ctx_t *ctx, const WCHAR *exp, int len, DWORD flags, DispatchEx **ret)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
 static HRESULT RegExpConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
@@ -195,3 +206,34 @@ HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx **ret)
     jsdisp_release(&regexp->dispex);
     return hres;
 }
+
+HRESULT create_regexp_str(script_ctx_t *ctx, const WCHAR *exp, DWORD exp_len, const WCHAR *opt,
+        DWORD opt_len, DispatchEx **ret)
+{
+    const WCHAR *p;
+    DWORD flags = 0;
+
+    if(opt) {
+        for (p = opt; p < opt+opt_len; p++) {
+            switch (*p) {
+            case 'g':
+                flags |= JSREG_GLOB;
+                break;
+            case 'i':
+                flags |= JSREG_FOLD;
+                break;
+            case 'm':
+                flags |= JSREG_MULTILINE;
+                break;
+            case 'y':
+                flags |= JSREG_STICKY;
+                break;
+            default:
+                WARN("wrong flag %c\n", *p);
+                return E_FAIL;
+            }
+        }
+    }
+
+    return create_regexp(ctx, exp, exp_len, flags, ret);
+}




More information about the wine-cvs mailing list