return FALSE;
}
+static BOOL lookup_args_name(compile_ctx_t *ctx, const WCHAR *name)
+{
+ unsigned i;
+
+ for(i = 0; i < ctx->func->arg_cnt; i++) {
+ if(!strcmpiW(ctx->func->args[i].name, name))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
{
dim_decl_t *dim_decl = stat->dim_decls;
while(1) {
- if(lookup_dim_decls(ctx, dim_decl->name)) {
+ if(lookup_dim_decls(ctx, dim_decl->name) || lookup_args_name(ctx, dim_decl->name)) {
FIXME("dim %s name redefined\n", debugstr_w(dim_decl->name));
return E_FAIL;
}
dim_decl->next = ctx->dim_decls;
ctx->dim_decls = stat->dim_decls;
+ ctx->func->var_cnt++;
return S_OK;
}
resolve_labels(ctx, func->code_off);
- if(ctx->dim_decls) {
+ if(func->var_cnt) {
dim_decl_t *dim_decl;
if(func->type == FUNC_GLOBAL) {
dynamic_var_t *new_var;
+ func->var_cnt = 0;
+
for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
new_var = compiler_alloc(ctx->code, sizeof(*new_var));
if(!new_var)
ctx->global_vars = new_var;
}
}else {
- FIXME("var not implemented for functions\n");
+ unsigned i;
+
+ func->vars = compiler_alloc(ctx->code, func->var_cnt * sizeof(var_desc_t));
+ if(!func->vars)
+ return E_OUTOFMEMORY;
+
+ for(dim_decl = ctx->dim_decls, i=0; dim_decl; dim_decl = dim_decl->next, i++) {
+ func->vars[i].name = compiler_alloc_string(ctx->code, dim_decl->name);
+ if(!func->vars[i].name)
+ return E_OUTOFMEMORY;
+ }
+
+ assert(i == func->var_cnt);
}
}
if(!func->name)
return E_OUTOFMEMORY;
+ func->vars = NULL;
+ func->var_cnt = 0;
func->code_ctx = ctx->code;
func->type = decl->type;
ret->global_code.type = FUNC_GLOBAL;
ret->global_code.name = NULL;
ret->global_code.code_ctx = ret;
+ ret->global_code.vars = NULL;
+ ret->global_code.var_cnt = 0;
ret->global_code.arg_cnt = 0;
ret->global_code.args = NULL;
function_t *func;
VARIANT *args;
+ VARIANT *vars;
unsigned stack_size;
unsigned top;
DISPID id;
HRESULT hres;
+ for(i=0; i < ctx->func->var_cnt; i++) {
+ if(!strcmpiW(ctx->func->vars[i].name, name)) {
+ ref->type = REF_VAR;
+ ref->u.v = ctx->vars+i;
+ return TRUE;
+ }
+ }
+
for(i=0; i < ctx->func->arg_cnt; i++) {
if(!strcmpiW(ctx->func->args[i].name, name)) {
ref->type = REF_VAR;
static void release_exec(exec_ctx_t *ctx)
{
- if(ctx->args) {
- unsigned i;
+ unsigned i;
+ if(ctx->args) {
for(i=0; i < ctx->func->arg_cnt; i++)
VariantClear(ctx->args+i);
}
+ if(ctx->vars) {
+ for(i=0; i < ctx->func->var_cnt; i++)
+ VariantClear(ctx->vars+i);
+ }
+
heap_free(ctx->args);
+ heap_free(ctx->vars);
heap_free(ctx->stack);
}
exec.args = NULL;
}
+ if(func->var_cnt) {
+ exec.vars = heap_alloc_zero(func->var_cnt * sizeof(VARIANT));
+ if(!exec.vars) {
+ release_exec(&exec);
+ return E_OUTOFMEMORY;
+ }
+ }else {
+ exec.vars = NULL;
+ }
+
exec.stack_size = 16;
exec.top = 0;
exec.stack = heap_alloc(exec.stack_size * sizeof(VARIANT));
TestSubMultiArgs 1, 2, 3, 4, 5
Call TestSubMultiArgs(1, 2, 3, 4, 5)
+Sub TestSubLocalVal
+ x = false
+ Call ok(not x, "local x is not false?")
+ Dim x
+End Sub
+
+x = true
+y = true
+Call TestSubLocalVal
+Call ok(x, "global x is not true?")
+
reportSuccess()