}
else if (parser->tok == TOKEN_KEYWORD)
{
- if (!strcmp(parser_tokval(parser), "local"))
+ if (!strcmp(parser_tokval(parser), "local") ||
+ !strcmp(parser_tokval(parser), "const"))
{
+ int cvq = parser_tokval(parser)[0] == 'c' ? CV_CONST : CV_VAR;
+
if (!block) {
parseerror(parser, "cannot declare a local variable here");
return false;
parseerror(parser, "expected variable declaration");
return false;
}
- if (!parse_variable(parser, block, true, CV_VAR, NULL))
+ if (!parse_variable(parser, block, true, cvq, NULL))
return false;
*out = NULL;
return true;
*out = (ast_expression*)inner;
return true;
}
+ else if (parser->tok == ':')
+ {
+ ast_label *label;
+ if (!parser_next(parser)) {
+ parseerror(parser, "expected label name");
+ return false;
+ }
+ if (parser->tok != TOKEN_IDENT) {
+ parseerror(parser, "label must be an identifier");
+ return false;
+ }
+ label = ast_label_new(parser_ctx(parser), parser_tokval(parser));
+ if (!label)
+ return false;
+ *out = (ast_expression*)label;
+ if (!parser_next(parser)) {
+ parseerror(parser, "parse error after label");
+ return false;
+ }
+ return true;
+ }
else if (parser->tok == ';')
{
if (!parser_next(parser)) {
ast_unref(cval);
}
} else {
+ bool cvq;
shunt sy = { NULL, NULL };
+ cvq = var->constant;
+ var->constant = false;
vec_push(sy.out, syexp(ast_ctx(var), (ast_expression*)var));
vec_push(sy.out, syexp(ast_ctx(cexp), (ast_expression*)cexp));
vec_push(sy.ops, syop(ast_ctx(var), parser->assign_op));
}
vec_free(sy.out);
vec_free(sy.ops);
+ var->constant = cvq;
}
}