koatl 0.1.16__tar.gz → 0.1.17__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 (104) hide show
  1. {koatl-0.1.16 → koatl-0.1.17}/Cargo.lock +1 -1
  2. {koatl-0.1.16 → koatl-0.1.17}/PKG-INFO +1 -1
  3. {koatl-0.1.16 → koatl-0.1.17}/koatl/Cargo.toml +1 -1
  4. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/runtime/__init__.py +1 -0
  5. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/match.tl +14 -1
  6. koatl-0.1.17/koatl/tests/parse/block-comments.tl +1 -0
  7. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/src/py/util.rs +4 -0
  8. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/src/transform.rs +107 -3
  9. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/runtime/__init__.py +1 -0
  10. {koatl-0.1.16 → koatl-0.1.17}/Cargo.toml +0 -0
  11. {koatl-0.1.16 → koatl-0.1.17}/README.md +0 -0
  12. {koatl-0.1.16 → koatl-0.1.17}/koatl/.github/workflows/CI.yml +0 -0
  13. {koatl-0.1.16 → koatl-0.1.17}/koatl/.gitignore +0 -0
  14. {koatl-0.1.16 → koatl-0.1.17}/koatl/LICENSE +0 -0
  15. {koatl-0.1.16 → koatl-0.1.17}/koatl/README.md +0 -0
  16. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/__init__.py +0 -0
  17. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/__main__.py +0 -0
  18. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/cli.py +0 -0
  19. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/notebook/__init__.py +0 -0
  20. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/notebook/magic.py +0 -0
  21. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/prelude/__init__.tl +0 -0
  22. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/prelude/functional/__init__.tl +0 -0
  23. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/prelude/functional/async.tl +0 -0
  24. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/prelude/functional/async_util.py +0 -0
  25. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/prelude/functional/monad.tl +0 -0
  26. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/prelude/functional/reader.tl +0 -0
  27. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/prelude/functional/result.tl +0 -0
  28. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/prelude/iterable.tl +0 -0
  29. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/runtime/helpers.py +0 -0
  30. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/runtime/meta_finder.py +0 -0
  31. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/runtime/record.py +0 -0
  32. {koatl-0.1.16 → koatl-0.1.17}/koatl/python/koatl/runtime/virtual.py +0 -0
  33. {koatl-0.1.16 → koatl-0.1.17}/koatl/requirements.txt +0 -0
  34. {koatl-0.1.16 → koatl-0.1.17}/koatl/src/emit_py.rs +0 -0
  35. {koatl-0.1.16 → koatl-0.1.17}/koatl/src/lib.rs +0 -0
  36. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/coal.tl +0 -0
  37. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/containers.tl +0 -0
  38. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/decorators.tl +0 -0
  39. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/destructure-for-and-fn.tl +0 -0
  40. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/destructure.tl +0 -0
  41. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/escape_ident.tl +0 -0
  42. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/fstr.tl +0 -0
  43. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/functions.tl +0 -0
  44. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/generator.tl +0 -0
  45. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/if_expr.tl +0 -0
  46. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/imports.tl +0 -0
  47. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/iterables.tl +0 -0
  48. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/loops.tl +0 -0
  49. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/nary-list.tl +0 -0
  50. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/placeholder.tl +0 -0
  51. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/precedence.tl +0 -0
  52. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/scopes.tl +0 -0
  53. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/semantic_whitespace.tl +0 -0
  54. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/slice.tl +0 -0
  55. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/base/try.tl +0 -0
  56. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/destructure.tl +0 -0
  57. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/prelude/async.tl +0 -0
  58. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/prelude/reader.tl +0 -0
  59. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/prelude/result.tl +0 -0
  60. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/prelude/virtual.tl +0 -0
  61. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/util/__init__.py +0 -0
  62. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/util/module0.tl +0 -0
  63. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/util/module1.tl +0 -0
  64. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/e2e/util/module2.tl +0 -0
  65. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/parse/arith.tl +0 -0
  66. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/parse/assign.tl +0 -0
  67. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/parse/deco.tl +0 -0
  68. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/parse/func.tl +0 -0
  69. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/parse/matches.tl +0 -0
  70. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/test_e2e.py +0 -0
  71. {koatl-0.1.16 → koatl-0.1.17}/koatl/tests/test_parse.py +0 -0
  72. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/Cargo.toml +0 -0
  73. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/parser/Cargo.toml +0 -0
  74. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/parser/src/ast.rs +0 -0
  75. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/parser/src/lexer.rs +0 -0
  76. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/parser/src/lib.rs +0 -0
  77. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/parser/src/parser.rs +0 -0
  78. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/parser/src/util.rs +0 -0
  79. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/parser/tests/lexer.rs +0 -0
  80. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/src/lib.rs +0 -0
  81. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/src/linecol.rs +0 -0
  82. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/src/main.rs +0 -0
  83. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/src/parser.rs +0 -0
  84. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/src/py/ast.rs +0 -0
  85. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/src/py/emit.rs +0 -0
  86. {koatl-0.1.16 → koatl-0.1.17}/koatl-core/src/py/mod.rs +0 -0
  87. {koatl-0.1.16 → koatl-0.1.17}/pyproject.toml +0 -0
  88. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/__init__.py +0 -0
  89. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/__main__.py +0 -0
  90. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/cli.py +0 -0
  91. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/notebook/__init__.py +0 -0
  92. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/notebook/magic.py +0 -0
  93. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/prelude/__init__.tl +0 -0
  94. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/prelude/functional/__init__.tl +0 -0
  95. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/prelude/functional/async.tl +0 -0
  96. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/prelude/functional/async_util.py +0 -0
  97. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/prelude/functional/monad.tl +0 -0
  98. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/prelude/functional/reader.tl +0 -0
  99. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/prelude/functional/result.tl +0 -0
  100. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/prelude/iterable.tl +0 -0
  101. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/runtime/helpers.py +0 -0
  102. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/runtime/meta_finder.py +0 -0
  103. {koatl-0.1.16 → koatl-0.1.17}/python/koatl/runtime/record.py +0 -0
  104. {koatl-0.1.16 → koatl-0.1.17}/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.16"
102
+ version = "0.1.17"
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.16
3
+ Version: 0.1.17
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.16"
3
+ version = "0.1.17"
4
4
  edition = "2021"
5
5
 
6
6
  [lib]
@@ -22,6 +22,7 @@ from .helpers import *
22
22
 
23
23
 
24
24
  __tl__ = SimpleNamespace(
25
+ Exception=Exception,
25
26
  slice=slice,
26
27
  vget=virtual.vget,
27
28
  vhas=virtual.vhas,
@@ -73,4 +73,17 @@ x = 1
73
73
  assert_eq([1, 2, 3] matches [1, 2, 3], True)
74
74
  assert_eq([1, 2, 3] matches [.x, _, 3], True)
75
75
 
76
- assert_eq(try 1 matches 1, True)
76
+ assert_eq(try 1 matches 1, True)
77
+
78
+ f = () =>
79
+ if [1, 2, 3] matches [1, 2, x]:
80
+ assert_eq(x, 3)
81
+ else:
82
+ assert False
83
+
84
+ if [1, 2, 3] matches not [1, 2, x]:
85
+ raise
86
+ else:
87
+ assert_eq(x, 3)
88
+
89
+ f()
@@ -0,0 +1 @@
1
+ a = #- 81937 (*A&F(*& #- asdf -##( *&U*( -# 3
@@ -233,6 +233,10 @@ impl PyAstBuilder {
233
233
  self.attribute(self.load_ident("__tl__"), name, PyAccessCtx::Load)
234
234
  }
235
235
 
236
+ pub fn py_builtin<'src>(&self, name: &'static str) -> SPyExpr<'src> {
237
+ self.attribute(self.load_ident("__builtins__"), name, PyAccessCtx::Load)
238
+ }
239
+
236
240
  pub fn subscript<'src>(
237
241
  &self,
238
242
  value: SPyExpr<'src>,
@@ -1268,6 +1268,89 @@ fn transform_if_matches_expr<'src, 'ast>(
1268
1268
  })
1269
1269
  }
1270
1270
 
1271
+ fn transform_if_matches_not_never_expr<'src, 'ast>(
1272
+ ctx: &mut TfCtx<'src>,
1273
+ subject: &'ast SExpr<'src>,
1274
+ pattern_neg: &'ast SPattern<'src>,
1275
+ pattern_meta: &'ast PatternInfo<'src>,
1276
+ then_block: &'ast SExpr<'src>,
1277
+ else_block: Option<&'ast SExpr<'src>>,
1278
+ span: &Span,
1279
+ ) -> TfResult<SPyExprWithPre<'src>> {
1280
+ let mut pre = PyBlock::new();
1281
+ let subject = pre.bind(subject.transform(ctx)?);
1282
+
1283
+ let a = PyAstBuilder::new(*span);
1284
+ let var = ctx.create_aux_var("if_matches_not", span.start);
1285
+
1286
+ let on_no_match = scoped(ctx, ScopeCtx::new(), |ctx| {
1287
+ let span = then_block.1;
1288
+
1289
+ let err = || {
1290
+ TfErrBuilder::default()
1291
+ .message(concat!(
1292
+ "then block of 'if ... matches not ...' with named captures ",
1293
+ "must have type Never (raise, return, continue, break)"
1294
+ ))
1295
+ .span(span)
1296
+ .build_errs()
1297
+ };
1298
+
1299
+ let Expr::Block(then_block) = &then_block.0 else {
1300
+ return Err(err());
1301
+ };
1302
+
1303
+ let then_block = then_block.transform(ctx)?;
1304
+
1305
+ let PyBlockExpr::Never = then_block.value else {
1306
+ return Err(err());
1307
+ };
1308
+
1309
+ Ok(then_block.pre)
1310
+ })?
1311
+ .0;
1312
+
1313
+ // these declarations are available to all code after this stmt
1314
+ for capture in &pattern_meta.captures {
1315
+ declare_var(ctx, &(capture.clone(), pattern_neg.1), DeclType::Let)?;
1316
+ }
1317
+
1318
+ let pattern_span = pattern_neg.1;
1319
+ let pattern = pre.bind(pattern_neg.transform(ctx)?);
1320
+
1321
+ let on_match = if let Some(else_block) = else_block {
1322
+ scoped(ctx, ScopeCtx::new(), |ctx| {
1323
+ let mut py_else = PyBlock::new();
1324
+ let py_else_expr = py_else.bind(else_block.transform_expecting_new_block_scope(ctx)?);
1325
+ py_else.push(a.assign(a.ident(var.clone(), PyAccessCtx::Store), py_else_expr));
1326
+ Ok(py_else)
1327
+ })?
1328
+ .0
1329
+ } else {
1330
+ PyBlock(vec![a.assign(
1331
+ a.ident(var.clone(), PyAccessCtx::Store),
1332
+ a.literal(PyLiteral::None),
1333
+ )])
1334
+ };
1335
+
1336
+ let mut cases = vec![a.match_case(pattern, None, on_match)];
1337
+
1338
+ if !pattern_meta.default {
1339
+ cases.push(a.match_case(
1340
+ (PyPattern::As(None, None), pattern_span).into(),
1341
+ None,
1342
+ on_no_match,
1343
+ ))
1344
+ }
1345
+
1346
+ pre.push(a.match_(subject, cases));
1347
+
1348
+ Ok(SPyExprWithPre {
1349
+ value: a.ident(var, PyAccessCtx::Load),
1350
+ pre,
1351
+ })
1352
+ }
1353
+
1271
1354
  fn transform_if_expr<'src, 'ast>(
1272
1355
  ctx: &mut TfCtx<'src>,
1273
1356
  cond: &'ast SExpr<'src>,
@@ -1279,6 +1362,18 @@ fn transform_if_expr<'src, 'ast>(
1279
1362
  return transform_if_matches_expr(ctx, expr, pattern, then_block, else_block, span);
1280
1363
  }
1281
1364
 
1365
+ if let Expr::Unary(UnaryOp::Not, expr) = &cond.0 {
1366
+ if let Expr::Matches(expr, pattern) = &expr.0 {
1367
+ let meta = pattern.preprocess()?;
1368
+
1369
+ if !meta.captures.is_empty() {
1370
+ return transform_if_matches_not_never_expr(
1371
+ ctx, expr, pattern, &meta, then_block, else_block, span,
1372
+ );
1373
+ }
1374
+ }
1375
+ }
1376
+
1282
1377
  let mut pre = PyBlock::new();
1283
1378
  let cond = pre.bind(cond.transform(ctx)?);
1284
1379
  let a = PyAstBuilder::new(*span);
@@ -2671,7 +2766,12 @@ impl<'src> SStmtExt<'src> for SStmt<'src> {
2671
2766
  match &stmt {
2672
2767
  Stmt::Expr(expr) => {
2673
2768
  let expr = pre.bind(expr.transform_with_placeholder_guard(ctx)?);
2674
- pre.push(a.expr(expr));
2769
+
2770
+ if let PyExpr::Ident(_, PyAccessCtx::Load) = &expr.value {
2771
+ // this is a no-op, so we can skip it
2772
+ } else {
2773
+ pre.push(a.expr(expr));
2774
+ }
2675
2775
  }
2676
2776
  Stmt::Assert(expr, msg) => {
2677
2777
  let expr = pre.bind(expr.transform_with_placeholder_guard(ctx)?);
@@ -2703,7 +2803,7 @@ impl<'src> SStmtExt<'src> for SStmt<'src> {
2703
2803
  let expr = pre.bind(expr.transform_with_placeholder_guard(ctx)?);
2704
2804
  pre.push(a.raise(Some(expr)));
2705
2805
  } else {
2706
- pre.push(a.raise(None));
2806
+ pre.push(a.raise(Some(a.call(a.tl_builtin("Exception"), vec![]))));
2707
2807
  }
2708
2808
  }
2709
2809
  Stmt::For(target, iter, body) => {
@@ -3137,7 +3237,11 @@ impl<'src> SExprExt<'src> for SExpr<'src> {
3137
3237
  let meta = pattern.preprocess()?;
3138
3238
  if meta.captures.len() > 0 {
3139
3239
  return Err(TfErrBuilder::default()
3140
- .message("Capturing non-'_' names in a 'matches' condition is only allowed in 'if ... matches ...'.")
3240
+ .message(concat!(
3241
+ "Non-'_' captures in a 'matches' are only ",
3242
+ "allowed in 'if ... matches ...', ",
3243
+ "or 'if ... matches not ...' constructions."
3244
+ ))
3141
3245
  .span(*span)
3142
3246
  .build_errs());
3143
3247
  }
@@ -22,6 +22,7 @@ from .helpers import *
22
22
 
23
23
 
24
24
  __tl__ = SimpleNamespace(
25
+ Exception=Exception,
25
26
  slice=slice,
26
27
  vget=virtual.vget,
27
28
  vhas=virtual.vhas,
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