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.
Files changed (111) hide show
  1. {koatl-0.1.20 → koatl-0.1.21}/Cargo.lock +1 -1
  2. {koatl-0.1.20 → koatl-0.1.21}/PKG-INFO +1 -1
  3. {koatl-0.1.20 → koatl-0.1.21}/koatl/Cargo.toml +1 -1
  4. {koatl-0.1.20 → koatl-0.1.21/koatl}/python/koatl/prelude/functional/memo.tl +23 -14
  5. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/Cargo.toml +4 -0
  6. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/src/ast.rs +0 -1
  7. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/src/parser.rs +251 -211
  8. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/inference.rs +0 -1
  9. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/main.rs +0 -2
  10. koatl-0.1.21/koatl-core/src/parse_timer.rs +35 -0
  11. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/resolve_scopes.rs +0 -1
  12. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/transform.rs +0 -6
  13. {koatl-0.1.20/koatl → koatl-0.1.21}/python/koatl/prelude/functional/memo.tl +23 -14
  14. {koatl-0.1.20 → koatl-0.1.21}/Cargo.toml +0 -0
  15. {koatl-0.1.20 → koatl-0.1.21}/README.md +0 -0
  16. {koatl-0.1.20 → koatl-0.1.21}/koatl/.github/workflows/CI.yml +0 -0
  17. {koatl-0.1.20 → koatl-0.1.21}/koatl/.gitignore +0 -0
  18. {koatl-0.1.20 → koatl-0.1.21}/koatl/LICENSE +0 -0
  19. {koatl-0.1.20 → koatl-0.1.21}/koatl/README.md +0 -0
  20. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/__init__.py +0 -0
  21. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/__main__.py +0 -0
  22. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/cli.py +0 -0
  23. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/notebook/__init__.py +0 -0
  24. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/notebook/magic.py +0 -0
  25. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/__init__.tl +0 -0
  26. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/__init__.tl +0 -0
  27. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/async.tl +0 -0
  28. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/async_util.py +0 -0
  29. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/monad.tl +0 -0
  30. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/reader.tl +0 -0
  31. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/functional/result.tl +0 -0
  32. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/prelude/iterable.tl +0 -0
  33. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/runtime/__init__.py +0 -0
  34. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/runtime/helpers.py +0 -0
  35. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/runtime/meta_finder.py +0 -0
  36. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/runtime/record.py +0 -0
  37. {koatl-0.1.20 → koatl-0.1.21}/koatl/python/koatl/runtime/virtual.py +0 -0
  38. {koatl-0.1.20 → koatl-0.1.21}/koatl/requirements.txt +0 -0
  39. {koatl-0.1.20 → koatl-0.1.21}/koatl/src/emit_py.rs +0 -0
  40. {koatl-0.1.20 → koatl-0.1.21}/koatl/src/lib.rs +0 -0
  41. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/coal.tl +0 -0
  42. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/containers.tl +0 -0
  43. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/decorators.tl +0 -0
  44. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/destructure-for-and-fn.tl +0 -0
  45. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/destructure.tl +0 -0
  46. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/escape_ident.tl +0 -0
  47. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/fstr.tl +0 -0
  48. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/functions.tl +0 -0
  49. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/generator.tl +0 -0
  50. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/if_expr.tl +0 -0
  51. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/imports.tl +0 -0
  52. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/loops.tl +0 -0
  53. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/match.tl +0 -0
  54. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/nary-list.tl +0 -0
  55. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/placeholder.tl +0 -0
  56. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/precedence.tl +0 -0
  57. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/scopes.tl +0 -0
  58. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/semantic_whitespace.tl +0 -0
  59. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/slice.tl +0 -0
  60. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/base/try.tl +0 -0
  61. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/destructure.tl +0 -0
  62. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/async.tl +0 -0
  63. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/iterables.tl +0 -0
  64. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/memo.tl +0 -0
  65. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/reader.tl +0 -0
  66. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/result.tl +0 -0
  67. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/prelude/virtual.tl +0 -0
  68. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/util/__init__.py +0 -0
  69. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/util/module0.tl +0 -0
  70. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/util/module1.tl +0 -0
  71. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/e2e/util/module2.tl +0 -0
  72. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/arith.tl +0 -0
  73. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/assign.tl +0 -0
  74. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/block-comments.tl +0 -0
  75. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/deco.tl +0 -0
  76. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/func.tl +0 -0
  77. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/parse/matches.tl +0 -0
  78. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/test_e2e.py +0 -0
  79. {koatl-0.1.20 → koatl-0.1.21}/koatl/tests/test_parse.py +0 -0
  80. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/Cargo.toml +0 -0
  81. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/src/lexer.rs +0 -0
  82. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/src/lib.rs +0 -0
  83. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/src/util.rs +0 -0
  84. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/parser/tests/lexer.rs +0 -0
  85. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/lib.rs +0 -0
  86. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/parser.rs +0 -0
  87. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/py/ast.rs +0 -0
  88. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/py/emit.rs +0 -0
  89. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/py/mod.rs +0 -0
  90. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/py/util.rs +0 -0
  91. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/types.rs +0 -0
  92. {koatl-0.1.20 → koatl-0.1.21}/koatl-core/src/util.rs +0 -0
  93. {koatl-0.1.20 → koatl-0.1.21}/pyproject.toml +0 -0
  94. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/__init__.py +0 -0
  95. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/__main__.py +0 -0
  96. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/cli.py +0 -0
  97. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/notebook/__init__.py +0 -0
  98. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/notebook/magic.py +0 -0
  99. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/__init__.tl +0 -0
  100. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/__init__.tl +0 -0
  101. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/async.tl +0 -0
  102. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/async_util.py +0 -0
  103. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/monad.tl +0 -0
  104. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/reader.tl +0 -0
  105. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/functional/result.tl +0 -0
  106. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/prelude/iterable.tl +0 -0
  107. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/runtime/__init__.py +0 -0
  108. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/runtime/helpers.py +0 -0
  109. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/runtime/meta_finder.py +0 -0
  110. {koatl-0.1.20 → koatl-0.1.21}/python/koatl/runtime/record.py +0 -0
  111. {koatl-0.1.20 → koatl-0.1.21}/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.20"
102
+ version = "0.1.21"
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.20
3
+ Version: 0.1.21
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.20"
3
+ version = "0.1.21"
4
4
  edition = "2021"
5
5
 
6
6
  [lib]
@@ -8,37 +8,46 @@ export Memo = class(Monad):
8
8
  __init__ = self =>
9
9
  self.cache = defaultdict(dict)
10
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
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
- let value = f()
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 => ctx.get_or_compute(id, tuple(deps), f))
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.get_or_compute(id, deps, () =>
34
- let v = f(*args, **kwargs)
35
- if v matches Memo():
36
- v = v.run(ctx)
37
- v
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=Cache()) => self.f(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
 
@@ -8,3 +8,7 @@ ariadne = "0.5.1"
8
8
  parser = { path = "parser" }
9
9
  once_cell = "1.19.0"
10
10
  slotmap = "1.0.7"
11
+
12
+ [[bin]]
13
+ name = "parse_timer"
14
+ path = "src/parse_timer.rs"
@@ -120,7 +120,6 @@ pub enum DeclType {
120
120
 
121
121
  #[derive(Debug, Clone)]
122
122
  pub enum Stmt<'a, TTree: Tree> {
123
- Module,
124
123
  Decl(Vec<SIdent<'a>>, DeclType),
125
124
  Assign(TTree::Expr, TTree::Expr, Option<DeclType>),
126
125
  Expr(TTree::Expr),
@@ -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(closed_pattern.clone())
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
- // Statements
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
- symbol("=").ignore_then(expr.clone()),
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
- inline_stmt.define(
1382
- choice((
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
  }
@@ -1,5 +1,3 @@
1
- #![allow(unused_variables)]
2
-
3
1
  use std::{
4
2
  io::Write,
5
3
  process::{Command, Stdio},
@@ -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
+ }
@@ -1555,7 +1555,6 @@ impl<'src> SStmtExt<'src> for Indirect<SStmt<'src>> {
1555
1555
  Stmt::Import(import_stmt)
1556
1556
  }
1557
1557
  Stmt::Break => Stmt::Break,
1558
- Stmt::Module => Stmt::Module,
1559
1558
  Stmt::Continue => Stmt::Continue,
1560
1559
  };
1561
1560
 
@@ -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
- get_or_compute = (self, name, deps, f) =>
12
- if try self.cache[name][deps] except KeyError() matches (Ok() as v):
13
- return v
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
- let value = f()
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 => ctx.get_or_compute(id, tuple(deps), f))
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.get_or_compute(id, deps, () =>
34
- let v = f(*args, **kwargs)
35
- if v matches Memo():
36
- v = v.run(ctx)
37
- v
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=Cache()) => self.f(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