Commit 9701bdb5 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

vbscript: Added support for exit do statement.

parent 1f5c56d1
...@@ -38,6 +38,7 @@ typedef struct { ...@@ -38,6 +38,7 @@ typedef struct {
unsigned labels_size; unsigned labels_size;
unsigned labels_cnt; unsigned labels_cnt;
unsigned while_end_label;
unsigned sub_end_label; unsigned sub_end_label;
unsigned func_end_label; unsigned func_end_label;
unsigned prop_end_label; unsigned prop_end_label;
...@@ -485,7 +486,7 @@ static HRESULT compile_if_statement(compile_ctx_t *ctx, if_statement_t *stat) ...@@ -485,7 +486,7 @@ static HRESULT compile_if_statement(compile_ctx_t *ctx, if_statement_t *stat)
static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *stat) static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *stat)
{ {
unsigned start_addr; unsigned start_addr, prev_label;
unsigned jmp_end; unsigned jmp_end;
HRESULT hres; HRESULT hres;
...@@ -499,6 +500,12 @@ static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *st ...@@ -499,6 +500,12 @@ static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *st
if(jmp_end == -1) if(jmp_end == -1)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
if(stat->stat.type != STAT_WHILE) {
prev_label = ctx->while_end_label;
if((ctx->while_end_label = alloc_label(ctx)) == -1)
return E_OUTOFMEMORY;
}
hres = compile_statement(ctx, stat->body); hres = compile_statement(ctx, stat->body);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
...@@ -508,6 +515,12 @@ static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *st ...@@ -508,6 +515,12 @@ static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *st
return hres; return hres;
instr_ptr(ctx, jmp_end)->arg1.uint = ctx->instr_cnt; instr_ptr(ctx, jmp_end)->arg1.uint = ctx->instr_cnt;
if(stat->stat.type != STAT_WHILE) {
label_set_addr(ctx, ctx->while_end_label);
ctx->while_end_label = prev_label;
}
return S_OK; return S_OK;
} }
...@@ -594,6 +607,16 @@ static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement ...@@ -594,6 +607,16 @@ static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement
return S_OK; return S_OK;
} }
static HRESULT compile_exitdo_statement(compile_ctx_t *ctx)
{
if(ctx->while_end_label == -1) {
FIXME("Exit Do outside Do Loop\n");
return E_FAIL;
}
return push_instr_addr(ctx, OP_jmp, ctx->while_end_label);
}
static HRESULT compile_exitsub_statement(compile_ctx_t *ctx) static HRESULT compile_exitsub_statement(compile_ctx_t *ctx)
{ {
if(ctx->sub_end_label == -1) { if(ctx->sub_end_label == -1) {
...@@ -639,6 +662,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat) ...@@ -639,6 +662,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
case STAT_DIM: case STAT_DIM:
hres = compile_dim_statement(ctx, (dim_statement_t*)stat); hres = compile_dim_statement(ctx, (dim_statement_t*)stat);
break; break;
case STAT_EXITDO:
hres = compile_exitdo_statement(ctx);
break;
case STAT_EXITFUNC: case STAT_EXITFUNC:
hres = compile_exitfunc_statement(ctx); hres = compile_exitfunc_statement(ctx);
break; break;
...@@ -698,6 +724,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f ...@@ -698,6 +724,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
func->code_off = ctx->instr_cnt; func->code_off = ctx->instr_cnt;
ctx->while_end_label = -1;
ctx->sub_end_label = -1; ctx->sub_end_label = -1;
ctx->func_end_label = -1; ctx->func_end_label = -1;
ctx->prop_end_label = -1; ctx->prop_end_label = -1;
...@@ -732,6 +759,8 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f ...@@ -732,6 +759,8 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
assert(ctx->while_end_label == -1);
if(ctx->sub_end_label != -1) if(ctx->sub_end_label != -1)
label_set_addr(ctx, ctx->sub_end_label); label_set_addr(ctx, ctx->sub_end_label);
if(ctx->func_end_label != -1) if(ctx->func_end_label != -1)
......
...@@ -93,6 +93,7 @@ typedef enum { ...@@ -93,6 +93,7 @@ typedef enum {
STAT_ASSIGN, STAT_ASSIGN,
STAT_CALL, STAT_CALL,
STAT_DIM, STAT_DIM,
STAT_EXITDO,
STAT_EXITFUNC, STAT_EXITFUNC,
STAT_EXITPROP, STAT_EXITPROP,
STAT_EXITSUB, STAT_EXITSUB,
......
...@@ -159,6 +159,7 @@ Statement ...@@ -159,6 +159,7 @@ Statement
| tDO tWHILE Expression tNL StatementsNl_opt tLOOP | tDO tWHILE Expression tNL StatementsNl_opt tLOOP
{ $$ = new_while_statement(ctx, STAT_WHILELOOP, $3, $5); CHECK_ERROR; } { $$ = new_while_statement(ctx, STAT_WHILELOOP, $3, $5); CHECK_ERROR; }
| FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; } | FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
| tEXIT tDO { $$ = new_statement(ctx, STAT_EXITDO, 0); 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; }
| tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; } | tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; }
......
...@@ -225,6 +225,11 @@ call ok((x and y), "x or y is false after while") ...@@ -225,6 +225,11 @@ call ok((x and y), "x or y is false after while")
do while false do while false
loop loop
do while true
exit do
ok false, "exit do didn't work"
loop
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