vbscript: Added const statement compiler implementation.
This commit is contained in:
parent
eb5e97a67f
commit
a968166224
|
@ -46,6 +46,9 @@ typedef struct {
|
|||
dim_decl_t *dim_decls;
|
||||
dynamic_var_t *global_vars;
|
||||
|
||||
const_decl_t *const_decls;
|
||||
const_decl_t *global_consts;
|
||||
|
||||
function_t *func;
|
||||
function_t *funcs;
|
||||
function_decl_t *func_decls;
|
||||
|
@ -302,6 +305,26 @@ static inline void label_set_addr(compile_ctx_t *ctx, unsigned label)
|
|||
ctx->labels[label & ~LABEL_FLAG] = ctx->instr_cnt;
|
||||
}
|
||||
|
||||
static expression_t *lookup_const_decls(compile_ctx_t *ctx, const WCHAR *name, BOOL lookup_global)
|
||||
{
|
||||
const_decl_t *decl;
|
||||
|
||||
for(decl = ctx->const_decls; decl; decl = decl->next) {
|
||||
if(!strcmpiW(decl->name, name))
|
||||
return decl->value_expr;
|
||||
}
|
||||
|
||||
if(!lookup_global)
|
||||
return NULL;
|
||||
|
||||
for(decl = ctx->global_consts; decl; decl = decl->next) {
|
||||
if(!strcmpiW(decl->name, name))
|
||||
return decl->value_expr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HRESULT compile_args(compile_ctx_t *ctx, expression_t *args, unsigned *ret)
|
||||
{
|
||||
unsigned arg_cnt = 0;
|
||||
|
@ -325,6 +348,14 @@ static HRESULT compile_member_expression(compile_ctx_t *ctx, member_expression_t
|
|||
unsigned arg_cnt = 0;
|
||||
HRESULT hres;
|
||||
|
||||
if(ret_val && !expr->args) {
|
||||
expression_t *const_expr;
|
||||
|
||||
const_expr = lookup_const_decls(ctx, expr->identifier, TRUE);
|
||||
if(const_expr)
|
||||
return compile_expression(ctx, const_expr);
|
||||
}
|
||||
|
||||
hres = compile_args(ctx, expr->args, &arg_cnt);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -627,7 +658,8 @@ 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)) {
|
||||
if(lookup_dim_decls(ctx, dim_decl->name) || lookup_args_name(ctx, dim_decl->name)
|
||||
|| lookup_const_decls(ctx, dim_decl->name, FALSE)) {
|
||||
FIXME("dim %s name redefined\n", debugstr_w(dim_decl->name));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
@ -643,6 +675,39 @@ static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
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 compile_function_statement(compile_ctx_t *ctx, function_statement_t *stat)
|
||||
{
|
||||
if(ctx->func != &ctx->code->global_code) {
|
||||
|
@ -712,6 +777,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
|
|||
case STAT_CALL:
|
||||
hres = compile_member_expression(ctx, ((call_statement_t*)stat)->expr, FALSE);
|
||||
break;
|
||||
case STAT_CONST:
|
||||
hres = compile_const_statement(ctx, (const_statement_t*)stat);
|
||||
break;
|
||||
case STAT_DIM:
|
||||
hres = compile_dim_statement(ctx, (dim_statement_t*)stat);
|
||||
break;
|
||||
|
@ -815,6 +883,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
|
|||
|
||||
ctx->func = func;
|
||||
ctx->dim_decls = NULL;
|
||||
ctx->const_decls = NULL;
|
||||
hres = compile_statement(ctx, stat);
|
||||
ctx->func = NULL;
|
||||
if(FAILED(hres))
|
||||
|
@ -893,7 +962,7 @@ static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, functi
|
|||
function_t *func;
|
||||
HRESULT hres;
|
||||
|
||||
if(lookup_dim_decls(ctx, decl->name) || lookup_funcs_name(ctx, decl->name)) {
|
||||
if(lookup_dim_decls(ctx, decl->name) || lookup_funcs_name(ctx, decl->name) || lookup_const_decls(ctx, decl->name, FALSE)) {
|
||||
FIXME("%s: redefinition\n", debugstr_w(decl->name));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
@ -1019,7 +1088,7 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
|
|||
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)) {
|
||||
|| lookup_const_decls(ctx, class_decl->name, FALSE) || lookup_class_name(ctx, class_decl->name)) {
|
||||
FIXME("%s: redefinition\n", debugstr_w(class_decl->name));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
@ -1247,6 +1316,7 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
|
|||
ctx.dim_decls = NULL;
|
||||
ctx.classes = NULL;
|
||||
ctx.labels = NULL;
|
||||
ctx.global_consts = NULL;
|
||||
ctx.labels_cnt = ctx.labels_size = 0;
|
||||
|
||||
hres = compile_func(&ctx, ctx.parser.stats, &ctx.code->global_code);
|
||||
|
@ -1255,6 +1325,8 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
|
|||
return hres;
|
||||
}
|
||||
|
||||
ctx.global_consts = ctx.const_decls;
|
||||
|
||||
for(func_decl = ctx.func_decls; func_decl; func_decl = func_decl->next) {
|
||||
hres = create_function(&ctx, func_decl, &new_func);
|
||||
if(FAILED(hres)) {
|
||||
|
|
|
@ -644,6 +644,13 @@ static HRESULT interp_set_member(exec_ctx_t *ctx)
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT interp_const(exec_ctx_t *ctx)
|
||||
{
|
||||
BSTR arg = ctx->instr->arg1.bstr;
|
||||
FIXME("%s\n", debugstr_w(arg));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT interp_new(exec_ctx_t *ctx)
|
||||
{
|
||||
const WCHAR *arg = ctx->instr->arg1.bstr;
|
||||
|
|
|
@ -184,6 +184,7 @@ typedef enum {
|
|||
X(assign_member, 1, ARG_BSTR, 0) \
|
||||
X(bool, 1, ARG_INT, 0) \
|
||||
X(concat, 1, 0, 0) \
|
||||
X(const, 1, ARG_BSTR, 0) \
|
||||
X(div, 1, 0, 0) \
|
||||
X(double, 1, ARG_DOUBLE, 0) \
|
||||
X(empty, 1, 0, 0) \
|
||||
|
|
Loading…
Reference in New Issue