about summary refs log tree commit diff stats
path: root/src/utils
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-06-19 18:13:10 +0200
committerbptato <nincsnevem662@gmail.com>2023-06-19 18:15:09 +0200
commit17097052794aef56bbc55327d3e6c84ae1c67378 (patch)
tree13b81e1105c07c69d7a8d1e7367a698f41663a01 /src/utils
parente372bdaa0344b23c91aefa4da44c578fbf8f49e2 (diff)
downloadchawan-17097052794aef56bbc55327d3e6c84ae1c67378.tar.gz
Rework JS exception system
Now we use Result for passing exceptions to JS. As a result, we can
finally get rid of the .jserr pragma.
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/opt.nim68
-rw-r--r--src/utils/twtstr.nim4
2 files changed, 45 insertions, 27 deletions
diff --git a/src/utils/opt.nim b/src/utils/opt.nim
index caba236e..3766516b 100644
--- a/src/utils/opt.nim
+++ b/src/utils/opt.nim
@@ -2,18 +2,26 @@
 
 type
   Result*[T, E] = object
-    when (T is void) and (E is void):
-      has: bool
-    else:
-      case has: bool
+    when E is void and T is void: # weirdness
+      has*: bool
+    elif E is void and not (T is void): # opt
+      case has*: bool
+      of true:
+        val*: T
+      else:
+        discard
+    elif not (E is void) and T is void: # err
+      case has*: bool
+      of true:
+        discard
+      else:
+        ex*: E
+    else: # result
+      case has*: bool
       of true:
-        when not (T is void):
-          val: T
+        val*: T
       else:
-        when not (E is void):
-          ex: E
-        else:
-          discard
+        ex*: E
 
   Opt*[T] = Result[T, void]
 
@@ -31,9 +39,12 @@ template ok*[T](x: T): auto =
 template ok*(): auto =
   ok(typeof(result))
 
-template ok*[T, E](res: var Result[T, E], x: T): Result[T, E] =
+template ok*[T, E](res: var Result[T, E], x: T) =
   res = Result[T, E](has: true, val: x)
 
+template ok*[E](res: var Result[void, E]) =
+  res = Result[void, E](has: true)
+
 template err*[T, E](t: type Result[T, E], e: E): Result[T, E] =
   Result[T, E](has: false, ex: e)
 
@@ -44,22 +55,39 @@ template err*(): auto =
   err(typeof(result))
 
 template err*[T, E](res: var Result[T, E], e: E) =
-  res.ex = e
+  res = Result[T, E](has: false, ex: e)
+
+template err*[T, E](res: var Result[T, E]) =
+  res = Result[T, E](has: false)
 
 template err*[E](e: E): auto =
   err(typeof(result), e)
 
+template opt*[T](v: T): auto =
+  ok(Opt[T], v)
+
+template opt*(t: typedesc): auto =
+  err(Result[t, void])
+
 template isOk*(res: Result): bool = res.has
 template isErr*(res: Result): bool = not res.has
 template isSome*(res: Result): bool = res.isOk
 template isNone*(res: Result): bool = res.isErr
-template get*[T, E](res: Result[T, E]): T = res.val
-template error*[T, E](res: Result[T, E]): E = res.ex
+func get*[T, E](res: Result[T, E]): T {.inline.} = res.val
+func get*[T, E](res: var Result[T, E]): var T = res.val
+func get*[T, E](res: Result[T, E], v: T): T =
+  if res.has:
+    res.val
+  else:
+    v
+func error*[T, E](res: Result[T, E]): E {.inline.} = res.ex
+template valType*[T, E](res: type Result[T, E]): auto = T
+template errType*[T, E](res: type Result[T, E]): auto = E
 
 func isSameErr[T, E, F](a: type Result[T, E], b: type F): bool =
   return E is F
 
-template `?`*[T, E](res: Result[T, E]): T =
+template `?`*[T, E](res: Result[T, E]): auto =
   let x = res # for when res is a funcall
   if x.has:
     when not (T is void):
@@ -73,13 +101,3 @@ template `?`*[T, E](res: Result[T, E]): T =
       return err(x.error)
     else:
       return err()
-
-template `?`*[E](res: Err[E]) =
-  let x = res # for when res is a funcall
-  if not x.has:
-    when typeof(result) is Err[E]:
-      return x
-    elif isSameErr(typeof(result), E):
-      return err(x.error)
-    else:
-      return err()
diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim
index a988c976..6d3c6f08 100644
--- a/src/utils/twtstr.nim
+++ b/src/utils/twtstr.nim
@@ -1074,9 +1074,9 @@ func twidth*(s: string, w: int): int =
 func breaksWord*(r: Rune): bool =
   return not (r.isDigitAscii() or r.width() == 0 or r.isAlpha())
 
-type BoundaryFunction* = proc(x: Rune): Option[bool]
+type BoundaryFunction* = proc(x: Rune): Opt[bool]
 
-proc breaksWord*(r: Rune, check: Option[BoundaryFunction]): bool =
+proc breaksWord*(r: Rune, check: Opt[BoundaryFunction]): bool =
   if check.isSome:
     let f = check.get()
     let v = f(r)