koatl 0.1.20__tar.gz → 0.1.21__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.20 → koatl-0.1.21}/Cargo.lock +1 -1
- {koatl-0.1.20 → koatl-0.1.21}/PKG-INFO +1 -1
- {koatl-0.1.20 → koatl-0.1.21}/koatl/Cargo.toml +1 -1
- {koatl-0.1.20 → koatl-0.1.21/koatl}/python/koatl/prelude/functional/memo.tl +23 -14
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/Cargo.toml +4 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/src/ast.rs +0 -1
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/src/parser.rs +251 -211
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/inference.rs +0 -1
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/main.rs +0 -2
- koatl-0.1.21/koatl-core/src/parse_timer.rs +35 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/resolve_scopes.rs +0 -1
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/transform.rs +0 -6
- {koatl-0.1.20/koatl → koatl-0.1.21}/python/koatl/prelude/functional/memo.tl +23 -14
- {koatl-0.1.20 → koatl-0.1.21}/Cargo.toml +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/README.md +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/.github/workflows/CI.yml +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/.gitignore +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/LICENSE +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/README.md +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/__init__.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/__main__.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/cli.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/notebook/__init__.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/notebook/magic.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/__init__.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/__init__.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/async.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/async_util.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/monad.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/reader.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/result.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/iterable.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/runtime/__init__.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/runtime/helpers.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/runtime/meta_finder.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/runtime/record.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/runtime/virtual.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/requirements.txt +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/src/emit_py.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/src/lib.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/coal.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/containers.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/decorators.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/destructure-for-and-fn.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/destructure.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/escape_ident.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/fstr.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/functions.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/generator.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/if_expr.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/imports.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/loops.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/match.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/nary-list.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/placeholder.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/precedence.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/scopes.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/semantic_whitespace.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/slice.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/try.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/destructure.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/async.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/iterables.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/memo.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/reader.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/result.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/virtual.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/util/__init__.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/util/module0.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/util/module1.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/util/module2.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/arith.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/assign.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/block-comments.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/deco.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/func.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/matches.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/test_e2e.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/test_parse.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/Cargo.toml +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/src/lexer.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/src/lib.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/src/util.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/tests/lexer.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/lib.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/parser.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/py/ast.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/py/emit.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/py/mod.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/py/util.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/types.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/util.rs +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/pyproject.toml +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/__init__.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/__main__.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/cli.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/notebook/__init__.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/notebook/magic.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/__init__.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/__init__.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/async.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/async_util.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/monad.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/reader.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/result.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/iterable.tl +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/runtime/__init__.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/runtime/helpers.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/runtime/meta_finder.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/runtime/record.py +0 -0
- {koatl-0.1.20 → koatl-0.1.21}/python/koatl/runtime/virtual.py +0 -0
|
@@ -8,37 +8,46 @@ export Memo = class(Monad):
|
|
|
8
8
|
__init__ = self =>
|
|
9
9
|
self.cache = defaultdict(dict)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
__repr__ = self => f"Memo.Cache({self.cache})"
|
|
12
|
+
|
|
13
|
+
try_get = (self, name, deps) =>
|
|
14
|
+
try self.cache[name][deps] except KeyError()
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
update = (self, name, deps, value) =>
|
|
16
17
|
self.cache[name][deps] = value
|
|
17
18
|
value
|
|
18
19
|
|
|
19
|
-
__repr__ = self => f"Memo.Cache({self.cache})"
|
|
20
|
-
|
|
21
20
|
__init__ = (self, f) => self.f = f
|
|
22
21
|
|
|
23
22
|
__repr__ = self => f"Memo(...)"
|
|
24
23
|
|
|
25
24
|
value = staticmethod& (id, deps, f) =>
|
|
26
|
-
Memo(ctx =>
|
|
25
|
+
Memo(ctx =>
|
|
26
|
+
if ctx.try_get(id, tuple(deps)) matches Ok() as value:
|
|
27
|
+
return value
|
|
28
|
+
|
|
29
|
+
ctx.update(id, tuple(deps), f())
|
|
30
|
+
)
|
|
27
31
|
|
|
28
32
|
fn = staticmethod& f => wraps(f)& (*args, **kwargs) =>
|
|
29
33
|
let id = f"{f.__module__}.{f.__qualname__}"
|
|
30
34
|
let deps = (tuple(args), tuple(kwargs.items()))
|
|
31
35
|
|
|
32
36
|
Memo(ctx =>
|
|
33
|
-
ctx.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
if ctx.try_get(id, deps) matches Ok() as value:
|
|
38
|
+
return value
|
|
39
|
+
|
|
40
|
+
let v = f(*args, **kwargs)
|
|
41
|
+
if v matches Memo():
|
|
42
|
+
v = v.run(ctx)
|
|
43
|
+
|
|
44
|
+
ctx.update(id, deps, v)
|
|
39
45
|
)
|
|
40
46
|
|
|
41
|
-
run = (self, ctx=
|
|
47
|
+
run = (self, ctx=None) =>
|
|
48
|
+
if ctx === None:
|
|
49
|
+
ctx = Memo.Cache()
|
|
50
|
+
self.f(ctx)
|
|
42
51
|
|
|
43
52
|
pure = staticmethod& value => Memo(ctx => value)
|
|
44
53
|
|
|
@@ -131,6 +131,7 @@ pub fn match_pattern<'tokens, 'src: 'tokens, TInput, PIdent, PQualIdent, PExpr,
|
|
|
131
131
|
) -> (
|
|
132
132
|
impl Parser<'tokens, TInput, SPattern<'src>, TExtra<'tokens, 'src>> + Clone,
|
|
133
133
|
impl Parser<'tokens, TInput, SPattern<'src>, TExtra<'tokens, 'src>> + Clone,
|
|
134
|
+
impl Parser<'tokens, TInput, SPattern<'src>, TExtra<'tokens, 'src>> + Clone,
|
|
134
135
|
)
|
|
135
136
|
where
|
|
136
137
|
TInput: ValueInput<'tokens, Token = Token<'src>, Span = Span>,
|
|
@@ -311,7 +312,7 @@ where
|
|
|
311
312
|
|
|
312
313
|
pattern.define(
|
|
313
314
|
choice((
|
|
314
|
-
as_pattern,
|
|
315
|
+
as_pattern.clone(),
|
|
315
316
|
value_pattern,
|
|
316
317
|
closed_pattern.clone(),
|
|
317
318
|
symbol("_")
|
|
@@ -323,6 +324,7 @@ where
|
|
|
323
324
|
|
|
324
325
|
(
|
|
325
326
|
closed_pattern.labelled("pattern").as_context(),
|
|
327
|
+
as_pattern.labelled("pattern").as_context(),
|
|
326
328
|
nary_sequence_pattern.labelled("pattern").as_context(),
|
|
327
329
|
)
|
|
328
330
|
}
|
|
@@ -475,6 +477,245 @@ where
|
|
|
475
477
|
})
|
|
476
478
|
}
|
|
477
479
|
|
|
480
|
+
pub fn statement<'tokens, 'src: 'tokens, TInput, PBody, PTuple, PExpr, PIdent, PPattern>(
|
|
481
|
+
expr_or_inline_stmt_or_block: PBody,
|
|
482
|
+
nary_tuple: PTuple,
|
|
483
|
+
expr: PExpr,
|
|
484
|
+
ident: PIdent,
|
|
485
|
+
nary_pattern: PPattern,
|
|
486
|
+
) -> (
|
|
487
|
+
impl Parser<'tokens, TInput, SStmt<'src>, TExtra<'tokens, 'src>> + Clone,
|
|
488
|
+
impl Parser<'tokens, TInput, SStmt<'src>, TExtra<'tokens, 'src>> + Clone,
|
|
489
|
+
)
|
|
490
|
+
where
|
|
491
|
+
TInput: ValueInput<'tokens, Token = Token<'src>, Span = Span>,
|
|
492
|
+
PBody: Parser<'tokens, TInput, SExpr<'src>, TExtra<'tokens, 'src>> + Clone + 'tokens,
|
|
493
|
+
PTuple: Parser<'tokens, TInput, SExpr<'src>, TExtra<'tokens, 'src>> + Clone + 'tokens,
|
|
494
|
+
PExpr: Parser<'tokens, TInput, SExpr<'src>, TExtra<'tokens, 'src>> + Clone + 'tokens,
|
|
495
|
+
PIdent: Parser<'tokens, TInput, SIdent<'src>, TExtra<'tokens, 'src>> + Clone + 'tokens,
|
|
496
|
+
PPattern: Parser<'tokens, TInput, SPattern<'src>, TExtra<'tokens, 'src>> + Clone + 'tokens,
|
|
497
|
+
{
|
|
498
|
+
let mut stmt = Recursive::<chumsky::recursive::Indirect<TInput, SStmt, TExtra>>::declare();
|
|
499
|
+
let mut inline_stmt =
|
|
500
|
+
Recursive::<chumsky::recursive::Indirect<TInput, SStmt, TExtra>>::declare();
|
|
501
|
+
|
|
502
|
+
let decl_mod = choice((
|
|
503
|
+
just(Token::Kw("export")).to(DeclType::Export),
|
|
504
|
+
just(Token::Kw("global")).to(DeclType::Global),
|
|
505
|
+
just(Token::Kw("let")).to(DeclType::Let),
|
|
506
|
+
just(Token::Kw("const")).to(DeclType::Const),
|
|
507
|
+
));
|
|
508
|
+
|
|
509
|
+
let decl_stmt = decl_mod
|
|
510
|
+
.clone()
|
|
511
|
+
.then(ident.clone().separated_by(symbol(",")).collect())
|
|
512
|
+
.map(|(decl, idents)| SStmtInner::Decl(idents, decl))
|
|
513
|
+
.boxed();
|
|
514
|
+
|
|
515
|
+
let assign_lhs = nary_tuple.clone();
|
|
516
|
+
let inline_assign_lhs = expr.clone();
|
|
517
|
+
|
|
518
|
+
let assign_stmt = group((
|
|
519
|
+
decl_mod.clone().or_not(),
|
|
520
|
+
assign_lhs.clone(),
|
|
521
|
+
symbol("=").ignore_then(nary_tuple.clone()),
|
|
522
|
+
))
|
|
523
|
+
.map(|(decl, lhs, rhs)| SStmtInner::Assign(lhs.indirect(), rhs.indirect(), decl))
|
|
524
|
+
.boxed();
|
|
525
|
+
|
|
526
|
+
let inline_assign_stmt = group((
|
|
527
|
+
decl_mod.clone().or_not(),
|
|
528
|
+
inline_assign_lhs.clone(),
|
|
529
|
+
symbol("=").ignore_then(expr.clone()),
|
|
530
|
+
))
|
|
531
|
+
.map(|(decl, lhs, rhs)| SStmtInner::Assign(lhs.indirect(), rhs.indirect(), decl))
|
|
532
|
+
.boxed();
|
|
533
|
+
|
|
534
|
+
let expr_stmt = assign_lhs
|
|
535
|
+
.clone()
|
|
536
|
+
.map(|x| SStmtInner::Expr(x.indirect()))
|
|
537
|
+
.boxed();
|
|
538
|
+
|
|
539
|
+
let inline_expr_stmt = inline_assign_lhs
|
|
540
|
+
.clone()
|
|
541
|
+
.map(|x| SStmtInner::Expr(x.indirect()))
|
|
542
|
+
.boxed();
|
|
543
|
+
|
|
544
|
+
let while_stmt = just(Token::Kw("while"))
|
|
545
|
+
.ignore_then(expr.clone())
|
|
546
|
+
.then_ignore(just(START_BLOCK))
|
|
547
|
+
.then(expr_or_inline_stmt_or_block.clone())
|
|
548
|
+
.map(|(cond, body)| SStmtInner::While(cond.indirect(), body.indirect()))
|
|
549
|
+
.labelled("while statement")
|
|
550
|
+
.boxed();
|
|
551
|
+
|
|
552
|
+
let except_block = just(Token::Eol)
|
|
553
|
+
.then(just(Token::Kw("except")))
|
|
554
|
+
.ignore_then(nary_pattern.clone().or_not())
|
|
555
|
+
.boxed()
|
|
556
|
+
.then(just(START_BLOCK).ignore_then(expr_or_inline_stmt_or_block.clone()))
|
|
557
|
+
.map(|(pattern, body)| SMatchCase {
|
|
558
|
+
pattern: pattern.map(|x| x.indirect()),
|
|
559
|
+
guard: None,
|
|
560
|
+
body: body.indirect(),
|
|
561
|
+
})
|
|
562
|
+
.labelled("except block")
|
|
563
|
+
.boxed();
|
|
564
|
+
|
|
565
|
+
let finally_block = one_of([Token::Eol])
|
|
566
|
+
.then(just(Token::Kw("finally")))
|
|
567
|
+
.then(just(START_BLOCK))
|
|
568
|
+
.ignore_then(expr_or_inline_stmt_or_block.clone())
|
|
569
|
+
.labelled("finally block")
|
|
570
|
+
.boxed();
|
|
571
|
+
|
|
572
|
+
let try_stmt = just(Token::Kw("try"))
|
|
573
|
+
.then(just(START_BLOCK))
|
|
574
|
+
.ignore_then(group((
|
|
575
|
+
expr_or_inline_stmt_or_block.clone(),
|
|
576
|
+
except_block.repeated().collect(),
|
|
577
|
+
finally_block.or_not(),
|
|
578
|
+
)))
|
|
579
|
+
.map(|(body, excepts, finally)| {
|
|
580
|
+
SStmtInner::Try(body.indirect(), excepts, finally.map(|x| x.indirect()))
|
|
581
|
+
})
|
|
582
|
+
.labelled("try statement")
|
|
583
|
+
.boxed();
|
|
584
|
+
|
|
585
|
+
let for_stmt = just(Token::Kw("for"))
|
|
586
|
+
.ignore_then(group((
|
|
587
|
+
nary_pattern.clone().then_ignore(just(Token::Kw("in"))),
|
|
588
|
+
expr.clone().then_ignore(just(START_BLOCK)),
|
|
589
|
+
expr_or_inline_stmt_or_block.clone(),
|
|
590
|
+
)))
|
|
591
|
+
.map(|(decl, iter, body)| {
|
|
592
|
+
SStmtInner::For(decl.indirect(), iter.indirect(), body.indirect())
|
|
593
|
+
})
|
|
594
|
+
.labelled("for statement")
|
|
595
|
+
.boxed();
|
|
596
|
+
|
|
597
|
+
let return_stmt = just(Token::Kw("return"))
|
|
598
|
+
.ignore_then(nary_tuple.clone())
|
|
599
|
+
.map(|x| SStmtInner::Return(x.indirect()))
|
|
600
|
+
.labelled("return statement")
|
|
601
|
+
.boxed();
|
|
602
|
+
|
|
603
|
+
let inline_return_stmt = just(Token::Kw("return"))
|
|
604
|
+
.ignore_then(expr.clone())
|
|
605
|
+
.map(|x| SStmtInner::Return(x.indirect()))
|
|
606
|
+
.labelled("inline return statement")
|
|
607
|
+
.boxed();
|
|
608
|
+
|
|
609
|
+
let assert_stmt = just(Token::Ident("assert"))
|
|
610
|
+
.ignore_then(expr.clone())
|
|
611
|
+
.then(symbol(",").ignore_then(expr.clone()).or_not())
|
|
612
|
+
.map(|(x, y)| SStmtInner::Assert(x.indirect(), y.map(|y| y.indirect())))
|
|
613
|
+
.labelled("assert statement")
|
|
614
|
+
.boxed();
|
|
615
|
+
|
|
616
|
+
let raise_stmt = just(Token::Kw("raise"))
|
|
617
|
+
.ignore_then(nary_tuple.clone().or_not())
|
|
618
|
+
.map(|x| SStmtInner::Raise(x.map(|x| x.indirect())))
|
|
619
|
+
.labelled("raise statement")
|
|
620
|
+
.boxed();
|
|
621
|
+
|
|
622
|
+
let inline_raise_stmt = just(Token::Kw("raise"))
|
|
623
|
+
.ignore_then(expr.clone().or_not())
|
|
624
|
+
.map(|x| SStmtInner::Raise(x.map(|x| x.indirect())))
|
|
625
|
+
.labelled("inline raise statement")
|
|
626
|
+
.boxed();
|
|
627
|
+
|
|
628
|
+
let break_stmt = just(Token::Kw("break"))
|
|
629
|
+
.map(|_| SStmtInner::Break)
|
|
630
|
+
.labelled("break statement")
|
|
631
|
+
.boxed();
|
|
632
|
+
|
|
633
|
+
let continue_stmt = just(Token::Kw("continue"))
|
|
634
|
+
.map(|_| SStmtInner::Continue)
|
|
635
|
+
.labelled("continue statement")
|
|
636
|
+
.boxed();
|
|
637
|
+
|
|
638
|
+
let import_stmt = just(Token::Kw("export"))
|
|
639
|
+
.to(1)
|
|
640
|
+
.or_not()
|
|
641
|
+
.then_ignore(just(Token::Kw("import")))
|
|
642
|
+
.then(group((
|
|
643
|
+
symbol(".").repeated().count(),
|
|
644
|
+
ident
|
|
645
|
+
.clone()
|
|
646
|
+
.then_ignore(symbol("."))
|
|
647
|
+
.repeated()
|
|
648
|
+
.collect()
|
|
649
|
+
.boxed(),
|
|
650
|
+
choice((
|
|
651
|
+
enumeration(
|
|
652
|
+
ident
|
|
653
|
+
.clone()
|
|
654
|
+
.then(just(Token::Kw("as")).ignore_then(ident.clone()).or_not()),
|
|
655
|
+
symbol(","),
|
|
656
|
+
)
|
|
657
|
+
.delimited_by_with_eol(symbol("("), symbol(")"))
|
|
658
|
+
.map(ImportList::Leaves)
|
|
659
|
+
.boxed(),
|
|
660
|
+
just(Token::Symbol("*")).map(|_| ImportList::Star),
|
|
661
|
+
ident
|
|
662
|
+
.clone()
|
|
663
|
+
.then(just(Token::Kw("as")).ignore_then(ident.clone()).or_not())
|
|
664
|
+
.map(|x| ImportList::Leaves(vec![x]))
|
|
665
|
+
.boxed(),
|
|
666
|
+
))
|
|
667
|
+
.boxed(),
|
|
668
|
+
)))
|
|
669
|
+
.map(|(reexport, (level, trunk, import_list))| {
|
|
670
|
+
SStmtInner::Import(ImportStmt {
|
|
671
|
+
trunk,
|
|
672
|
+
imports: import_list,
|
|
673
|
+
level,
|
|
674
|
+
reexport: reexport.is_some(),
|
|
675
|
+
})
|
|
676
|
+
})
|
|
677
|
+
.labelled("import statement")
|
|
678
|
+
.boxed();
|
|
679
|
+
|
|
680
|
+
stmt.define(
|
|
681
|
+
choice((
|
|
682
|
+
decl_stmt.then_ignore(just(Token::Eol)),
|
|
683
|
+
assign_stmt.then_ignore(just(Token::Eol)),
|
|
684
|
+
expr_stmt.then_ignore(just(Token::Eol)),
|
|
685
|
+
while_stmt.clone().then_ignore(just(Token::Eol)),
|
|
686
|
+
for_stmt.clone().then_ignore(just(Token::Eol)),
|
|
687
|
+
return_stmt.then_ignore(just(Token::Eol)),
|
|
688
|
+
assert_stmt.then_ignore(just(Token::Eol)),
|
|
689
|
+
raise_stmt.then_ignore(just(Token::Eol)),
|
|
690
|
+
break_stmt.clone().then_ignore(just(Token::Eol)),
|
|
691
|
+
continue_stmt.clone().then_ignore(just(Token::Eol)),
|
|
692
|
+
import_stmt.then_ignore(just(Token::Eol)),
|
|
693
|
+
try_stmt.then_ignore(just(Token::Eol)),
|
|
694
|
+
))
|
|
695
|
+
.labelled("statement")
|
|
696
|
+
.map_with(|x, e| x.spanned(e.span()))
|
|
697
|
+
.boxed(),
|
|
698
|
+
);
|
|
699
|
+
|
|
700
|
+
inline_stmt.define(
|
|
701
|
+
choice((
|
|
702
|
+
inline_assign_stmt,
|
|
703
|
+
inline_expr_stmt,
|
|
704
|
+
while_stmt,
|
|
705
|
+
for_stmt,
|
|
706
|
+
inline_return_stmt,
|
|
707
|
+
inline_raise_stmt,
|
|
708
|
+
break_stmt,
|
|
709
|
+
continue_stmt,
|
|
710
|
+
))
|
|
711
|
+
.labelled("inline-statement")
|
|
712
|
+
.map_with(|x, e| x.spanned(e.span()))
|
|
713
|
+
.boxed(),
|
|
714
|
+
);
|
|
715
|
+
|
|
716
|
+
(stmt, inline_stmt)
|
|
717
|
+
}
|
|
718
|
+
|
|
478
719
|
pub fn parser<'tokens, 'src: 'tokens, TInput>()
|
|
479
720
|
-> impl Parser<'tokens, TInput, SExpr<'src>, TExtra<'tokens, 'src>> + Clone
|
|
480
721
|
where
|
|
@@ -483,6 +724,7 @@ where
|
|
|
483
724
|
let mut stmt = Recursive::<chumsky::recursive::Indirect<TInput, SStmt, TExtra>>::declare();
|
|
484
725
|
let mut inline_stmt =
|
|
485
726
|
Recursive::<chumsky::recursive::Indirect<TInput, SStmt, TExtra>>::declare();
|
|
727
|
+
|
|
486
728
|
let mut atom = Recursive::<chumsky::recursive::Indirect<TInput, SExpr, TExtra>>::declare();
|
|
487
729
|
let mut expr = Recursive::<chumsky::recursive::Indirect<TInput, SExpr, TExtra>>::declare();
|
|
488
730
|
let mut unary = Recursive::<chumsky::recursive::Indirect<TInput, SExpr, TExtra>>::declare();
|
|
@@ -722,7 +964,7 @@ where
|
|
|
722
964
|
)
|
|
723
965
|
.boxed();
|
|
724
966
|
|
|
725
|
-
let (closed_pattern, nary_pattern) = match_pattern(
|
|
967
|
+
let (closed_pattern, as_pattern, nary_pattern) = match_pattern(
|
|
726
968
|
ident.clone(),
|
|
727
969
|
qualified_ident.clone(),
|
|
728
970
|
expr.clone(),
|
|
@@ -1113,7 +1355,7 @@ where
|
|
|
1113
1355
|
.then(
|
|
1114
1356
|
just(Token::Ident("matches"))
|
|
1115
1357
|
.ignore_then(just(Token::Kw("not")).to(0).or_not())
|
|
1116
|
-
.then(
|
|
1358
|
+
.then(as_pattern.clone())
|
|
1117
1359
|
.or_not(),
|
|
1118
1360
|
)
|
|
1119
1361
|
.map_with(|(expr, matches_part), e| {
|
|
@@ -1181,218 +1423,16 @@ where
|
|
|
1181
1423
|
binary6.labelled("expression").as_context().boxed(), // .memoized(),
|
|
1182
1424
|
);
|
|
1183
1425
|
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
let decl_mod = choice((
|
|
1187
|
-
just(Token::Kw("export")).to(DeclType::Export),
|
|
1188
|
-
just(Token::Kw("global")).to(DeclType::Global),
|
|
1189
|
-
just(Token::Kw("let")).to(DeclType::Let),
|
|
1190
|
-
just(Token::Kw("const")).to(DeclType::Const),
|
|
1191
|
-
));
|
|
1192
|
-
|
|
1193
|
-
let decl_stmt = decl_mod
|
|
1194
|
-
.clone()
|
|
1195
|
-
.then(ident.clone().separated_by(symbol(",")).collect())
|
|
1196
|
-
.map(|(decl, idents)| SStmtInner::Decl(idents, decl))
|
|
1197
|
-
.boxed();
|
|
1198
|
-
|
|
1199
|
-
let assign_stmt = group((
|
|
1200
|
-
decl_mod.clone().or_not(),
|
|
1426
|
+
let (stmt_, inline_stmt_) = statement(
|
|
1427
|
+
expr_or_inline_stmt_or_block.clone(),
|
|
1201
1428
|
nary_tuple.clone(),
|
|
1202
|
-
symbol("=").ignore_then(nary_tuple.clone()),
|
|
1203
|
-
))
|
|
1204
|
-
.map(|(decl, lhs, rhs)| SStmtInner::Assign(lhs.indirect(), rhs.indirect(), decl))
|
|
1205
|
-
.boxed();
|
|
1206
|
-
|
|
1207
|
-
let inline_assign_stmt = group((
|
|
1208
|
-
decl_mod.clone().or_not(),
|
|
1209
1429
|
expr.clone(),
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
.map(|(decl, lhs, rhs)| SStmtInner::Assign(lhs.indirect(), rhs.indirect(), decl))
|
|
1213
|
-
.boxed();
|
|
1214
|
-
|
|
1215
|
-
let expr_stmt = nary_tuple
|
|
1216
|
-
.clone()
|
|
1217
|
-
.map(|x| SStmtInner::Expr(x.indirect()))
|
|
1218
|
-
.boxed();
|
|
1219
|
-
|
|
1220
|
-
let inline_expr_stmt = expr.clone().map(|x| SStmtInner::Expr(x.indirect())).boxed();
|
|
1221
|
-
|
|
1222
|
-
let while_stmt = just(Token::Kw("while"))
|
|
1223
|
-
.ignore_then(expr.clone())
|
|
1224
|
-
.then_ignore(just(START_BLOCK))
|
|
1225
|
-
.then(expr_or_inline_stmt_or_block.clone())
|
|
1226
|
-
.map(|(cond, body)| SStmtInner::While(cond.indirect(), body.indirect()))
|
|
1227
|
-
.labelled("while statement")
|
|
1228
|
-
.boxed();
|
|
1229
|
-
|
|
1230
|
-
let except_block = just(Token::Eol)
|
|
1231
|
-
.then(just(Token::Kw("except")))
|
|
1232
|
-
.ignore_then(nary_pattern.clone().or_not())
|
|
1233
|
-
.boxed()
|
|
1234
|
-
.then(just(START_BLOCK).ignore_then(expr_or_inline_stmt_or_block.clone()))
|
|
1235
|
-
.map(|(pattern, body)| SMatchCase {
|
|
1236
|
-
pattern: pattern.map(|x| x.indirect()),
|
|
1237
|
-
guard: None,
|
|
1238
|
-
body: body.indirect(),
|
|
1239
|
-
})
|
|
1240
|
-
.labelled("except block")
|
|
1241
|
-
.boxed();
|
|
1242
|
-
|
|
1243
|
-
let finally_block = one_of([Token::Eol])
|
|
1244
|
-
.then(just(Token::Kw("finally")))
|
|
1245
|
-
.then(just(START_BLOCK))
|
|
1246
|
-
.ignore_then(expr_or_inline_stmt_or_block.clone())
|
|
1247
|
-
.labelled("finally block")
|
|
1248
|
-
.boxed();
|
|
1249
|
-
|
|
1250
|
-
let try_stmt = just(Token::Kw("try"))
|
|
1251
|
-
.then(just(START_BLOCK))
|
|
1252
|
-
.ignore_then(group((
|
|
1253
|
-
expr_or_inline_stmt_or_block.clone(),
|
|
1254
|
-
except_block.repeated().collect(),
|
|
1255
|
-
finally_block.or_not(),
|
|
1256
|
-
)))
|
|
1257
|
-
.map(|(body, excepts, finally)| {
|
|
1258
|
-
SStmtInner::Try(body.indirect(), excepts, finally.map(|x| x.indirect()))
|
|
1259
|
-
})
|
|
1260
|
-
.labelled("try statement")
|
|
1261
|
-
.boxed();
|
|
1262
|
-
|
|
1263
|
-
let for_stmt = just(Token::Kw("for"))
|
|
1264
|
-
.ignore_then(group((
|
|
1265
|
-
nary_pattern.clone().then_ignore(just(Token::Kw("in"))),
|
|
1266
|
-
expr.clone().then_ignore(just(START_BLOCK)),
|
|
1267
|
-
expr_or_inline_stmt_or_block.clone(),
|
|
1268
|
-
)))
|
|
1269
|
-
.map(|(decl, iter, body)| {
|
|
1270
|
-
SStmtInner::For(decl.indirect(), iter.indirect(), body.indirect())
|
|
1271
|
-
})
|
|
1272
|
-
.labelled("for statement")
|
|
1273
|
-
.boxed();
|
|
1274
|
-
|
|
1275
|
-
let return_stmt = just(Token::Kw("return"))
|
|
1276
|
-
.ignore_then(nary_tuple.clone())
|
|
1277
|
-
.map(|x| SStmtInner::Return(x.indirect()))
|
|
1278
|
-
.labelled("return statement")
|
|
1279
|
-
.boxed();
|
|
1280
|
-
|
|
1281
|
-
let inline_return_stmt = just(Token::Kw("return"))
|
|
1282
|
-
.ignore_then(expr.clone())
|
|
1283
|
-
.map(|x| SStmtInner::Return(x.indirect()))
|
|
1284
|
-
.labelled("inline return statement")
|
|
1285
|
-
.boxed();
|
|
1286
|
-
|
|
1287
|
-
let assert_stmt = just(Token::Ident("assert"))
|
|
1288
|
-
.ignore_then(expr.clone())
|
|
1289
|
-
.then(symbol(",").ignore_then(expr.clone()).or_not())
|
|
1290
|
-
.map(|(x, y)| SStmtInner::Assert(x.indirect(), y.map(|y| y.indirect())))
|
|
1291
|
-
.labelled("assert statement")
|
|
1292
|
-
.boxed();
|
|
1293
|
-
|
|
1294
|
-
let raise_stmt = just(Token::Kw("raise"))
|
|
1295
|
-
.ignore_then(nary_tuple.clone().or_not())
|
|
1296
|
-
.map(|x| SStmtInner::Raise(x.map(|x| x.indirect())))
|
|
1297
|
-
.labelled("raise statement")
|
|
1298
|
-
.boxed();
|
|
1299
|
-
|
|
1300
|
-
let inline_raise_stmt = just(Token::Kw("raise"))
|
|
1301
|
-
.ignore_then(expr.clone().or_not())
|
|
1302
|
-
.map(|x| SStmtInner::Raise(x.map(|x| x.indirect())))
|
|
1303
|
-
.labelled("inline raise statement")
|
|
1304
|
-
.boxed();
|
|
1305
|
-
|
|
1306
|
-
let break_stmt = just(Token::Kw("break"))
|
|
1307
|
-
.map(|_| SStmtInner::Break)
|
|
1308
|
-
.labelled("break statement")
|
|
1309
|
-
.boxed();
|
|
1310
|
-
|
|
1311
|
-
let continue_stmt = just(Token::Kw("continue"))
|
|
1312
|
-
.map(|_| SStmtInner::Continue)
|
|
1313
|
-
.labelled("continue statement")
|
|
1314
|
-
.boxed();
|
|
1315
|
-
|
|
1316
|
-
let import_stmt = just(Token::Kw("export"))
|
|
1317
|
-
.to(1)
|
|
1318
|
-
.or_not()
|
|
1319
|
-
.then_ignore(just(Token::Kw("import")))
|
|
1320
|
-
.then(group((
|
|
1321
|
-
symbol(".").repeated().count(),
|
|
1322
|
-
ident
|
|
1323
|
-
.clone()
|
|
1324
|
-
.then_ignore(symbol("."))
|
|
1325
|
-
.repeated()
|
|
1326
|
-
.collect()
|
|
1327
|
-
.boxed(),
|
|
1328
|
-
choice((
|
|
1329
|
-
enumeration(
|
|
1330
|
-
ident
|
|
1331
|
-
.clone()
|
|
1332
|
-
.then(just(Token::Kw("as")).ignore_then(ident.clone()).or_not()),
|
|
1333
|
-
symbol(","),
|
|
1334
|
-
)
|
|
1335
|
-
.delimited_by_with_eol(symbol("("), symbol(")"))
|
|
1336
|
-
.map(ImportList::Leaves)
|
|
1337
|
-
.boxed(),
|
|
1338
|
-
just(Token::Symbol("*")).map(|_| ImportList::Star),
|
|
1339
|
-
ident
|
|
1340
|
-
.clone()
|
|
1341
|
-
.then(just(Token::Kw("as")).ignore_then(ident.clone()).or_not())
|
|
1342
|
-
.map(|x| ImportList::Leaves(vec![x]))
|
|
1343
|
-
.boxed(),
|
|
1344
|
-
))
|
|
1345
|
-
.boxed(),
|
|
1346
|
-
)))
|
|
1347
|
-
.map(|(reexport, (level, trunk, import_list))| {
|
|
1348
|
-
SStmtInner::Import(ImportStmt {
|
|
1349
|
-
trunk,
|
|
1350
|
-
imports: import_list,
|
|
1351
|
-
level,
|
|
1352
|
-
reexport: reexport.is_some(),
|
|
1353
|
-
})
|
|
1354
|
-
})
|
|
1355
|
-
.labelled("import statement")
|
|
1356
|
-
.boxed();
|
|
1357
|
-
|
|
1358
|
-
let module_stmt = just(Token::Kw("module")).map(|_| SStmtInner::Module);
|
|
1359
|
-
|
|
1360
|
-
stmt.define(
|
|
1361
|
-
choice((
|
|
1362
|
-
decl_stmt.then_ignore(just(Token::Eol)),
|
|
1363
|
-
assign_stmt.then_ignore(just(Token::Eol)),
|
|
1364
|
-
expr_stmt.then_ignore(just(Token::Eol)),
|
|
1365
|
-
module_stmt.then_ignore(just(Token::Eol)),
|
|
1366
|
-
while_stmt.clone().then_ignore(just(Token::Eol)),
|
|
1367
|
-
for_stmt.clone().then_ignore(just(Token::Eol)),
|
|
1368
|
-
return_stmt.then_ignore(just(Token::Eol)),
|
|
1369
|
-
assert_stmt.then_ignore(just(Token::Eol)),
|
|
1370
|
-
raise_stmt.then_ignore(just(Token::Eol)),
|
|
1371
|
-
break_stmt.clone().then_ignore(just(Token::Eol)),
|
|
1372
|
-
continue_stmt.clone().then_ignore(just(Token::Eol)),
|
|
1373
|
-
import_stmt.then_ignore(just(Token::Eol)),
|
|
1374
|
-
try_stmt.then_ignore(just(Token::Eol)),
|
|
1375
|
-
))
|
|
1376
|
-
.labelled("statement")
|
|
1377
|
-
.map_with(|x, e| x.spanned(e.span()))
|
|
1378
|
-
.boxed(),
|
|
1430
|
+
ident.clone(),
|
|
1431
|
+
nary_pattern.clone(),
|
|
1379
1432
|
);
|
|
1380
1433
|
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
inline_assign_stmt,
|
|
1384
|
-
inline_expr_stmt,
|
|
1385
|
-
while_stmt,
|
|
1386
|
-
for_stmt,
|
|
1387
|
-
inline_return_stmt,
|
|
1388
|
-
inline_raise_stmt,
|
|
1389
|
-
break_stmt,
|
|
1390
|
-
continue_stmt,
|
|
1391
|
-
))
|
|
1392
|
-
.labelled("inline-statement")
|
|
1393
|
-
.map_with(|x, e| x.spanned(e.span()))
|
|
1394
|
-
.boxed(),
|
|
1395
|
-
);
|
|
1434
|
+
stmt.define(stmt_.labelled("statement").boxed());
|
|
1435
|
+
inline_stmt.define(inline_stmt_.labelled("inline-statement").boxed());
|
|
1396
1436
|
|
|
1397
1437
|
block.labelled("program")
|
|
1398
1438
|
}
|
|
@@ -53,7 +53,6 @@ impl<'src, 'ast> SStmtExt<'src, 'ast> for Indirect<SStmt<'src>> {
|
|
|
53
53
|
}
|
|
54
54
|
Stmt::Raise(..) | Stmt::Return(..) | Stmt::Break | Stmt::Continue => Type::Bottom,
|
|
55
55
|
Stmt::Import(..) => Type::NoReturn,
|
|
56
|
-
Stmt::Module => Type::NoReturn,
|
|
57
56
|
Stmt::Decl(..) => Type::NoReturn,
|
|
58
57
|
}
|
|
59
58
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
use std::time::Instant;
|
|
2
|
+
|
|
3
|
+
use koatl_core::parse_tl;
|
|
4
|
+
|
|
5
|
+
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
6
|
+
let filename = std::env::args().nth(1).ok_or("Missing filename argument")?;
|
|
7
|
+
let src = std::fs::read_to_string(&filename).unwrap();
|
|
8
|
+
|
|
9
|
+
let now = Instant::now();
|
|
10
|
+
|
|
11
|
+
let n = 1000;
|
|
12
|
+
|
|
13
|
+
for _ in 0..n {
|
|
14
|
+
match parse_tl(&src) {
|
|
15
|
+
Ok(_) => {}
|
|
16
|
+
Err(errs) => {
|
|
17
|
+
errs.0.into_iter().for_each(|e| {
|
|
18
|
+
eprintln!("Error: {}", e.message);
|
|
19
|
+
if let Some(span) = e.span {
|
|
20
|
+
eprintln!("At span: {:?}", span);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return Err("Parsing failed".into());
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
println!(
|
|
29
|
+
"Parsed {} in {}us",
|
|
30
|
+
filename,
|
|
31
|
+
now.elapsed().as_nanos() as f64 / 1000.0 / n as f64
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
Ok(())
|
|
35
|
+
}
|
|
@@ -1978,12 +1978,6 @@ impl<'src> SStmtExt<'src> for SStmt<'src> {
|
|
|
1978
1978
|
pre.push(a.import(aliases));
|
|
1979
1979
|
};
|
|
1980
1980
|
}
|
|
1981
|
-
Stmt::Module => {
|
|
1982
|
-
return Err(simple_err(
|
|
1983
|
-
"Module statements are not allowed in the transform phase",
|
|
1984
|
-
span,
|
|
1985
|
-
));
|
|
1986
|
-
}
|
|
1987
1981
|
};
|
|
1988
1982
|
|
|
1989
1983
|
Ok(pre)
|
|
@@ -8,37 +8,46 @@ export Memo = class(Monad):
|
|
|
8
8
|
__init__ = self =>
|
|
9
9
|
self.cache = defaultdict(dict)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
__repr__ = self => f"Memo.Cache({self.cache})"
|
|
12
|
+
|
|
13
|
+
try_get = (self, name, deps) =>
|
|
14
|
+
try self.cache[name][deps] except KeyError()
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
update = (self, name, deps, value) =>
|
|
16
17
|
self.cache[name][deps] = value
|
|
17
18
|
value
|
|
18
19
|
|
|
19
|
-
__repr__ = self => f"Memo.Cache({self.cache})"
|
|
20
|
-
|
|
21
20
|
__init__ = (self, f) => self.f = f
|
|
22
21
|
|
|
23
22
|
__repr__ = self => f"Memo(...)"
|
|
24
23
|
|
|
25
24
|
value = staticmethod& (id, deps, f) =>
|
|
26
|
-
Memo(ctx =>
|
|
25
|
+
Memo(ctx =>
|
|
26
|
+
if ctx.try_get(id, tuple(deps)) matches Ok() as value:
|
|
27
|
+
return value
|
|
28
|
+
|
|
29
|
+
ctx.update(id, tuple(deps), f())
|
|
30
|
+
)
|
|
27
31
|
|
|
28
32
|
fn = staticmethod& f => wraps(f)& (*args, **kwargs) =>
|
|
29
33
|
let id = f"{f.__module__}.{f.__qualname__}"
|
|
30
34
|
let deps = (tuple(args), tuple(kwargs.items()))
|
|
31
35
|
|
|
32
36
|
Memo(ctx =>
|
|
33
|
-
ctx.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
if ctx.try_get(id, deps) matches Ok() as value:
|
|
38
|
+
return value
|
|
39
|
+
|
|
40
|
+
let v = f(*args, **kwargs)
|
|
41
|
+
if v matches Memo():
|
|
42
|
+
v = v.run(ctx)
|
|
43
|
+
|
|
44
|
+
ctx.update(id, deps, v)
|
|
39
45
|
)
|
|
40
46
|
|
|
41
|
-
run = (self, ctx=
|
|
47
|
+
run = (self, ctx=None) =>
|
|
48
|
+
if ctx === None:
|
|
49
|
+
ctx = Memo.Cache()
|
|
50
|
+
self.f(ctx)
|
|
42
51
|
|
|
43
52
|
pure = staticmethod& value => Memo(ctx => value)
|
|
44
53
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|