|
@@ -1702,6 +1702,7 @@ node_t *parse_block(list_t *tokens, size_t *pos) {
|
|
}
|
|
}
|
|
|
|
|
|
#define BLOCK() (CLIFF||MATCH(COLON)?parse_stmt(tokens, pos):parse_block(tokens, pos))
|
|
#define BLOCK() (CLIFF||MATCH(COLON)?parse_stmt(tokens, pos):parse_block(tokens, pos))
|
|
|
|
+#define STMT_OR_BLOCK() (MATCH(COLON)?parse_stmt(tokens, pos):AT(LCB)?parse_block(tokens, pos):parse_stmt(tokens, pos))
|
|
|
|
|
|
node_t *parse_if(list_t *tokens, size_t *pos) {
|
|
node_t *parse_if(list_t *tokens, size_t *pos) {
|
|
node_t *a = parse_expr(tokens, pos);
|
|
node_t *a = parse_expr(tokens, pos);
|
|
@@ -1709,7 +1710,7 @@ node_t *parse_if(list_t *tokens, size_t *pos) {
|
|
node_t *c = NULL;
|
|
node_t *c = NULL;
|
|
|
|
|
|
if (MATCH(ELSE))
|
|
if (MATCH(ELSE))
|
|
- c = BLOCK();
|
|
|
|
|
|
+ c = STMT_OR_BLOCK();
|
|
else if (MATCH(ELIF))
|
|
else if (MATCH(ELIF))
|
|
c = parse_if(tokens, pos);
|
|
c = parse_if(tokens, pos);
|
|
|
|
|
|
@@ -2607,17 +2608,8 @@ void compile_block(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, st
|
|
|
|
|
|
const char *STD[][2] = {
|
|
const char *STD[][2] = {
|
|
{"std",
|
|
{"std",
|
|
- "func exit(c) {\n"
|
|
|
|
- " if type(c) != \"number\"\n"
|
|
|
|
- " throw \"expected first argument to be: number, but got: \" + type(c)\n"
|
|
|
|
- " inline `qi_exit(state, qi_get(state, \"c\")->value.number)`\n"
|
|
|
|
- "}\n"
|
|
|
|
"func head(l): return l[0]\n"
|
|
"func head(l): return l[0]\n"
|
|
- "func tail(l): return slice(l, 1)\n"
|
|
|
|
- "func die(msg, c=1) {\n"
|
|
|
|
- " fputs(STDERR, str(msg) + \"\\n\")\n"
|
|
|
|
- " exit(c)\n"
|
|
|
|
- "}\n"
|
|
|
|
|
|
+ "func tail(l): return slice(l, 1)\n"
|
|
"func min(x, y): x < y? x: y\n"
|
|
"func min(x, y): x < y? x: y\n"
|
|
"func max(x, y): x > y? x: y\n"
|
|
"func max(x, y): x > y? x: y\n"
|
|
"func reverse(x) {\n"
|
|
"func reverse(x) {\n"
|
|
@@ -3265,6 +3257,38 @@ const char *STD[][2] = {
|
|
" inline `return qi_make_boolean(state, qi_thread_main())`\n"
|
|
" inline `return qi_make_boolean(state, qi_thread_main())`\n"
|
|
},
|
|
},
|
|
|
|
|
|
|
|
+ {"os",
|
|
|
|
+ "header `#ifdef _WIN32`\n"
|
|
|
|
+ "include `Windows.h`\n"
|
|
|
|
+ "header `#endif`\n"
|
|
|
|
+ "func getenv(n) {\n"
|
|
|
|
+ " if type(n) != \"string\"\n"
|
|
|
|
+ " throw \"expected first argument to be: string, but got: \" + type(n)\n"
|
|
|
|
+ " inline `char *value = getenv(qi_get(state, \"n\")->value.string)`\n"
|
|
|
|
+ " inline `return value? qi_make_string_copy(state, value): state->nil`\n"
|
|
|
|
+ "}\n"
|
|
|
|
+ "func setenv(n, v) {\n"
|
|
|
|
+ " if type(n) != \"string\"\n"
|
|
|
|
+ " throw \"expected first argument to be: string, but got: \" + type(n)\n"
|
|
|
|
+ " v = str(v)\n"
|
|
|
|
+ " inline \"#ifdef _WIN32\"\n"
|
|
|
|
+ " var s = n + \"=\" + v\n"
|
|
|
|
+ " inline `_putenv(qi_get(state, \"s\")->value.string)`\n"
|
|
|
|
+ " inline \"#else\"\n"
|
|
|
|
+ " inline `setenv(qi_get(state, \"n\")->value.string, qi_get(state, \"v\")->value.string, 1)`\n"
|
|
|
|
+ " inline \"#endif\"\n"
|
|
|
|
+ "}\n"
|
|
|
|
+ "func exit(c) {\n"
|
|
|
|
+ " if type(c) != \"number\"\n"
|
|
|
|
+ " throw \"expected first argument to be: number, but got: \" + type(c)\n"
|
|
|
|
+ " inline `qi_exit(state, qi_get(state, \"c\")->value.number)`\n"
|
|
|
|
+ "}\n"
|
|
|
|
+ "func die(msg, c=1) {\n"
|
|
|
|
+ " fputs(STDERR, str(msg) + \"\\n\")\n"
|
|
|
|
+ " exit(c)\n"
|
|
|
|
+ "}\n"
|
|
|
|
+ },
|
|
|
|
+
|
|
{"string",
|
|
{"string",
|
|
"let STR_LETTERS = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n"
|
|
"let STR_LETTERS = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n"
|
|
"let STR_ASCII_LC = \"abcdefghijklmnopqrstuvwxyz\"\n"
|
|
"let STR_ASCII_LC = \"abcdefghijklmnopqrstuvwxyz\"\n"
|