jscript: Added parser support for regular expressions.
This commit is contained in:
parent
f2e7626c7a
commit
cf1863ed09
|
@ -18,6 +18,11 @@
|
||||||
|
|
||||||
typedef struct _source_elements_t source_elements_t;
|
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 {
|
typedef struct _parser_ctx_t {
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
|
||||||
|
@ -33,6 +38,8 @@ typedef struct _parser_ctx_t {
|
||||||
jsheap_t tmp_heap;
|
jsheap_t tmp_heap;
|
||||||
jsheap_t heap;
|
jsheap_t heap;
|
||||||
|
|
||||||
|
obj_literal_t *obj_literals;
|
||||||
|
|
||||||
struct _parser_ctx_t *next;
|
struct _parser_ctx_t *next;
|
||||||
} parser_ctx_t;
|
} parser_ctx_t;
|
||||||
|
|
||||||
|
@ -105,6 +112,8 @@ typedef struct {
|
||||||
} u;
|
} u;
|
||||||
} literal_t;
|
} literal_t;
|
||||||
|
|
||||||
|
literal_t *parse_regexp(parser_ctx_t*);
|
||||||
|
|
||||||
typedef struct _variable_declaration_t {
|
typedef struct _variable_declaration_t {
|
||||||
const WCHAR *identifier;
|
const WCHAR *identifier;
|
||||||
expression_t *expr;
|
expression_t *expr;
|
||||||
|
|
|
@ -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_object(script_ctx_t*,DispatchEx*,DispatchEx**);
|
||||||
HRESULT create_math(script_ctx_t*,DispatchEx**);
|
HRESULT create_math(script_ctx_t*,DispatchEx**);
|
||||||
HRESULT create_array(script_ctx_t*,DWORD,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_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
|
||||||
HRESULT to_boolean(VARIANT*,VARIANT_BOOL*);
|
HRESULT to_boolean(VARIANT*,VARIANT_BOOL*);
|
||||||
|
|
|
@ -684,3 +684,49 @@ int parser_lex(void *lval, parser_ctx_t *ctx)
|
||||||
WARN("unexpected char '%c' %d\n", *ctx->ptr, *ctx->ptr);
|
WARN("unexpected char '%c' %d\n", *ctx->ptr, *ctx->ptr);
|
||||||
return 0;
|
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, ®exp);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -775,7 +775,8 @@ Literal
|
||||||
| BooleanLiteral { $$ = $1; }
|
| BooleanLiteral { $$ = $1; }
|
||||||
| tNumericLiteral { $$ = $1; }
|
| tNumericLiteral { $$ = $1; }
|
||||||
| tStringLiteral { $$ = new_string_literal(ctx, $1); }
|
| tStringLiteral { $$ = new_string_literal(ctx, $1); }
|
||||||
| '/' { FIXME("RegExp literal\n"); YYABORT; }
|
| '/' { $$ = parse_regexp(ctx);
|
||||||
|
if(!$$) YYABORT; }
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 7.8.2 */
|
/* ECMA-262 3rd Edition 7.8.2 */
|
||||||
BooleanLiteral
|
BooleanLiteral
|
||||||
|
@ -1509,9 +1510,14 @@ static void program_parsed(parser_ctx_t *ctx, source_elements_t *source)
|
||||||
|
|
||||||
void parser_release(parser_ctx_t *ctx)
|
void parser_release(parser_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
obj_literal_t *iter;
|
||||||
|
|
||||||
if(--ctx->ref)
|
if(--ctx->ref)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
for(iter = ctx->obj_literals; iter; iter = iter->next)
|
||||||
|
jsdisp_release(iter->obj);
|
||||||
|
|
||||||
jsheap_free(&ctx->heap);
|
jsheap_free(&ctx->heap);
|
||||||
heap_free(ctx);
|
heap_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
|
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 {
|
typedef struct {
|
||||||
DispatchEx dispex;
|
DispatchEx dispex;
|
||||||
} RegExpInstance;
|
} RegExpInstance;
|
||||||
|
@ -174,6 +179,12 @@ static HRESULT alloc_regexp(script_ctx_t *ctx, BOOL use_constr, RegExpInstance *
|
||||||
return S_OK;
|
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,
|
static HRESULT RegExpConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||||
{
|
{
|
||||||
|
@ -195,3 +206,34 @@ HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx **ret)
|
||||||
jsdisp_release(®exp->dispex);
|
jsdisp_release(®exp->dispex);
|
||||||
return hres;
|
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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue