koatl 0.1.14__tar.gz → 0.1.15__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.14 → koatl-0.1.15}/Cargo.lock +2 -1
- {koatl-0.1.14 → koatl-0.1.15}/PKG-INFO +1 -1
- {koatl-0.1.14 → koatl-0.1.15}/koatl/Cargo.toml +1 -1
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/notebook/__init__.py +14 -5
- {koatl-0.1.14 → koatl-0.1.15/koatl}/python/koatl/prelude/functional/__init__.tl +2 -2
- {koatl-0.1.14 → koatl-0.1.15/koatl}/python/koatl/prelude/functional/async.tl +5 -4
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/prelude/functional/reader.tl +3 -5
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/prelude/iterable.tl +3 -3
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/runtime/__init__.py +1 -0
- {koatl-0.1.14 → koatl-0.1.15/koatl}/python/koatl/runtime/helpers.py +3 -1
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/runtime/meta_finder.py +1 -1
- {koatl-0.1.14 → koatl-0.1.15}/koatl/src/emit_py.rs +24 -11
- {koatl-0.1.14 → koatl-0.1.15}/koatl/src/lib.rs +1 -1
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/coal.tl +5 -4
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/if_expr.tl +1 -1
- koatl-0.1.15/koatl/tests/e2e/base/scopes.tl +49 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/semantic_whitespace.tl +2 -2
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/test_e2e.py +26 -9
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/Cargo.toml +1 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/parser/Cargo.toml +1 -1
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/parser/src/ast.rs +56 -40
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/parser/src/lexer.rs +2 -2
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/parser/src/parser.rs +220 -153
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/parser/src/util.rs +33 -36
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/src/lib.rs +2 -2
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/src/main.rs +1 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/src/py/ast.rs +19 -12
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/src/py/emit.rs +16 -2
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/src/py/util.rs +18 -2
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/src/transform.rs +1595 -1186
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/notebook/__init__.py +14 -5
- {koatl-0.1.14/koatl → koatl-0.1.15}/python/koatl/prelude/functional/__init__.tl +2 -2
- {koatl-0.1.14/koatl → koatl-0.1.15}/python/koatl/prelude/functional/async.tl +5 -4
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/prelude/functional/reader.tl +3 -5
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/prelude/iterable.tl +3 -3
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/runtime/__init__.py +1 -0
- {koatl-0.1.14/koatl → koatl-0.1.15}/python/koatl/runtime/helpers.py +3 -1
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/runtime/meta_finder.py +1 -1
- {koatl-0.1.14 → koatl-0.1.15}/Cargo.toml +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/README.md +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/.github/workflows/CI.yml +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/.gitignore +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/LICENSE +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/README.md +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/__init__.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/__main__.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/cli.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/notebook/magic.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/prelude/__init__.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/prelude/functional/async_util.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/prelude/functional/monad.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/prelude/functional/result.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/runtime/record.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/python/koatl/runtime/virtual.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/requirements.txt +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/containers.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/decorators.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/destructure-for-and-fn.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/destructure.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/escape_ident.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/fstr.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/functions.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/generator.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/imports.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/iterables.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/loops.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/match.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/nary-list.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/placeholder.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/precedence.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/slice.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/base/try.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/destructure.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/prelude/async.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/prelude/reader.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/prelude/result.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/prelude/virtual.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/util/__init__.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/util/module0.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/util/module1.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/e2e/util/module2.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/parse/arith.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/parse/assign.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/parse/deco.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/parse/func.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/parse/matches.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl/tests/test_parse.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/parser/src/lib.rs +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/parser/tests/lexer.rs +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/src/linecol.rs +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/src/parser.rs +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/koatl-core/src/py/mod.rs +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/pyproject.toml +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/__init__.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/__main__.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/cli.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/notebook/magic.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/prelude/__init__.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/prelude/functional/async_util.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/prelude/functional/monad.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/prelude/functional/result.tl +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/runtime/record.py +0 -0
- {koatl-0.1.14 → koatl-0.1.15}/python/koatl/runtime/virtual.py +0 -0
|
@@ -99,7 +99,7 @@ checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
|
|
|
99
99
|
|
|
100
100
|
[[package]]
|
|
101
101
|
name = "koatl"
|
|
102
|
-
version = "0.1.
|
|
102
|
+
version = "0.1.15"
|
|
103
103
|
dependencies = [
|
|
104
104
|
"ariadne",
|
|
105
105
|
"koatl-core",
|
|
@@ -112,6 +112,7 @@ name = "koatl-core"
|
|
|
112
112
|
version = "0.1.0"
|
|
113
113
|
dependencies = [
|
|
114
114
|
"ariadne",
|
|
115
|
+
"once_cell",
|
|
115
116
|
"parser",
|
|
116
117
|
]
|
|
117
118
|
|
|
@@ -21,14 +21,23 @@ def source_code_transformer(lines):
|
|
|
21
21
|
return lines
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
def
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
def try_import_prelude(namespace):
|
|
25
|
+
try:
|
|
26
|
+
exec("from koatl.runtime import *", namespace)
|
|
27
|
+
exec("from koatl.prelude import *", namespace)
|
|
28
|
+
except Exception as e:
|
|
29
|
+
import traceback
|
|
30
|
+
|
|
31
|
+
print(
|
|
32
|
+
"There was an error importing the Koatl prelude. Some features may not work."
|
|
33
|
+
)
|
|
34
|
+
traceback.print_exc()
|
|
27
35
|
|
|
28
36
|
|
|
29
37
|
def load_ipython_extension(ipython):
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
print("Switched notebook to Koatl.")
|
|
39
|
+
|
|
40
|
+
try_import_prelude(ipython.user_ns)
|
|
32
41
|
|
|
33
42
|
ttm = ipython.input_transformer_manager
|
|
34
43
|
|
|
@@ -9,8 +9,8 @@ export Fn = class:
|
|
|
9
9
|
[] => raise ValueError("At least one function is required for composition")
|
|
10
10
|
[f] => f
|
|
11
11
|
[*fs] =>
|
|
12
|
-
composed = (*args, **kwargs) =>
|
|
13
|
-
value = fs[-1](*args, **kwargs)
|
|
12
|
+
let composed = (*args, **kwargs) =>
|
|
13
|
+
let value = fs[-1](*args, **kwargs)
|
|
14
14
|
for f in fs[..-1..-1]:
|
|
15
15
|
value = f(value)
|
|
16
16
|
value
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import functools.wraps
|
|
2
2
|
import asyncio
|
|
3
|
+
|
|
3
4
|
import .async_util
|
|
5
|
+
import .monad.Monad
|
|
4
6
|
|
|
5
|
-
export Async = class:
|
|
7
|
+
export Async = class(Monad):
|
|
6
8
|
__init__ = (self, awaitable) => self.generator = awaitable.__await__()
|
|
7
9
|
|
|
8
10
|
__await__ = self => self.generator
|
|
@@ -10,14 +12,14 @@ export Async = class:
|
|
|
10
12
|
__repr__ = self => "Async(...)"
|
|
11
13
|
|
|
12
14
|
from_generator_fn = staticmethod& (generator_fn, *args, **kwargs) =>
|
|
13
|
-
m = object.__new__(Async)
|
|
15
|
+
let m = object.__new__(Async)
|
|
14
16
|
m.generator = generator_fn(*args, **kwargs)
|
|
15
17
|
return m
|
|
16
18
|
|
|
17
19
|
run = self => asyncio.run(async_util.to_coro(self))
|
|
18
20
|
|
|
19
21
|
bind_once = (self, f) => Async.from_generator_fn& () =>
|
|
20
|
-
result = f(yield from self.__await__())
|
|
22
|
+
let result = f(yield from self.__await__())
|
|
21
23
|
|
|
22
24
|
if hasattr(result, "__await__"):
|
|
23
25
|
return yield from result.__await__()
|
|
@@ -25,7 +27,6 @@ export Async = class:
|
|
|
25
27
|
return result
|
|
26
28
|
|
|
27
29
|
bind_gen = (self, gen) => Async.from_generator_fn& () =>
|
|
28
|
-
nonlocal self = self
|
|
29
30
|
try:
|
|
30
31
|
while True:
|
|
31
32
|
self = gen.send(yield from self.__await__())
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import functools.wraps
|
|
2
|
+
import .monad.Monad
|
|
2
3
|
|
|
3
|
-
export Reader = class:
|
|
4
|
+
export Reader = class(Monad):
|
|
4
5
|
__init__ = (self, fn) => self.fn = fn
|
|
5
6
|
|
|
6
7
|
__repr__ = self => "Reader(...)"
|
|
@@ -8,16 +9,13 @@ export Reader = class:
|
|
|
8
9
|
run = (self, ctx) => self.fn(ctx)
|
|
9
10
|
|
|
10
11
|
bind_once = (self, f) => Reader& ctx =>
|
|
11
|
-
v = f(self.fn(ctx))
|
|
12
|
+
let v = f(self.fn(ctx))
|
|
12
13
|
if v matches Reader():
|
|
13
14
|
v.fn(ctx)
|
|
14
15
|
else:
|
|
15
16
|
v
|
|
16
17
|
|
|
17
|
-
# TODO: this is a workaround to avoid recursion.
|
|
18
|
-
# how to get bind_gen directly from bind_once?
|
|
19
18
|
bind_gen = (self, gen) => Reader& ctx =>
|
|
20
|
-
nonlocal self = self
|
|
21
19
|
try:
|
|
22
20
|
while True:
|
|
23
21
|
self = gen.send(self.fn(ctx))
|
|
@@ -13,7 +13,7 @@ methods = {
|
|
|
13
13
|
yield from f(i)
|
|
14
14
|
|
|
15
15
|
fold: (x, init, f) =>
|
|
16
|
-
acc = init
|
|
16
|
+
let acc = init
|
|
17
17
|
for i in x:
|
|
18
18
|
acc = f(acc, i)
|
|
19
19
|
acc
|
|
@@ -25,7 +25,7 @@ methods = {
|
|
|
25
25
|
return None
|
|
26
26
|
|
|
27
27
|
last: (x, f) =>
|
|
28
|
-
result = None
|
|
28
|
+
let result = None
|
|
29
29
|
for i in x:
|
|
30
30
|
if f(i):
|
|
31
31
|
result = i
|
|
@@ -38,7 +38,7 @@ methods = {
|
|
|
38
38
|
raise IndexError("Index out of range")
|
|
39
39
|
|
|
40
40
|
sum: x =>
|
|
41
|
-
acc = 0
|
|
41
|
+
let acc = 0
|
|
42
42
|
for i in x:
|
|
43
43
|
acc = acc + i
|
|
44
44
|
acc
|
|
@@ -75,7 +75,9 @@ def do(f):
|
|
|
75
75
|
return e.value
|
|
76
76
|
|
|
77
77
|
try:
|
|
78
|
-
|
|
78
|
+
# TODO: this is a workaround to avoid recursion.
|
|
79
|
+
# is it possible to get bind_gen directly from bind_once?
|
|
80
|
+
|
|
79
81
|
return vget(m, "bind_gen")(gen)
|
|
80
82
|
except (NotImplementedError, AttributeError):
|
|
81
83
|
return vget(m, "bind_once")(recurse)
|
|
@@ -54,7 +54,7 @@ class TlLoader(Loader):
|
|
|
54
54
|
|
|
55
55
|
if module.__name__.startswith("koatl.prelude"):
|
|
56
56
|
transpiled_code = transpile(
|
|
57
|
-
source_code, mode="
|
|
57
|
+
source_code, mode="no_prelude", filename=self.filepath
|
|
58
58
|
)
|
|
59
59
|
else:
|
|
60
60
|
transpiled_code = transpile(
|
|
@@ -333,18 +333,31 @@ impl<'src> PyStmtExt<'src> for SPyStmt<'src> {
|
|
|
333
333
|
&self.tl_span,
|
|
334
334
|
)
|
|
335
335
|
}
|
|
336
|
-
PyStmt::FnDef(
|
|
337
|
-
let arguments = args.emit_py(ctx)?;
|
|
338
|
-
let body_ast = body.emit_py(ctx)?;
|
|
339
|
-
let decorators = decorators.emit_py(ctx)?;
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
336
|
+
PyStmt::FnDef(fndef) => {
|
|
337
|
+
let arguments = fndef.args.emit_py(ctx)?;
|
|
338
|
+
let body_ast = fndef.body.emit_py(ctx)?;
|
|
339
|
+
let decorators = fndef.decorators.emit_py(ctx)?;
|
|
340
|
+
|
|
341
|
+
if fndef.async_ {
|
|
342
|
+
ctx.ast_node(
|
|
343
|
+
"AsyncFunctionDef",
|
|
344
|
+
(fndef.name.as_ref(), arguments, body_ast, decorators),
|
|
345
|
+
&self.tl_span,
|
|
346
|
+
)
|
|
347
|
+
} else {
|
|
348
|
+
ctx.ast_node(
|
|
349
|
+
"FunctionDef",
|
|
350
|
+
(fndef.name.as_ref(), arguments, body_ast, decorators),
|
|
351
|
+
&self.tl_span,
|
|
352
|
+
)
|
|
353
|
+
}
|
|
346
354
|
}
|
|
347
|
-
PyStmt::ClassDef(
|
|
355
|
+
PyStmt::ClassDef(PyClassDef {
|
|
356
|
+
name,
|
|
357
|
+
bases,
|
|
358
|
+
body,
|
|
359
|
+
decorators,
|
|
360
|
+
}) => {
|
|
348
361
|
let mut bases_ast = Vec::new();
|
|
349
362
|
let mut keywords_ast = Vec::new();
|
|
350
363
|
|
|
@@ -14,7 +14,7 @@ use pyo3::{
|
|
|
14
14
|
fn get_option(mode: &str) -> PyResult<TranspileOptions> {
|
|
15
15
|
Ok(match mode {
|
|
16
16
|
"module" => TranspileOptions::module(),
|
|
17
|
-
"
|
|
17
|
+
"no_prelude" => TranspileOptions::no_prelude(),
|
|
18
18
|
"interactive" => TranspileOptions::interactive(),
|
|
19
19
|
"script" => TranspileOptions::script(),
|
|
20
20
|
_ => {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import util.assert_eq
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
assert_eq(
|
|
5
|
-
assert_eq(
|
|
6
|
-
assert_eq(
|
|
3
|
+
none = None
|
|
4
|
+
assert_eq(none?(1)?(2), None)
|
|
5
|
+
assert_eq(none?[1]?.a, None)
|
|
6
|
+
assert_eq(none?.a, None)
|
|
7
|
+
assert_eq(none?.(a), None)
|
|
7
8
|
|
|
8
9
|
obj = (class:
|
|
9
10
|
a = 1
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import util.assert_eq
|
|
2
|
+
|
|
3
|
+
test = 1
|
|
4
|
+
if True:
|
|
5
|
+
test = 2
|
|
6
|
+
assert_eq(test, 2)
|
|
7
|
+
|
|
8
|
+
let test = 3
|
|
9
|
+
assert_eq(test, 3)
|
|
10
|
+
|
|
11
|
+
test = 4
|
|
12
|
+
assert_eq(test, 4)
|
|
13
|
+
|
|
14
|
+
assert_eq(test, 2)
|
|
15
|
+
|
|
16
|
+
f = () =>
|
|
17
|
+
let test = 5
|
|
18
|
+
assert_eq(test, 5)
|
|
19
|
+
|
|
20
|
+
f()
|
|
21
|
+
assert_eq(test, 2)
|
|
22
|
+
|
|
23
|
+
f = () =>
|
|
24
|
+
test = 5
|
|
25
|
+
let g = () =>
|
|
26
|
+
test = 6
|
|
27
|
+
g()
|
|
28
|
+
assert_eq(test, 6)
|
|
29
|
+
|
|
30
|
+
f()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
f = () =>
|
|
34
|
+
test = 5
|
|
35
|
+
let g = () =>
|
|
36
|
+
let test = 6
|
|
37
|
+
g()
|
|
38
|
+
assert_eq(test, 5)
|
|
39
|
+
|
|
40
|
+
f()
|
|
41
|
+
|
|
42
|
+
test = 0
|
|
43
|
+
|
|
44
|
+
f = test =>
|
|
45
|
+
test = 1
|
|
46
|
+
assert_eq(test, 1)
|
|
47
|
+
|
|
48
|
+
f(1)
|
|
49
|
+
assert_eq(test, 0)
|
|
@@ -64,7 +64,7 @@ assert_eq([
|
|
|
64
64
|
apply = (x, y) => x(y)
|
|
65
65
|
assert_eq(apply(
|
|
66
66
|
x =>
|
|
67
|
-
y = x * 2
|
|
67
|
+
let y = x * 2
|
|
68
68
|
y * 2
|
|
69
69
|
8
|
|
70
70
|
), 8 * 2 * 2)
|
|
@@ -72,7 +72,7 @@ assert_eq(apply(
|
|
|
72
72
|
assert_eq(
|
|
73
73
|
apply(
|
|
74
74
|
x =>
|
|
75
|
-
y = x * 2
|
|
75
|
+
let y = x * 2
|
|
76
76
|
y * 2
|
|
77
77
|
8
|
|
78
78
|
)
|
|
@@ -6,10 +6,9 @@ from pathlib import Path
|
|
|
6
6
|
sys.path.append(str(Path(__file__).parent / "e2e"))
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def get_test_data():
|
|
9
|
+
def get_test_data(dirs):
|
|
10
10
|
data_dirs = [
|
|
11
|
-
Path(__file__).parent / "e2e" /
|
|
12
|
-
Path(__file__).parent / "e2e" / "prelude",
|
|
11
|
+
Path(__file__).parent / "e2e" / dirs,
|
|
13
12
|
]
|
|
14
13
|
|
|
15
14
|
test_cases = []
|
|
@@ -20,13 +19,32 @@ def get_test_data():
|
|
|
20
19
|
return test_cases
|
|
21
20
|
|
|
22
21
|
|
|
23
|
-
@pytest.mark.parametrize("test_file", get_test_data())
|
|
24
|
-
def
|
|
22
|
+
@pytest.mark.parametrize("test_file", get_test_data("base"))
|
|
23
|
+
def test_e2e_native_emit_base(test_file):
|
|
24
|
+
e2e_native_emit(test_file, "no_prelude")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@pytest.mark.parametrize("test_file", get_test_data("prelude"))
|
|
28
|
+
def test_e2e_native_emit_prelude(test_file):
|
|
29
|
+
e2e_native_emit(test_file, "script")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@pytest.mark.parametrize("test_file", get_test_data("base"))
|
|
33
|
+
def test_e2e_base(test_file):
|
|
34
|
+
e2e(test_file, "no_prelude")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@pytest.mark.parametrize("test_file", get_test_data("prelude"))
|
|
38
|
+
def test_e2e_prelude(test_file):
|
|
39
|
+
e2e(test_file, "script")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def e2e_native_emit(test_file, mode):
|
|
25
43
|
import linecache
|
|
26
44
|
|
|
27
45
|
with open(test_file, "r") as f:
|
|
28
46
|
source = f.read()
|
|
29
|
-
source, source_map = koatl.transpile_raw(source, mode=
|
|
47
|
+
source, source_map = koatl.transpile_raw(source, mode=mode)
|
|
30
48
|
|
|
31
49
|
global_dict = {}
|
|
32
50
|
|
|
@@ -46,6 +64,5 @@ def test_e2e_native_emit(test_file):
|
|
|
46
64
|
print("end", test_file)
|
|
47
65
|
|
|
48
66
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
koatl.cli.run_from_path(test_file, mode="script")
|
|
67
|
+
def e2e(test_file, mode):
|
|
68
|
+
koatl.cli.run_from_path(test_file, mode=mode)
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
use std::borrow::Cow;
|
|
1
|
+
use std::{borrow::Cow, rc::Rc};
|
|
2
2
|
|
|
3
3
|
use chumsky::span::SimpleSpan;
|
|
4
4
|
|
|
5
5
|
pub type Span = SimpleSpan<usize, ()>;
|
|
6
6
|
pub type Spanned<T> = (T, Span);
|
|
7
|
+
pub type Indirect<T> = Rc<T>;
|
|
7
8
|
|
|
8
9
|
#[derive(Debug, Copy, Clone)]
|
|
9
10
|
pub enum BinaryOp {
|
|
@@ -40,7 +41,15 @@ pub enum UnaryOp {
|
|
|
40
41
|
Bind,
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
|
45
|
+
pub struct Ident<'a>(pub Cow<'a, str>);
|
|
46
|
+
|
|
47
|
+
impl<'a> From<Cow<'a, str>> for Ident<'a> {
|
|
48
|
+
fn from(value: Cow<'a, str>) -> Self {
|
|
49
|
+
Ident(value)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
44
53
|
pub type SIdent<'a> = Spanned<Ident<'a>>;
|
|
45
54
|
|
|
46
55
|
#[derive(Debug, Clone)]
|
|
@@ -62,24 +71,26 @@ pub struct ImportStmt<'a> {
|
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
65
|
-
pub enum
|
|
74
|
+
pub enum DeclType {
|
|
66
75
|
Export,
|
|
67
76
|
Global,
|
|
68
|
-
|
|
77
|
+
Let,
|
|
78
|
+
Const,
|
|
69
79
|
}
|
|
70
80
|
|
|
71
81
|
// TODO should these be cows
|
|
72
82
|
#[derive(Debug, Clone)]
|
|
73
83
|
pub enum Stmt<'a> {
|
|
74
84
|
Module,
|
|
75
|
-
|
|
85
|
+
Decl(Vec<SIdent<'a>>, DeclType),
|
|
86
|
+
Assign(SExpr<'a>, SExpr<'a>, Option<DeclType>),
|
|
76
87
|
Expr(SExpr<'a>),
|
|
77
88
|
|
|
78
89
|
Return(SExpr<'a>),
|
|
79
90
|
While(SExpr<'a>, SExpr<'a>),
|
|
80
91
|
For(SPattern<'a>, SExpr<'a>, SExpr<'a>),
|
|
81
92
|
Import(ImportStmt<'a>),
|
|
82
|
-
Try(SExpr<'a>, Vec<MatchCase<'a
|
|
93
|
+
Try(SExpr<'a>, Vec<Indirect<MatchCase<'a>>>, Option<SExpr<'a>>),
|
|
83
94
|
Assert(SExpr<'a>, Option<SExpr<'a>>),
|
|
84
95
|
Raise(Option<SExpr<'a>>),
|
|
85
96
|
Break,
|
|
@@ -101,7 +112,7 @@ pub type SLiteral<'a> = Spanned<Literal<'a>>;
|
|
|
101
112
|
|
|
102
113
|
#[derive(Debug, Clone)]
|
|
103
114
|
pub struct FmtExpr<'a> {
|
|
104
|
-
pub
|
|
115
|
+
pub expr: SExpr<'a>,
|
|
105
116
|
pub fmt: Option<Ident<'a>>,
|
|
106
117
|
}
|
|
107
118
|
|
|
@@ -132,7 +143,7 @@ pub type SCallItem<'a> = Spanned<CallItem<'a>>;
|
|
|
132
143
|
|
|
133
144
|
#[derive(Debug, Clone)]
|
|
134
145
|
pub enum ArgDefItem<'a> {
|
|
135
|
-
Arg(
|
|
146
|
+
Arg(ISPattern<'a>, Option<SExpr<'a>>),
|
|
136
147
|
ArgSpread(SIdent<'a>),
|
|
137
148
|
KwargSpread(SIdent<'a>),
|
|
138
149
|
}
|
|
@@ -141,7 +152,7 @@ pub type SArgItem<'a> = Spanned<ArgDefItem<'a>>;
|
|
|
141
152
|
|
|
142
153
|
#[derive(Debug, Clone)]
|
|
143
154
|
pub struct MatchCase<'src> {
|
|
144
|
-
pub pattern: Option<SPattern<'src
|
|
155
|
+
pub pattern: Option<Indirect<SPattern<'src>>>,
|
|
145
156
|
pub guard: Option<SExpr<'src>>,
|
|
146
157
|
pub body: SExpr<'src>,
|
|
147
158
|
}
|
|
@@ -155,41 +166,45 @@ pub enum Expr<'a> {
|
|
|
155
166
|
List(Vec<ListItem<'a>>),
|
|
156
167
|
Mapping(Vec<MappingItem<'a>>),
|
|
157
168
|
Slice(
|
|
158
|
-
Option<
|
|
159
|
-
Option<
|
|
160
|
-
Option<
|
|
169
|
+
Option<Indirect<SExpr<'a>>>,
|
|
170
|
+
Option<Indirect<SExpr<'a>>>,
|
|
171
|
+
Option<Indirect<SExpr<'a>>>,
|
|
161
172
|
),
|
|
162
173
|
|
|
163
|
-
Unary(UnaryOp,
|
|
164
|
-
Binary(BinaryOp,
|
|
174
|
+
Unary(UnaryOp, Indirect<SExpr<'a>>),
|
|
175
|
+
Binary(BinaryOp, Indirect<SExpr<'a>>, Indirect<SExpr<'a>>),
|
|
165
176
|
|
|
166
|
-
Await(
|
|
167
|
-
Yield(
|
|
168
|
-
YieldFrom(
|
|
177
|
+
Await(Indirect<SExpr<'a>>),
|
|
178
|
+
Yield(Indirect<SExpr<'a>>),
|
|
179
|
+
YieldFrom(Indirect<SExpr<'a>>),
|
|
169
180
|
|
|
170
|
-
If(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
181
|
+
If(
|
|
182
|
+
Indirect<SExpr<'a>>,
|
|
183
|
+
Indirect<SExpr<'a>>,
|
|
184
|
+
Option<Indirect<SExpr<'a>>>,
|
|
185
|
+
),
|
|
186
|
+
Match(Indirect<SExpr<'a>>, Vec<Indirect<MatchCase<'a>>>),
|
|
187
|
+
Matches(Indirect<SExpr<'a>>, ISPattern<'a>),
|
|
188
|
+
Class(Vec<SCallItem<'a>>, Indirect<SExpr<'a>>),
|
|
174
189
|
|
|
175
|
-
Call(
|
|
176
|
-
Subscript(
|
|
177
|
-
RawAttribute(
|
|
178
|
-
ScopedAttribute(
|
|
179
|
-
Attribute(
|
|
190
|
+
Call(Indirect<SExpr<'a>>, Vec<SCallItem<'a>>),
|
|
191
|
+
Subscript(Indirect<SExpr<'a>>, Vec<ListItem<'a>>),
|
|
192
|
+
RawAttribute(Indirect<SExpr<'a>>, SIdent<'a>),
|
|
193
|
+
ScopedAttribute(Indirect<SExpr<'a>>, Indirect<SExpr<'a>>),
|
|
194
|
+
Attribute(Indirect<SExpr<'a>>, SIdent<'a>),
|
|
180
195
|
|
|
181
|
-
MappedCall(
|
|
182
|
-
MappedSubscript(
|
|
183
|
-
MappedRawAttribute(
|
|
184
|
-
MappedScopedAttribute(
|
|
185
|
-
MappedAttribute(
|
|
196
|
+
MappedCall(Indirect<SExpr<'a>>, Vec<SCallItem<'a>>),
|
|
197
|
+
MappedSubscript(Indirect<SExpr<'a>>, Vec<ListItem<'a>>),
|
|
198
|
+
MappedRawAttribute(Indirect<SExpr<'a>>, SIdent<'a>),
|
|
199
|
+
MappedScopedAttribute(Indirect<SExpr<'a>>, Indirect<SExpr<'a>>),
|
|
200
|
+
MappedAttribute(Indirect<SExpr<'a>>, SIdent<'a>),
|
|
186
201
|
|
|
187
|
-
Checked(
|
|
202
|
+
Checked(Indirect<SExpr<'a>>, Option<ISPattern<'a>>),
|
|
188
203
|
|
|
189
|
-
Fn(Vec<ArgDefItem<'a>>,
|
|
204
|
+
Fn(Vec<ArgDefItem<'a>>, Indirect<SExpr<'a>>),
|
|
190
205
|
Fstr(Spanned<String>, Vec<(SFmtExpr<'a>, Spanned<String>)>),
|
|
191
206
|
|
|
192
|
-
Decorated(
|
|
207
|
+
Decorated(Indirect<SExpr<'a>>, Indirect<SExpr<'a>>),
|
|
193
208
|
|
|
194
209
|
Block(Vec<SStmt<'a>>),
|
|
195
210
|
}
|
|
@@ -198,29 +213,29 @@ pub type SExpr<'a> = Spanned<Expr<'a>>;
|
|
|
198
213
|
|
|
199
214
|
#[derive(Debug, Clone)]
|
|
200
215
|
pub enum PatternSequenceItem<'a> {
|
|
201
|
-
Item(
|
|
216
|
+
Item(ISPattern<'a>),
|
|
202
217
|
Spread(Option<SIdent<'a>>),
|
|
203
218
|
}
|
|
204
219
|
|
|
205
220
|
#[derive(Debug, Clone)]
|
|
206
221
|
pub enum PatternMappingItem<'a> {
|
|
207
222
|
Ident(SIdent<'a>),
|
|
208
|
-
Item(SExpr<'a>,
|
|
223
|
+
Item(SExpr<'a>, ISPattern<'a>),
|
|
209
224
|
Spread(Option<SIdent<'a>>),
|
|
210
225
|
}
|
|
211
226
|
|
|
212
227
|
#[derive(Debug, Clone)]
|
|
213
228
|
pub enum PatternClassItem<'a> {
|
|
214
|
-
Item(
|
|
215
|
-
Kw(SIdent<'a>,
|
|
229
|
+
Item(ISPattern<'a>),
|
|
230
|
+
Kw(SIdent<'a>, ISPattern<'a>),
|
|
216
231
|
}
|
|
217
232
|
|
|
218
233
|
#[derive(Debug, Clone)]
|
|
219
234
|
pub enum Pattern<'a> {
|
|
220
235
|
Capture(Option<SIdent<'a>>),
|
|
221
236
|
Value(SExpr<'a>),
|
|
222
|
-
As(
|
|
223
|
-
Or(Vec<
|
|
237
|
+
As(ISPattern<'a>, SIdent<'a>),
|
|
238
|
+
Or(Vec<ISPattern<'a>>),
|
|
224
239
|
Literal(SLiteral<'a>),
|
|
225
240
|
Sequence(Vec<PatternSequenceItem<'a>>),
|
|
226
241
|
Mapping(Vec<PatternMappingItem<'a>>),
|
|
@@ -228,3 +243,4 @@ pub enum Pattern<'a> {
|
|
|
228
243
|
}
|
|
229
244
|
|
|
230
245
|
pub type SPattern<'a> = Spanned<Pattern<'a>>;
|
|
246
|
+
pub type ISPattern<'a> = Indirect<SPattern<'a>>;
|
|
@@ -139,8 +139,8 @@ where
|
|
|
139
139
|
fn new(input: &'input mut InputRef<'src, 'parse, TInput, TExtra<'src>>) -> Self {
|
|
140
140
|
static KEYWORDS: &[&str] = &[
|
|
141
141
|
"match", "if", "then", "else", "import", "export", "as", "class", "while", "for", "in",
|
|
142
|
-
"break", "continue", "with", "yield", "global", "
|
|
143
|
-
"
|
|
142
|
+
"break", "continue", "with", "yield", "global", "return", "raise", "try", "except",
|
|
143
|
+
"finally", "and", "or", "not", "await", "let", "const",
|
|
144
144
|
];
|
|
145
145
|
|
|
146
146
|
let keywords = HashSet::<String>::from_iter(KEYWORDS.iter().map(|s| s.to_string()));
|