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.
Files changed (112) hide show
  1. {koatl-0.1.19 → koatl-0.1.20}/Cargo.lock +1 -1
  2. {koatl-0.1.19 → koatl-0.1.20}/PKG-INFO +1 -1
  3. {koatl-0.1.19 → koatl-0.1.20}/koatl/Cargo.toml +1 -1
  4. koatl-0.1.20/koatl/python/koatl/prelude/functional/memo.tl +63 -0
  5. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/memo.tl +2 -1
  6. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/resolve_scopes.rs +12 -11
  7. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/transform.rs +24 -6
  8. koatl-0.1.20/python/koatl/prelude/functional/memo.tl +63 -0
  9. koatl-0.1.19/koatl/python/koatl/prelude/functional/memo.tl +0 -57
  10. koatl-0.1.19/python/koatl/prelude/functional/memo.tl +0 -57
  11. {koatl-0.1.19 → koatl-0.1.20}/Cargo.toml +0 -0
  12. {koatl-0.1.19 → koatl-0.1.20}/README.md +0 -0
  13. {koatl-0.1.19 → koatl-0.1.20}/koatl/.github/workflows/CI.yml +0 -0
  14. {koatl-0.1.19 → koatl-0.1.20}/koatl/.gitignore +0 -0
  15. {koatl-0.1.19 → koatl-0.1.20}/koatl/LICENSE +0 -0
  16. {koatl-0.1.19 → koatl-0.1.20}/koatl/README.md +0 -0
  17. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/__init__.py +0 -0
  18. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/__main__.py +0 -0
  19. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/cli.py +0 -0
  20. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/notebook/__init__.py +0 -0
  21. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/notebook/magic.py +0 -0
  22. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/__init__.tl +0 -0
  23. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/__init__.tl +0 -0
  24. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/async.tl +0 -0
  25. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/async_util.py +0 -0
  26. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/monad.tl +0 -0
  27. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/reader.tl +0 -0
  28. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/functional/result.tl +0 -0
  29. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/prelude/iterable.tl +0 -0
  30. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/runtime/__init__.py +0 -0
  31. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/runtime/helpers.py +0 -0
  32. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/runtime/meta_finder.py +0 -0
  33. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/runtime/record.py +0 -0
  34. {koatl-0.1.19 → koatl-0.1.20}/koatl/python/koatl/runtime/virtual.py +0 -0
  35. {koatl-0.1.19 → koatl-0.1.20}/koatl/requirements.txt +0 -0
  36. {koatl-0.1.19 → koatl-0.1.20}/koatl/src/emit_py.rs +0 -0
  37. {koatl-0.1.19 → koatl-0.1.20}/koatl/src/lib.rs +0 -0
  38. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/coal.tl +0 -0
  39. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/containers.tl +0 -0
  40. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/decorators.tl +0 -0
  41. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/destructure-for-and-fn.tl +0 -0
  42. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/destructure.tl +0 -0
  43. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/escape_ident.tl +0 -0
  44. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/fstr.tl +0 -0
  45. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/functions.tl +0 -0
  46. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/generator.tl +0 -0
  47. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/if_expr.tl +0 -0
  48. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/imports.tl +0 -0
  49. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/loops.tl +0 -0
  50. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/match.tl +0 -0
  51. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/nary-list.tl +0 -0
  52. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/placeholder.tl +0 -0
  53. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/precedence.tl +0 -0
  54. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/scopes.tl +0 -0
  55. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/semantic_whitespace.tl +0 -0
  56. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/slice.tl +0 -0
  57. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/base/try.tl +0 -0
  58. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/destructure.tl +0 -0
  59. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/async.tl +0 -0
  60. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/iterables.tl +0 -0
  61. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/reader.tl +0 -0
  62. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/result.tl +0 -0
  63. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/prelude/virtual.tl +0 -0
  64. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/util/__init__.py +0 -0
  65. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/util/module0.tl +0 -0
  66. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/util/module1.tl +0 -0
  67. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/e2e/util/module2.tl +0 -0
  68. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/arith.tl +0 -0
  69. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/assign.tl +0 -0
  70. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/block-comments.tl +0 -0
  71. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/deco.tl +0 -0
  72. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/func.tl +0 -0
  73. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/parse/matches.tl +0 -0
  74. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/test_e2e.py +0 -0
  75. {koatl-0.1.19 → koatl-0.1.20}/koatl/tests/test_parse.py +0 -0
  76. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/Cargo.toml +0 -0
  77. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/Cargo.toml +0 -0
  78. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/src/ast.rs +0 -0
  79. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/src/lexer.rs +0 -0
  80. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/src/lib.rs +0 -0
  81. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/src/parser.rs +0 -0
  82. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/src/util.rs +0 -0
  83. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/parser/tests/lexer.rs +0 -0
  84. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/inference.rs +0 -0
  85. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/lib.rs +0 -0
  86. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/main.rs +0 -0
  87. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/parser.rs +0 -0
  88. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/py/ast.rs +0 -0
  89. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/py/emit.rs +0 -0
  90. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/py/mod.rs +0 -0
  91. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/py/util.rs +0 -0
  92. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/types.rs +0 -0
  93. {koatl-0.1.19 → koatl-0.1.20}/koatl-core/src/util.rs +0 -0
  94. {koatl-0.1.19 → koatl-0.1.20}/pyproject.toml +0 -0
  95. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/__init__.py +0 -0
  96. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/__main__.py +0 -0
  97. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/cli.py +0 -0
  98. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/notebook/__init__.py +0 -0
  99. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/notebook/magic.py +0 -0
  100. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/__init__.tl +0 -0
  101. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/__init__.tl +0 -0
  102. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/async.tl +0 -0
  103. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/async_util.py +0 -0
  104. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/monad.tl +0 -0
  105. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/reader.tl +0 -0
  106. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/functional/result.tl +0 -0
  107. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/prelude/iterable.tl +0 -0
  108. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/runtime/__init__.py +0 -0
  109. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/runtime/helpers.py +0 -0
  110. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/runtime/meta_finder.py +0 -0
  111. {koatl-0.1.19 → koatl-0.1.20}/python/koatl/runtime/record.py +0 -0
  112. {koatl-0.1.19 → koatl-0.1.20}/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.19"
102
+ version = "0.1.20"
103
103
  dependencies = [
104
104
  "ariadne",
105
105
  "koatl-core",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: koatl
3
- Version: 0.1.19
3
+ Version: 0.1.20
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "koatl"
3
- version = "0.1.19"
3
+ version = "0.1.20"
4
4
  edition = "2021"
5
5
 
6
6
  [lib]
@@ -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
@@ -23,8 +23,9 @@ f = x =>
23
23
  counts = counts + 1
24
24
  x * 2
25
25
 
26
- ctx = MemoCtx()
26
+ ctx = Memo.Cache()
27
27
  assert_eq(f(10).run(ctx), 20)
28
28
  assert_eq(f(10).run(ctx), 20)
29
29
  assert_eq(f(5).run(ctx), 10)
30
+ assert_eq(f(5).run(ctx), 10)
30
31
  assert_eq(counts, 2)
@@ -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 let Some(found) = decls[..i]
1146
- .iter()
1147
- .find(|x| 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
- );
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(_)) = &pattern.value {
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
- let decl = pattern_meta.decls.iter().next().unwrap();
1038
- return Ok((PyBlock::new(), ctx.decl_py_ident(*decl)?));
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
- PyArgDefItem::ArgSpread(ctx.decl_py_ident(*decl)?)
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
- PyArgDefItem::KwargSpread(ctx.decl_py_ident(*decl)?)
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
- if ctx.scopes[ctx.declarations[*capture].scope].is_global {
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