|
@@ -2066,19 +2066,37 @@ const char *STD[][2] = {
|
|
"func frewind(file)\n"
|
|
"func frewind(file)\n"
|
|
" return file.rewind()\n"
|
|
" return file.rewind()\n"
|
|
"func file_read(filename) {\n"
|
|
"func file_read(filename) {\n"
|
|
- " var file = fopen(filename, \"r\")\n"
|
|
|
|
|
|
+ " let file = fopen(filename, \"r\")\n"
|
|
" defer fclose(file)\n"
|
|
" defer fclose(file)\n"
|
|
" fseek(file, 0, SEEK_END)\n"
|
|
" fseek(file, 0, SEEK_END)\n"
|
|
" let size = ftell(file)\n"
|
|
" let size = ftell(file)\n"
|
|
" frewind(file)\n"
|
|
" frewind(file)\n"
|
|
" return str(fread(file, size))\n"
|
|
" return str(fread(file, size))\n"
|
|
"}\n"
|
|
"}\n"
|
|
|
|
+ "func file_write(filename, data) {\n"
|
|
|
|
+ " let file = fopen(filename, \"w\")\n"
|
|
|
|
+ " defer fclose(file)\n"
|
|
|
|
+ " fwrite(file, bytes(data))\n"
|
|
|
|
+ "}\n"
|
|
"func is_defined(name) {\n"
|
|
"func is_defined(name) {\n"
|
|
" if type(name) != \"string\"\n"
|
|
" if type(name) != \"string\"\n"
|
|
" throw \"expected first argument to be: string, but got: \" + type(name)\n"
|
|
" throw \"expected first argument to be: string, but got: \" + type(name)\n"
|
|
" inline `bool b = qi_find(state, qi_get(state, \"name\")->value.string) != NULL`\n"
|
|
" inline `bool b = qi_find(state, qi_get(state, \"name\")->value.string) != NULL`\n"
|
|
" inline `return qi_make_boolean(state, b)`\n"
|
|
" inline `return qi_make_boolean(state, b)`\n"
|
|
"}\n"
|
|
"}\n"
|
|
|
|
+ "func list_remove(l, x, first=false) {\n"
|
|
|
|
+ " if type(l) != \"list\"\n"
|
|
|
|
+ " throw \"expected first argument to be: list, but got: \" + type(l)\n"
|
|
|
|
+ " repeat:\n"
|
|
|
|
+ " for var i = 0; i < len(l); i++\n"
|
|
|
|
+ " if l[i] == x {\n"
|
|
|
|
+ " list_delete(l, i)\n"
|
|
|
|
+ " if first\n"
|
|
|
|
+ " break\n"
|
|
|
|
+ " goto repeat\n"
|
|
|
|
+ " }\n"
|
|
|
|
+ "}\n"
|
|
|
|
+ "set_pseudomethod(\"list.remove\", list_remove)\n"
|
|
},
|
|
},
|
|
|
|
|
|
{"str",
|
|
{"str",
|
|
@@ -2362,12 +2380,16 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
|
|
LPUSH(gid);
|
|
LPUSH(gid);
|
|
CTXPUSH("for");
|
|
CTXPUSH("for");
|
|
compile_node(gbuf, buf, ctx, lstk, lbl, node->d);
|
|
compile_node(gbuf, buf, ctx, lstk, lbl, node->d);
|
|
- CTXPOP();
|
|
|
|
- LPOP();
|
|
|
|
|
|
|
|
- if (node->c)
|
|
|
|
|
|
+ if (node->c) {
|
|
compile_node(gbuf, buf, ctx, lstk, lbl, node->c);
|
|
compile_node(gbuf, buf, ctx, lstk, lbl, node->c);
|
|
|
|
|
|
|
|
+ EMIT(";\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ CTXPOP();
|
|
|
|
+ LPOP();
|
|
|
|
+
|
|
EMIT("__continue%d:;\n", gid);
|
|
EMIT("__continue%d:;\n", gid);
|
|
EMIT("}\n");
|
|
EMIT("}\n");
|
|
|
|
|
|
@@ -2608,6 +2630,14 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
|
|
BINOP("band");
|
|
BINOP("band");
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
+ case N_LOGOR:
|
|
|
|
+ BINOP("or");
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case N_LOGAND:
|
|
|
|
+ BINOP("and");
|
|
|
|
+ break;
|
|
|
|
+
|
|
case N_NEGATE:
|
|
case N_NEGATE:
|
|
UNOP("negate");
|
|
UNOP("negate");
|
|
break;
|
|
break;
|