vbscript: Added do until..loop statement implementation.
This commit is contained in:
parent
9701bdb563
commit
223a407a7f
|
@ -496,7 +496,7 @@ static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *st
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
jmp_end = push_instr(ctx, OP_jmp_false);
|
jmp_end = push_instr(ctx, stat->stat.type == STAT_UNTIL ? OP_jmp_true : OP_jmp_false);
|
||||||
if(jmp_end == -1)
|
if(jmp_end == -1)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
@ -686,6 +686,7 @@ 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_UNTIL:
|
||||||
case STAT_WHILE:
|
case STAT_WHILE:
|
||||||
case STAT_WHILELOOP:
|
case STAT_WHILELOOP:
|
||||||
hres = compile_while_statement(ctx, (while_statement_t*)stat);
|
hres = compile_while_statement(ctx, (while_statement_t*)stat);
|
||||||
|
|
|
@ -611,6 +611,31 @@ static HRESULT interp_jmp_false(exec_ctx_t *ctx)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT interp_jmp_true(exec_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
const unsigned arg = ctx->instr->arg1.uint;
|
||||||
|
variant_val_t val;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("%u\n", arg);
|
||||||
|
|
||||||
|
hres = stack_pop_val(ctx, &val);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
if(V_VT(val.v) != VT_BOOL) {
|
||||||
|
FIXME("unsupported for %s\n", debugstr_variant(val.v));
|
||||||
|
release_val(&val);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(V_BOOL(val.v))
|
||||||
|
instr_jmp(ctx, ctx->instr->arg1.uint);
|
||||||
|
else
|
||||||
|
ctx->instr++;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT interp_ret(exec_ctx_t *ctx)
|
static HRESULT interp_ret(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
|
@ -101,6 +101,7 @@ typedef enum {
|
||||||
STAT_IF,
|
STAT_IF,
|
||||||
STAT_SET,
|
STAT_SET,
|
||||||
STAT_STOP,
|
STAT_STOP,
|
||||||
|
STAT_UNTIL,
|
||||||
STAT_WHILE,
|
STAT_WHILE,
|
||||||
STAT_WHILELOOP
|
STAT_WHILELOOP
|
||||||
} statement_type_t;
|
} statement_type_t;
|
||||||
|
|
|
@ -114,7 +114,7 @@ static class_decl_t *add_variant_prop(parser_ctx_t*,class_decl_t*,const WCHAR*,u
|
||||||
%type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
|
%type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
|
||||||
%type <member> MemberExpression
|
%type <member> MemberExpression
|
||||||
%type <expression> Arguments_opt ArgumentList_opt ArgumentList
|
%type <expression> Arguments_opt ArgumentList_opt ArgumentList
|
||||||
%type <bool> OptionExplicit_opt
|
%type <bool> OptionExplicit_opt DoType
|
||||||
%type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
|
%type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
|
||||||
%type <func_decl> FunctionDecl PropertyDecl
|
%type <func_decl> FunctionDecl PropertyDecl
|
||||||
%type <elseif> ElseIfs_opt ElseIfs ElseIf
|
%type <elseif> ElseIfs_opt ElseIfs ElseIf
|
||||||
|
@ -156,8 +156,9 @@ Statement
|
||||||
| IfStatement { $$ = $1; }
|
| IfStatement { $$ = $1; }
|
||||||
| tWHILE Expression tNL StatementsNl_opt tWEND
|
| tWHILE Expression tNL StatementsNl_opt tWEND
|
||||||
{ $$ = new_while_statement(ctx, STAT_WHILE, $2, $4); CHECK_ERROR; }
|
{ $$ = new_while_statement(ctx, STAT_WHILE, $2, $4); CHECK_ERROR; }
|
||||||
| tDO tWHILE Expression tNL StatementsNl_opt tLOOP
|
| tDO DoType Expression tNL StatementsNl_opt tLOOP
|
||||||
{ $$ = new_while_statement(ctx, STAT_WHILELOOP, $3, $5); CHECK_ERROR; }
|
{ $$ = new_while_statement(ctx, $2 ? STAT_WHILELOOP : STAT_UNTIL, $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 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; }
|
||||||
|
@ -175,6 +176,10 @@ DimDeclList /* FIXME: Support arrays */
|
||||||
: tIdentifier { $$ = new_dim_decl(ctx, $1, NULL); CHECK_ERROR; }
|
: tIdentifier { $$ = new_dim_decl(ctx, $1, NULL); CHECK_ERROR; }
|
||||||
| tIdentifier ',' DimDeclList { $$ = new_dim_decl(ctx, $1, $3); CHECK_ERROR; }
|
| tIdentifier ',' DimDeclList { $$ = new_dim_decl(ctx, $1, $3); CHECK_ERROR; }
|
||||||
|
|
||||||
|
DoType
|
||||||
|
: tWHILE { $$ = TRUE; }
|
||||||
|
| tUNTIL { $$ = FALSE; }
|
||||||
|
|
||||||
IfStatement
|
IfStatement
|
||||||
: tIF Expression tTHEN tNL StatementsNl ElseIfs_opt Else_opt tEND tIF
|
: tIF Expression tTHEN tNL StatementsNl ElseIfs_opt Else_opt tEND tIF
|
||||||
{ $$ = new_if_statement(ctx, $2, $5, $6, $7); CHECK_ERROR; }
|
{ $$ = new_if_statement(ctx, $2, $5, $6, $7); CHECK_ERROR; }
|
||||||
|
|
|
@ -230,6 +230,24 @@ do while true
|
||||||
ok false, "exit do didn't work"
|
ok false, "exit do didn't work"
|
||||||
loop
|
loop
|
||||||
|
|
||||||
|
x = false
|
||||||
|
y = false
|
||||||
|
do until x and y
|
||||||
|
if x then
|
||||||
|
y = true
|
||||||
|
end if
|
||||||
|
x = true
|
||||||
|
loop
|
||||||
|
call ok((x and y), "x or y is false after do until")
|
||||||
|
|
||||||
|
do until true
|
||||||
|
loop
|
||||||
|
|
||||||
|
do until false
|
||||||
|
exit do
|
||||||
|
ok false, "exit do didn't work"
|
||||||
|
loop
|
||||||
|
|
||||||
if false then
|
if false then
|
||||||
Sub testsub
|
Sub testsub
|
||||||
x = true
|
x = true
|
||||||
|
|
|
@ -167,6 +167,7 @@ typedef enum {
|
||||||
X(imp, 1, 0, 0) \
|
X(imp, 1, 0, 0) \
|
||||||
X(jmp, 0, ARG_ADDR, 0) \
|
X(jmp, 0, ARG_ADDR, 0) \
|
||||||
X(jmp_false, 0, ARG_ADDR, 0) \
|
X(jmp_false, 0, ARG_ADDR, 0) \
|
||||||
|
X(jmp_true, 0, ARG_ADDR, 0) \
|
||||||
X(long, 1, ARG_INT, 0) \
|
X(long, 1, ARG_INT, 0) \
|
||||||
X(mcall, 1, ARG_BSTR, ARG_UINT) \
|
X(mcall, 1, ARG_BSTR, ARG_UINT) \
|
||||||
X(mcallv, 1, ARG_BSTR, ARG_UINT) \
|
X(mcallv, 1, ARG_BSTR, ARG_UINT) \
|
||||||
|
|
Loading…
Reference in New Issue