Commit 3d349258 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

vbscript: Added while..wend statement implementation.

parent a99dc8cb
...@@ -483,6 +483,34 @@ static HRESULT compile_if_statement(compile_ctx_t *ctx, if_statement_t *stat) ...@@ -483,6 +483,34 @@ static HRESULT compile_if_statement(compile_ctx_t *ctx, if_statement_t *stat)
return S_OK; 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) static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
{ {
HRESULT hres; HRESULT hres;
...@@ -632,6 +660,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat) ...@@ -632,6 +660,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
case STAT_STOP: case STAT_STOP:
hres = push_instr(ctx, OP_stop) == -1 ? E_OUTOFMEMORY : S_OK; hres = push_instr(ctx, OP_stop) == -1 ? E_OUTOFMEMORY : S_OK;
break; break;
case STAT_WHILE:
hres = compile_while_statement(ctx, (while_statement_t*)stat);
break;
default: default:
FIXME("Unimplemented statement type %d\n", stat->type); FIXME("Unimplemented statement type %d\n", stat->type);
hres = E_NOTIMPL; hres = E_NOTIMPL;
......
...@@ -99,7 +99,8 @@ typedef enum { ...@@ -99,7 +99,8 @@ typedef enum {
STAT_FUNC, STAT_FUNC,
STAT_IF, STAT_IF,
STAT_SET, STAT_SET,
STAT_STOP STAT_STOP,
STAT_WHILE
} statement_type_t; } statement_type_t;
typedef struct _statement_t { typedef struct _statement_t {
...@@ -177,6 +178,12 @@ typedef struct { ...@@ -177,6 +178,12 @@ typedef struct {
} if_statement_t; } if_statement_t;
typedef struct { typedef struct {
statement_t stat;
expression_t *expr;
statement_t *body;
} while_statement_t;
typedef struct {
const WCHAR *code; const WCHAR *code;
const WCHAR *ptr; const WCHAR *ptr;
const WCHAR *end; const WCHAR *end;
......
...@@ -52,6 +52,7 @@ static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*); ...@@ -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_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_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_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_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*); static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
...@@ -153,6 +154,8 @@ Statement ...@@ -153,6 +154,8 @@ Statement
{ $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; } { $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
| tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; } | tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
| IfStatement { $$ = $1; } | 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; } | FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
| tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; } | tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; }
| tEXIT tPROPERTY { $$ = new_statement(ctx, STAT_EXITPROP, 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 ...@@ -565,6 +568,19 @@ static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, expression_t *expr, sta
return decl; 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, 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) statement_t *else_stat)
{ {
......
...@@ -199,6 +199,19 @@ ElseIf not False Then ...@@ -199,6 +199,19 @@ ElseIf not False Then
End If End If
Call ok(x, "elseif not called?") 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 if false then
Sub testsub Sub testsub
x = true x = true
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment