snail-lang 0.7.5__tar.gz → 0.7.6__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 (59) hide show
  1. {snail_lang-0.7.5 → snail_lang-0.7.6}/Cargo.lock +5 -5
  2. {snail_lang-0.7.5 → snail_lang-0.7.6}/PKG-INFO +1 -1
  3. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-ast/Cargo.toml +1 -1
  4. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-error/Cargo.toml +1 -1
  5. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/Cargo.toml +1 -1
  6. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/Cargo.toml +1 -1
  7. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/desugar.rs +12 -207
  8. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/expr.rs +3 -81
  9. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/validate.rs +2 -2
  10. {snail_lang-0.7.5 → snail_lang-0.7.6}/pyproject.toml +1 -1
  11. {snail_lang-0.7.5 → snail_lang-0.7.6}/Cargo.toml +0 -0
  12. {snail_lang-0.7.5 → snail_lang-0.7.6}/LICENSE +0 -0
  13. {snail_lang-0.7.5 → snail_lang-0.7.6}/README.md +0 -0
  14. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-ast/README.md +0 -0
  15. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-ast/src/ast.rs +0 -0
  16. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-ast/src/awk.rs +0 -0
  17. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-ast/src/lib.rs +0 -0
  18. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-error/README.md +0 -0
  19. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-error/src/lib.rs +0 -0
  20. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/README.md +0 -0
  21. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/src/awk.rs +0 -0
  22. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/src/expr.rs +0 -0
  23. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/src/lib.rs +0 -0
  24. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/src/literal.rs +0 -0
  25. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/src/snail.pest +0 -0
  26. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/src/stmt.rs +0 -0
  27. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/src/string.rs +0 -0
  28. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/src/util.rs +0 -0
  29. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/tests/common.rs +0 -0
  30. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/tests/errors.rs +0 -0
  31. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/tests/parser.rs +0 -0
  32. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/tests/statements.rs +0 -0
  33. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/tests/syntax_expressions.rs +0 -0
  34. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-parser/tests/syntax_strings.rs +0 -0
  35. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/build.rs +0 -0
  36. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/compiler.rs +0 -0
  37. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lib.rs +0 -0
  38. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/linecache.rs +0 -0
  39. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/awk.rs +0 -0
  40. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/constants.rs +0 -0
  41. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/helpers.rs +0 -0
  42. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/map.rs +0 -0
  43. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/mod.rs +0 -0
  44. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/operators.rs +0 -0
  45. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/program.rs +0 -0
  46. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/py_ast.rs +0 -0
  47. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/lower/stmt.rs +0 -0
  48. {snail_lang-0.7.5 → snail_lang-0.7.6}/crates/snail-python/src/profiling.rs +0 -0
  49. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/__init__.py +0 -0
  50. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/cli.py +0 -0
  51. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/runtime/__init__.py +0 -0
  52. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/runtime/augmented.py +0 -0
  53. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/runtime/compact_try.py +0 -0
  54. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/runtime/env.py +0 -0
  55. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/runtime/lazy_file.py +0 -0
  56. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/runtime/lazy_text.py +0 -0
  57. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/runtime/regex.py +0 -0
  58. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/runtime/structured_accessor.py +0 -0
  59. {snail_lang-0.7.5 → snail_lang-0.7.6}/python/snail/runtime/subprocess.py +0 -0
@@ -312,25 +312,25 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
312
312
 
313
313
  [[package]]
314
314
  name = "snail-ast"
315
- version = "0.7.5"
315
+ version = "0.7.6"
316
316
 
317
317
  [[package]]
318
318
  name = "snail-error"
319
- version = "0.7.5"
319
+ version = "0.7.6"
320
320
  dependencies = [
321
321
  "snail-ast",
322
322
  ]
323
323
 
324
324
  [[package]]
325
325
  name = "snail-lower"
326
- version = "0.7.5"
326
+ version = "0.7.6"
327
327
  dependencies = [
328
328
  "snail-python",
329
329
  ]
330
330
 
331
331
  [[package]]
332
332
  name = "snail-parser"
333
- version = "0.7.5"
333
+ version = "0.7.6"
334
334
  dependencies = [
335
335
  "pest",
336
336
  "pest_derive",
@@ -340,7 +340,7 @@ dependencies = [
340
340
 
341
341
  [[package]]
342
342
  name = "snail-python"
343
- version = "0.7.5"
343
+ version = "0.7.6"
344
344
  dependencies = [
345
345
  "pyo3",
346
346
  "snail-ast",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: snail-lang
3
- Version: 0.7.5
3
+ Version: 0.7.6
4
4
  Requires-Dist: astunparse>=1.6.3 ; python_full_version < '3.9'
5
5
  Requires-Dist: jmespath>=1.0.1
6
6
  Requires-Dist: maturin>=1.5 ; extra == 'dev'
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "snail-ast"
3
- version = "0.7.5"
3
+ version = "0.7.6"
4
4
  edition = "2024"
5
5
  readme = "README.md"
6
6
 
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "snail-error"
3
- version = "0.7.5"
3
+ version = "0.7.6"
4
4
  edition = "2024"
5
5
  readme = "README.md"
6
6
 
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "snail-parser"
3
- version = "0.7.5"
3
+ version = "0.7.6"
4
4
  edition = "2024"
5
5
  readme = "README.md"
6
6
 
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "snail-python"
3
- version = "0.7.5"
3
+ version = "0.7.6"
4
4
  edition.workspace = true
5
5
  build = "build.rs"
6
6
 
@@ -553,26 +553,18 @@ impl LambdaHoister {
553
553
  span: span.clone(),
554
554
  },
555
555
  Expr::Lambda { params, body, span } => {
556
- if lambda_requires_def(params, body) {
557
- let params = self.desugar_params(params, prelude);
558
- let body = ensure_lambda_return(self.desugar_block(body));
559
- let name = self.next_lambda_name();
560
- prelude.push(Stmt::Def {
561
- name: name.clone(),
562
- params,
563
- body,
564
- span: span.clone(),
565
- });
566
- Expr::Name {
567
- name,
568
- span: span.clone(),
569
- }
570
- } else {
571
- Expr::Lambda {
572
- params: params.clone(),
573
- body: body.clone(),
574
- span: span.clone(),
575
- }
556
+ let params = self.desugar_params(params, prelude);
557
+ let body = self.desugar_block(body);
558
+ let name = self.next_lambda_name();
559
+ prelude.push(Stmt::Def {
560
+ name: name.clone(),
561
+ params,
562
+ body,
563
+ span: span.clone(),
564
+ });
565
+ Expr::Name {
566
+ name,
567
+ span: span.clone(),
576
568
  }
577
569
  }
578
570
  Expr::Compound { expressions, span } => Expr::Compound {
@@ -717,190 +709,3 @@ impl LambdaHoister {
717
709
  }
718
710
  }
719
711
  }
720
-
721
- fn lambda_requires_def(params: &[Parameter], body: &[Stmt]) -> bool {
722
- if body.iter().any(|stmt| !matches!(stmt, Stmt::Expr { .. })) {
723
- return true;
724
- }
725
-
726
- for param in params {
727
- if let Parameter::Regular { default, .. } = param
728
- && let Some(default) = default
729
- && expr_contains_complex_lambda(default)
730
- {
731
- return true;
732
- }
733
- }
734
-
735
- for stmt in body {
736
- if let Stmt::Expr { value, .. } = stmt
737
- && expr_contains_complex_lambda(value)
738
- {
739
- return true;
740
- }
741
- }
742
-
743
- false
744
- }
745
-
746
- fn expr_contains_complex_lambda(expr: &Expr) -> bool {
747
- match expr {
748
- Expr::Yield { value, .. } => value
749
- .as_ref()
750
- .is_some_and(|expr| expr_contains_complex_lambda(expr)),
751
- Expr::YieldFrom { expr, .. } => expr_contains_complex_lambda(expr),
752
- Expr::Lambda { params, body, .. } => lambda_requires_def(params, body),
753
- Expr::Unary { expr, .. } => expr_contains_complex_lambda(expr),
754
- Expr::Binary { left, right, .. } => {
755
- expr_contains_complex_lambda(left) || expr_contains_complex_lambda(right)
756
- }
757
- Expr::AugAssign { target, value, .. } => {
758
- assign_target_contains_complex_lambda(target) || expr_contains_complex_lambda(value)
759
- }
760
- Expr::PrefixIncr { target, .. } | Expr::PostfixIncr { target, .. } => {
761
- assign_target_contains_complex_lambda(target)
762
- }
763
- Expr::Compare {
764
- left, comparators, ..
765
- } => {
766
- if expr_contains_complex_lambda(left) {
767
- return true;
768
- }
769
- comparators.iter().any(expr_contains_complex_lambda)
770
- }
771
- Expr::IfExpr {
772
- test, body, orelse, ..
773
- } => {
774
- expr_contains_complex_lambda(test)
775
- || expr_contains_complex_lambda(body)
776
- || expr_contains_complex_lambda(orelse)
777
- }
778
- Expr::TryExpr { expr, fallback, .. } => {
779
- expr_contains_complex_lambda(expr)
780
- || fallback
781
- .as_ref()
782
- .is_some_and(|expr| expr_contains_complex_lambda(expr))
783
- }
784
- Expr::Compound { expressions, .. } => expressions.iter().any(expr_contains_complex_lambda),
785
- Expr::Regex { pattern, .. } => regex_pattern_contains_complex_lambda(pattern),
786
- Expr::RegexMatch { value, pattern, .. } => {
787
- expr_contains_complex_lambda(value) || regex_pattern_contains_complex_lambda(pattern)
788
- }
789
- Expr::Subprocess { parts, .. } => parts.iter().any(|part| match part {
790
- SubprocessPart::Expr(expr) => expr_contains_complex_lambda(expr),
791
- SubprocessPart::Text(_) => false,
792
- }),
793
- Expr::Call { func, args, .. } => {
794
- if expr_contains_complex_lambda(func) {
795
- return true;
796
- }
797
- args.iter().any(|arg| match arg {
798
- Argument::Positional { value, .. }
799
- | Argument::Keyword { value, .. }
800
- | Argument::Star { value, .. }
801
- | Argument::KwStar { value, .. } => expr_contains_complex_lambda(value),
802
- })
803
- }
804
- Expr::Attribute { value, .. } => expr_contains_complex_lambda(value),
805
- Expr::Index { value, index, .. } => {
806
- expr_contains_complex_lambda(value) || expr_contains_complex_lambda(index)
807
- }
808
- Expr::Paren { expr, .. } => expr_contains_complex_lambda(expr),
809
- Expr::List { elements, .. } | Expr::Tuple { elements, .. } => {
810
- elements.iter().any(expr_contains_complex_lambda)
811
- }
812
- Expr::Set { elements, .. } => elements.iter().any(expr_contains_complex_lambda),
813
- Expr::Dict { entries, .. } => entries.iter().any(|(key, value)| {
814
- expr_contains_complex_lambda(key) || expr_contains_complex_lambda(value)
815
- }),
816
- Expr::Slice { start, end, .. } => {
817
- start
818
- .as_ref()
819
- .is_some_and(|expr| expr_contains_complex_lambda(expr))
820
- || end
821
- .as_ref()
822
- .is_some_and(|expr| expr_contains_complex_lambda(expr))
823
- }
824
- Expr::ListComp {
825
- element, iter, ifs, ..
826
- } => {
827
- expr_contains_complex_lambda(element)
828
- || expr_contains_complex_lambda(iter)
829
- || ifs.iter().any(expr_contains_complex_lambda)
830
- }
831
- Expr::DictComp {
832
- key,
833
- value,
834
- iter,
835
- ifs,
836
- ..
837
- } => {
838
- expr_contains_complex_lambda(key)
839
- || expr_contains_complex_lambda(value)
840
- || expr_contains_complex_lambda(iter)
841
- || ifs.iter().any(expr_contains_complex_lambda)
842
- }
843
- Expr::FString { parts, .. } => parts.iter().any(fstring_part_contains_complex_lambda),
844
- Expr::Name { .. }
845
- | Expr::Placeholder { .. }
846
- | Expr::Number { .. }
847
- | Expr::String { .. }
848
- | Expr::Bool { .. }
849
- | Expr::None { .. }
850
- | Expr::StructuredAccessor { .. }
851
- | Expr::FieldIndex { .. } => false,
852
- }
853
- }
854
-
855
- fn assign_target_contains_complex_lambda(target: &AssignTarget) -> bool {
856
- match target {
857
- AssignTarget::Name { .. } => false,
858
- AssignTarget::Attribute { value, .. } => expr_contains_complex_lambda(value),
859
- AssignTarget::Index { value, index, .. } => {
860
- expr_contains_complex_lambda(value) || expr_contains_complex_lambda(index)
861
- }
862
- AssignTarget::Starred { target, .. } => assign_target_contains_complex_lambda(target),
863
- AssignTarget::Tuple { elements, .. } | AssignTarget::List { elements, .. } => {
864
- elements.iter().any(assign_target_contains_complex_lambda)
865
- }
866
- }
867
- }
868
-
869
- fn regex_pattern_contains_complex_lambda(pattern: &RegexPattern) -> bool {
870
- match pattern {
871
- RegexPattern::Literal(_) => false,
872
- RegexPattern::Interpolated(parts) => parts.iter().any(fstring_part_contains_complex_lambda),
873
- }
874
- }
875
-
876
- fn fstring_part_contains_complex_lambda(part: &FStringPart) -> bool {
877
- match part {
878
- FStringPart::Text(_) => false,
879
- FStringPart::Expr(expr) => fstring_expr_contains_complex_lambda(expr),
880
- }
881
- }
882
-
883
- fn fstring_expr_contains_complex_lambda(expr: &FStringExpr) -> bool {
884
- if expr_contains_complex_lambda(expr.expr.as_ref()) {
885
- return true;
886
- }
887
- expr.format_spec
888
- .as_ref()
889
- .is_some_and(|parts| parts.iter().any(fstring_part_contains_complex_lambda))
890
- }
891
-
892
- fn ensure_lambda_return(mut body: Vec<Stmt>) -> Vec<Stmt> {
893
- let Some(last) = body.pop() else {
894
- return body;
895
- };
896
- match last {
897
- Stmt::Expr { value, span, .. } => {
898
- body.push(Stmt::Return {
899
- value: Some(value),
900
- span,
901
- });
902
- }
903
- other => body.push(other),
904
- }
905
- body
906
- }
@@ -10,7 +10,6 @@ use super::operators::{
10
10
  lower_unary_op,
11
11
  };
12
12
  use super::py_ast::{AstBuilder, py_err_to_lower};
13
- use super::stmt::lower_parameters;
14
13
 
15
14
  pub(crate) fn lower_expr(builder: &AstBuilder<'_>, expr: &Expr) -> Result<PyObject, LowerError> {
16
15
  lower_expr_with_exception(builder, expr, None)
@@ -782,9 +781,9 @@ pub(crate) fn lower_expr_with_exception(
782
781
  .call_node("YieldFrom", vec![value], span)
783
782
  .map_err(py_err_to_lower)
784
783
  }
785
- Expr::Lambda { params, body, span } => {
786
- lower_lambda_expr(builder, params, body, span, exception_name)
787
- }
784
+ Expr::Lambda { .. } => Err(LowerError::new(
785
+ "def expressions should be desugared before lowering",
786
+ )),
788
787
  Expr::Compound { expressions, span } => {
789
788
  let mut lowered = Vec::new();
790
789
  for expr in expressions {
@@ -1431,83 +1430,6 @@ fn lower_subprocess_parts(
1431
1430
  Ok(lowered_parts)
1432
1431
  }
1433
1432
 
1434
- fn lower_lambda_expr(
1435
- builder: &AstBuilder<'_>,
1436
- params: &[Parameter],
1437
- body: &[Stmt],
1438
- span: &SourceSpan,
1439
- exception_name: Option<&str>,
1440
- ) -> Result<PyObject, LowerError> {
1441
- let args = lower_parameters(builder, params, exception_name)?;
1442
- let body_expr = lower_lambda_body_expr(builder, body, span, exception_name)?;
1443
- builder
1444
- .call_node("Lambda", vec![args, body_expr], span)
1445
- .map_err(py_err_to_lower)
1446
- }
1447
-
1448
- fn lower_lambda_body_expr(
1449
- builder: &AstBuilder<'_>,
1450
- body: &[Stmt],
1451
- span: &SourceSpan,
1452
- exception_name: Option<&str>,
1453
- ) -> Result<PyObject, LowerError> {
1454
- let mut lowered = Vec::new();
1455
- for stmt in body {
1456
- match stmt {
1457
- Stmt::Expr { value, .. } => {
1458
- lowered.push(lower_expr_with_exception(builder, value, exception_name)?);
1459
- }
1460
- _ => {
1461
- return Err(LowerError::new(
1462
- "def expression bodies must contain only expression statements",
1463
- ));
1464
- }
1465
- }
1466
- }
1467
-
1468
- if lowered.is_empty() {
1469
- return builder
1470
- .call_node(
1471
- "Constant",
1472
- vec![builder.py().None().into_py(builder.py())],
1473
- span,
1474
- )
1475
- .map_err(py_err_to_lower);
1476
- }
1477
-
1478
- if lowered.len() == 1 {
1479
- return Ok(lowered.pop().unwrap());
1480
- }
1481
-
1482
- let tuple_expr = builder
1483
- .call_node(
1484
- "Tuple",
1485
- vec![
1486
- PyList::new_bound(builder.py(), lowered).into_py(builder.py()),
1487
- builder.load_ctx().map_err(py_err_to_lower)?,
1488
- ],
1489
- span,
1490
- )
1491
- .map_err(py_err_to_lower)?;
1492
- let index_expr = builder
1493
- .call_node(
1494
- "UnaryOp",
1495
- vec![
1496
- lower_unary_op(builder, UnaryOp::Minus)?,
1497
- number_expr(builder, "1", span)?,
1498
- ],
1499
- span,
1500
- )
1501
- .map_err(py_err_to_lower)?;
1502
- subscript_expr(
1503
- builder,
1504
- tuple_expr,
1505
- index_expr,
1506
- builder.load_ctx().map_err(py_err_to_lower)?,
1507
- span,
1508
- )
1509
- }
1510
-
1511
1433
  fn lower_call_arguments(
1512
1434
  builder: &AstBuilder<'_>,
1513
1435
  args: &[Argument],
@@ -269,8 +269,8 @@ fn check_expr(expr: &Expr, in_function: bool) -> Result<(), LowerError> {
269
269
  for param in params {
270
270
  check_param(param)?;
271
271
  }
272
- // Lambdas lower to Python lambdas; disallow yield in their bodies.
273
- check_stmts(body, false)?;
272
+ // Anonymous defs are hoisted to defs; allow yield in their bodies.
273
+ check_stmts(body, true)?;
274
274
  }
275
275
  Expr::Compound { expressions, .. } => {
276
276
  for expr in expressions {
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "snail-lang"
7
- version = "0.7.5"
7
+ version = "0.7.6"
8
8
  description = "Snail programming language interpreter"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
File without changes
File without changes
File without changes