vbscript: Added parser support for select case statement.
This commit is contained in:
parent
7bcfb02169
commit
119c985cda
|
@ -752,6 +752,12 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT compile_select_statement(compile_ctx_t *ctx, select_statement_t *stat)
|
||||||
|
{
|
||||||
|
FIXME("\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT compile_assignment(compile_ctx_t *ctx, member_expression_t *member_expr, expression_t *value_expr, BOOL is_set)
|
static HRESULT compile_assignment(compile_ctx_t *ctx, member_expression_t *member_expr, expression_t *value_expr, BOOL is_set)
|
||||||
{
|
{
|
||||||
unsigned args_cnt;
|
unsigned args_cnt;
|
||||||
|
@ -1058,6 +1064,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_ctx_t *stat_ctx,
|
||||||
case STAT_ONERROR:
|
case STAT_ONERROR:
|
||||||
hres = compile_onerror_statement(ctx, (onerror_statement_t*)stat);
|
hres = compile_onerror_statement(ctx, (onerror_statement_t*)stat);
|
||||||
break;
|
break;
|
||||||
|
case STAT_SELECT:
|
||||||
|
hres = compile_select_statement(ctx, (select_statement_t*)stat);
|
||||||
|
break;
|
||||||
case STAT_SET:
|
case STAT_SET:
|
||||||
hres = compile_assign_statement(ctx, (assign_statement_t*)stat, TRUE);
|
hres = compile_assign_statement(ctx, (assign_statement_t*)stat, TRUE);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -30,6 +30,7 @@ static const WCHAR andW[] = {'a','n','d',0};
|
||||||
static const WCHAR byrefW[] = {'b','y','r','e','f',0};
|
static const WCHAR byrefW[] = {'b','y','r','e','f',0};
|
||||||
static const WCHAR byvalW[] = {'b','y','v','a','l',0};
|
static const WCHAR byvalW[] = {'b','y','v','a','l',0};
|
||||||
static const WCHAR callW[] = {'c','a','l','l',0};
|
static const WCHAR callW[] = {'c','a','l','l',0};
|
||||||
|
static const WCHAR caseW[] = {'c','a','s','e',0};
|
||||||
static const WCHAR classW[] = {'c','l','a','s','s',0};
|
static const WCHAR classW[] = {'c','l','a','s','s',0};
|
||||||
static const WCHAR constW[] = {'c','o','n','s','t',0};
|
static const WCHAR constW[] = {'c','o','n','s','t',0};
|
||||||
static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
|
static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
|
||||||
|
@ -70,6 +71,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
|
||||||
static const WCHAR publicW[] = {'p','u','b','l','i','c',0};
|
static const WCHAR publicW[] = {'p','u','b','l','i','c',0};
|
||||||
static const WCHAR remW[] = {'r','e','m',0};
|
static const WCHAR remW[] = {'r','e','m',0};
|
||||||
static const WCHAR resumeW[] = {'r','e','s','u','m','e',0};
|
static const WCHAR resumeW[] = {'r','e','s','u','m','e',0};
|
||||||
|
static const WCHAR selectW[] = {'s','e','l','e','c','t',0};
|
||||||
static const WCHAR setW[] = {'s','e','t',0};
|
static const WCHAR setW[] = {'s','e','t',0};
|
||||||
static const WCHAR stepW[] = {'s','t','e','p',0};
|
static const WCHAR stepW[] = {'s','t','e','p',0};
|
||||||
static const WCHAR stopW[] = {'s','t','o','p',0};
|
static const WCHAR stopW[] = {'s','t','o','p',0};
|
||||||
|
@ -90,6 +92,7 @@ static const struct {
|
||||||
{byrefW, tBYREF},
|
{byrefW, tBYREF},
|
||||||
{byvalW, tBYVAL},
|
{byvalW, tBYVAL},
|
||||||
{callW, tCALL},
|
{callW, tCALL},
|
||||||
|
{caseW, tCASE},
|
||||||
{classW, tCLASS},
|
{classW, tCLASS},
|
||||||
{constW, tCONST},
|
{constW, tCONST},
|
||||||
{defaultW, tDEFAULT},
|
{defaultW, tDEFAULT},
|
||||||
|
@ -130,6 +133,7 @@ static const struct {
|
||||||
{publicW, tPUBLIC},
|
{publicW, tPUBLIC},
|
||||||
{remW, tREM},
|
{remW, tREM},
|
||||||
{resumeW, tRESUME},
|
{resumeW, tRESUME},
|
||||||
|
{selectW, tSELECT},
|
||||||
{setW, tSET},
|
{setW, tSET},
|
||||||
{stepW, tSTEP},
|
{stepW, tSTEP},
|
||||||
{stopW, tSTOP},
|
{stopW, tSTOP},
|
||||||
|
|
|
@ -113,6 +113,7 @@ typedef enum {
|
||||||
STAT_FUNC,
|
STAT_FUNC,
|
||||||
STAT_IF,
|
STAT_IF,
|
||||||
STAT_ONERROR,
|
STAT_ONERROR,
|
||||||
|
STAT_SELECT,
|
||||||
STAT_SET,
|
STAT_SET,
|
||||||
STAT_STOP,
|
STAT_STOP,
|
||||||
STAT_UNTIL,
|
STAT_UNTIL,
|
||||||
|
@ -233,6 +234,18 @@ typedef struct {
|
||||||
const_decl_t *decls;
|
const_decl_t *decls;
|
||||||
} const_statement_t;
|
} const_statement_t;
|
||||||
|
|
||||||
|
typedef struct _case_clausule_t {
|
||||||
|
expression_t *expr;
|
||||||
|
statement_t *stat;
|
||||||
|
struct _case_clausule_t *next;
|
||||||
|
} case_clausule_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
statement_t stat;
|
||||||
|
expression_t *expr;
|
||||||
|
case_clausule_t *case_clausules;
|
||||||
|
} select_statement_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const WCHAR *code;
|
const WCHAR *code;
|
||||||
const WCHAR *ptr;
|
const WCHAR *ptr;
|
||||||
|
|
|
@ -58,12 +58,14 @@ static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,el
|
||||||
static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
|
static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
|
||||||
static statement_t *new_onerror_statement(parser_ctx_t*,BOOL);
|
static statement_t *new_onerror_statement(parser_ctx_t*,BOOL);
|
||||||
static statement_t *new_const_statement(parser_ctx_t*,const_decl_t*);
|
static statement_t *new_const_statement(parser_ctx_t*,const_decl_t*);
|
||||||
|
static statement_t *new_select_statement(parser_ctx_t*,expression_t*,case_clausule_t*);
|
||||||
|
|
||||||
static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,dim_decl_t*);
|
static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,dim_decl_t*);
|
||||||
static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
|
static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
|
||||||
static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,unsigned,arg_decl_t*,statement_t*);
|
static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,unsigned,arg_decl_t*,statement_t*);
|
||||||
static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
|
static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
|
||||||
static const_decl_t *new_const_decl(parser_ctx_t*,const WCHAR*,expression_t*);
|
static const_decl_t *new_const_decl(parser_ctx_t*,const WCHAR*,expression_t*);
|
||||||
|
static case_clausule_t *new_case_clausule(parser_ctx_t*,expression_t*,statement_t*,case_clausule_t*);
|
||||||
|
|
||||||
static class_decl_t *new_class_decl(parser_ctx_t*);
|
static class_decl_t *new_class_decl(parser_ctx_t*);
|
||||||
static class_decl_t *add_class_function(parser_ctx_t*,class_decl_t*,function_decl_t*);
|
static class_decl_t *add_class_function(parser_ctx_t*,class_decl_t*,function_decl_t*);
|
||||||
|
@ -94,6 +96,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
|
||||||
arg_decl_t *arg_decl;
|
arg_decl_t *arg_decl;
|
||||||
class_decl_t *class_decl;
|
class_decl_t *class_decl;
|
||||||
const_decl_t *const_decl;
|
const_decl_t *const_decl;
|
||||||
|
case_clausule_t *case_clausule;
|
||||||
unsigned uint;
|
unsigned uint;
|
||||||
LONG lng;
|
LONG lng;
|
||||||
BOOL bool;
|
BOOL bool;
|
||||||
|
@ -107,6 +110,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
|
||||||
%token tCALL tDIM tSUB tFUNCTION tPROPERTY tGET tLET tCONST
|
%token tCALL tDIM tSUB tFUNCTION tPROPERTY tGET tLET tCONST
|
||||||
%token tIF tELSE tELSEIF tEND tTHEN tEXIT
|
%token tIF tELSE tELSEIF tEND tTHEN tEXIT
|
||||||
%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tSTEP tEACH tIN
|
%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tSTEP tEACH tIN
|
||||||
|
%token tSELECT tCASE
|
||||||
%token tBYREF tBYVAL
|
%token tBYREF tBYVAL
|
||||||
%token tOPTION tEXPLICIT
|
%token tOPTION tEXPLICIT
|
||||||
%token tSTOP
|
%token tSTOP
|
||||||
|
@ -122,7 +126,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
|
||||||
%type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
|
%type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
|
||||||
%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 Step_opt
|
%type <expression> Arguments_opt ArgumentList_opt Step_opt ExpressionList
|
||||||
%type <bool> OptionExplicit_opt DoType
|
%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
|
||||||
|
@ -132,6 +136,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
|
||||||
%type <dim_decl> DimDeclList
|
%type <dim_decl> DimDeclList
|
||||||
%type <const_decl> ConstDecl ConstDeclList
|
%type <const_decl> ConstDecl ConstDeclList
|
||||||
%type <string> Identifier
|
%type <string> Identifier
|
||||||
|
%type <case_clausule> CaseClausules
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
@ -196,6 +201,8 @@ SimpleStatement
|
||||||
{ $$ = new_forto_statement(ctx, $2, $4, $6, $7, $9); CHECK_ERROR; }
|
{ $$ = new_forto_statement(ctx, $2, $4, $6, $7, $9); CHECK_ERROR; }
|
||||||
| tFOR tEACH Identifier tIN Expression tNL StatementsNl_opt tNEXT
|
| tFOR tEACH Identifier tIN Expression tNL StatementsNl_opt tNEXT
|
||||||
{ $$ = new_foreach_statement(ctx, $3, $5, $7); }
|
{ $$ = new_foreach_statement(ctx, $3, $5, $7); }
|
||||||
|
| tSELECT tCASE Expression tNL CaseClausules tEND tSELECT
|
||||||
|
{ $$ = new_select_statement(ctx, $3, $5); }
|
||||||
|
|
||||||
MemberExpression
|
MemberExpression
|
||||||
: Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
|
: Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
|
||||||
|
@ -247,22 +254,28 @@ Else_opt
|
||||||
: /* empty */ { $$ = NULL; }
|
: /* empty */ { $$ = NULL; }
|
||||||
| tELSE tNL StatementsNl { $$ = $3; }
|
| tELSE tNL StatementsNl { $$ = $3; }
|
||||||
|
|
||||||
|
CaseClausules
|
||||||
|
: /* empty */ { $$ = NULL; }
|
||||||
|
| tCASE tELSE tNL StatementsNl { $$ = new_case_clausule(ctx, NULL, $4, NULL); }
|
||||||
|
| tCASE ExpressionList tNL StatementsNl_opt CaseClausules
|
||||||
|
{ $$ = new_case_clausule(ctx, $2, $4, $5); }
|
||||||
|
|
||||||
Arguments_opt
|
Arguments_opt
|
||||||
: EmptyBrackets_opt { $$ = NULL; }
|
: EmptyBrackets_opt { $$ = NULL; }
|
||||||
| '(' ArgumentList ')' { $$ = $2; }
|
| '(' ExpressionList ')' { $$ = $2; }
|
||||||
|
|
||||||
ArgumentList_opt
|
ArgumentList_opt
|
||||||
: EmptyBrackets_opt { $$ = NULL; }
|
: EmptyBrackets_opt { $$ = NULL; }
|
||||||
| ArgumentList { $$ = $1; }
|
| ExpressionList { $$ = $1; }
|
||||||
|
|
||||||
ArgumentList
|
|
||||||
: Expression { $$ = $1; }
|
|
||||||
| Expression ',' ArgumentList { $1->next = $3; $$ = $1; }
|
|
||||||
|
|
||||||
EmptyBrackets_opt
|
EmptyBrackets_opt
|
||||||
: /* empty */
|
: /* empty */
|
||||||
| tEMPTYBRACKETS
|
| tEMPTYBRACKETS
|
||||||
|
|
||||||
|
ExpressionList
|
||||||
|
: Expression { $$ = $1; }
|
||||||
|
| Expression ',' ExpressionList { $1->next = $3; $$ = $1; }
|
||||||
|
|
||||||
Expression
|
Expression
|
||||||
: EqvExpression { $$ = $1; }
|
: EqvExpression { $$ = $1; }
|
||||||
| Expression tIMP EqvExpression { $$ = new_binary_expression(ctx, EXPR_IMP, $1, $3); CHECK_ERROR; }
|
| Expression tIMP EqvExpression { $$ = new_binary_expression(ctx, EXPR_IMP, $1, $3); CHECK_ERROR; }
|
||||||
|
@ -697,6 +710,33 @@ static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, stat
|
||||||
return &stat->stat;
|
return &stat->stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static statement_t *new_select_statement(parser_ctx_t *ctx, expression_t *expr, case_clausule_t *case_clausules)
|
||||||
|
{
|
||||||
|
select_statement_t *stat;
|
||||||
|
|
||||||
|
stat = new_statement(ctx, STAT_SELECT, sizeof(*stat));
|
||||||
|
if(!stat)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
stat->expr = expr;
|
||||||
|
stat->case_clausules = case_clausules;
|
||||||
|
return &stat->stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, expression_t *expr, statement_t *stat, case_clausule_t *next)
|
||||||
|
{
|
||||||
|
case_clausule_t *ret;
|
||||||
|
|
||||||
|
ret = parser_alloc(ctx, sizeof(*ret));
|
||||||
|
if(!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ret->expr = expr;
|
||||||
|
ret->stat = stat;
|
||||||
|
ret->next = next;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static statement_t *new_onerror_statement(parser_ctx_t *ctx, BOOL resume_next)
|
static statement_t *new_onerror_statement(parser_ctx_t *ctx, BOOL resume_next)
|
||||||
{
|
{
|
||||||
onerror_statement_t *stat;
|
onerror_statement_t *stat;
|
||||||
|
|
Loading…
Reference in New Issue