txlyre 5 дней назад
Родитель
Сommit
d4428e3dd5
4 измененных файлов с 861 добавлено и 458 удалено
  1. 202 187
      qirt.c
  2. 9 1
      qirt.h
  3. 549 176
      qistd.c
  4. 101 94
      std.qi

Разница между файлами не показана из-за своего большого размера
+ 202 - 187
qirt.c


+ 9 - 1
qirt.h

@@ -178,6 +178,13 @@ struct _qi_state_t {
   qi_value_t *numbers[256];
 
   qi_value_t *listiterator;
+  qi_value_t *typeerror;
+  qi_value_t *valueerror;
+  qi_value_t *indexerror;
+  qi_value_t *keyerror;
+  qi_value_t *recursionerror;
+  qi_value_t *nameerror;
+  qi_value_t *ioerror;
 
   qi_table_t *pseudomethods;
   void *pseudomethods_mutex;
@@ -301,7 +308,7 @@ struct _qi_symbol_t {
                          : qi_to_table(state, x)->value.table.table)
 #define qi_get_data(state, t, x)                                               \
   ((x)->type != QI_DATA || (x)->value.data.tag != (t)                          \
-       ? (qi_throw_format((state), "expected data (tag: %d)", (t)), NULL)      \
+       ? (qi_throw_class((state), (state)->typeerror, "expected data (tag: %d)", (t)), NULL)      \
        : (x)->value.data.data)
 
 #define qi_push_trace(state, fn, debug_data)                                   \
@@ -424,6 +431,7 @@ qi_trap_t *qi_set_trap(qi_state_t *state, qi_defer_t finally);
 void qi_unset_trap(qi_state_t *state, qi_trap_t *trap);
 void qi_throw(qi_state_t *state, qi_value_t *value);
 void qi_throw_format(qi_state_t *state, char *format, ...);
+void qi_throw_class(qi_state_t *state, qi_value_t *class, char *format, ...);
 qi_value_t *qi_find(qi_state_t *state, char *name);
 qi_value_t *qi_get(qi_state_t *state, char *name);
 void qi_decl_const(qi_state_t *state, char *name, qi_value_t *value);

Разница между файлами не показана из-за своего большого размера
+ 549 - 176
qistd.c


+ 101 - 94
std.qi

@@ -1,10 +1,56 @@
+func Object(t, p=nil, o={}): return p !is nil? set_meta_table(p, get_meta_table(p) + t): set_meta_table(o, t)
+func is_object(o): return has_meta_table(o)
+func __class_wrapper(n, p, t, mt, st): return Object({
+    "t": t,
+    "mt": mt,
+    "super": p,
+    "__type": func (this) use (n): return n,
+    "__str": func (this) use (n): return "<class " + n + ">",
+    "__call": func (this, pargs) use (n, p) {
+        var t = {}
+        var mt = { "__type": func (this) use (n): n }
+        if p {
+          var i = 0
+          for i < len(p) {
+            t += p[i].t
+            mt += p[i].mt
+
+            i += 1
+          }
+        }
+        t += this.t
+        mt += this.mt
+        mt.super = this.super
+        var obj = set_meta_table(t, mt)
+        if "constructor" in mt
+          func_call(mt.constructor, [obj] + pargs)
+        return obj
+    }
+}, nil, st)
+class Error {
+  msg = nil
+
+  constructor (this, msg=nil) {
+    this.msg = msg
+  }
+
+  __str (this): this.msg is nil? type(this): type(this) + ": " + this.msg
+}
+class AssertionError(Error)
+class TypeError(Error)
+class ValueError(Error)
+class IndexError(Error)
+class KeyError(Error)
+class RecursionError(Error)
+class NameError(Error)
+class IOError(Error)
 func head(l): return l[0]
 func tail(l): return slice(l, 1)
 func min(x, y): x < y? x: y
 func max(x, y): x > y? x: y
 func reverse(x) {
   if type(x) !in ("list", "string", "bytes")
-    throw "expected first argument to be: list, string or bytes, but got: " + type(x)
+    throw TypeError("expected first argument to be: list, string or bytes, but got: " + type(x))
   var r = []
   for var i = len(x)-1; i >= 0; i--
     list_push(r, x[i])
@@ -31,11 +77,11 @@ func range(f) {
     s = 1
   }
   if type(f) != "number"
-    throw "expected first argument to be: number, but got: " + type(f)
+    throw TypeError("expected first argument to be: number, but got: " + type(f))
   if type(t) != "number"
-    throw "expected second argument to be: number, but got: " + type(t)
+    throw TypeError("expected second argument to be: number, but got: " + type(t))
   if type(s) != "number"
-    throw "expected third argument to be: number, but got: " + type(s)
+    throw TypeError("expected third argument to be: number, but got: " + type(s))
   if f > t
     return reverse(range(t, f, s))
   var r = []
@@ -61,7 +107,7 @@ func file_write(filename, data) {
 }
 func is_defined(name) {
   if type(name) != "string"
-    throw "expected first argument to be: string, but got: " + type(name)
+    throw TypeError("expected first argument to be: string, but got: " + type(name))
   inline `qi_bool b = qi_find(state, qi_get(state, "name")->value.string) != NULL`
   inline `return qi_make_boolean(state, b)`
 }
@@ -70,7 +116,7 @@ func is_table(a) {
 }
 func list_remove(l, x, first=false) {
   if type(l) != "list"
-    throw "expected first argument to be: list, but got: " + type(l)
+    throw TypeError("expected first argument to be: list, but got: " + type(l))
   repeat:
   for var i = 0; i < len(l); i++
     if l[i] == x {
@@ -83,7 +129,7 @@ func list_remove(l, x, first=false) {
 set_pseudomethod("list.remove", list_remove)
 func list_join(l) {
   if type(l) != "list"
-    throw "expected first argumient to be: list, but got: " + type(l)
+    throw TypeError("expected first argumient to be: list, but got: " + type(l))
   var r = ""
   var s
   if len(arguments) == 1
@@ -91,11 +137,11 @@ func list_join(l) {
   else
     s = arguments[1]
   if type(s) != "string"
-    throw "expected second argument to be: string, but got: " + type(s)
+    throw TypeError("expected second argument to be: string, but got: " + type(s))
   var first = true
   for var x of l {
     if type(x) != "string"
-      throw "expected sequence item to be: string, but got: " + type(x)
+      throw TypeError("expected sequence item to be: string, but got: " + type(x))
     if s != "" && !first
       r += s
     r += x
@@ -106,9 +152,9 @@ func list_join(l) {
 set_pseudomethod("list.join", list_join)
 func list_pop_at(l, i) {
   if type(l) != "list"
-    throw "expected first argument to be: list, but got: " + type(l)
+    throw TypeError("expected first argument to be: list, but got: " + type(l))
   if type(i) != "number"
-    throw "expected second argument to be: number, but got: " + type(i)
+    throw TypeError("expected second argument to be: number, but got: " + type(i))
   var x = l[i]
   list_delete(l, i)
   return x
@@ -117,9 +163,9 @@ set_pseudomethod("list.popAt", list_pop_at)
 func __cmp(x, y): x > y? 1: x < y? -1: 0
 func list_sort(l, cmp=__cmp) {
   if type(l) != "list"
-    throw "expected first argument to be: list, but got: " + type(l)
+    throw TypeError("expected first argument to be: list, but got: " + type(l))
   if type(cmp) != "function"
-    throw "expected second argument to be: function, but got: " + type(cmp)
+    throw TypeError("expected second argument to be: function, but got: " + type(cmp))
   if len(l) == 0
     return l
   var z = len(l)
@@ -140,9 +186,9 @@ set_pseudomethod("list.sort", list_sort)
 set_pseudomethod("list.sorted", list_sorted)
 func list_shift(l) {
   if type(l) != "list"
-    throw "expected first argument to be: list, but got: " + type(l)
+    throw TypeError("expected first argument to be: list, but got: " + type(l))
   if is_empty(l)
-    throw "shift from empty list"
+    throw IndexError("shift from empty list")
   var a = l[0]
   list_delete(l, 0)
   return a
@@ -156,12 +202,12 @@ set_pseudomethod("list.insert", list_insert)
 set_pseudomethod("list.delete", list_delete)
 func slice(l) {
   if type(l) !in ("list", "string", "bytes", "ustr")
-    throw "expected first argument to be: list, string, bytes or ustr, but got: " + type(l)
+    throw TypeError("expected first argument to be: list, string, bytes or ustr, but got: " + type(l))
   var r = []
   if len(arguments) == 2 {
     var f = arguments[1]
     if type(f) != "number"
-      throw "expected second argument to be: number, but got: " + type(f)
+      throw TypeError("expected second argument to be: number, but got: " + type(f))
     if f < 0
       f += len(l)
     for var i = f; i < len(l); i++
@@ -169,9 +215,9 @@ func slice(l) {
   } elif len(arguments) == 3 {
     var f = arguments[1], t = arguments[2]
     if type(f) != "number"
-      throw "expected second argument to be: number, but got: " + type(f)
+      throw TypeError("expected second argument to be: number, but got: " + type(f))
     if type(t) != "number"
-      throw "expected third argument to be: number, but got: " + type(t)
+      throw TypeError("expected third argument to be: number, but got: " + type(t))
     if f < 0
       f += len(l)
     if t < 0
@@ -193,7 +239,7 @@ set_pseudomethod("bytes.slice", slice)
 let __slice = slice;
 func str_startswith(s, p) {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(s)
+    throw TypeError("expected first argument to be: string, but got: " + type(s))
   if len(s) < len(p)
     return false
   return slice(s, 0, len(p)-1) == p
@@ -201,7 +247,7 @@ func str_startswith(s, p) {
 set_pseudomethod("string.startsWith", str_startswith)
 func str_endswith(s, p) {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(s)
+    throw TypeError("expected first argument to be: string, but got: " + type(s))
   if len(s) < len(p)
     return false
   return slice(s, len(s) - len(p)) == p
@@ -211,11 +257,11 @@ func str_split(s) {
   if len(arguments) == 1 || arguments[1] == ""
     return list(s)
   if type(s) != "string"
-    throw "expected first argument to be:!string, but got: " + type(s)
+    throw TypeError("expected first argument to be:!string, but got: " + type(s))
   var r = []
   var d = arguments[1]
   if type(d) != "string"
-    throw "expected second argument to be: string, but got: " + type(s)
+    throw TypeError("expected second argument to be: string, but got: " + type(s))
   var t = ""
   for var i = 0; i < len(s); i++ {
     if slice(s, i, i+len(d)-1) == d {
@@ -233,11 +279,11 @@ func str_split(s) {
 set_pseudomethod("string.split", str_split)
 func str_replace(s, w, b) {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(s)
+    throw TypeError("expected first argument to be: string, but got: " + type(s))
   if type(w) != "string"
-    throw "expected second argument to be: string, but got: " + type(w)
+    throw TypeError("expected second argument to be: string, but got: " + type(w))
   if type(b) != "string"
-    throw "expected third argument to be: string, but got: " + type(b)
+    throw TypeError("expected third argument to be: string, but got: " + type(b))
   var r = ""
   for var i = 0; i < len(s); i++ {
     if slice(s, i, i+len(w)-1) == w {
@@ -252,7 +298,7 @@ func str_replace(s, w, b) {
 set_pseudomethod("string.replace", str_replace)
 func table_keys(t) {
   if type(t) != "table"
-    throw "expected first argument to be: table, but got: " + type(t)
+    throw TypeError("expected first argument to be: table, but got: " + type(t))
   var r = []
   for var k of t
     list_push(r, k)
@@ -261,7 +307,7 @@ func table_keys(t) {
 set_pseudomethod("table.keys", table_keys)
 func table_values(t) {
   if type(t) != "table"
-    throw "expected first argument to be: table, but got: " + type(t)
+    throw TypeError("expected first argument to be: table, but got: " + type(t))
   var r = []
   for var k of t
     list_push(r, t[k])
@@ -270,11 +316,11 @@ func table_values(t) {
 set_pseudomethod("table.values", table_values)
 func reduce(f, xs) {
   if type(f) != "function"
-    throw "expected first argument to be: function, but got: " + type(f)
+    throw TypeError("expected first argument to be: function, but got: " + type(f))
   if type(xs) !in ("list", "tuple", "string", "bytes")
-    throw "expected second argument to be: list, tuple, string or bytes, but got: " + type(xs)
+    throw TypeError("expected second argument to be: list, tuple, string or bytes, but got: " + type(xs))
   if len(xs) == 0
-    throw "cannot reduce empty list"
+    throw ValueError("cannot reduce empty list")
   r = xs[0]
   for var x of slice(xs, 1)
     r = f(r, x)
@@ -306,9 +352,9 @@ set_pseudomethod("list.any", any)
 set_pseudomethod("tuple.any", any)
 func map(f, xs) {
   if type(f) != "function"
-    throw "expected first argument to be: function, but got: " + type(f)
+    throw TypeError("expected first argument to be: function, but got: " + type(f))
   if type(xs) !in ("list", "tuple", "string", "bytes")
-    throw "expected second argument to be: list, tuple, string or bytes, but got: " + type(xs)
+    throw TypeError("expected second argument to be: list, tuple, string or bytes, but got: " + type(xs))
   if len(xs) == 0
     return xs
   var r = []
@@ -328,9 +374,9 @@ set_pseudomethod("string.map", func (xs, f): map(f, xs))
 set_pseudomethod("bytes.map", func (xs, f): map(f, xs))
 func filter(f, xs) {
   if type(f) != "function"
-    throw "expected first argument to be: function, but got: " + type(f)
+    throw TypeError("expected first argument to be: function, but got: " + type(f))
   if type(xs) !in ("list", "tuple", "string", "bytes")
-    throw "expected second argument to be: list, tuple, string or bytes, but got: " + type(xs)
+    throw TypeError("expected second argument to be: list, tuple, string or bytes, but got: " + type(xs))
   if len(xs) == 0
     return xs
   var r = []
@@ -353,9 +399,9 @@ func str_index(s, w) {
   if s == "" || w == ""
     return -1
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(s)
+    throw TypeError("expected first argument to be: string, but got: " + type(s))
   if type(w) != "string"
-    throw "expected second argument to be: string, but got: " + type(w)
+    throw TypeError("expected second argument to be: string, but got: " + type(w))
   for var i = 0; i < len(s); i++
     if len(w) == 1 && s[i] == w
       return i
@@ -366,9 +412,9 @@ func str_index(s, w) {
 set_pseudomethod("string.index", str_index)
 func str_lstrip(s, cs=" \t\n\r\x0b\x0c") {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(s)
+    throw TypeError("expected first argument to be: string, but got: " + type(s))
   if type(cs) != "string"
-    throw "expected second argument to be: string, but got: " + type(cs)
+    throw TypeError("expected second argument to be: string, but got: " + type(cs))
   if s == ""
     return s
   var i
@@ -379,9 +425,9 @@ func str_lstrip(s, cs=" \t\n\r\x0b\x0c") {
 set_pseudomethod("string.lstrip", str_lstrip)
 func str_rstrip(s, cs=" \t\n\r\x0b\x0c") {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(s)
+    throw TypeError("expected first argument to be: string, but got: " + type(s))
   if type(cs) != "string"
-    throw "expected second argument to be: string, but got: " + type(cs)
+    throw TypeError("expected second argument to be: string, but got: " + type(cs))
   if s == ""
     return s
   var k, i
@@ -392,9 +438,9 @@ func str_rstrip(s, cs=" \t\n\r\x0b\x0c") {
 set_pseudomethod("string.rstrip", str_rstrip)
 func str_strip(s, cs=" \t\n\r\x0b\x0c") {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(s)
+    throw TypeError("expected first argument to be: string, but got: " + type(s))
   if type(cs) != "string"
-    throw "expected second argument to be: string, but got: " + type(cs)
+    throw TypeError("expected second argument to be: string, but got: " + type(cs))
   return str_lstrip(str_rstrip(s, cs), cs)
 }
 set_pseudomethod("string.strip", str_strip)
@@ -419,48 +465,19 @@ func enumerate(l)
     return zip(range(len(l)), l)
 func str_toupper(s) {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(c)
+    throw TypeError("expected first argument to be: string, but got: " + type(c))
   return map(func (c): c >= 'a' && c <= 'z'? chr(ord(c) - 32): c, s)
 }
 set_pseudomethod("string.toupper", str_toupper)
 func str_tolower(s) {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(c)
+    throw TypeError("expected first argument to be: string, but got: " + type(c))
   return map(func (c): c >= 'A' && c <= 'Z'? chr(ord(c) + 32): c, s)
 }
 set_pseudomethod("string.tolower", str_tolower)
-func Object(t, p=nil, o={}): return p !is nil? set_meta_table(p, get_meta_table(p) + t): set_meta_table(o, t)
-func is_object(o): return has_meta_table(o)
-func __class_wrapper(n, p, t, mt, st): return Object({
-    "t": t,
-    "mt": mt,
-    "super": p,
-    "__type": func (this) use (n): return n,
-    "__str": func (this) use (n): return "<class " + n + ">",
-    "__call": func (this, pargs) use (n, p) {
-        var t = {}
-        var mt = { "__type": func (this) use (n): n }
-        if p {
-          var i = 0
-          for i < len(p) {
-            t += p[i].t
-            mt += p[i].mt
-
-            i += 1
-          }
-        }
-        t += this.t
-        mt += this.mt
-        mt.super = this.super
-        var obj = set_meta_table(t, mt)
-        if "constructor" in mt
-          func_call(mt.constructor, [obj] + pargs)
-        return obj
-    }
-}, nil, st)
 func hex(x) {
     if type(x) != "number"
-      throw "expected first argument to be: number, but got: " + type(x)
+      throw TypeError("expected first argument to be: number, but got: " + type(x))
     if x == 0
       return "0x0"
     let sgn = x < 0
@@ -475,7 +492,7 @@ func hex(x) {
 }
 func oct(x) {
     if type(x) != "number"
-      throw "expected first argument to be: number, but got: " + type(x)
+      throw TypeError("expected first argument to be: number, but got: " + type(x))
     if x == 0
       return "0o0"
     let sgn = x < 0
@@ -490,7 +507,7 @@ func oct(x) {
 }
 func format(s) {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(s)
+    throw TypeError("expected first argument to be: string, but got: " + type(s))
   var r = ""
   var n = 1
   for var i = 0; i < len(s); i++
@@ -511,15 +528,15 @@ func format(s) {
 set_pseudomethod("string.format", format)
 func formatl(s, l) {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(s)
+    throw TypeError("expected first argument to be: string, but got: " + type(s))
   if type(l) != "list"
-    throw "expected second argument to be: list, but got: " + type(l)
+    throw TypeError("expected second argument to be: list, but got: " + type(l))
   return func_call(str_format, [s] + l)
 }
 set_pseudomethod("string.formatl", formatl)
 func formatd(s, t) {
   if type(s) != "string"
-    throw "expected first argument to be: string, but got: " + type(s)
+    throw TypeError("expected first argument to be: string, but got: " + type(s))
   var r = ""
   var n = 1
   for var i = 0; i < len(s); i++
@@ -535,9 +552,9 @@ func formatd(s, t) {
         for i < len(s) && s[i] != '}'
           k += s[i++]
         if i >= len(s) || s[i] != '}'
-          throw "unmatched { in format specifier"
+          throw ValueError("unmatched { in format specifier")
         if !k
-          throw "empty format key"
+          throw ValueError("empty format key")
         r += repr(t[k])
         break
       default
@@ -568,16 +585,6 @@ set_pseudomethod("file.puts", fputs)
 set_pseudomethod("file.tell", ftell)
 set_pseudomethod("reference.deref", deref)
 set_pseudomethod("reference.set", ref_set)
-class Error {
-  msg = nil
-
-  constructor (this, msg=nil) {
-    this.msg = msg
-  }
-
-  __str (this): this.msg is nil? type(this): type(this) + ": " + this.msg
-}
-class AssertionError(Error)
 func assert(cond, msg=AssertionError())
   if !cond
     throw msg
@@ -710,7 +717,7 @@ class OrderedTable {
                 return
             }
 
-        throw "no such key: " + k
+        throw KeyError(k)
     }
 
     __index (this, k) {
@@ -720,7 +727,7 @@ class OrderedTable {
             if ok == k
                 return v
 
-        throw "no such key: " + k
+        throw KeyError(k)
     }
 
     __index_set (this, k, v) {

Некоторые файлы не были показаны из-за большого количества измененных файлов