|
@@ -2174,19 +2174,35 @@ node_t *parse_stmt(list_t *tokens, size_t *pos) {
|
|
|
list_t *triples = list_new();
|
|
|
|
|
|
for (;;) {
|
|
|
- if (!AT(NAME))
|
|
|
+ int is_out = 0;
|
|
|
+ int is_static = 0;
|
|
|
+
|
|
|
+ if (AT(RCB))
|
|
|
break;
|
|
|
|
|
|
+ if (MATCH(LET))
|
|
|
+ is_out = 1;
|
|
|
+ else if (MATCH(CONST))
|
|
|
+ is_static = 1;
|
|
|
+
|
|
|
+ if (!AT(NAME))
|
|
|
+ PARSE_ERROR("expected identifier");
|
|
|
+
|
|
|
list_t *triple = list_new();
|
|
|
|
|
|
token_t *t = tokens->data[(*pos)++];
|
|
|
list_push(triple, t);
|
|
|
|
|
|
+ int *flagp = malloc(sizeof(int));
|
|
|
+ int flag = is_static? 2: is_out? 1: 0;
|
|
|
+
|
|
|
+ memcpy(flagp, &flag, sizeof(int));
|
|
|
+
|
|
|
if (MATCH(ASSIGN)) {
|
|
|
- list_push(triple, t);
|
|
|
+ list_push(triple, flagp);
|
|
|
list_push(triple, parse_expr(tokens, pos));
|
|
|
} else {
|
|
|
- list_push(triple, NULL);
|
|
|
+ list_push(triple, flagp);
|
|
|
list_push(triple, parse_func(tokens, pos, 1));
|
|
|
}
|
|
|
|
|
@@ -2596,27 +2612,37 @@ void compile_block(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, st
|
|
|
|
|
|
buffer_fmt(tbuf, "qi_table_t *table = qi_table_make();\n");
|
|
|
buffer_fmt(tbuf, "qi_table_t *metatable = qi_table_make();\n");
|
|
|
+ buffer_fmt(tbuf, "qi_table_t *statictable = qi_table_make();\n");
|
|
|
|
|
|
for (size_t i = 0; i < triples->length; i++) {
|
|
|
list_t *triple = triples->data[i];
|
|
|
token_t *t = triple->data[0];
|
|
|
+ int flag = *(int *)triple->data[1];
|
|
|
+
|
|
|
+ if (flag == 0) {
|
|
|
+ buffer_fmt(tbuf, "qi_table_set(metatable, \"%s\", ", t->text);
|
|
|
|
|
|
- buffer_t *methodname = buffer_new();
|
|
|
- buffer_fmt(methodname, "%s.%s", name, t->text);
|
|
|
+ if (((node_t *)triple->data[2])->tag == N_FUNCEXPR) {
|
|
|
+ buffer_t *methodname = buffer_new();
|
|
|
+ buffer_fmt(methodname, "%s.%s", name, t->text);
|
|
|
+
|
|
|
+ compile_func(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, triple->data[2], buffer_read(methodname));
|
|
|
+ } else compile_node(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, triple->data[2]);
|
|
|
+ } else {
|
|
|
+ buffer_fmt(tbuf, "qi_table_set(%s, \"%s\", ", flag == 1? "table": "statictable", t->text);
|
|
|
|
|
|
- buffer_fmt(tbuf, "qi_table_set(%s, \"%s\", ", triple->data[1] != NULL? "table": "metatable", t->text);
|
|
|
- if (triple->data[1] == NULL)
|
|
|
- compile_func(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, triple->data[2], buffer_read(methodname));
|
|
|
- else
|
|
|
compile_node(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, triple->data[2]);
|
|
|
+ }
|
|
|
+
|
|
|
buffer_fmt(tbuf, ");\n");
|
|
|
}
|
|
|
|
|
|
- buffer_fmt(tbuf, "qi_list_t *pargs = qi_list_make_n(4);\n");
|
|
|
+ buffer_fmt(tbuf, "qi_list_t *pargs = qi_list_make_n(5);\n");
|
|
|
buffer_fmt(tbuf, "qi_list_data(pargs, 0) = qi_make_string(state, \"%s\");\n", name);
|
|
|
buffer_fmt(tbuf, "qi_list_data(pargs, 1) = qi_make_list(state, supers);\n");
|
|
|
buffer_fmt(tbuf, "qi_list_data(pargs, 2) = qi_make_table(state, table);\n");
|
|
|
buffer_fmt(tbuf, "qi_list_data(pargs, 3) = qi_make_table(state, metatable);\n");
|
|
|
+ buffer_fmt(tbuf, "qi_list_data(pargs, 4) = qi_make_table(state, statictable);\n");
|
|
|
|
|
|
buffer_fmt(tbuf, "return qi_call(state, qi_get(state, \"__class_wrapper\"), pargs);\n");
|
|
|
buffer_fmt(tbuf, "}\n");
|
|
@@ -3069,7 +3095,7 @@ const char *STD[][2] = {
|
|
|
"set_pseudomethod(\"string.tolower\", str_tolower)\n"
|
|
|
"func Object(t, p=nil): return p !is nil? set_meta_table(p, get_meta_table(p) + t): set_meta_table({}, t)\n"
|
|
|
"func is_object(o): return has_meta_table(o)\n"
|
|
|
- "func __class_wrapper(n, p, t, mt): return Object({\n"
|
|
|
+ "func __class_wrapper(n, p, t, mt, st): return Object(st + {\n"
|
|
|
" t: t,\n"
|
|
|
" mt: mt,\n"
|
|
|
" super: [],\n"
|