+static bool create_array_accessors(parser_t *parser, ast_value *var)
+{
+ char name[1024];
+ util_snprintf(name, sizeof(name), "%s##SET", var->name);
+ if (!parser_create_array_setter(parser, var, name))
+ return false;
+ util_snprintf(name, sizeof(name), "%s##GET", var->name);
+ if (!parser_create_array_getter(parser, var, var->expression.next, name))
+ return false;
+ return true;
+}
+
+static bool parse_array(parser_t *parser, ast_value *array)
+{
+ size_t i;
+ if (array->initlist) {
+ parseerror(parser, "array already initialized elsewhere");
+ return false;
+ }
+ if (!parser_next(parser)) {
+ parseerror(parser, "parse error in array initializer");
+ return false;
+ }
+ i = 0;
+ while (parser->tok != '}') {
+ ast_value *v = (ast_value*)parse_expression_leave(parser, true, false, false);
+ if (!v)
+ return false;
+ if (!ast_istype(v, ast_value) || !v->hasvalue || v->cvq != CV_CONST) {
+ ast_unref(v);
+ parseerror(parser, "initializing element must be a compile time constant");
+ return false;
+ }
+ vec_push(array->initlist, v->constval);
+ if (v->expression.vtype == TYPE_STRING) {
+ array->initlist[i].vstring = util_strdupe(array->initlist[i].vstring);
+ ++i;
+ }
+ ast_unref(v);
+ if (parser->tok == '}')
+ break;
+ if (parser->tok != ',' || !parser_next(parser)) {
+ parseerror(parser, "expected comma or '}' in element list");
+ return false;
+ }
+ }
+ if (!parser_next(parser) || parser->tok != ';') {
+ parseerror(parser, "expected semicolon after initializer, got %s");
+ return false;
+ }
+ /*
+ if (!parser_next(parser)) {
+ parseerror(parser, "parse error after initializer");
+ return false;
+ }
+ */
+
+ if (array->expression.flags & AST_FLAG_ARRAY_INIT) {
+ if (array->expression.count != (size_t)-1) {
+ parseerror(parser, "array `%s' has already been initialized with %u elements",
+ array->name, (unsigned)array->expression.count);
+ }
+ array->expression.count = vec_size(array->initlist);
+ if (!create_array_accessors(parser, array))
+ return false;
+ }
+ return true;
+}
+