txlyre 3 долоо хоног өмнө
parent
commit
4ae13fd91a
1 өөрчлөгдсөн 265 нэмэгдсэн , 11 устгасан
  1. 265 11
      qic.c

+ 265 - 11
qic.c

@@ -229,13 +229,7 @@ buffer_t *buffer_new(void) {
 
 void buffer_append(buffer_t *buf, char c) {
   buf->size++;
-
-  void *p = malloc(sizeof(char) * buf->size);
-  if (buf->str)
-    memcpy(p, buf->str, buf->size - 1);
-
-  buf->str = p;
-
+  buf->str = realloc(buf->str, sizeof(char) * buf->size);
   buf->str[buf->size - 1] = c;
 }
 
@@ -2203,11 +2197,11 @@ void compile_func(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
       if (pair->data[1]) {
         optargc++;
 
-        buffer_fmt(tbuf, "qi_set(state, false, \"%s\", pargc >= %d? qi_list_index(pargs, %d): ", entry.key, argc+1, argc);
+        buffer_fmt(tbuf, "qi_decl(state, \"%s\", pargc >= %d? qi_list_index(pargs, %d): ", entry.key, argc+1, argc);
         compile_node(gbuf, tbuf, ctx, lstk, lbl, pair->data[1]);
         buffer_fmt(tbuf, ");\n");
       } else
-        buffer_fmt(tbuf, "qi_set(state, false, \"%s\", qi_list_index(pargs, %d));\n", entry.key, argc);
+        buffer_fmt(tbuf, "qi_decl(state, \"%s\", qi_list_index(pargs, %d));\n", entry.key, argc);
 
       argc++;
     });
@@ -2460,6 +2454,43 @@ const char *STD[][2] = {
     "  return x\n"
     "}\n"
     "set_pseudomethod(\"list.popAt\", list_pop_at)\n"
+    "func list_sort(l, cmp=func (x, y): x > y) {\n"
+    "  if type(l) != \"list\"\n"
+    "    throw \"expected first argument to be: list, but got: \" + type(l)\n"
+    "  if type(cmp) != \"function\"\n"
+    "    throw \"expected second argument to be: function, but got: \" + type(cmp)\n"
+    "  if len(l) == 0\n"
+    "    return l\n"
+    "  var z = len(l)\n"
+    "  for var i = 0; i < z - 1; i++\n"
+    "    for var j = 0; j < z - 1 - i; j++\n"
+    "      if cmp(l[j], l[j+1]) {\n"
+    "        let tmp = l[j]\n"
+    "        l[j] = l[j+1]\n"
+    "        l[j+1] = tmp\n"
+    "      }\n"
+    "  return l\n"
+    "}\n"
+    "func list_sorted(l, cmp=func (x, y): x > y) {\n"
+    "  l = list_copy(l)\n"
+    "  return list_sort(l, cmp)\n"
+    "}\n"
+    "set_pseudomethod(\"list.sort\", list_sort)\n"
+    "set_pseudomethod(\"list.sorted\", list_sorted)\n"
+    "func list_shift(l) {\n"
+    "  if type(l) != \"list\"\n"
+    "    throw \"expected first argument to be: list, but got: \" + type(l)\n"
+    "  if is_empty(l)\n"
+    "    throw \"shift from empty list\"\n"
+    "  var a = l[0]\n"
+    "  list_delete(l, 0)\n"
+    "  return a\n"
+    "}\n"
+    "func list_unshift(l, x) {\n"
+    "  list_insert(l, 0, x)\n"
+    "}\n"
+    "set_pseudomethod(\"list.shift\", list_shift)\n"
+    "set_pseudomethod(\"list.unshift\", list_unshift)\n"
     "func slice(l) {\n"
     "  if type(l) !in (\"list\", \"string\", \"bytes\")\n"
     "    throw \"expected first argument to be: list, string or bytes, but got: \" + type(l)\n"
@@ -2488,6 +2519,221 @@ const char *STD[][2] = {
     "set_pseudomethod(\"list.slice\", slice)\n"
     "set_pseudomethod(\"string.slice\", slice)\n"
     "set_pseudomethod(\"bytes.slice\", slice)\n"
+    "func str_startswith(s, p) {\n"
+    "  if type(s) != \"string\"\n"
+    "    throw \"expected first argument to be: string, but got: \" + type(s)\n"
+    "  if len(s) < len(p)\n"
+    "    return false\n"
+    "  return slice(s, 0, len(p)-1) == p\n"
+    "}\n"
+    "set_pseudomethod(\"string.startsWith\", str_startswith)\n"
+    "func str_endswith(s, p) {\n"
+    "  if type(s) != \"string\"\n"
+    "    throw \"expected first argument to be: string, but got: \" + type(s)\n"
+    "  if len(s) < len(p)\n"
+    "    return false\n"
+    "  return slice(s, len(s) - len(p)) == p\n"
+    "}\n"
+    "set_pseudomethod(\"string.endsWith\", str_endswith)\n"
+    "func str_split(s) {\n"
+    "  if len(arguments) == 1 || arguments[1] == \"\"\n"
+    "    return list(s)\n"
+    "  if type(s) != \"string\"\n"
+    "    throw \"expected first argument to be:!string, but got: \" + type(s)\n"
+    "  var r = []\n"
+    "  var d = arguments[1]\n"
+    "  if type(d) != \"string\"\n"
+    "    throw \"expected second argument to be: string, but got: \" + type(s)\n"
+    "  var t = \"\"\n"
+    "  for var i = 0; i < len(s); i++ {\n"
+    "    if slice(s, i, i+len(d)-1) == d {\n"
+    "      list_push(r, t)\n"
+    "      t = \"\"\n"
+    "      i += len(d)-1\n"
+    "      continue\n"
+    "    }\n"
+    "    t += s[i]\n"
+    "  }\n"
+    "  if t != \"\"\n"
+    "    list_push(r, t)\n"
+    "  return r\n"
+    "}\n"
+    "set_pseudomethod(\"string.split\", str_split)\n"
+    "func str_replace(s, w, b) {\n"
+    "  if type(s) != \"string\"\n"
+    "    throw \"expected first argument to be: string, but got: \" + type(s)\n"
+    "  if type(w) != \"string\"\n"
+    "    throw \"expected second argument to be: string, but got: \" + type(w)\n"
+    "  if type(b) != \"string\"\n"
+    "    throw \"expected third argument to be: string, but got: \" + type(b)\n"
+    "  var r = \"\"\n"
+    "  for var i = 0; i < len(s); i++ {\n"
+    "    if slice(s, i, i+len(w)-1) == w {\n"
+    "      r += b\n"
+    "      i += len(w)-1\n"
+    "      continue\n"
+    "    }\n"
+    "    r += s[i]\n"
+    "  }\n"
+    "  return r\n"
+    "}\n"
+    "set_pseudomethod(\"string.replace\", str_replace)\n"
+    "func table_keys(t) {\n"
+    "  if type(t) != \"table\"\n"
+    "    throw \"expected first argument to be: table, but got: \" + type(t)\n"
+    "  var r = []\n"
+    "  for var k of t\n"
+    "    list_push(r, k)\n"
+    "  return r\n"
+    "}\n"
+    "set_pseudomethod(\"table.keys\", table_keys)\n"
+    "func table_values(t) {\n"
+    "  if type(t) != \"table\"\n"
+    "    throw \"expected first argument to be: table, but got: \" + type(t)\n"
+    "  var r = []\n"
+    "  for var k of t\n"
+    "    list_push(r, t[k])\n"                                                                          "  return r\n"
+    "}\n"
+    "set_pseudomethod(\"table.values\", table_values)\n"
+    "func reduce(f, xs) {\n"
+    "  if type(f) != \"function\"\n"
+    "    throw \"expected first argument to be: function, but got: \" + type(f)\n"
+    "  if type(xs) !in (\"list\", \"tuple\", \"string\", \"bytes\")\n"
+    "    throw \"expected second argument to be: list, tuple, string or bytes, but got: \" + type(xs)\n"
+    "  if len(xs) == 0\n"
+    "    throw \"cannot reduce empty list\"\n"
+    "  r = xs[0]\n"
+    "  for var x of slice(xs, 1)\n"
+    "    r = f(r, x)\n"
+    "  if type(xs) == \"tuple\"\n"
+    "    return tuple(r)\n"
+    "  elif type(xs) == \"string\"\n"
+    "    return list_join(r)\n"
+    "  elif type(xs) == \"bytes\"\n"
+    "    return bytes(r)\n"
+    "  return r\n"
+    "}\n"
+    "set_pseudomethod(\"list.reduce\", reduce)\n"
+    "set_pseudomethod(\"tuple.reduce\", reduce)\n"
+    "set_pseudomethod(\"string.reduce\", reduce)\n"
+    "set_pseudomethod(\"bytes.reduce\", reduce)\n"
+    "func sum(xs)\n"
+    "  return reduce(func (x, y): x + y, xs)\n"
+    "set_pseudomethod(\"list.sum\", sum)\n"
+    "set_pseudomethod(\"tuple.sum\", sum)\n"
+    "func product(xs)\n"
+    "  return reduce(func (x, y): x * y, xs)\n"
+    "set_pseudomethod(\"list.product\", product)\n"
+    "set_pseudomethod(\"tuple.product\", product)\n"
+    "func map(f, xs) {\n"
+    "  if type(f) != \"function\"\n"
+    "    throw \"expected first argument to be: function, but got: \" + type(f)\n"
+    "  if type(xs) !in (\"list\", \"tuple\", \"string\", \"bytes\")\n"
+    "    throw \"expected second argument to be: list, tuple, string or bytes, but got: \" + type(xs)\n"
+    "  if len(xs) == 0\n"
+    "    return xs\n"
+    "  var r = []\n"
+    "  for var x of xs\n"
+    "    list_push(r, f(x))\n"
+    "  if type(xs) == \"tuple\"\n"
+    "    return tuple(r)\n"
+    "  elif type(xs) == \"string\"\n"
+    "    return list_join(r)\n"
+    "  elif type(xs) == \"bytes\"\n"
+    "    return bytes(r)\n"
+    "  return r\n"
+    "}\n"
+    "set_pseudomethod(\"list.map\", map)\n"
+    "set_pseudomethod(\"tuple.map\", map)\n"
+    "set_pseudomethod(\"string.map\", map)\n"
+    "set_pseudomethod(\"bytes.map\", map)\n"
+    "func filter(f, xs) {\n"
+    "  if type(f) != \"function\"\n"
+    "    throw \"expected first argument to be: function, but got: \" + type(f)\n"
+    "  if type(xs) !in (\"list\", \"tuple\", \"string\", \"bytes\")\n"
+    "    throw \"expected second argument to be: list, tuple, string or bytes, but got: \" + type(xs)\n"
+    "  if len(xs) == 0\n"
+    "    return xs\n"
+    "  var r = []\n"
+    "  for var x of xs\n"
+    "    if f(x)\n"
+    "      list_push(r, x)\n"
+    "  if type(xs) == \"tuple\"\n"
+    "    return tuple(r)\n"
+    "  elif type(xs) == \"string\"\n"
+    "    return list_join(r)\n"
+    "  elif type(xs) == \"bytes\"\n"
+    "    return bytes(r)\n"
+    "  return r\n"
+    "}\n"
+    "set_pseudomethod(\"list.filter\", filter)\n"
+    "set_pseudomethod(\"tuple.filter\", filter)\n"
+    "set_pseudomethod(\"string.filter\", filter)\n"
+    "set_pseudomethod(\"bytes.filter\", filter)\n"
+    "func str_index(s, w) {\n"
+    "  if s == \"\" || w == \"\"\n"
+    "    return -1\n"
+    "  if type(s) != \"string\"\n"
+    "    throw \"expected first argument to be: string, but got: \" + type(s)\n"
+    "  if type(w) != \"string\"\n"
+    "    throw \"expected second argument to be: string, but got: \" + type(w)\n"
+    "  for var i = 0; i < len(s); i++\n"
+    "    if slice(s, i, i+len(w)-1) == w\n"
+    "      return i\n"
+    "  return -1\n"
+    "}\n"
+    "set_pseudomethod(\"string.index\", str_index)\n"
+    "func str_lstrip(s, cs=\" \\t\\n\\r\\x0b\\x0c\") {\n"
+    "  if type(s) != \"string\"\n"
+    "    throw \"expected first argument to be: string, but got: \" + type(s)\n"
+    "  if type(cs) != \"string\"\n"
+    "    throw \"expected second argument to be: string, but got: \" + type(cs)\n"
+    "  if s == \"\"\n"
+    "    return s\n"
+    "  for var i = 0; s[i] in cs && i < len(s); i++\n"
+    "    pass\n"
+    "  return slice(s, i)\n"
+    "}\n"
+    "set_pseudomethod(\"string.lstrip\", str_lstrip)\n"
+    "func str_rstrip(s, cs=\" \\t\\n\\r\\x0b\\x0c\") {\n"
+    "  if type(s) != \"string\"\n"
+    "    throw \"expected first argument to be: string, but got: \" + type(s)\n"
+    "  if type(cs) != \"string\"\n"
+    "    throw \"expected second argument to be: string, but got: \" + type(cs)\n"
+    "  if s == \"\"\n"
+    "    return s\n"
+    "  for var k = 0, i = len(s)-1; s[i] in cs && i >= 0; k++\n"
+    "    i--\n"
+    "  return slice(s, 0, len(s)-k-1)\n"
+    "}\n"
+    "set_pseudomethod(\"string.rstrip\", str_rstrip)\n"
+    "func str_strip(s, cs=\" \\t\\n\\r\\x0b\\x0c\") {\n"
+    "  if type(s) != \"string\"\n"
+    "    throw \"expected first argument to be: string, but got: \" + type(s)\n"
+    "  if type(cs) != \"string\"\n"
+    "    throw \"expected second argument to be: string, but got: \" + type(cs)\n"
+    "  return str_lstrip(str_rstrip(s, cs), cs)\n"
+    "}\n"
+    "set_pseudomethod(\"string.strip\", str_strip)\n"
+    "func zip() {\n"
+    "  if !arguments\n"
+    "    return []\n"
+    "  var l = map(len, arguments)\n"
+    "  l = reduce(min, l)\n"
+    "  var r = []\n"
+    "  for var i = 0; i < l; i++ {\n"
+    "    var t = []\n"
+    "    for var xs of arguments\n"
+    "      list_push(t, xs[i])\n"
+    "    list_push(r, t)\n"
+    "  }\n"
+    "  return r\n"
+    "}\n"
+    "func enumerate(l)\n"
+    "  if type(l) == \"table\"\n"
+    "    return zip(table_keys(l), table_values(l))\n"
+    "  else\n"
+    "    return zip(range(len(l)), l)\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"
@@ -2515,6 +2761,13 @@ const char *STD[][2] = {
     "        return obj\n"
     "    }\n"
     "})\n"
+    "func getline()\n"
+    "  return fgets(STDIN, 256)\n"
+    "func input() {\n"
+    "  if len(arguments) > 0\n"
+    "    func_call(print, arguments)\n"
+    "  return str_rstrip(getline(), \"\\n\\r\")\n"
+    "}\n"
     "func open(path, mode=\"r\"): fopen(path, mode)\n"
   },
 
@@ -2976,6 +3229,8 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
       CTXPUSH("for");
       compile_node(gbuf, buf, ctx, lstk, lbl, node->d);
 
+      EMIT("__continue%d:;\n", gid);
+
       if (node->c) {
         compile_node(gbuf, buf, ctx, lstk, lbl, node->c);
 
@@ -2984,8 +3239,7 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
 
       CTXPOP();
       LPOP();
-
-      EMIT("__continue%d:;\n", gid);
+     
       EMIT("}\n");
 
       EMIT("__break%d:;\n", gid);