vbscript: Added while..wend statement implementation.

This commit is contained in:
Jacek Caban 2011-09-16 13:29:59 +02:00 committed by Alexandre Julliard
parent a99dc8cb3d
commit 3d34925802
4 changed files with 68 additions and 1 deletions

View File

@ -483,6 +483,34 @@ static HRESULT compile_if_statement(compile_ctx_t *ctx, if_statement_t *stat)
return S_OK;
}
static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *stat)
{
unsigned start_addr;
unsigned jmp_end;
HRESULT hres;
start_addr = ctx->instr_cnt;
hres = compile_expression(ctx, stat->expr);
if(FAILED(hres))
return hres;
jmp_end = push_instr(ctx, OP_jmp_false);
if(jmp_end == -1)
return E_OUTOFMEMORY;
hres = compile_statement(ctx, stat->body);
if(FAILED(hres))
return hres;
hres = push_instr_addr(ctx, OP_jmp, start_addr);
if(FAILED(hres))
return hres;
instr_ptr(ctx, jmp_end)->arg1.uint = ctx->instr_cnt;
return S_OK;
}
static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
{
HRESULT hres;
@ -632,6 +660,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
case STAT_STOP:
hres = push_instr(ctx, OP_stop) == -1 ? E_OUTOFMEMORY : S_OK;
break;
case STAT_WHILE:
hres = compile_while_statement(ctx, (while_statement_t*)stat);
break;
default:
FIXME("Unimplemented statement type %d\n", stat->type);
hres = E_NOTIMPL;

View File

@ -99,7 +99,8 @@ typedef enum {
STAT_FUNC,
STAT_IF,
STAT_SET,
STAT_STOP
STAT_STOP,
STAT_WHILE
} statement_type_t;
typedef struct _statement_t {
@ -176,6 +177,12 @@ typedef struct {
statement_t *else_stat;
} if_statement_t;
typedef struct {
statement_t stat;
expression_t *expr;
statement_t *body;
} while_statement_t;
typedef struct {
const WCHAR *code;
const WCHAR *ptr;

View File

@ -52,6 +52,7 @@ static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
static statement_t *new_assign_statement(parser_ctx_t*,member_expression_t*,expression_t*);
static statement_t *new_set_statement(parser_ctx_t*,member_expression_t*,expression_t*);
static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*);
static statement_t *new_while_statement(parser_ctx_t*,statement_type_t,expression_t*,statement_t*);
static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
@ -153,6 +154,8 @@ Statement
{ $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
| tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
| IfStatement { $$ = $1; }
| tWHILE Expression tNL StatementsNl_opt tWEND
{ $$ = new_while_statement(ctx, STAT_WHILE, $2, $4); CHECK_ERROR; }
| FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
| tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; }
| tEXIT tPROPERTY { $$ = new_statement(ctx, STAT_EXITPROP, 0); CHECK_ERROR; }
@ -565,6 +568,19 @@ static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, expression_t *expr, sta
return decl;
}
static statement_t *new_while_statement(parser_ctx_t *ctx, statement_type_t type, expression_t *expr, statement_t *body)
{
while_statement_t *stat;
stat = new_statement(ctx, type, sizeof(*stat));
if(!stat)
return NULL;
stat->expr = expr;
stat->body = body;
return &stat->stat;
}
static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl,
statement_t *else_stat)
{

View File

@ -199,6 +199,19 @@ ElseIf not False Then
End If
Call ok(x, "elseif not called?")
x = false
y = false
while not (x and y)
if x then
y = true
end if
x = true
wend
call ok((x and y), "x or y is false after while")
while false
wend
if false then
Sub testsub
x = true