vbscript: Added while..wend statement implementation.
This commit is contained in:
parent
a99dc8cb3d
commit
3d34925802
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue