vbscript: Added exit for statement support.
This commit is contained in:
parent
cbb735e2ce
commit
ed53c40eda
@ -39,6 +39,7 @@ typedef struct {
|
|||||||
unsigned labels_cnt;
|
unsigned labels_cnt;
|
||||||
|
|
||||||
unsigned while_end_label;
|
unsigned while_end_label;
|
||||||
|
unsigned for_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;
|
||||||
@ -617,7 +618,7 @@ static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *
|
|||||||
|
|
||||||
static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat)
|
static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat)
|
||||||
{
|
{
|
||||||
unsigned step_instr, instr;
|
unsigned step_instr, instr, prev_label;
|
||||||
BSTR identifier;
|
BSTR identifier;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
@ -654,10 +655,16 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st
|
|||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prev_label = ctx->for_end_label;
|
||||||
|
ctx->for_end_label = alloc_label(ctx);
|
||||||
|
if(ctx->for_end_label == -1)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
step_instr = push_instr(ctx, OP_step);
|
step_instr = push_instr(ctx, OP_step);
|
||||||
if(step_instr == -1)
|
if(step_instr == -1)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
|
instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
|
||||||
|
instr_ptr(ctx, step_instr)->arg1.uint = ctx->for_end_label;
|
||||||
|
|
||||||
hres = compile_statement(ctx, stat->body);
|
hres = compile_statement(ctx, stat->body);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
@ -672,7 +679,8 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st
|
|||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
instr_ptr(ctx, step_instr)->arg1.uint = ctx->instr_cnt;
|
label_set_addr(ctx, ctx->for_end_label);
|
||||||
|
ctx->for_end_label = prev_label;
|
||||||
|
|
||||||
return push_instr_uint(ctx, OP_pop, 2);
|
return push_instr_uint(ctx, OP_pop, 2);
|
||||||
}
|
}
|
||||||
@ -804,6 +812,16 @@ static HRESULT compile_exitdo_statement(compile_ctx_t *ctx)
|
|||||||
return push_instr_addr(ctx, OP_jmp, ctx->while_end_label);
|
return push_instr_addr(ctx, OP_jmp, ctx->while_end_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT compile_exitfor_statement(compile_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
if(ctx->for_end_label == -1) {
|
||||||
|
FIXME("Exit For outside For Loop\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return push_instr_addr(ctx, OP_jmp, ctx->for_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) {
|
||||||
@ -864,6 +882,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
|
|||||||
case STAT_EXITDO:
|
case STAT_EXITDO:
|
||||||
hres = compile_exitdo_statement(ctx);
|
hres = compile_exitdo_statement(ctx);
|
||||||
break;
|
break;
|
||||||
|
case STAT_EXITFOR:
|
||||||
|
hres = compile_exitfor_statement(ctx);
|
||||||
|
break;
|
||||||
case STAT_EXITFUNC:
|
case STAT_EXITFUNC:
|
||||||
hres = compile_exitfunc_statement(ctx);
|
hres = compile_exitfunc_statement(ctx);
|
||||||
break;
|
break;
|
||||||
@ -931,6 +952,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->while_end_label = -1;
|
||||||
|
ctx->for_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;
|
||||||
@ -967,6 +989,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
|
|||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
assert(ctx->while_end_label == -1);
|
assert(ctx->while_end_label == -1);
|
||||||
|
assert(ctx->for_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);
|
||||||
|
@ -103,6 +103,7 @@ typedef enum {
|
|||||||
STAT_DOUNTIL,
|
STAT_DOUNTIL,
|
||||||
STAT_DOWHILE,
|
STAT_DOWHILE,
|
||||||
STAT_EXITDO,
|
STAT_EXITDO,
|
||||||
|
STAT_EXITFOR,
|
||||||
STAT_EXITFUNC,
|
STAT_EXITFUNC,
|
||||||
STAT_EXITPROP,
|
STAT_EXITPROP,
|
||||||
STAT_EXITSUB,
|
STAT_EXITSUB,
|
||||||
|
@ -178,6 +178,7 @@ SimpleStatement
|
|||||||
CHECK_ERROR; }
|
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 tDO { $$ = new_statement(ctx, STAT_EXITDO, 0); CHECK_ERROR; }
|
||||||
|
| tEXIT tFOR { $$ = new_statement(ctx, STAT_EXITFOR, 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; }
|
||||||
|
@ -387,6 +387,15 @@ for x = 5 to 8
|
|||||||
next
|
next
|
||||||
Call ok(y = "for8: 5 7", "y = " & y)
|
Call ok(y = "for8: 5 7", "y = " & y)
|
||||||
|
|
||||||
|
for x = 1.5 to 1
|
||||||
|
Call ok(false, "for..to called when unexpected")
|
||||||
|
next
|
||||||
|
|
||||||
|
for x = 1 to 100
|
||||||
|
exit for
|
||||||
|
Call ok(false, "exit for not escaped the loop?")
|
||||||
|
next
|
||||||
|
|
||||||
if false then
|
if false then
|
||||||
Sub testsub
|
Sub testsub
|
||||||
x = true
|
x = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user