Commit d04ba41a authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

vbscript: Added exit sub statement implementation.

parent 1936dd7e
......@@ -38,6 +38,8 @@ typedef struct {
unsigned labels_size;
unsigned labels_cnt;
unsigned sub_end_label;
dim_decl_t *dim_decls;
dynamic_var_t *global_vars;
......@@ -530,6 +532,16 @@ static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement
return S_OK;
}
static HRESULT compile_exitsub_statement(compile_ctx_t *ctx)
{
if(ctx->sub_end_label == -1) {
FIXME("Exit Sub outside Sub?\n");
return E_FAIL;
}
return push_instr_addr(ctx, OP_jmp, ctx->sub_end_label);
}
static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
{
HRESULT hres;
......@@ -545,6 +557,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
case STAT_DIM:
hres = compile_dim_statement(ctx, (dim_statement_t*)stat);
break;
case STAT_EXITSUB:
hres = compile_exitsub_statement(ctx);
break;
case STAT_FUNC:
hres = compile_function_statement(ctx, (function_statement_t*)stat);
break;
......@@ -585,6 +600,18 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
func->code_off = ctx->instr_cnt;
ctx->sub_end_label = -1;
switch(func->type) {
case FUNC_SUB:
ctx->sub_end_label = alloc_label(ctx);
if(ctx->sub_end_label == -1)
return E_OUTOFMEMORY;
break;
case FUNC_GLOBAL:
break;
}
ctx->func = func;
ctx->dim_decls = NULL;
hres = compile_statement(ctx, stat);
......@@ -592,6 +619,9 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
if(FAILED(hres))
return hres;
if(ctx->sub_end_label != -1)
label_set_addr(ctx, ctx->sub_end_label);
if(push_instr(ctx, OP_ret) == -1)
return E_OUTOFMEMORY;
......
......@@ -86,6 +86,7 @@ typedef enum {
STAT_ASSIGN,
STAT_CALL,
STAT_DIM,
STAT_EXITSUB,
STAT_FUNC,
STAT_IF
} statement_type_t;
......
......@@ -45,6 +45,7 @@ static expression_t *new_binary_expression(parser_ctx_t*,expression_type_t,expre
static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,const WCHAR*);
static void *new_statement(parser_ctx_t*,statement_type_t,size_t);
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_dim_statement(parser_ctx_t*,dim_decl_t*);
......@@ -138,6 +139,7 @@ Statement
| tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
| IfStatement { $$ = $1; }
| FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
| tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; }
MemberExpression
: tIdentifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
......@@ -388,11 +390,11 @@ static member_expression_t *new_member_expression(parser_ctx_t *ctx, expression_
return expr;
}
static void *new_statement(parser_ctx_t *ctx, statement_type_t type, unsigned size)
static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size)
{
statement_t *stat;
stat = parser_alloc(ctx, size);
stat = parser_alloc(ctx, size ? size : sizeof(*stat));
if(stat) {
stat->type = type;
stat->next = NULL;
......
......@@ -218,6 +218,15 @@ Sub TestSubMultiArgs(a,b,c,d,e)
Call ok(e=5, "e = " & e)
End Sub
Sub TestSubExit(ByRef a)
If a Then
Exit Sub
End If
Call ok(false, "Exit Sub not called?")
End Sub
Call TestSubExit(true)
TestSubMultiArgs 1, 2, 3, 4, 5
Call TestSubMultiArgs(1, 2, 3, 4, 5)
......
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