koatl 0.1.19__tar.gz → 0.1.20__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.19 → koatl-0.1.20}/Cargo.lock +1 -1
- {koatl-0.1.19 → koatl-0.1.20}/PKG-INFO +1 -1
- {koatl-0.1.19 → koatl-0.1.20}/koatl/Cargo.toml +1 -1
- koatl-0.1.20/koatl/python/koatl/prelude/functional/memo.tl +63 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/memo.tl +2 -1
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/resolve_scopes.rs +12 -11
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/transform.rs +24 -6
- koatl-0.1.20/python/koatl/prelude/functional/memo.tl +63 -0
- koatl-0.1.19/koatl/python/koatl/prelude/functional/memo.tl +0 -57
- koatl-0.1.19/python/koatl/prelude/functional/memo.tl +0 -57
- {koatl-0.1.19 → koatl-0.1.20}/Cargo.toml +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/README.md +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/.github/workflows/CI.yml +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/.gitignore +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/LICENSE +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/README.md +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/__init__.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/__main__.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/cli.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/notebook/__init__.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/notebook/magic.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/__init__.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/__init__.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/async.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/async_util.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/monad.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/reader.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/result.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/iterable.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/runtime/__init__.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/runtime/helpers.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/runtime/meta_finder.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/runtime/record.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/runtime/virtual.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/requirements.txt +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/src/emit_py.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/src/lib.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/coal.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/containers.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/decorators.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/destructure-for-and-fn.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/destructure.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/escape_ident.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/fstr.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/functions.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/generator.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/if_expr.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/imports.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/loops.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/match.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/nary-list.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/placeholder.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/precedence.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/scopes.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/semantic_whitespace.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/slice.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/try.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/destructure.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/async.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/iterables.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/reader.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/result.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/virtual.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/util/__init__.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/util/module0.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/util/module1.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/util/module2.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/arith.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/assign.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/block-comments.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/deco.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/func.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/matches.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/test_e2e.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/test_parse.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/Cargo.toml +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/Cargo.toml +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/src/ast.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/src/lexer.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/src/lib.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/src/parser.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/src/util.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/tests/lexer.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/inference.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/lib.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/main.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/parser.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/py/ast.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/py/emit.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/py/mod.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/py/util.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/types.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/util.rs +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/pyproject.toml +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/__init__.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/__main__.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/cli.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/notebook/__init__.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/notebook/magic.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/__init__.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/__init__.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/async.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/async_util.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/monad.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/reader.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/result.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/iterable.tl +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/runtime/__init__.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/runtime/helpers.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/runtime/meta_finder.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/runtime/record.py +0 -0
- {koatl-0.1.19 → koatl-0.1.20}/python/koatl/runtime/virtual.py +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import collections.defaultdict
|
|
2
|
+
import functools.wraps
|
|
3
|
+
import .result.Ok
|
|
4
|
+
import .Monad
|
|
5
|
+
|
|
6
|
+
export Memo = class(Monad):
|
|
7
|
+
Cache = class:
|
|
8
|
+
__init__ = self =>
|
|
9
|
+
self.cache = defaultdict(dict)
|
|
10
|
+
|
|
11
|
+
get_or_compute = (self, name, deps, f) =>
|
|
12
|
+
if try self.cache[name][deps] except KeyError() matches (Ok() as v):
|
|
13
|
+
return v
|
|
14
|
+
|
|
15
|
+
let value = f()
|
|
16
|
+
self.cache[name][deps] = value
|
|
17
|
+
value
|
|
18
|
+
|
|
19
|
+
__repr__ = self => f"Memo.Cache({self.cache})"
|
|
20
|
+
|
|
21
|
+
__init__ = (self, f) => self.f = f
|
|
22
|
+
|
|
23
|
+
__repr__ = self => f"Memo(...)"
|
|
24
|
+
|
|
25
|
+
value = staticmethod& (id, deps, f) =>
|
|
26
|
+
Memo(ctx => ctx.get_or_compute(id, tuple(deps), f))
|
|
27
|
+
|
|
28
|
+
fn = staticmethod& f => wraps(f)& (*args, **kwargs) =>
|
|
29
|
+
let id = f"{f.__module__}.{f.__qualname__}"
|
|
30
|
+
let deps = (tuple(args), tuple(kwargs.items()))
|
|
31
|
+
|
|
32
|
+
Memo(ctx =>
|
|
33
|
+
ctx.get_or_compute(id, deps, () =>
|
|
34
|
+
let v = f(*args, **kwargs)
|
|
35
|
+
if v matches Memo():
|
|
36
|
+
v = v.run(ctx)
|
|
37
|
+
v
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
run = (self, ctx=Cache()) => self.f(ctx)
|
|
42
|
+
|
|
43
|
+
pure = staticmethod& value => Memo(ctx => value)
|
|
44
|
+
|
|
45
|
+
bind_once = (self, f) => Memo(ctx =>
|
|
46
|
+
let value = f(self.run(ctx))
|
|
47
|
+
if value matches Memo():
|
|
48
|
+
value = value.run(ctx)
|
|
49
|
+
value
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
bind_gen = (self, gen) => Memo(ctx =>
|
|
53
|
+
self = self.run(ctx)
|
|
54
|
+
try:
|
|
55
|
+
while True:
|
|
56
|
+
self = gen.send(self)
|
|
57
|
+
if self matches Memo():
|
|
58
|
+
self = self.run(ctx)
|
|
59
|
+
except StopIteration(value=value):
|
|
60
|
+
return value
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
__tl__.memo = Memo.value
|
|
@@ -1142,17 +1142,18 @@ impl<'src> SExprExt<'src> for Indirect<SExpr<'src>> {
|
|
|
1142
1142
|
|
|
1143
1143
|
let mut fn_info = FnInfo::new();
|
|
1144
1144
|
for (i, decl) in decls.iter().enumerate() {
|
|
1145
|
-
if
|
|
1146
|
-
.iter()
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1145
|
+
if state.declarations[*decl].name.0 != "_" {
|
|
1146
|
+
if let Some(found) = decls[..i].iter().find(|x| {
|
|
1147
|
+
state.declarations[**x].name == state.declarations[*decl].name
|
|
1148
|
+
}) {
|
|
1149
|
+
state.errors.extend(
|
|
1150
|
+
TlErrBuilder::new()
|
|
1151
|
+
.message("Duplicate declaration in function arguments")
|
|
1152
|
+
.context("First declared here", state.declarations[*found].loc)
|
|
1153
|
+
.span(state.declarations[*decl].loc)
|
|
1154
|
+
.build(),
|
|
1155
|
+
);
|
|
1156
|
+
}
|
|
1156
1157
|
}
|
|
1157
1158
|
|
|
1158
1159
|
fn_info.arg_names.push(*decl);
|
|
@@ -1026,7 +1026,7 @@ fn create_throwing_matcher<'src, 'ast>(
|
|
|
1026
1026
|
pattern: &'ast SPattern<'src>,
|
|
1027
1027
|
pattern_meta: &'ast PatternInfo,
|
|
1028
1028
|
) -> TlResult<(PyBlock<'src>, PyIdent<'src>)> {
|
|
1029
|
-
if let Pattern::Capture(Some(
|
|
1029
|
+
if let Pattern::Capture(Some(ident)) = &pattern.value {
|
|
1030
1030
|
if pattern_meta.decls.len() != 1 {
|
|
1031
1031
|
return Err(simple_err(
|
|
1032
1032
|
"Internal: expected exactly one decl",
|
|
@@ -1034,8 +1034,10 @@ fn create_throwing_matcher<'src, 'ast>(
|
|
|
1034
1034
|
));
|
|
1035
1035
|
}
|
|
1036
1036
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1037
|
+
if ident.value.0 != "_" {
|
|
1038
|
+
let decl = pattern_meta.decls.iter().next().unwrap();
|
|
1039
|
+
return Ok((PyBlock::new(), ctx.decl_py_ident(*decl)?));
|
|
1040
|
+
}
|
|
1039
1041
|
}
|
|
1040
1042
|
|
|
1041
1043
|
let cursor = ctx.create_aux_var("matcher", pattern.span.start);
|
|
@@ -1290,7 +1292,15 @@ fn make_arglist<'src, 'ast>(
|
|
|
1290
1292
|
.iter()
|
|
1291
1293
|
.find(|key| ctx.declarations[**key].name == name.value)
|
|
1292
1294
|
.ok_or_else(|| simple_err("Internal: missing arg name", name.span))?;
|
|
1293
|
-
|
|
1295
|
+
|
|
1296
|
+
let decl_value = &ctx.declarations[*decl];
|
|
1297
|
+
|
|
1298
|
+
if decl_value.name.0 == "_" {
|
|
1299
|
+
// need to create a unique name to prevent python complaining
|
|
1300
|
+
PyArgDefItem::ArgSpread(ctx.create_aux_var("_", name.span.start))
|
|
1301
|
+
} else {
|
|
1302
|
+
PyArgDefItem::ArgSpread(ctx.decl_py_ident(*decl)?)
|
|
1303
|
+
}
|
|
1294
1304
|
}
|
|
1295
1305
|
ArgDefItem::KwargSpread(name) => {
|
|
1296
1306
|
let decl = info
|
|
@@ -1298,7 +1308,14 @@ fn make_arglist<'src, 'ast>(
|
|
|
1298
1308
|
.iter()
|
|
1299
1309
|
.find(|key| ctx.declarations[**key].name == name.value)
|
|
1300
1310
|
.ok_or_else(|| simple_err("Internal: missing arg name", name.span))?;
|
|
1301
|
-
|
|
1311
|
+
|
|
1312
|
+
let decl_value = &ctx.declarations[*decl];
|
|
1313
|
+
|
|
1314
|
+
if decl_value.name.0 == "_" {
|
|
1315
|
+
PyArgDefItem::KwargSpread(ctx.create_aux_var("_", name.span.start))
|
|
1316
|
+
} else {
|
|
1317
|
+
PyArgDefItem::KwargSpread(ctx.decl_py_ident(*decl)?)
|
|
1318
|
+
}
|
|
1302
1319
|
}
|
|
1303
1320
|
};
|
|
1304
1321
|
args_vec.push(arg);
|
|
@@ -1390,7 +1407,8 @@ fn prepare_py_fn<'src, 'ast>(
|
|
|
1390
1407
|
let mut globals = vec![];
|
|
1391
1408
|
|
|
1392
1409
|
for capture in fn_info.captures.iter() {
|
|
1393
|
-
|
|
1410
|
+
let scope = &ctx.scopes[ctx.declarations[*capture].scope];
|
|
1411
|
+
if scope.is_global || scope.is_class {
|
|
1394
1412
|
globals.push(ctx.decl_py_ident(*capture)?);
|
|
1395
1413
|
} else {
|
|
1396
1414
|
nonlocals.push(ctx.decl_py_ident(*capture)?);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import collections.defaultdict
|
|
2
|
+
import functools.wraps
|
|
3
|
+
import .result.Ok
|
|
4
|
+
import .Monad
|
|
5
|
+
|
|
6
|
+
export Memo = class(Monad):
|
|
7
|
+
Cache = class:
|
|
8
|
+
__init__ = self =>
|
|
9
|
+
self.cache = defaultdict(dict)
|
|
10
|
+
|
|
11
|
+
get_or_compute = (self, name, deps, f) =>
|
|
12
|
+
if try self.cache[name][deps] except KeyError() matches (Ok() as v):
|
|
13
|
+
return v
|
|
14
|
+
|
|
15
|
+
let value = f()
|
|
16
|
+
self.cache[name][deps] = value
|
|
17
|
+
value
|
|
18
|
+
|
|
19
|
+
__repr__ = self => f"Memo.Cache({self.cache})"
|
|
20
|
+
|
|
21
|
+
__init__ = (self, f) => self.f = f
|
|
22
|
+
|
|
23
|
+
__repr__ = self => f"Memo(...)"
|
|
24
|
+
|
|
25
|
+
value = staticmethod& (id, deps, f) =>
|
|
26
|
+
Memo(ctx => ctx.get_or_compute(id, tuple(deps), f))
|
|
27
|
+
|
|
28
|
+
fn = staticmethod& f => wraps(f)& (*args, **kwargs) =>
|
|
29
|
+
let id = f"{f.__module__}.{f.__qualname__}"
|
|
30
|
+
let deps = (tuple(args), tuple(kwargs.items()))
|
|
31
|
+
|
|
32
|
+
Memo(ctx =>
|
|
33
|
+
ctx.get_or_compute(id, deps, () =>
|
|
34
|
+
let v = f(*args, **kwargs)
|
|
35
|
+
if v matches Memo():
|
|
36
|
+
v = v.run(ctx)
|
|
37
|
+
v
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
run = (self, ctx=Cache()) => self.f(ctx)
|
|
42
|
+
|
|
43
|
+
pure = staticmethod& value => Memo(ctx => value)
|
|
44
|
+
|
|
45
|
+
bind_once = (self, f) => Memo(ctx =>
|
|
46
|
+
let value = f(self.run(ctx))
|
|
47
|
+
if value matches Memo():
|
|
48
|
+
value = value.run(ctx)
|
|
49
|
+
value
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
bind_gen = (self, gen) => Memo(ctx =>
|
|
53
|
+
self = self.run(ctx)
|
|
54
|
+
try:
|
|
55
|
+
while True:
|
|
56
|
+
self = gen.send(self)
|
|
57
|
+
if self matches Memo():
|
|
58
|
+
self = self.run(ctx)
|
|
59
|
+
except StopIteration(value=value):
|
|
60
|
+
return value
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
__tl__.memo = Memo.value
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import collections.defaultdict
|
|
2
|
-
import functools.wraps
|
|
3
|
-
import .result.Ok
|
|
4
|
-
|
|
5
|
-
export MemoCtx = class:
|
|
6
|
-
__init__ = self =>
|
|
7
|
-
self.cache = defaultdict(dict)
|
|
8
|
-
|
|
9
|
-
get_or_compute = (self, name, args, f) =>
|
|
10
|
-
if try self.cache[name][args] except KeyError() matches (Ok() as v):
|
|
11
|
-
return v
|
|
12
|
-
|
|
13
|
-
let value = f()
|
|
14
|
-
self.cache[name][args] = value
|
|
15
|
-
value
|
|
16
|
-
|
|
17
|
-
__repr__ = self => f"MemoCtx({self.cache})"
|
|
18
|
-
|
|
19
|
-
export Memo = class:
|
|
20
|
-
__init__ = (self, id, deps, f) =>
|
|
21
|
-
self.id = id
|
|
22
|
-
self.deps = deps
|
|
23
|
-
self.f = f
|
|
24
|
-
|
|
25
|
-
__repr__ = self => f"Memo(...)"
|
|
26
|
-
|
|
27
|
-
run = (self, ctx=MemoCtx()) =>
|
|
28
|
-
ctx.get_or_compute(self.id, tuple(self.deps), self.f)
|
|
29
|
-
|
|
30
|
-
fn = staticmethod& f => wraps(f)& (*args, **kwargs) =>
|
|
31
|
-
let m = object.__new__(Memo)
|
|
32
|
-
let name = f"{f.__module__}.{f.__qualname__}"
|
|
33
|
-
m.run = (ctx=MemoCtx()) =>
|
|
34
|
-
let arg_key = (tuple(args), tuple(kwargs.items()))
|
|
35
|
-
|
|
36
|
-
ctx.get_or_compute(name, arg_key, () =>
|
|
37
|
-
let v = f(*args, **kwargs)
|
|
38
|
-
if v matches Memo():
|
|
39
|
-
v = v.run(ctx)
|
|
40
|
-
v
|
|
41
|
-
)
|
|
42
|
-
m
|
|
43
|
-
|
|
44
|
-
bind_gen = (self, gen) =>
|
|
45
|
-
let m = object.__new__(Memo)
|
|
46
|
-
m.run = (ctx=MemoCtx()) =>
|
|
47
|
-
self = self.run(ctx)
|
|
48
|
-
try:
|
|
49
|
-
while True:
|
|
50
|
-
self = gen.send(self)
|
|
51
|
-
if self matches Memo():
|
|
52
|
-
self = self.run(ctx)
|
|
53
|
-
except StopIteration(value=value):
|
|
54
|
-
return value
|
|
55
|
-
m
|
|
56
|
-
|
|
57
|
-
__tl__.memo = Memo
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import collections.defaultdict
|
|
2
|
-
import functools.wraps
|
|
3
|
-
import .result.Ok
|
|
4
|
-
|
|
5
|
-
export MemoCtx = class:
|
|
6
|
-
__init__ = self =>
|
|
7
|
-
self.cache = defaultdict(dict)
|
|
8
|
-
|
|
9
|
-
get_or_compute = (self, name, args, f) =>
|
|
10
|
-
if try self.cache[name][args] except KeyError() matches (Ok() as v):
|
|
11
|
-
return v
|
|
12
|
-
|
|
13
|
-
let value = f()
|
|
14
|
-
self.cache[name][args] = value
|
|
15
|
-
value
|
|
16
|
-
|
|
17
|
-
__repr__ = self => f"MemoCtx({self.cache})"
|
|
18
|
-
|
|
19
|
-
export Memo = class:
|
|
20
|
-
__init__ = (self, id, deps, f) =>
|
|
21
|
-
self.id = id
|
|
22
|
-
self.deps = deps
|
|
23
|
-
self.f = f
|
|
24
|
-
|
|
25
|
-
__repr__ = self => f"Memo(...)"
|
|
26
|
-
|
|
27
|
-
run = (self, ctx=MemoCtx()) =>
|
|
28
|
-
ctx.get_or_compute(self.id, tuple(self.deps), self.f)
|
|
29
|
-
|
|
30
|
-
fn = staticmethod& f => wraps(f)& (*args, **kwargs) =>
|
|
31
|
-
let m = object.__new__(Memo)
|
|
32
|
-
let name = f"{f.__module__}.{f.__qualname__}"
|
|
33
|
-
m.run = (ctx=MemoCtx()) =>
|
|
34
|
-
let arg_key = (tuple(args), tuple(kwargs.items()))
|
|
35
|
-
|
|
36
|
-
ctx.get_or_compute(name, arg_key, () =>
|
|
37
|
-
let v = f(*args, **kwargs)
|
|
38
|
-
if v matches Memo():
|
|
39
|
-
v = v.run(ctx)
|
|
40
|
-
v
|
|
41
|
-
)
|
|
42
|
-
m
|
|
43
|
-
|
|
44
|
-
bind_gen = (self, gen) =>
|
|
45
|
-
let m = object.__new__(Memo)
|
|
46
|
-
m.run = (ctx=MemoCtx()) =>
|
|
47
|
-
self = self.run(ctx)
|
|
48
|
-
try:
|
|
49
|
-
while True:
|
|
50
|
-
self = gen.send(self)
|
|
51
|
-
if self matches Memo():
|
|
52
|
-
self = self.run(ctx)
|
|
53
|
-
except StopIteration(value=value):
|
|
54
|
-
return value
|
|
55
|
-
m
|
|
56
|
-
|
|
57
|
-
__tl__.memo = Memo
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|