static HRESULT compile_const_statement(compile_ctx_t *ctx, const_statement_t *stat) { const_decl_t *decl, *next_decl = stat->decls; do { decl = next_decl; if(lookup_const_decls(ctx, decl->name, FALSE) || lookup_args_name(ctx, decl->name) || lookup_dim_decls(ctx, decl->name)) { FIXME("%s redefined\n", debugstr_w(decl->name)); return E_FAIL; } if(ctx->func->type == FUNC_GLOBAL) { HRESULT hres; hres = compile_expression(ctx, decl->value_expr); if(FAILED(hres)) return hres; hres = push_instr_bstr(ctx, OP_const, decl->name); if(FAILED(hres)) return hres; } next_decl = decl->next; decl->next = ctx->const_decls; ctx->const_decls = decl; } while(next_decl); return S_OK; }
static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, function_t **ret) { function_t *func; HRESULT hres; if(lookup_dim_decls(ctx, decl->name) || lookup_funcs_name(ctx, decl->name)) { FIXME("%s: redefinition\n", debugstr_w(decl->name)); return E_FAIL; } func = compiler_alloc(ctx->code, sizeof(*func)); if(!func) return E_OUTOFMEMORY; func->name = compiler_alloc_string(ctx->code, decl->name); if(!func->name) return E_OUTOFMEMORY; func->vars = NULL; func->var_cnt = 0; func->code_ctx = ctx->code; func->type = decl->type; func->is_public = decl->is_public; func->arg_cnt = 0; if(decl->args) { arg_decl_t *arg; unsigned i; for(arg = decl->args; arg; arg = arg->next) func->arg_cnt++; func->args = compiler_alloc(ctx->code, func->arg_cnt * sizeof(arg_desc_t)); if(!func->args) return E_OUTOFMEMORY; for(i = 0, arg = decl->args; arg; arg = arg->next, i++) { func->args[i].name = compiler_alloc_string(ctx->code, arg->name); if(!func->args[i].name) return E_OUTOFMEMORY; func->args[i].by_ref = arg->by_ref; } }else { func->args = NULL; } hres = compile_func(ctx, decl->body, func); if(FAILED(hres)) return hres; *ret = func; return S_OK; }
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) || lookup_args_name(ctx, dim_decl->name)) { FIXME("dim %s name redefined\n", debugstr_w(dim_decl->name)); return E_FAIL; } if(!dim_decl->next) break; dim_decl = dim_decl->next; } dim_decl->next = ctx->dim_decls; ctx->dim_decls = stat->dim_decls; ctx->func->var_cnt++; return S_OK; }
static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl) { function_decl_t *func_decl, *func_prop_decl; class_prop_decl_t *prop_decl; class_desc_t *class_desc; unsigned i; HRESULT hres; static const WCHAR class_initializeW[] = {'c','l','a','s','s','_','i','n','i','t','i','a','l','i','z','e',0}; static const WCHAR class_terminateW[] = {'c','l','a','s','s','_','t','e','r','m','i','n','a','t','e',0}; if(lookup_dim_decls(ctx, class_decl->name) || lookup_funcs_name(ctx, class_decl->name) || lookup_class_name(ctx, class_decl->name)) { FIXME("%s: redefinition\n", debugstr_w(class_decl->name)); return E_FAIL; } class_desc = compiler_alloc_zero(ctx->code, sizeof(*class_desc)); if(!class_desc) return E_OUTOFMEMORY; class_desc->name = compiler_alloc_string(ctx->code, class_decl->name); if(!class_desc->name) return E_OUTOFMEMORY; class_desc->func_cnt = 1; /* always allocate slot for default getter */ for(func_decl = class_decl->funcs; func_decl; func_decl = func_decl->next) { for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) { if(func_prop_decl->type == FUNC_DEFGET) break; } if(!func_prop_decl) class_desc->func_cnt++; } class_desc->funcs = compiler_alloc(ctx->code, class_desc->func_cnt*sizeof(*class_desc->funcs)); if(!class_desc->funcs) return E_OUTOFMEMORY; memset(class_desc->funcs, 0, class_desc->func_cnt*sizeof(*class_desc->funcs)); for(func_decl = class_decl->funcs, i=1; func_decl; func_decl = func_decl->next, i++) { for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) { if(func_prop_decl->type == FUNC_DEFGET) { i--; break; } } if(!strcmpiW(class_initializeW, func_decl->name)) { if(func_decl->type != FUNC_SUB) { FIXME("class initializer is not sub\n"); return E_FAIL; } class_desc->class_initialize_id = i; }else if(!strcmpiW(class_terminateW, func_decl->name)) { if(func_decl->type != FUNC_SUB) { FIXME("class terminator is not sub\n"); return E_FAIL; } class_desc->class_terminate_id = i; } hres = create_class_funcprop(ctx, func_decl, class_desc->funcs + (func_prop_decl ? 0 : i)); if(FAILED(hres)) return hres; } for(prop_decl = class_decl->props; prop_decl; prop_decl = prop_decl->next) class_desc->prop_cnt++; class_desc->props = compiler_alloc(ctx->code, class_desc->prop_cnt*sizeof(*class_desc->props)); if(!class_desc->props) return E_OUTOFMEMORY; for(prop_decl = class_decl->props, i=0; prop_decl; prop_decl = prop_decl->next, i++) { if(lookup_class_funcs(class_desc, prop_decl->name)) { FIXME("Property %s redefined\n", debugstr_w(prop_decl->name)); return E_FAIL; } class_desc->props[i].name = compiler_alloc_string(ctx->code, prop_decl->name); if(!class_desc->props[i].name) return E_OUTOFMEMORY; class_desc->props[i].is_public = prop_decl->is_public; } class_desc->next = ctx->classes; ctx->classes = class_desc; return S_OK; }