koatl 0.1.41__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {koatl-0.1.41 → koatl-0.2.2}/Cargo.lock +9 -9
- koatl-0.2.2/Cargo.toml +3 -0
- {koatl-0.1.41 → koatl-0.2.2}/PKG-INFO +1 -1
- {koatl-0.1.41 → koatl-0.2.2}/koatl/Cargo.toml +1 -1
- {koatl-0.1.41 → koatl-0.2.2/koatl}/python/koatl/cli.py +15 -1
- {koatl-0.1.41 → koatl-0.2.2/koatl}/python/koatl/runtime/__init__.py +4 -3
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/runtime/meta_finder.py +1 -1
- {koatl-0.1.41 → koatl-0.2.2/koatl}/python/koatl/std/alg/async.tl +1 -1
- {koatl-0.1.41 → koatl-0.2.2/koatl}/python/koatl/std/alg/do.tl +5 -5
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/alg/env.tl +3 -3
- {koatl-0.1.41 → koatl-0.2.2/koatl}/python/koatl/std/alg/memo.tl +7 -8
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/alg/result.tl +5 -5
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/data/list.tl +3 -3
- koatl-0.2.2/koatl/python/koatl/std/io.tl +7 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/iter.tl +10 -6
- koatl-0.2.2/koatl/python/koatl/std/json.tl +34 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/lazy_module.tl +1 -1
- koatl-0.2.2/koatl/python/koatl/std/pickle.tl +10 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/trait.py +2 -2
- {koatl-0.1.41 → koatl-0.2.2}/koatl/src/emit_py.rs +1 -1
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/match.tl +27 -12
- koatl-0.2.2/koatl/tests/e2e/prelude/try.tl +28 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/virtual.tl +2 -2
- koatl-0.2.2/koatl/tests/parse/matches.tl +2 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/Cargo.toml +1 -1
- {koatl-0.1.41/koatl-core/parser → koatl-0.2.2/koatl-core}/src/ast.rs +5 -61
- koatl-0.1.41/koatl-core/parser/src/util.rs → koatl-0.2.2/koatl-core/src/ast_builder.rs +12 -5
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/inference.rs +17 -21
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/lib.rs +25 -15
- koatl-0.2.2/koatl-core/src/lift_cst.rs +663 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/parse_timer.rs +10 -11
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/py/ast.rs +7 -1
- koatl-0.1.41/koatl-core/src/py/util.rs → koatl-0.2.2/koatl-core/src/py/ast_builder.rs +2 -1
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/py/emit.rs +15 -6
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/py/mod.rs +1 -1
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/resolve_scopes.rs +31 -38
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/transform.rs +52 -30
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/util.rs +1 -1
- {koatl-0.1.41/koatl-core/parser → koatl-0.2.2/koatl-parser}/Cargo.toml +1 -1
- koatl-0.2.2/koatl-parser/src/cst.rs +720 -0
- koatl-0.2.2/koatl-parser/src/lexer.rs +1683 -0
- {koatl-0.1.41/koatl-core/parser → koatl-0.2.2/koatl-parser}/src/lib.rs +3 -2
- koatl-0.2.2/koatl-parser/src/parser.rs +2398 -0
- koatl-0.2.2/koatl-parser/src/parser_error.rs +419 -0
- koatl-0.2.2/koatl-parser/src/simple_fmt.rs +743 -0
- {koatl-0.1.41/koatl → koatl-0.2.2}/python/koatl/cli.py +15 -1
- {koatl-0.1.41/koatl → koatl-0.2.2}/python/koatl/runtime/__init__.py +4 -3
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/runtime/meta_finder.py +1 -1
- {koatl-0.1.41/koatl → koatl-0.2.2}/python/koatl/std/alg/async.tl +1 -1
- {koatl-0.1.41/koatl → koatl-0.2.2}/python/koatl/std/alg/do.tl +5 -5
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/alg/env.tl +3 -3
- {koatl-0.1.41/koatl → koatl-0.2.2}/python/koatl/std/alg/memo.tl +7 -8
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/alg/result.tl +5 -5
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/data/list.tl +3 -3
- koatl-0.2.2/python/koatl/std/io.tl +7 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/iter.tl +10 -6
- koatl-0.2.2/python/koatl/std/json.tl +34 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/lazy_module.tl +1 -1
- koatl-0.2.2/python/koatl/std/pickle.tl +10 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/trait.py +2 -2
- koatl-0.1.41/Cargo.toml +0 -3
- koatl-0.1.41/koatl/python/koatl/std/io.tl +0 -3
- koatl-0.1.41/koatl/tests/e2e/prelude/try.tl +0 -29
- koatl-0.1.41/koatl/tests/parse/matches.tl +0 -2
- koatl-0.1.41/koatl-core/parser/src/lexer.rs +0 -1106
- koatl-0.1.41/koatl-core/parser/src/parser.rs +0 -1577
- koatl-0.1.41/koatl-core/src/parser.rs +0 -1
- koatl-0.1.41/python/koatl/std/io.tl +0 -3
- {koatl-0.1.41 → koatl-0.2.2}/README.md +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/.github/workflows/CI.yml +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/.gitignore +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/LICENSE +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/README.md +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/__init__.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/__main__.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/notebook/__init__.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/notebook/magic.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/prelude/__init__.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/runtime/record.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/runtime/vattr.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/alg/__init__.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/alg/base.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/data/__init__.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/data/record.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/ext.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/python/koatl/std/re.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/requirements.txt +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/src/lib.rs +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/containers.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/data.txt +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/decorators.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/destructure-for-and-fn.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/destructure.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/escape_ident.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/fstr.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/functions.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/generator.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/if_expr.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/loops.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/nary-list.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/placeholder.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/precedence.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/scopes.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/semantic_whitespace.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/short_circuit.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/base/with.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/async.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/aug_assign.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/coal.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/env.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/imports.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/iterables.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/list.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/memo.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/record.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/result.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/prelude/slice.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/util/__init__.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/util/module0.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/util/module1.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/e2e/util/module2.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/parse/arith.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/parse/assign.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/parse/block-comments.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/parse/deco.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/parse/func.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/test_e2e.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl/tests/test_parse.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/main.rs +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/koatl-core/src/types.rs +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/pyproject.toml +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/__init__.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/__main__.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/notebook/__init__.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/notebook/magic.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/prelude/__init__.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/runtime/record.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/runtime/vattr.py +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/alg/__init__.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/alg/base.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/data/__init__.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/data/record.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/ext.tl +0 -0
- {koatl-0.1.41 → koatl-0.2.2}/python/koatl/std/re.tl +0 -0
|
@@ -99,7 +99,7 @@ checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
|
|
|
99
99
|
|
|
100
100
|
[[package]]
|
|
101
101
|
name = "koatl"
|
|
102
|
-
version = "0.
|
|
102
|
+
version = "0.2.2"
|
|
103
103
|
dependencies = [
|
|
104
104
|
"ariadne",
|
|
105
105
|
"koatl-core",
|
|
@@ -112,11 +112,18 @@ name = "koatl-core"
|
|
|
112
112
|
version = "0.1.0"
|
|
113
113
|
dependencies = [
|
|
114
114
|
"ariadne",
|
|
115
|
+
"koatl-parser",
|
|
115
116
|
"once_cell",
|
|
116
|
-
"parser",
|
|
117
117
|
"slotmap",
|
|
118
118
|
]
|
|
119
119
|
|
|
120
|
+
[[package]]
|
|
121
|
+
name = "koatl-parser"
|
|
122
|
+
version = "0.1.0"
|
|
123
|
+
dependencies = [
|
|
124
|
+
"chumsky",
|
|
125
|
+
]
|
|
126
|
+
|
|
120
127
|
[[package]]
|
|
121
128
|
name = "libc"
|
|
122
129
|
version = "0.2.174"
|
|
@@ -144,13 +151,6 @@ version = "1.21.3"
|
|
|
144
151
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
145
152
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
|
146
153
|
|
|
147
|
-
[[package]]
|
|
148
|
-
name = "parser"
|
|
149
|
-
version = "0.1.0"
|
|
150
|
-
dependencies = [
|
|
151
|
-
"chumsky",
|
|
152
|
-
]
|
|
153
|
-
|
|
154
154
|
[[package]]
|
|
155
155
|
name = "portable-atomic"
|
|
156
156
|
version = "1.11.1"
|
koatl-0.2.2/Cargo.toml
ADDED
|
@@ -9,9 +9,23 @@ def transpile_from_source(source, mode="script", script_path="<string>"):
|
|
|
9
9
|
|
|
10
10
|
def run_from_source(source, mode="script", script_path="<string>"):
|
|
11
11
|
from koatl import transpile
|
|
12
|
+
import ast
|
|
12
13
|
|
|
13
14
|
transpiled_code = transpile(source, mode=mode, filename=str(script_path))
|
|
14
|
-
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
code_obj = compile(transpiled_code, script_path, "exec")
|
|
18
|
+
except Exception as e:
|
|
19
|
+
|
|
20
|
+
class Visitor(ast.NodeVisitor):
|
|
21
|
+
def generic_visit(self, node):
|
|
22
|
+
if hasattr(node, "lineno"):
|
|
23
|
+
if node.lineno > node.end_lineno:
|
|
24
|
+
print(f"Error: {node.lineno} > {node.end_lineno} for {node}")
|
|
25
|
+
super().generic_visit(node)
|
|
26
|
+
|
|
27
|
+
Visitor().visit(transpiled_code)
|
|
28
|
+
raise
|
|
15
29
|
|
|
16
30
|
script_globals = {"__name__": "__main__"}
|
|
17
31
|
|
|
@@ -3,7 +3,8 @@ import importlib
|
|
|
3
3
|
from types import SimpleNamespace
|
|
4
4
|
|
|
5
5
|
from koatl.runtime.record import Record
|
|
6
|
-
from . import meta_finder
|
|
6
|
+
from . import meta_finder
|
|
7
|
+
from .vattr import vhas, vget
|
|
7
8
|
|
|
8
9
|
meta_finder.install_hook()
|
|
9
10
|
|
|
@@ -42,6 +43,6 @@ __tl__ = SimpleNamespace(
|
|
|
42
43
|
#
|
|
43
44
|
set_exports=set_exports,
|
|
44
45
|
#
|
|
45
|
-
vget=
|
|
46
|
-
vhas=
|
|
46
|
+
vget=vget,
|
|
47
|
+
vhas=vhas,
|
|
47
48
|
)
|
|
@@ -31,7 +31,7 @@ export Async = class(MonadOnce):
|
|
|
31
31
|
self = gen.send(yield from self.__await__())
|
|
32
32
|
if not hasattr(self, "__await__"):
|
|
33
33
|
raise ValueError(f"Expected the binder to return an Awaitable, but got {type(self).__name__}")
|
|
34
|
-
except StopIteration(value=value)
|
|
34
|
+
except StopIteration(value=value) =>
|
|
35
35
|
return value
|
|
36
36
|
|
|
37
37
|
pure = staticmethod& x => Async.from_generator_fn& () =>
|
|
@@ -7,10 +7,10 @@ export do = f => wraps(f)& (*args, **kwargs) =>
|
|
|
7
7
|
let m
|
|
8
8
|
try:
|
|
9
9
|
m = gen.send(None)
|
|
10
|
-
except StopIteration() as e
|
|
10
|
+
except StopIteration() as e =>
|
|
11
11
|
raise ValueError(
|
|
12
12
|
"Returning before `@` is not allowed. "
|
|
13
|
-
"Use `return @MonadType.pure(value)` instead."
|
|
13
|
+
+ "Use `return @MonadType.pure(value)` instead."
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
try:
|
|
@@ -18,17 +18,17 @@ export do = f => wraps(f)& (*args, **kwargs) =>
|
|
|
18
18
|
# is it possible to derive bind_gen directly from bind_once?
|
|
19
19
|
|
|
20
20
|
return m.bind_gen(gen)
|
|
21
|
-
except AttributeError()
|
|
21
|
+
except AttributeError() =>
|
|
22
22
|
None
|
|
23
23
|
|
|
24
24
|
let recurse = v =>
|
|
25
25
|
try:
|
|
26
26
|
m = gen.send(v)
|
|
27
27
|
return m.bind_once(recurse)
|
|
28
|
-
except StopIteration() as e
|
|
28
|
+
except StopIteration() as e =>
|
|
29
29
|
return m.pure(e.value)
|
|
30
30
|
|
|
31
31
|
try:
|
|
32
32
|
return m.bind_once(recurse)
|
|
33
|
-
except AttributeError()
|
|
33
|
+
except AttributeError() =>
|
|
34
34
|
raise ValueError("@ can only be used with an object that has `bind_once`.")
|
|
@@ -26,7 +26,7 @@ export Env = class(MonadOnce):
|
|
|
26
26
|
|
|
27
27
|
bind_once = (self, f) => Env& ctx =>
|
|
28
28
|
let v = f(self.f(ctx))
|
|
29
|
-
if v matches
|
|
29
|
+
if v not matches Env():
|
|
30
30
|
raise ValueError(f"Expected the binder to return an Env, but got {type(v)}")
|
|
31
31
|
|
|
32
32
|
v.f(ctx)
|
|
@@ -35,9 +35,9 @@ export Env = class(MonadOnce):
|
|
|
35
35
|
try:
|
|
36
36
|
while True:
|
|
37
37
|
self = gen.send(self.f(ctx))
|
|
38
|
-
if self matches
|
|
38
|
+
if self not matches Env():
|
|
39
39
|
raise ValueError(f"Expected the binder to return an Env, but got {type(self)}")
|
|
40
|
-
except StopIteration(value=value)
|
|
40
|
+
except StopIteration(value=value) =>
|
|
41
41
|
return value
|
|
42
42
|
|
|
43
43
|
NoKey = object()
|
|
@@ -24,7 +24,7 @@ export Memo = class(MonadOnce):
|
|
|
24
24
|
|
|
25
25
|
__repr__ = self => f"Memo.Cache({self.cache})"
|
|
26
26
|
|
|
27
|
-
try_get = (self, name, deps) =>
|
|
27
|
+
try_get = (self, name, deps) => check self.cache[name][deps] except KeyError()
|
|
28
28
|
|
|
29
29
|
update = (self, name, deps, value) =>
|
|
30
30
|
self.cache[name][deps] = value
|
|
@@ -88,7 +88,7 @@ export Memo = class(MonadOnce):
|
|
|
88
88
|
bind_once = (self, f) => Memo(ctx =>
|
|
89
89
|
let value = f(self.f(ctx))
|
|
90
90
|
|
|
91
|
-
if value matches
|
|
91
|
+
if value not matches Memo():
|
|
92
92
|
raise ValueError(f"Expected the binder to return a Memo, but got {type(value)}")
|
|
93
93
|
|
|
94
94
|
return value.f(ctx)
|
|
@@ -100,10 +100,9 @@ export Memo = class(MonadOnce):
|
|
|
100
100
|
let inner = self.f(ctx)
|
|
101
101
|
self = gen.send(inner)
|
|
102
102
|
|
|
103
|
-
if self matches
|
|
103
|
+
if self not matches Memo():
|
|
104
104
|
raise ValueError(f"Expected the binder to return a Memo, but got {type(value)}")
|
|
105
|
-
|
|
106
|
-
except StopIteration(value=value):
|
|
105
|
+
except StopIteration(value=value) =>
|
|
107
106
|
return value
|
|
108
107
|
)
|
|
109
108
|
|
|
@@ -164,7 +163,7 @@ export AsyncMemo = class(MonadOnce):
|
|
|
164
163
|
bind_once = (self, f) => AsyncMemo(ctx =>
|
|
165
164
|
let value = f(@self.f(ctx))
|
|
166
165
|
|
|
167
|
-
if value matches
|
|
166
|
+
if value not matches AsyncMemo():
|
|
168
167
|
raise ValueError(f"Expected the binder to return a Memo, but got {type(value)}")
|
|
169
168
|
|
|
170
169
|
return value.f(ctx)
|
|
@@ -176,9 +175,9 @@ export AsyncMemo = class(MonadOnce):
|
|
|
176
175
|
let inner = @self.f(ctx)
|
|
177
176
|
self = gen.send(inner)
|
|
178
177
|
|
|
179
|
-
if self matches
|
|
178
|
+
if self not matches AsyncMemo():
|
|
180
179
|
raise ValueError(f"Expected the binder to return a Memo, but got {type(value)}")
|
|
181
180
|
|
|
182
|
-
except StopIteration(value=value)
|
|
181
|
+
except StopIteration(value=value) =>
|
|
183
182
|
return value
|
|
184
183
|
)
|
|
@@ -5,7 +5,7 @@ infer_ok = x =>
|
|
|
5
5
|
x match:
|
|
6
6
|
None => False
|
|
7
7
|
BaseException() => False
|
|
8
|
-
|
|
8
|
+
_ => True
|
|
9
9
|
|
|
10
10
|
op_coal = (x, f) =>
|
|
11
11
|
if x matches Result():
|
|
@@ -42,7 +42,7 @@ export Result = class(MonadOnce):
|
|
|
42
42
|
"""
|
|
43
43
|
try:
|
|
44
44
|
return Ok(f())
|
|
45
|
-
except BaseException() as e
|
|
45
|
+
except BaseException() as e =>
|
|
46
46
|
return Err(e)
|
|
47
47
|
|
|
48
48
|
bind_once = (self, f) =>
|
|
@@ -50,7 +50,7 @@ export Result = class(MonadOnce):
|
|
|
50
50
|
return self
|
|
51
51
|
|
|
52
52
|
let value = f(self.value)
|
|
53
|
-
if value matches
|
|
53
|
+
if value not matches Result():
|
|
54
54
|
raise ValueError(f"Expected the binder to return a Result, but got {type(value)}")
|
|
55
55
|
value
|
|
56
56
|
|
|
@@ -61,9 +61,9 @@ export Result = class(MonadOnce):
|
|
|
61
61
|
return self
|
|
62
62
|
|
|
63
63
|
self = gen.send(self.value)
|
|
64
|
-
if self matches
|
|
64
|
+
if self not matches Result():
|
|
65
65
|
raise ValueError(f"Expected the binder to return a Result, but got {type(self)}")
|
|
66
|
-
except StopIteration(value=value)
|
|
66
|
+
except StopIteration(value=value) =>
|
|
67
67
|
return Result(value)
|
|
68
68
|
|
|
69
69
|
pure = staticmethod& x => Ok(x)
|
|
@@ -5,14 +5,14 @@ import koatl.std.alg.Monad
|
|
|
5
5
|
export List = class(Monad):
|
|
6
6
|
__new__ = (cls, *args, **kwargs) => raise ValueError(
|
|
7
7
|
"List cannot be instantiated directly. "
|
|
8
|
-
"Use [] or list()."
|
|
8
|
+
+ "Use [] or list()."
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
bind_once = (self, f) =>
|
|
12
12
|
raise NotImplementedError(
|
|
13
13
|
"List may not be bound using @ "
|
|
14
|
-
"due to generator limitations. "
|
|
15
|
-
"Wrap in Ok to use the Result monad."
|
|
14
|
+
+ "due to generator limitations. "
|
|
15
|
+
+ "Wrap in Ok to use the Result monad."
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
bind = (self, f) => List(self.flat_map(f))
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import itertools
|
|
2
2
|
import builtins
|
|
3
3
|
|
|
4
|
+
import koatl.std.data.Record
|
|
4
5
|
import koatl.std.trait.Trait
|
|
5
6
|
import .alg.(Traversable, Ok, Err, Memo, Async, AsyncMemo, Result)
|
|
6
7
|
|
|
@@ -20,7 +21,7 @@ export Iterable = class(Traversable, Trait):
|
|
|
20
21
|
let value = next(it)
|
|
21
22
|
if not f(value):
|
|
22
23
|
return Iterable.chain([value], it)
|
|
23
|
-
except StopIteration()
|
|
24
|
+
except StopIteration() =>
|
|
24
25
|
return it
|
|
25
26
|
|
|
26
27
|
take = (self, n) =>
|
|
@@ -29,7 +30,7 @@ export Iterable = class(Traversable, Trait):
|
|
|
29
30
|
for _ in ..n:
|
|
30
31
|
try:
|
|
31
32
|
yield next(it)
|
|
32
|
-
except StopIteration(value=value)
|
|
33
|
+
except StopIteration(value=value) =>
|
|
33
34
|
return value
|
|
34
35
|
|
|
35
36
|
impl.__name__ = f"take"
|
|
@@ -52,6 +53,9 @@ export Iterable = class(Traversable, Trait):
|
|
|
52
53
|
chain = (self, *others) =>
|
|
53
54
|
itertools.chain(self.iter, *others.map($.iter))
|
|
54
55
|
|
|
56
|
+
product = (self, *others) =>
|
|
57
|
+
itertools.product(self.iter, *others.map($.iter))
|
|
58
|
+
|
|
55
59
|
zip = (self, *others) =>
|
|
56
60
|
zip(self.iter, *others.map($.iter))
|
|
57
61
|
|
|
@@ -148,7 +152,7 @@ export Iterable = class(Traversable, Trait):
|
|
|
148
152
|
return Err()
|
|
149
153
|
|
|
150
154
|
first = self =>
|
|
151
|
-
(
|
|
155
|
+
(check next(self.iter)).map_err(_ => None)
|
|
152
156
|
|
|
153
157
|
last = (self, f) =>
|
|
154
158
|
let result = Err()
|
|
@@ -208,7 +212,7 @@ export Iterable = class(Traversable, Trait):
|
|
|
208
212
|
m = v
|
|
209
213
|
else:
|
|
210
214
|
m = key(v)
|
|
211
|
-
except StopIteration(value=value)
|
|
215
|
+
except StopIteration(value=value) =>
|
|
212
216
|
raise ValueError("max of empty iterable")
|
|
213
217
|
|
|
214
218
|
|
|
@@ -235,7 +239,7 @@ export Iterable = class(Traversable, Trait):
|
|
|
235
239
|
m = v
|
|
236
240
|
else:
|
|
237
241
|
m = key(v)
|
|
238
|
-
except StopIteration(value=value)
|
|
242
|
+
except StopIteration(value=value) =>
|
|
239
243
|
raise ValueError("min of empty iterable")
|
|
240
244
|
|
|
241
245
|
if key === None:
|
|
@@ -268,7 +272,7 @@ export Iterable = class(Traversable, Trait):
|
|
|
268
272
|
let v
|
|
269
273
|
try:
|
|
270
274
|
v = next(it)
|
|
271
|
-
except StopIteration()
|
|
275
|
+
except StopIteration() =>
|
|
272
276
|
return []
|
|
273
277
|
|
|
274
278
|
let m = f(v)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import koatl.std.io
|
|
3
|
+
import koatl.std.data.Record
|
|
4
|
+
|
|
5
|
+
export JSONEncoder = class(json.JSONEncoder):
|
|
6
|
+
default = (self, o) =>
|
|
7
|
+
o match:
|
|
8
|
+
Record() => o.__dict__
|
|
9
|
+
default => super().default(o)
|
|
10
|
+
|
|
11
|
+
export JSONDecoder = class(json.JSONDecoder):
|
|
12
|
+
__init__ = (self, **kwargs) =>
|
|
13
|
+
let object_hook = d =>
|
|
14
|
+
d match:
|
|
15
|
+
dict() => Record(d)
|
|
16
|
+
default => d
|
|
17
|
+
|
|
18
|
+
super().__init__(object_hook=object_hook, **kwargs)
|
|
19
|
+
|
|
20
|
+
export parse = json_str => JSONDecoder().decode(json_str)
|
|
21
|
+
|
|
22
|
+
export stringify = (obj, **kwargs) => JSONEncoder(**kwargs).encode(obj)
|
|
23
|
+
|
|
24
|
+
export pretty = obj => stringify(obj, indent=2)
|
|
25
|
+
|
|
26
|
+
export compact = obj => stringify(obj, separators=(",", ":"))
|
|
27
|
+
|
|
28
|
+
export read_file = filename =>
|
|
29
|
+
let s = io.read_file(filename)
|
|
30
|
+
parse(s)
|
|
31
|
+
|
|
32
|
+
export write_file = (filename, obj, indent=2, sort_keys=True) =>
|
|
33
|
+
let s = stringify(obj, indent=indent, sort_keys=sort_keys)
|
|
34
|
+
io.write_file(filename, s)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import pickle
|
|
2
|
+
import koatl.std.io
|
|
3
|
+
|
|
4
|
+
export write_file = (filename, obj, protocol=None) =>
|
|
5
|
+
with f = open(filename, "wb"):
|
|
6
|
+
pickle.dump(obj, f, protocol=protocol ?? pickle.DEFAULT_PROTOCOL)
|
|
7
|
+
|
|
8
|
+
export load_file = filename =>
|
|
9
|
+
with f = open(filename, "rb"):
|
|
10
|
+
pickle.load(f)
|
|
@@ -2,7 +2,7 @@ import abc
|
|
|
2
2
|
import collections
|
|
3
3
|
import inspect
|
|
4
4
|
|
|
5
|
-
from koatl.
|
|
5
|
+
from koatl.runtime import vhas
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
@collections.abc.Mapping.register
|
|
@@ -90,7 +90,7 @@ class TraitMeta(MappingMeta):
|
|
|
90
90
|
# Check if the exact class has _trait_reqs, in which case it's a trait.
|
|
91
91
|
if "_trait_reqs" in cls.__dict__:
|
|
92
92
|
for req in cls._trait_reqs:
|
|
93
|
-
if not
|
|
93
|
+
if not vhas(instance, req):
|
|
94
94
|
return False
|
|
95
95
|
|
|
96
96
|
return True
|
|
@@ -1,28 +1,36 @@
|
|
|
1
1
|
import util.assert_eq
|
|
2
2
|
|
|
3
3
|
# parsing test
|
|
4
|
-
1 match
|
|
4
|
+
1 match:
|
|
5
|
+
1 if False => 2
|
|
6
|
+
_ => 3
|
|
5
7
|
|
|
6
8
|
assert_eq(
|
|
7
|
-
1 match
|
|
9
|
+
1 match:
|
|
10
|
+
1 if False => 2
|
|
11
|
+
_ => 3
|
|
8
12
|
3
|
|
9
13
|
)
|
|
10
14
|
|
|
11
15
|
assert_eq(
|
|
12
|
-
1 match
|
|
16
|
+
1 match:
|
|
17
|
+
1 if False => 2
|
|
18
|
+
_ => 3
|
|
13
19
|
3
|
|
14
20
|
)
|
|
15
21
|
|
|
16
22
|
x = 1
|
|
17
23
|
assert_eq(
|
|
18
|
-
1 match
|
|
24
|
+
1 match:
|
|
25
|
+
.x => 2
|
|
26
|
+
_ => 3
|
|
19
27
|
2
|
|
20
28
|
)
|
|
21
29
|
|
|
22
30
|
assert_eq(
|
|
23
31
|
1 match:
|
|
24
32
|
.x => 2
|
|
25
|
-
|
|
33
|
+
_ => 3
|
|
26
34
|
2
|
|
27
35
|
)
|
|
28
36
|
|
|
@@ -34,7 +42,7 @@ assert_eq(
|
|
|
34
42
|
)
|
|
35
43
|
|
|
36
44
|
assert_eq(
|
|
37
|
-
match
|
|
45
|
+
1 match:
|
|
38
46
|
.x => 2
|
|
39
47
|
_ => 3
|
|
40
48
|
2
|
|
@@ -42,29 +50,36 @@ assert_eq(
|
|
|
42
50
|
|
|
43
51
|
x = 1
|
|
44
52
|
assert_eq(
|
|
45
|
-
2 match
|
|
53
|
+
2 match:
|
|
54
|
+
.x => 2
|
|
55
|
+
_ => 3
|
|
46
56
|
3
|
|
47
57
|
)
|
|
48
58
|
|
|
49
59
|
assert_eq(
|
|
50
|
-
2 match
|
|
60
|
+
2 match:
|
|
61
|
+
x => 2
|
|
51
62
|
2
|
|
52
63
|
)
|
|
53
64
|
|
|
54
65
|
assert_eq(
|
|
55
|
-
[1, 2, 3] match
|
|
66
|
+
[1, 2, 3] match:
|
|
67
|
+
[3, *x] => x
|
|
68
|
+
_ => 123
|
|
56
69
|
123
|
|
57
70
|
)
|
|
58
71
|
|
|
59
72
|
assert_eq(
|
|
60
|
-
[1, 2, 3] match
|
|
73
|
+
[1, 2, 3] match:
|
|
74
|
+
[1, *x] => x
|
|
75
|
+
_ => 123
|
|
61
76
|
[2, 3] | list
|
|
62
77
|
)
|
|
63
78
|
|
|
64
79
|
assert_eq(
|
|
65
80
|
[1, 2, 3] match:
|
|
66
81
|
[1, *x] => x
|
|
67
|
-
|
|
82
|
+
_ =>
|
|
68
83
|
123
|
|
69
84
|
[2, 3] | list
|
|
70
85
|
)
|
|
@@ -79,7 +94,7 @@ f = () =>
|
|
|
79
94
|
else:
|
|
80
95
|
raise
|
|
81
96
|
|
|
82
|
-
if [1, 2, 3] matches
|
|
97
|
+
if [1, 2, 3] not matches [1, 2, x]:
|
|
83
98
|
raise
|
|
84
99
|
else:
|
|
85
100
|
assert_eq(x, 3)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import util.assert_eq
|
|
2
|
+
|
|
3
|
+
# precedence
|
|
4
|
+
assert_eq(check 1 ?? 2, 1)
|
|
5
|
+
assert_eq(check z ?? 2, 2)
|
|
6
|
+
assert_eq(check z matches Err(NameError()), True)
|
|
7
|
+
assert_eq(check z ?? check 1 ?? 2, 1)
|
|
8
|
+
assert_eq(check z ?? check None ?? 2, None)
|
|
9
|
+
assert_eq(check z ?? Err(None) ?? 2, 2)
|
|
10
|
+
|
|
11
|
+
err_type = NameError
|
|
12
|
+
assert_eq(check a except err_type() matches Err(), True)
|
|
13
|
+
|
|
14
|
+
# handlers
|
|
15
|
+
assert_eq(check 1 except ValueError() ?? 2, 1)
|
|
16
|
+
assert_eq(check a except NameError() ?? 2, 2)
|
|
17
|
+
assert_eq(check a except (ValueError() | NameError()) ?? 2, 2)
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
check a except (ValueError() | StopIteration())
|
|
21
|
+
raise
|
|
22
|
+
except _ =>
|
|
23
|
+
None
|
|
24
|
+
|
|
25
|
+
assert_eq(check 1 matches Ok(1), True)
|
|
26
|
+
|
|
27
|
+
assert_eq((check 5)?.($+1), Ok(6))
|
|
28
|
+
assert_eq((check x)?.($+1) matches Err(), True)
|
|
@@ -28,5 +28,5 @@ assert_eq(None.some_global_prop, ())
|
|
|
28
28
|
assert_eq({required_method: Record.method& self => 42}.derived_method(), 42)
|
|
29
29
|
assert_eq({required_method: Record.method& self => 42}.derived_property, 42)
|
|
30
30
|
|
|
31
|
-
assert_eq((
|
|
32
|
-
assert_eq((
|
|
31
|
+
assert_eq((check "asdf".derived_method).ok, False)
|
|
32
|
+
assert_eq((check "asdf".derived_prop).ok, False)
|