vbscript: Added is expression implementation.

This commit is contained in:
Jacek Caban 2011-09-19 14:08:02 +02:00 committed by Alexandre Julliard
parent 33a81218ad
commit 2de6982f46
6 changed files with 88 additions and 0 deletions

View File

@ -387,6 +387,8 @@ static HRESULT compile_expression(compile_ctx_t *ctx, expression_t *expr)
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gteq); return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gteq);
case EXPR_IDIV: case EXPR_IDIV:
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_idiv); return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_idiv);
case EXPR_IS:
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_is);
case EXPR_IMP: case EXPR_IMP:
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_imp); return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_imp);
case EXPR_LT: case EXPR_LT:

View File

@ -1005,6 +1005,77 @@ static HRESULT interp_lteq(exec_ctx_t *ctx)
return stack_push(ctx, &v); return stack_push(ctx, &v);
} }
static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, VARIANT_BOOL *ret)
{
IObjectIdentity *identity;
IUnknown *unk1, *unk2;
HRESULT hres;
if(disp1 == disp2) {
*ret = VARIANT_TRUE;
return S_OK;
}
if(!disp1 || !disp2) {
*ret = VARIANT_FALSE;
return S_OK;
}
hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
if(FAILED(hres))
return hres;
hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
if(FAILED(hres)) {
IUnknown_Release(unk1);
return hres;
}
if(unk1 == unk2) {
*ret = VARIANT_TRUE;
}else {
hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
if(SUCCEEDED(hres)) {
hres = IObjectIdentity_IsEqualObject(identity, unk2);
IObjectIdentity_Release(identity);
*ret = hres == S_OK ? VARIANT_TRUE : VARIANT_FALSE;
}else {
*ret = VARIANT_FALSE;
}
}
IUnknown_Release(unk1);
IUnknown_Release(unk2);
return S_OK;
}
static HRESULT interp_is(exec_ctx_t *ctx)
{
IDispatch *l, *r;
VARIANT v;
HRESULT hres;
TRACE("\n");
hres = stack_pop_disp(ctx, &r);
if(FAILED(hres))
return hres;
hres = stack_pop_disp(ctx, &l);
if(SUCCEEDED(hres)) {
V_VT(&v) = VT_BOOL;
hres = disp_cmp(l, r, &V_BOOL(&v));
if(l)
IDispatch_Release(l);
}
if(r)
IDispatch_Release(r);
if(FAILED(hres))
return hres;
return stack_push(ctx, &v);
}
static HRESULT interp_concat(exec_ctx_t *ctx) static HRESULT interp_concat(exec_ctx_t *ctx)
{ {
variant_val_t r, l; variant_val_t r, l;

View File

@ -31,6 +31,7 @@ typedef enum {
EXPR_GTEQ, EXPR_GTEQ,
EXPR_IDIV, EXPR_IDIV,
EXPR_IMP, EXPR_IMP,
EXPR_IS,
EXPR_LT, EXPR_LT,
EXPR_LTEQ, EXPR_LTEQ,
EXPR_MEMBER, EXPR_MEMBER,

View File

@ -252,6 +252,7 @@ EqualityExpression
| EqualityExpression '<' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LT, $1, $3); CHECK_ERROR; } | EqualityExpression '<' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LT, $1, $3); CHECK_ERROR; }
| EqualityExpression tGTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GTEQ, $1, $3); CHECK_ERROR; } | EqualityExpression tGTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GTEQ, $1, $3); CHECK_ERROR; }
| EqualityExpression tLTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LTEQ, $1, $3); CHECK_ERROR; } | EqualityExpression tLTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LTEQ, $1, $3); CHECK_ERROR; }
| EqualityExpression tIS ConcatExpression { $$ = new_binary_expression(ctx, EXPR_IS, $1, $3); CHECK_ERROR; }
ConcatExpression ConcatExpression
: AdditiveExpression { $$ = $1; } : AdditiveExpression { $$ = $1; }

View File

@ -608,4 +608,16 @@ funcCalled = ""
Set obj = Nothing Set obj = Nothing
Call ok(funcCalled = "terminate", "funcCalled = " & funcCalled) Call ok(funcCalled = "terminate", "funcCalled = " & funcCalled)
Set obj = new EmptyClass
Set x = obj
Set y = new EmptyClass
Call ok(obj is x, "obj is not x")
Call ok(x is obj, "x is not obj")
Call ok(not (obj is y), "obj is not y")
Call ok(not obj is y, "obj is not y")
Call ok(not (x is Nothing), "x is 1")
Call ok(Nothing is Nothing, "Nothing is not Nothing")
Call ok(x is obj and true, "x is obj and true is false")
reportSuccess() reportSuccess()

View File

@ -167,6 +167,7 @@ typedef enum {
X(icallv, 1, ARG_BSTR, ARG_UINT) \ X(icallv, 1, ARG_BSTR, ARG_UINT) \
X(idiv, 1, 0, 0) \ X(idiv, 1, 0, 0) \
X(imp, 1, 0, 0) \ X(imp, 1, 0, 0) \
X(is, 1, 0, 0) \
X(jmp, 0, ARG_ADDR, 0) \ X(jmp, 0, ARG_ADDR, 0) \
X(jmp_false, 0, ARG_ADDR, 0) \ X(jmp_false, 0, ARG_ADDR, 0) \
X(jmp_true, 0, ARG_ADDR, 0) \ X(jmp_true, 0, ARG_ADDR, 0) \