vbscript: Added compiler support for select case statement.

This commit is contained in:
Jacek Caban 2012-07-20 16:28:45 +02:00 committed by Alexandre Julliard
parent 119c985cda
commit f17aaf8da7
3 changed files with 90 additions and 2 deletions

View File

@ -754,8 +754,89 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st
static HRESULT compile_select_statement(compile_ctx_t *ctx, select_statement_t *stat)
{
FIXME("\n");
return E_NOTIMPL;
unsigned end_label, case_cnt = 0, *case_labels = NULL, i;
case_clausule_t *case_iter;
expression_t *expr_iter;
HRESULT hres;
hres = compile_expression(ctx, stat->expr);
if(FAILED(hres))
return hres;
if(!push_instr(ctx, OP_val))
return E_OUTOFMEMORY;
end_label = alloc_label(ctx);
if(!end_label)
return E_OUTOFMEMORY;
for(case_iter = stat->case_clausules; case_iter; case_iter = case_iter->next)
case_cnt++;
if(case_cnt) {
case_labels = heap_alloc(case_cnt*sizeof(*case_labels));
if(!case_labels)
return E_OUTOFMEMORY;
}
for(case_iter = stat->case_clausules, i=0; case_iter; case_iter = case_iter->next, i++) {
case_labels[i] = alloc_label(ctx);
if(!case_labels[i]) {
hres = E_OUTOFMEMORY;
break;
}
if(!case_iter->expr)
break;
for(expr_iter = case_iter->expr; expr_iter; expr_iter = expr_iter->next) {
hres = compile_expression(ctx, expr_iter);
if(FAILED(hres))
break;
hres = push_instr_addr(ctx, OP_case, case_labels[i]);
if(FAILED(hres))
break;
}
}
if(FAILED(hres)) {
heap_free(case_labels);
return hres;
}
hres = push_instr_uint(ctx, OP_pop, 1);
if(FAILED(hres)) {
heap_free(case_labels);
return hres;
}
hres = push_instr_addr(ctx, OP_jmp, case_iter ? case_labels[i] : end_label);
if(FAILED(hres)) {
heap_free(case_labels);
return hres;
}
for(case_iter = stat->case_clausules, i=0; case_iter; case_iter = case_iter->next, i++) {
label_set_addr(ctx, case_labels[i]);
hres = compile_statement(ctx, NULL, case_iter->stat);
if(FAILED(hres))
break;
if(!case_iter->next)
break;
hres = push_instr_addr(ctx, OP_jmp, end_label);
if(FAILED(hres))
return hres;
}
heap_free(case_labels);
if(FAILED(hres))
return hres;
label_set_addr(ctx, end_label);
return S_OK;
}
static HRESULT compile_assignment(compile_ctx_t *ctx, member_expression_t *member_expr, expression_t *value_expr, BOOL is_set)

View File

@ -1422,6 +1422,12 @@ static HRESULT interp_lteq(exec_ctx_t *ctx)
return stack_push(ctx, &v);
}
static HRESULT interp_case(exec_ctx_t *ctx)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, VARIANT_BOOL *ret)
{
IObjectIdentity *identity;

View File

@ -189,6 +189,7 @@ typedef enum {
X(assign_ident, 1, ARG_BSTR, ARG_UINT) \
X(assign_member, 1, ARG_BSTR, ARG_UINT) \
X(bool, 1, ARG_INT, 0) \
X(case, 0, ARG_ADDR, 0) \
X(concat, 1, 0, 0) \
X(const, 1, ARG_BSTR, 0) \
X(div, 1, 0, 0) \