koatl 0.1.12__tar.gz → 0.1.13__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 (101) hide show
  1. {koatl-0.1.12 → koatl-0.1.13}/Cargo.lock +1 -1
  2. {koatl-0.1.12 → koatl-0.1.13}/PKG-INFO +1 -1
  3. {koatl-0.1.12 → koatl-0.1.13}/koatl/Cargo.toml +1 -1
  4. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/coal.tl +3 -3
  5. koatl-0.1.13/koatl/tests/e2e/base/placeholder.tl +37 -0
  6. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/parser/src/ast.rs +4 -4
  7. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/parser/src/parser.rs +25 -21
  8. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/parser/src/util.rs +2 -2
  9. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/src/transform.rs +177 -187
  10. koatl-0.1.12/koatl/tests/e2e/base/placeholder.tl +0 -23
  11. {koatl-0.1.12 → koatl-0.1.13}/Cargo.toml +0 -0
  12. {koatl-0.1.12 → koatl-0.1.13}/README.md +0 -0
  13. {koatl-0.1.12 → koatl-0.1.13}/koatl/.github/workflows/CI.yml +0 -0
  14. {koatl-0.1.12 → koatl-0.1.13}/koatl/.gitignore +0 -0
  15. {koatl-0.1.12 → koatl-0.1.13}/koatl/LICENSE +0 -0
  16. {koatl-0.1.12 → koatl-0.1.13}/koatl/README.md +0 -0
  17. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/__init__.py +0 -0
  18. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/__main__.py +0 -0
  19. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/cli.py +0 -0
  20. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/notebook/__init__.py +0 -0
  21. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/notebook/magic.py +0 -0
  22. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/prelude/__init__.tl +0 -0
  23. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/prelude/functional/__init__.tl +0 -0
  24. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/prelude/functional/async.tl +0 -0
  25. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/prelude/functional/async_util.py +0 -0
  26. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/prelude/functional/ok.tl +0 -0
  27. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/prelude/functional/reader.tl +0 -0
  28. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/prelude/iterable.tl +0 -0
  29. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/runtime/__init__.py +0 -0
  30. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/runtime/helpers.py +0 -0
  31. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/runtime/meta_finder.py +0 -0
  32. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/runtime/record.py +0 -0
  33. {koatl-0.1.12 → koatl-0.1.13}/koatl/python/koatl/runtime/virtual.py +0 -0
  34. {koatl-0.1.12 → koatl-0.1.13}/koatl/requirements.txt +0 -0
  35. {koatl-0.1.12 → koatl-0.1.13}/koatl/src/emit_py.rs +0 -0
  36. {koatl-0.1.12 → koatl-0.1.13}/koatl/src/lib.rs +0 -0
  37. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/containers.tl +0 -0
  38. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/decorators.tl +0 -0
  39. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/destructure-for-and-fn.tl +0 -0
  40. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/destructure.tl +0 -0
  41. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/escape_ident.tl +0 -0
  42. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/fstr.tl +0 -0
  43. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/functions.tl +0 -0
  44. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/generator.tl +0 -0
  45. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/if_expr.tl +0 -0
  46. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/imports.tl +0 -0
  47. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/iterables.tl +0 -0
  48. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/loops.tl +0 -0
  49. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/match.tl +0 -0
  50. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/nary-list.tl +0 -0
  51. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/precedence.tl +0 -0
  52. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/semantic_whitespace.tl +0 -0
  53. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/slice.tl +0 -0
  54. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/base/try.tl +0 -0
  55. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/destructure.tl +0 -0
  56. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/prelude/async.tl +0 -0
  57. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/prelude/ok.tl +0 -0
  58. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/prelude/reader.tl +0 -0
  59. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/prelude/virtual.tl +0 -0
  60. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/util/__init__.py +0 -0
  61. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/util/module0.tl +0 -0
  62. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/util/module1.tl +0 -0
  63. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/e2e/util/module2.tl +0 -0
  64. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/parse/arith.tl +0 -0
  65. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/parse/assign.tl +0 -0
  66. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/parse/deco.tl +0 -0
  67. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/parse/func.tl +0 -0
  68. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/parse/matches.tl +0 -0
  69. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/test_e2e.py +0 -0
  70. {koatl-0.1.12 → koatl-0.1.13}/koatl/tests/test_parse.py +0 -0
  71. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/Cargo.toml +0 -0
  72. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/parser/Cargo.toml +0 -0
  73. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/parser/src/lexer.rs +0 -0
  74. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/parser/src/lib.rs +0 -0
  75. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/parser/tests/lexer.rs +0 -0
  76. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/src/lib.rs +0 -0
  77. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/src/linecol.rs +0 -0
  78. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/src/main.rs +0 -0
  79. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/src/parser.rs +0 -0
  80. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/src/py/ast.rs +0 -0
  81. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/src/py/emit.rs +0 -0
  82. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/src/py/mod.rs +0 -0
  83. {koatl-0.1.12 → koatl-0.1.13}/koatl-core/src/py/util.rs +0 -0
  84. {koatl-0.1.12 → koatl-0.1.13}/pyproject.toml +0 -0
  85. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/__init__.py +0 -0
  86. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/__main__.py +0 -0
  87. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/cli.py +0 -0
  88. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/notebook/__init__.py +0 -0
  89. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/notebook/magic.py +0 -0
  90. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/prelude/__init__.tl +0 -0
  91. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/prelude/functional/__init__.tl +0 -0
  92. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/prelude/functional/async.tl +0 -0
  93. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/prelude/functional/async_util.py +0 -0
  94. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/prelude/functional/ok.tl +0 -0
  95. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/prelude/functional/reader.tl +0 -0
  96. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/prelude/iterable.tl +0 -0
  97. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/runtime/__init__.py +0 -0
  98. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/runtime/helpers.py +0 -0
  99. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/runtime/meta_finder.py +0 -0
  100. {koatl-0.1.12 → koatl-0.1.13}/python/koatl/runtime/record.py +0 -0
  101. {koatl-0.1.12 → koatl-0.1.13}/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.12"
102
+ version = "0.1.13"
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.12
3
+ Version: 0.1.13
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.12"
3
+ version = "0.1.13"
4
4
  edition = "2021"
5
5
 
6
6
  [lib]
@@ -12,7 +12,7 @@ obj = (class:
12
12
  assert_eq((x => x)?(1), 1)
13
13
  assert_eq([1]?[0], 1)
14
14
  assert_eq(obj?.a, 1)
15
- assert_eq(1?.($ + 1), 2)
15
+ assert_eq(1?.($ + 1)(), 2)
16
16
 
17
17
  assert_eq(None ?? 1, 1)
18
18
  assert_eq(int(5) ?? 1, 5)
@@ -26,5 +26,5 @@ assert_eq(type(try [0][5]), IndexError)
26
26
  assert_eq(try 5, 5)
27
27
 
28
28
 
29
- assert_eq((try 5)?.($+1), 6)
30
- assert_eq(type((try x)?.($+1)), NameError)
29
+ assert_eq((try 5)?.($+1)?(), 6)
30
+ assert_eq(type((try x)?.($+1)?()), NameError)
@@ -0,0 +1,37 @@
1
+ import util.assert_eq
2
+
3
+ # basic usage
4
+
5
+ call_with_five = f => f(5)
6
+
7
+ assert_eq(call_with_five($ + 1), 6)
8
+
9
+ res = call_with_five($)
10
+ assert_eq(callable(res), True)
11
+
12
+ assert_eq(callable([1, 2, $]), True)
13
+
14
+
15
+ # weird cases
16
+
17
+ assert_eq((x => x)($ + 1)(1), 2)
18
+
19
+ assert_eq(1
20
+ | $ + 1
21
+ | $ * 2
22
+ | $ * 5, 20)
23
+
24
+ f = $ + 1
25
+
26
+ assert_eq(f(2), 3)
27
+
28
+ f = x => x * 2
29
+ g = f($)
30
+
31
+ assert_eq(g(3), 6)
32
+
33
+ assert_eq(3 | f($), 6)
34
+
35
+ assert_eq(3 | [$, 2, 3], [3, 2, 3])
36
+ f = [$, 2, 3]
37
+ assert_eq(f(3), [3, 2, 3])
@@ -174,15 +174,15 @@ pub enum Expr<'a> {
174
174
 
175
175
  Call(Box<SExpr<'a>>, Vec<SCallItem<'a>>),
176
176
  Subscript(Box<SExpr<'a>>, Vec<ListItem<'a>>),
177
+ RawAttribute(Box<SExpr<'a>>, SIdent<'a>),
178
+ ScopedAttribute(Box<SExpr<'a>>, Box<SExpr<'a>>),
177
179
  Attribute(Box<SExpr<'a>>, SIdent<'a>),
178
- ScopedExtension(Box<SExpr<'a>>, Box<SExpr<'a>>),
179
- Extension(Box<SExpr<'a>>, SIdent<'a>),
180
180
 
181
181
  MappedCall(Box<SExpr<'a>>, Vec<SCallItem<'a>>),
182
182
  MappedSubscript(Box<SExpr<'a>>, Vec<ListItem<'a>>),
183
+ MappedRawAttribute(Box<SExpr<'a>>, SIdent<'a>),
184
+ MappedScopedAttribute(Box<SExpr<'a>>, Box<SExpr<'a>>),
183
185
  MappedAttribute(Box<SExpr<'a>>, SIdent<'a>),
184
- MappedThen(Box<SExpr<'a>>, Box<SExpr<'a>>),
185
- MappedExtension(Box<SExpr<'a>>, SIdent<'a>),
186
186
 
187
187
  Checked(Box<SExpr<'a>>, Option<Box<SPattern<'a>>>),
188
188
 
@@ -121,7 +121,7 @@ where
121
121
  .or_not()
122
122
  .then(qualified_ident.clone())
123
123
  .try_map(|(q, value), _e| {
124
- Ok(if let Expr::Attribute(..) = value.0 {
124
+ Ok(if let Expr::RawAttribute(..) = value.0 {
125
125
  Pattern::Value(value)
126
126
  } else if q.is_some() {
127
127
  Pattern::Value(value)
@@ -588,7 +588,7 @@ where
588
588
  .clone()
589
589
  .foldl_with(
590
590
  symbol(".").ignore_then(ident.clone()).repeated(),
591
- |lhs, rhs, e| (Expr::Attribute(Box::new(lhs), rhs), e.span()),
591
+ |lhs, rhs, e| (Expr::RawAttribute(Box::new(lhs), rhs), e.span()),
592
592
  )
593
593
  .boxed();
594
594
 
@@ -687,10 +687,10 @@ where
687
687
  enum Postfix<'a> {
688
688
  Call(Vec<SCallItem<'a>>),
689
689
  Subscript(Vec<ListItem<'a>>),
690
- Extension(SIdent<'a>),
691
- Then(SExpr<'a>),
692
- ThenCall(SExpr<'a>, Vec<SCallItem<'a>>),
693
690
  Attribute(SIdent<'a>),
691
+ ScopedAttribute(SExpr<'a>),
692
+ ScopedAttributeCall(SExpr<'a>, Vec<SCallItem<'a>>),
693
+ RawAttribute(SIdent<'a>),
694
694
  }
695
695
 
696
696
  let call_args = enumeration(
@@ -735,7 +735,7 @@ where
735
735
 
736
736
  let attribute = symbol(".")
737
737
  .ignore_then(ident.clone())
738
- .map(Postfix::Extension)
738
+ .map(Postfix::Attribute)
739
739
  .labelled("extension-attribute");
740
740
 
741
741
  let then = symbol(".")
@@ -743,9 +743,9 @@ where
743
743
  .then(call_args.or_not())
744
744
  .map(|(rhs, args)| {
745
745
  if let Some(args) = args {
746
- Postfix::ThenCall(rhs, args)
746
+ Postfix::ScopedAttributeCall(rhs, args)
747
747
  } else {
748
- Postfix::Then(rhs)
748
+ Postfix::ScopedAttribute(rhs)
749
749
  }
750
750
  })
751
751
  .labelled("then-attribute")
@@ -753,8 +753,8 @@ where
753
753
 
754
754
  let extension = symbol("!")
755
755
  .ignore_then(ident.clone())
756
- .map(Postfix::Attribute)
757
- .labelled("native-attribute")
756
+ .map(Postfix::RawAttribute)
757
+ .labelled("raw-attribute")
758
758
  .boxed();
759
759
 
760
760
  let postfix = atom
@@ -771,34 +771,38 @@ where
771
771
  match op {
772
772
  Postfix::Call(args) => Expr::Call(Box::new(expr), args),
773
773
  Postfix::Subscript(args) => Expr::Subscript(Box::new(expr), args),
774
- Postfix::Attribute(attr) => Expr::Attribute(Box::new(expr), attr),
775
- Postfix::Then(rhs) => {
776
- Expr::ScopedExtension(Box::new(expr), Box::new(rhs))
774
+ Postfix::RawAttribute(attr) => Expr::RawAttribute(Box::new(expr), attr),
775
+ Postfix::ScopedAttribute(rhs) => {
776
+ Expr::ScopedAttribute(Box::new(expr), Box::new(rhs))
777
777
  }
778
- Postfix::ThenCall(rhs, args) => Expr::Call(
778
+ Postfix::ScopedAttributeCall(rhs, args) => Expr::Call(
779
779
  // TODO optimize this case in the AST by skipping partial application
780
780
  Box::new((
781
- Expr::ScopedExtension(Box::new(expr), Box::new(rhs)),
781
+ Expr::ScopedAttribute(Box::new(expr), Box::new(rhs)),
782
782
  e.span(),
783
783
  )),
784
784
  args,
785
785
  ),
786
- Postfix::Extension(rhs) => Expr::Extension(Box::new(expr), rhs),
786
+ Postfix::Attribute(rhs) => Expr::Attribute(Box::new(expr), rhs),
787
787
  }
788
788
  } else {
789
789
  match op {
790
790
  Postfix::Call(args) => Expr::MappedCall(Box::new(expr), args),
791
791
  Postfix::Subscript(args) => Expr::MappedSubscript(Box::new(expr), args),
792
- Postfix::Attribute(attr) => Expr::MappedAttribute(Box::new(expr), attr),
793
- Postfix::Then(rhs) => Expr::MappedThen(Box::new(expr), Box::new(rhs)),
794
- Postfix::ThenCall(rhs, args) => Expr::Call(
792
+ Postfix::RawAttribute(attr) => {
793
+ Expr::MappedRawAttribute(Box::new(expr), attr)
794
+ }
795
+ Postfix::ScopedAttribute(rhs) => {
796
+ Expr::MappedScopedAttribute(Box::new(expr), Box::new(rhs))
797
+ }
798
+ Postfix::ScopedAttributeCall(rhs, args) => Expr::Call(
795
799
  Box::new((
796
- Expr::MappedThen(Box::new(expr), Box::new(rhs)),
800
+ Expr::MappedScopedAttribute(Box::new(expr), Box::new(rhs)),
797
801
  e.span(),
798
802
  )),
799
803
  args,
800
804
  ),
801
- Postfix::Extension(rhs) => Expr::MappedExtension(Box::new(expr), rhs),
805
+ Postfix::Attribute(rhs) => Expr::MappedAttribute(Box::new(expr), rhs),
802
806
  }
803
807
  },
804
808
  e.span(),
@@ -147,14 +147,14 @@ impl AstBuilder {
147
147
  attr: impl Into<Cow<'src, str>>,
148
148
  ) -> SExpr<'src> {
149
149
  (
150
- Expr::Attribute(Box::new(value), (attr.into(), self.span)),
150
+ Expr::RawAttribute(Box::new(value), (attr.into(), self.span)),
151
151
  self.span,
152
152
  )
153
153
  }
154
154
 
155
155
  pub fn then<'src>(&self, left: SExpr<'src>, right: SExpr<'src>) -> SExpr<'src> {
156
156
  (
157
- Expr::ScopedExtension(Box::new(left), Box::new(right)),
157
+ Expr::ScopedAttribute(Box::new(left), Box::new(right)),
158
158
  self.span,
159
159
  )
160
160
  }
@@ -505,13 +505,13 @@ fn destructure<'src, 'ast>(
505
505
  let assign_to: SPyExpr<'src>;
506
506
 
507
507
  match &target.0 {
508
- Expr::Ident(..) | Expr::Attribute(..) | Expr::Extension(..) | Expr::Subscript(..) => {
508
+ Expr::Ident(..) | Expr::RawAttribute(..) | Expr::Attribute(..) | Expr::Subscript(..) => {
509
509
  let target_node = match &target.0 {
510
510
  Expr::Ident(id) => {
511
511
  decls.push(ctx.escape_ident(&id.0));
512
512
  target.transform_with_access(ctx, PyAccessCtx::Store)?
513
513
  }
514
- Expr::Attribute(..) | Expr::Subscript(..) => {
514
+ Expr::RawAttribute(..) | Expr::Subscript(..) => {
515
515
  if decl_only {
516
516
  return Err(TfErrBuilder::default()
517
517
  .message("Only identifiers allowed in this destructuring")
@@ -520,7 +520,7 @@ fn destructure<'src, 'ast>(
520
520
  }
521
521
  target.transform_with_access(ctx, PyAccessCtx::Store)?
522
522
  }
523
- Expr::Extension(lhs, ext) => {
523
+ Expr::Attribute(lhs, ext) => {
524
524
  if decl_only {
525
525
  return Err(TfErrBuilder::default()
526
526
  .message("Only identifiers allowed in this destructuring")
@@ -532,7 +532,7 @@ fn destructure<'src, 'ast>(
532
532
  // when assigning to it
533
533
 
534
534
  // TODO avoid this clone
535
- let new_target = (Expr::Attribute(lhs.clone(), ext.clone()), target.1);
535
+ let new_target = (Expr::RawAttribute(lhs.clone(), ext.clone()), target.1);
536
536
 
537
537
  new_target.transform_with_access(ctx, PyAccessCtx::Store)?
538
538
  }
@@ -1282,7 +1282,7 @@ fn transform_match_expr<'src, 'ast>(
1282
1282
  fill_default_case: bool,
1283
1283
  span: &Span,
1284
1284
  ) -> TfResult<(SPyExprWithPre<'src>, bool)> {
1285
- let subject = subject.transform_with_placeholder_guard(ctx)?;
1285
+ let subject = subject.transform(ctx)?;
1286
1286
  let mut pre = subject.pre;
1287
1287
  let a = PyAstBuilder::new(*span);
1288
1288
 
@@ -1321,10 +1321,7 @@ fn transform_match_expr<'src, 'ast>(
1321
1321
  };
1322
1322
 
1323
1323
  let guard = if let Some(guard) = &case.guard {
1324
- Some(bind_pre(
1325
- &mut pre,
1326
- guard.transform_with_placeholder_guard(ctx)?,
1327
- ))
1324
+ Some(bind_pre(&mut pre, guard.transform(ctx)?))
1328
1325
  } else {
1329
1326
  None
1330
1327
  };
@@ -1669,7 +1666,7 @@ fn transform_subscript_items<'src, 'ast>(
1669
1666
  };
1670
1667
 
1671
1668
  let subscript_expr = if let Some(single_item) = single_item {
1672
- let e = single_item.transform_with_deep_placeholder_guard(ctx)?;
1669
+ let e = single_item.transform(ctx)?;
1673
1670
  aux_stmts.extend(e.pre);
1674
1671
  e.value
1675
1672
  } else {
@@ -1679,12 +1676,12 @@ fn transform_subscript_items<'src, 'ast>(
1679
1676
  .into_iter()
1680
1677
  .map(|i| match i {
1681
1678
  ListItem::Item(expr) => {
1682
- let e = expr.transform_with_deep_placeholder_guard(ctx)?;
1679
+ let e = expr.transform(ctx)?;
1683
1680
  aux_stmts.extend(e.pre);
1684
1681
  Ok(PyListItem::Item(e.value))
1685
1682
  }
1686
1683
  ListItem::Spread(expr) => {
1687
- let e = expr.transform_with_deep_placeholder_guard(ctx)?;
1684
+ let e = expr.transform(ctx)?;
1688
1685
  aux_stmts.extend(e.pre);
1689
1686
  Ok(PyListItem::Spread(e.value))
1690
1687
  }
@@ -1860,16 +1857,16 @@ fn transform_postfix_expr<'src, 'ast>(
1860
1857
  ) -> TfResult<SPyExprWithPre<'src>> {
1861
1858
  let mut aux = PyBlock::new();
1862
1859
  let (lift_lhs, lhs_node) = match &expr.0 {
1863
- Expr::Attribute(obj, _) => (false, obj),
1860
+ Expr::RawAttribute(obj, _) => (false, obj),
1864
1861
  Expr::Subscript(obj, _) => (false, obj),
1865
1862
  Expr::Call(obj, _) => (false, obj),
1866
- Expr::ScopedExtension(obj, _) => (false, obj),
1867
- Expr::Extension(obj, _) => (false, obj),
1868
- Expr::MappedAttribute(obj, _) => (true, obj),
1863
+ Expr::ScopedAttribute(obj, _) => (false, obj),
1864
+ Expr::Attribute(obj, _) => (false, obj),
1865
+ Expr::MappedRawAttribute(obj, _) => (true, obj),
1869
1866
  Expr::MappedSubscript(obj, _) => (true, obj),
1870
1867
  Expr::MappedCall(obj, _) => (true, obj),
1871
- Expr::MappedThen(obj, _) => (true, obj),
1872
- Expr::MappedExtension(obj, _) => (true, obj),
1868
+ Expr::MappedScopedAttribute(obj, _) => (true, obj),
1869
+ Expr::MappedAttribute(obj, _) => (true, obj),
1873
1870
  _ => {
1874
1871
  return Err(TfErrBuilder::default()
1875
1872
  .message("Internal error: Postfix expressions can only be attributes, subscripts, calls, or extensions")
@@ -1895,81 +1892,85 @@ fn transform_postfix_expr<'src, 'ast>(
1895
1892
  t.value
1896
1893
  };
1897
1894
 
1898
- placeholder_guard(ctx, &expr.1, |ctx| {
1899
- let a = PyAstBuilder::new(expr.1);
1895
+ let a = PyAstBuilder::new(expr.1);
1900
1896
 
1901
- let guard_if_expr = |expr| {
1902
- a.if_expr(
1903
- a.call(a.tl_builtin("ok"), vec![a.call_arg(lhs.clone())]),
1904
- expr,
1905
- lhs.clone(),
1906
- )
1907
- };
1897
+ let guard_if_expr = |expr| {
1898
+ a.if_expr(
1899
+ a.call(a.tl_builtin("ok"), vec![a.call_arg(lhs.clone())]),
1900
+ expr,
1901
+ lhs.clone(),
1902
+ )
1903
+ };
1908
1904
 
1909
- let node = match &expr.0 {
1910
- Expr::Call(_, list) => {
1911
- let t = transform_call_items(ctx, &list, &expr.1)?;
1912
- aux.extend(t.0);
1913
- a.call(lhs, t.1)
1914
- }
1915
- Expr::MappedCall(_, list) => {
1916
- let t = transform_call_items(ctx, &list, &expr.1)?;
1917
- aux.extend(t.0);
1918
- guard_if_expr(a.call(lhs.clone(), t.1))
1919
- }
1920
- Expr::Subscript(_, list) => {
1921
- let t = transform_subscript_items(ctx, &list, &expr.1)?;
1922
- aux.extend(t.0);
1923
- a.subscript(lhs, t.1, access_ctx)
1924
- }
1925
- Expr::MappedSubscript(_, list) => {
1926
- let t = transform_subscript_items(ctx, &list, &expr.1)?;
1927
- aux.extend(t.0);
1928
- guard_if_expr(a.subscript(lhs.clone(), t.1, access_ctx))
1929
- }
1930
- Expr::Attribute(_, attr) => a.attribute(lhs, ctx.escape_ident(&attr.0), access_ctx),
1931
- Expr::MappedAttribute(_, attr) => {
1932
- guard_if_expr(a.attribute(lhs.clone(), ctx.escape_ident(&attr.0), access_ctx))
1933
- }
1934
- Expr::ScopedExtension(_, rhs) => {
1935
- let rhs_node = rhs.transform_with_placeholder_guard(ctx)?;
1936
- aux.extend(rhs_node.pre);
1937
- a.call(
1938
- a.tl_builtin("partial"),
1939
- vec![PyCallItem::Arg(rhs_node.value), PyCallItem::Arg(lhs)],
1940
- )
1941
- }
1942
- Expr::MappedThen(_, rhs) => {
1943
- let rhs_node = rhs.transform_with_placeholder_guard(ctx)?;
1944
- aux.extend(rhs_node.pre);
1945
- guard_if_expr(a.call(rhs_node.value, vec![PyCallItem::Arg(lhs.clone())]))
1946
- }
1947
- Expr::Extension(_, rhs) => a.call(
1948
- a.tl_builtin("vget"),
1949
- vec![
1950
- a.call_arg(lhs),
1951
- a.call_arg(a.literal(PyLiteral::Str(ctx.escape_ident(&rhs.0)))),
1952
- ],
1953
- ),
1954
- Expr::MappedExtension(_, rhs) => guard_if_expr(a.call(
1955
- a.tl_builtin("vget"),
1905
+ let node = match &expr.0 {
1906
+ Expr::Call(_, list) => {
1907
+ let t = transform_call_items(ctx, &list, &expr.1)?;
1908
+ aux.extend(t.0);
1909
+ a.call(lhs, t.1)
1910
+ }
1911
+ Expr::MappedCall(_, list) => {
1912
+ let t = transform_call_items(ctx, &list, &expr.1)?;
1913
+ aux.extend(t.0);
1914
+ guard_if_expr(a.call(lhs.clone(), t.1))
1915
+ }
1916
+ Expr::Subscript(_, list) => {
1917
+ let t = transform_subscript_items(ctx, &list, &expr.1)?;
1918
+ aux.extend(t.0);
1919
+ a.subscript(lhs, t.1, access_ctx)
1920
+ }
1921
+ Expr::MappedSubscript(_, list) => {
1922
+ let t = transform_subscript_items(ctx, &list, &expr.1)?;
1923
+ aux.extend(t.0);
1924
+ guard_if_expr(a.subscript(lhs.clone(), t.1, access_ctx))
1925
+ }
1926
+ Expr::RawAttribute(_, attr) => a.attribute(lhs, ctx.escape_ident(&attr.0), access_ctx),
1927
+ Expr::MappedRawAttribute(_, attr) => {
1928
+ guard_if_expr(a.attribute(lhs.clone(), ctx.escape_ident(&attr.0), access_ctx))
1929
+ }
1930
+ Expr::ScopedAttribute(_, rhs) => {
1931
+ let rhs_node = rhs.transform_with_placeholder_guard(ctx)?;
1932
+ aux.extend(rhs_node.pre);
1933
+ a.call(
1934
+ a.tl_builtin("partial"),
1935
+ vec![PyCallItem::Arg(rhs_node.value), PyCallItem::Arg(lhs)],
1936
+ )
1937
+ }
1938
+ Expr::MappedScopedAttribute(_, rhs) => {
1939
+ let rhs_node = rhs.transform_with_placeholder_guard(ctx)?;
1940
+ aux.extend(rhs_node.pre);
1941
+ guard_if_expr(a.call(
1942
+ a.tl_builtin("partial"),
1956
1943
  vec![
1957
- a.call_arg(lhs.clone()),
1958
- a.call_arg(a.literal(PyLiteral::Str(ctx.escape_ident(&rhs.0)))),
1944
+ PyCallItem::Arg(rhs_node.value),
1945
+ PyCallItem::Arg(lhs.clone()),
1959
1946
  ],
1960
- )),
1961
- _ => {
1962
- return Err(TfErrBuilder::default()
1947
+ ))
1948
+ }
1949
+ Expr::Attribute(_, rhs) => a.call(
1950
+ a.tl_builtin("vget"),
1951
+ vec![
1952
+ a.call_arg(lhs),
1953
+ a.call_arg(a.literal(PyLiteral::Str(ctx.escape_ident(&rhs.0)))),
1954
+ ],
1955
+ ),
1956
+ Expr::MappedAttribute(_, rhs) => guard_if_expr(a.call(
1957
+ a.tl_builtin("vget"),
1958
+ vec![
1959
+ a.call_arg(lhs.clone()),
1960
+ a.call_arg(a.literal(PyLiteral::Str(ctx.escape_ident(&rhs.0)))),
1961
+ ],
1962
+ )),
1963
+ _ => {
1964
+ return Err(TfErrBuilder::default()
1963
1965
  .message("Internal error: Postfix expressions can only be attributes, subscripts, calls, or extensions")
1964
1966
  .span(expr.1)
1965
1967
  .build_errs());
1966
- }
1967
- };
1968
+ }
1969
+ };
1968
1970
 
1969
- Ok(SPyExprWithPre {
1970
- value: node,
1971
- pre: aux,
1972
- })
1971
+ Ok(SPyExprWithPre {
1972
+ value: node,
1973
+ pre: aux,
1973
1974
  })
1974
1975
  }
1975
1976
 
@@ -2064,8 +2065,8 @@ impl<'src> ListItemsExt<'src> for Vec<ListItem<'src>> {
2064
2065
 
2065
2066
  for expr in self {
2066
2067
  let e = match expr {
2067
- ListItem::Spread(expr) => expr.transform_with_deep_placeholder_guard(ctx)?,
2068
- ListItem::Item(expr) => expr.transform_with_deep_placeholder_guard(ctx)?,
2068
+ ListItem::Spread(expr) => expr.transform(ctx)?,
2069
+ ListItem::Item(expr) => expr.transform(ctx)?,
2069
2070
  };
2070
2071
  aux_stmts.extend(e.pre);
2071
2072
  items.push(match expr {
@@ -2203,7 +2204,7 @@ impl<'src> SExprExt<'src> for SExpr<'src> {
2203
2204
  let a = PyAstBuilder::new(*span);
2204
2205
 
2205
2206
  match &expr {
2206
- Expr::Attribute(..) | Expr::Subscript(..) | Expr::Ident(..) => {}
2207
+ Expr::RawAttribute(..) | Expr::Subscript(..) | Expr::Ident(..) => {}
2207
2208
  _ => {
2208
2209
  if access_ctx != PyAccessCtx::Load {
2209
2210
  return Err(TfErrBuilder::default()
@@ -2309,16 +2310,16 @@ impl<'src> SExprExt<'src> for SExpr<'src> {
2309
2310
  value: (PyExpr::Ident(ctx.escape_ident(&ident.0), access_ctx), *span).into(),
2310
2311
  pre: PyBlock::new(),
2311
2312
  }),
2312
- Expr::Attribute(..)
2313
- | Expr::MappedAttribute(..)
2313
+ Expr::RawAttribute(..)
2314
+ | Expr::MappedRawAttribute(..)
2314
2315
  | Expr::Call(..)
2315
2316
  | Expr::MappedCall(..)
2316
2317
  | Expr::Subscript(..)
2317
2318
  | Expr::MappedSubscript(..)
2318
- | Expr::ScopedExtension(..)
2319
- | Expr::MappedThen(..)
2320
- | Expr::Extension(..)
2321
- | Expr::MappedExtension(..) => transform_postfix_expr(ctx, self, access_ctx),
2319
+ | Expr::ScopedAttribute(..)
2320
+ | Expr::MappedScopedAttribute(..)
2321
+ | Expr::Attribute(..)
2322
+ | Expr::MappedAttribute(..) => transform_postfix_expr(ctx, self, access_ctx),
2322
2323
  Expr::If(cond, then_block, else_block) => transform_if_expr(
2323
2324
  ctx,
2324
2325
  cond,
@@ -2507,127 +2508,116 @@ impl<'src> SExprExt<'src> for SExpr<'src> {
2507
2508
  });
2508
2509
  }
2509
2510
  Expr::List(exprs) => {
2510
- return placeholder_guard(ctx, span, |ctx| {
2511
- let (items, aux_stmts) = exprs.transform(ctx)?;
2511
+ let (items, aux_stmts) = exprs.transform(ctx)?;
2512
2512
 
2513
- return Ok(SPyExprWithPre {
2514
- value: (PyExpr::List(items, PyAccessCtx::Load), *span).into(),
2515
- pre: aux_stmts,
2516
- });
2513
+ return Ok(SPyExprWithPre {
2514
+ value: (PyExpr::List(items, PyAccessCtx::Load), *span).into(),
2515
+ pre: aux_stmts,
2517
2516
  });
2518
2517
  }
2519
2518
  Expr::Tuple(exprs) => {
2520
- return placeholder_guard(ctx, span, |ctx| {
2521
- let (items, aux_stmts) = exprs.transform(ctx)?;
2519
+ let (items, aux_stmts) = exprs.transform(ctx)?;
2522
2520
 
2523
- return Ok(SPyExprWithPre {
2524
- value: (PyExpr::Tuple(items, PyAccessCtx::Load), *span).into(),
2525
- pre: aux_stmts,
2526
- });
2521
+ return Ok(SPyExprWithPre {
2522
+ value: (PyExpr::Tuple(items, PyAccessCtx::Load), *span).into(),
2523
+ pre: aux_stmts,
2527
2524
  });
2528
2525
  }
2529
2526
  Expr::Mapping(items) => {
2530
- return placeholder_guard(ctx, span, |ctx| {
2531
- let mut aux_stmts = PyBlock::new();
2532
- let mut dict_items = vec![];
2533
-
2534
- for item in items {
2535
- match item {
2536
- MappingItem::Ident(id) => {
2537
- dict_items.push(PyDictItem::Item(
2538
- a.literal(PyLiteral::Str(ctx.escape_ident(&id.0))),
2539
- a.load_ident(ctx.escape_ident(&id.0)),
2540
- ));
2541
- }
2542
- MappingItem::Item(key, value) => {
2543
- let key = key.transform_with_deep_placeholder_guard(ctx)?;
2544
- let value = value.transform_with_deep_placeholder_guard(ctx)?;
2527
+ let mut aux_stmts = PyBlock::new();
2528
+ let mut dict_items = vec![];
2545
2529
 
2546
- aux_stmts.extend(key.pre);
2547
- aux_stmts.extend(value.pre);
2530
+ for item in items {
2531
+ match item {
2532
+ MappingItem::Ident(id) => {
2533
+ dict_items.push(PyDictItem::Item(
2534
+ a.literal(PyLiteral::Str(ctx.escape_ident(&id.0))),
2535
+ a.load_ident(ctx.escape_ident(&id.0)),
2536
+ ));
2537
+ }
2538
+ MappingItem::Item(key, value) => {
2539
+ let key = key.transform(ctx)?;
2540
+ let value = value.transform(ctx)?;
2548
2541
 
2549
- dict_items.push(PyDictItem::Item(key.value, value.value));
2550
- }
2551
- MappingItem::Spread(expr) => {
2552
- let e = expr.transform_with_deep_placeholder_guard(ctx)?;
2553
- aux_stmts.extend(e.pre);
2542
+ aux_stmts.extend(key.pre);
2543
+ aux_stmts.extend(value.pre);
2554
2544
 
2555
- dict_items.push(PyDictItem::Spread(e.value));
2556
- }
2545
+ dict_items.push(PyDictItem::Item(key.value, value.value));
2546
+ }
2547
+ MappingItem::Spread(expr) => {
2548
+ let e = expr.transform(ctx)?;
2549
+ aux_stmts.extend(e.pre);
2550
+
2551
+ dict_items.push(PyDictItem::Spread(e.value));
2557
2552
  }
2558
2553
  }
2554
+ }
2559
2555
 
2560
- return Ok(SPyExprWithPre {
2561
- value: a.call(a.load_ident("Record"), vec![a.call_arg(a.dict(dict_items))]),
2562
- pre: aux_stmts,
2563
- });
2556
+ return Ok(SPyExprWithPre {
2557
+ value: a.call(a.load_ident("Record"), vec![a.call_arg(a.dict(dict_items))]),
2558
+ pre: aux_stmts,
2564
2559
  });
2565
2560
  }
2566
2561
  Expr::Slice(start, end, step) => {
2567
- return placeholder_guard(ctx, span, |ctx| {
2568
- let start_node = start
2569
- .as_ref()
2570
- .map(|e| e.as_ref().transform_with_deep_placeholder_guard(ctx))
2571
- .transpose()?;
2572
- let end_node = end
2573
- .as_ref()
2574
- .map(|e| e.as_ref().transform_with_deep_placeholder_guard(ctx))
2575
- .transpose()?;
2576
- let step_node = step
2577
- .as_ref()
2578
- .map(|e| e.as_ref().transform_with_deep_placeholder_guard(ctx))
2579
- .transpose()?;
2580
-
2581
- let mut aux_stmts = PyBlock::new();
2582
-
2583
- let mut get = |x: Option<SPyExprWithPre<'src>>| {
2584
- let expr = if let Some(x) = x {
2585
- aux_stmts.extend(x.pre);
2586
- x.value
2587
- } else {
2588
- (PyExpr::Literal(PyLiteral::None), *span).into()
2589
- };
2562
+ let start_node = start
2563
+ .as_ref()
2564
+ .map(|e| e.as_ref().transform(ctx))
2565
+ .transpose()?;
2566
+ let end_node = end
2567
+ .as_ref()
2568
+ .map(|e| e.as_ref().transform(ctx))
2569
+ .transpose()?;
2570
+ let step_node = step
2571
+ .as_ref()
2572
+ .map(|e| e.as_ref().transform(ctx))
2573
+ .transpose()?;
2574
+
2575
+ let mut aux_stmts = PyBlock::new();
2590
2576
 
2591
- PyCallItem::Arg(expr)
2577
+ let mut get = |x: Option<SPyExprWithPre<'src>>| {
2578
+ let expr = if let Some(x) = x {
2579
+ aux_stmts.extend(x.pre);
2580
+ x.value
2581
+ } else {
2582
+ (PyExpr::Literal(PyLiteral::None), *span).into()
2592
2583
  };
2593
2584
 
2594
- return Ok(SPyExprWithPre {
2595
- value: (
2596
- PyExpr::Call(
2597
- Box::new(
2598
- (PyExpr::Ident("slice".into(), PyAccessCtx::Load), *span)
2599
- .into(),
2600
- ),
2601
- vec![get(start_node), get(end_node), get(step_node)],
2585
+ PyCallItem::Arg(expr)
2586
+ };
2587
+
2588
+ return Ok(SPyExprWithPre {
2589
+ value: (
2590
+ PyExpr::Call(
2591
+ Box::new(
2592
+ (PyExpr::Ident("slice".into(), PyAccessCtx::Load), *span).into(),
2602
2593
  ),
2603
- *span,
2604
- )
2605
- .into(),
2606
- pre: aux_stmts,
2607
- });
2594
+ vec![get(start_node), get(end_node), get(step_node)],
2595
+ ),
2596
+ *span,
2597
+ )
2598
+ .into(),
2599
+ pre: aux_stmts,
2608
2600
  });
2609
2601
  }
2610
2602
  Expr::Fstr(begin, parts) => {
2611
- return placeholder_guard(ctx, span, |ctx| {
2612
- let mut aux_stmts = PyBlock::new();
2613
- let mut nodes = Vec::new();
2603
+ let mut aux_stmts = PyBlock::new();
2604
+ let mut nodes = Vec::new();
2614
2605
 
2615
- nodes.push(PyFstrPart::Str(begin.0.clone().into()));
2606
+ nodes.push(PyFstrPart::Str(begin.0.clone().into()));
2616
2607
 
2617
- for (fmt_expr, str_part) in parts {
2618
- // TODO format specifiers?
2619
- let block_node = fmt_expr.0.block.transform(ctx)?;
2620
- aux_stmts.extend(block_node.pre);
2608
+ for (fmt_expr, str_part) in parts {
2609
+ // TODO format specifiers?
2610
+ let block_node = fmt_expr.0.block.transform(ctx)?;
2611
+ aux_stmts.extend(block_node.pre);
2621
2612
 
2622
- nodes.push(PyFstrPart::Expr(block_node.value, None));
2623
- nodes.push(PyFstrPart::Str(str_part.0.clone().into()));
2624
- }
2613
+ nodes.push(PyFstrPart::Expr(block_node.value, None));
2614
+ nodes.push(PyFstrPart::Str(str_part.0.clone().into()));
2615
+ }
2625
2616
 
2626
- let expr = (PyExpr::Fstr(nodes), *span).into();
2627
- return Ok(SPyExprWithPre {
2628
- value: expr,
2629
- pre: aux_stmts,
2630
- });
2617
+ let expr = (PyExpr::Fstr(nodes), *span).into();
2618
+ return Ok(SPyExprWithPre {
2619
+ value: expr,
2620
+ pre: aux_stmts,
2631
2621
  });
2632
2622
  }
2633
2623
  }
@@ -1,23 +0,0 @@
1
- import util.assert_eq
2
-
3
- assert_eq((x => x)($)(1), 1)
4
-
5
- assert_eq(1
6
- | $ + 1
7
- | $ * 2
8
- | $ * 5, 20)
9
-
10
- f = $ + 1
11
-
12
- assert_eq(f(2), 3)
13
-
14
- f = x => x * 2
15
- g = f($)
16
-
17
- assert_eq(g(3), 6)
18
-
19
- assert_eq(3 | f($), 6)
20
- assert_eq(f($)(3), 6)
21
-
22
- assert_eq(3 | [$, 2, 3], [3, 2, 3])
23
- assert_eq([$, 2, 3](3), [3, 2, 3])
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