@tishlang/tish 1.6.0 → 1.8.0

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 (113) hide show
  1. package/Cargo.toml +2 -0
  2. package/README.md +2 -0
  3. package/bin/tish +0 -0
  4. package/crates/js_to_tish/src/error.rs +2 -8
  5. package/crates/js_to_tish/src/transform/expr.rs +128 -137
  6. package/crates/js_to_tish/src/transform/stmt.rs +62 -32
  7. package/crates/tish/Cargo.toml +15 -5
  8. package/crates/tish/src/cargo_native_registry.rs +29 -0
  9. package/crates/tish/src/cli_help.rs +92 -39
  10. package/crates/tish/src/main.rs +172 -86
  11. package/crates/tish/src/repl_completion.rs +3 -3
  12. package/crates/tish/tests/cargo_example_compile.rs +4 -2
  13. package/crates/tish/tests/integration_test.rs +216 -54
  14. package/crates/tish/tests/run_optimize_stdout_parity.rs +3 -7
  15. package/crates/tish/tests/shortcircuit.rs +20 -5
  16. package/crates/tish_ast/src/ast.rs +92 -23
  17. package/crates/tish_build_utils/Cargo.toml +4 -0
  18. package/crates/tish_build_utils/src/lib.rs +136 -8
  19. package/crates/tish_builtins/Cargo.toml +5 -1
  20. package/crates/tish_builtins/src/array.rs +65 -33
  21. package/crates/tish_builtins/src/construct.rs +34 -39
  22. package/crates/tish_builtins/src/globals.rs +42 -26
  23. package/crates/tish_builtins/src/helpers.rs +2 -1
  24. package/crates/tish_builtins/src/lib.rs +5 -5
  25. package/crates/tish_builtins/src/math.rs +5 -3
  26. package/crates/tish_builtins/src/object.rs +3 -2
  27. package/crates/tish_builtins/src/string.rs +144 -22
  28. package/crates/tish_bytecode/src/chunk.rs +0 -1
  29. package/crates/tish_bytecode/src/compiler.rs +173 -71
  30. package/crates/tish_bytecode/src/opcode.rs +24 -6
  31. package/crates/tish_bytecode/src/peephole.rs +2 -2
  32. package/crates/tish_compile/Cargo.toml +1 -0
  33. package/crates/tish_compile/src/codegen.rs +1621 -453
  34. package/crates/tish_compile/src/infer.rs +75 -19
  35. package/crates/tish_compile/src/lib.rs +19 -8
  36. package/crates/tish_compile/src/resolve.rs +278 -137
  37. package/crates/tish_compile/src/types.rs +184 -24
  38. package/crates/tish_compile_js/Cargo.toml +1 -0
  39. package/crates/tish_compile_js/src/codegen.rs +181 -37
  40. package/crates/tish_compile_js/src/lib.rs +3 -1
  41. package/crates/tish_compile_js/src/tests_jsx.rs +30 -6
  42. package/crates/tish_compiler_wasm/src/lib.rs +16 -13
  43. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +69 -59
  44. package/crates/tish_core/Cargo.toml +8 -0
  45. package/crates/tish_core/src/json.rs +107 -56
  46. package/crates/tish_core/src/lib.rs +4 -2
  47. package/crates/tish_core/src/macros.rs +5 -5
  48. package/crates/tish_core/src/uri.rs +9 -6
  49. package/crates/tish_core/src/value.rs +145 -43
  50. package/crates/tish_core/src/vmref.rs +178 -0
  51. package/crates/tish_cranelift/src/link.rs +6 -9
  52. package/crates/tish_cranelift/src/lower.rs +14 -8
  53. package/crates/tish_eval/Cargo.toml +17 -2
  54. package/crates/tish_eval/src/eval.rs +474 -165
  55. package/crates/tish_eval/src/http.rs +61 -0
  56. package/crates/tish_eval/src/lib.rs +12 -8
  57. package/crates/tish_eval/src/natives.rs +136 -38
  58. package/crates/tish_eval/src/promise.rs +14 -8
  59. package/crates/tish_eval/src/timers.rs +28 -19
  60. package/crates/tish_eval/src/value.rs +17 -6
  61. package/crates/tish_eval/src/value_convert.rs +13 -5
  62. package/crates/tish_fmt/src/lib.rs +149 -43
  63. package/crates/tish_lexer/src/lib.rs +232 -63
  64. package/crates/tish_lexer/src/token.rs +10 -6
  65. package/crates/tish_llvm/src/lib.rs +17 -8
  66. package/crates/tish_lsp/Cargo.toml +4 -1
  67. package/crates/tish_lsp/README.md +1 -1
  68. package/crates/tish_lsp/src/builtin_goto.rs +261 -0
  69. package/crates/tish_lsp/src/import_goto.rs +549 -0
  70. package/crates/tish_lsp/src/main.rs +504 -106
  71. package/crates/tish_native/src/build.rs +4 -8
  72. package/crates/tish_native/src/lib.rs +54 -21
  73. package/crates/tish_opt/src/lib.rs +84 -52
  74. package/crates/tish_parser/src/lib.rs +45 -13
  75. package/crates/tish_parser/src/parser.rs +505 -130
  76. package/crates/tish_resolve/Cargo.toml +13 -0
  77. package/crates/tish_resolve/src/lib.rs +3436 -0
  78. package/crates/tish_resolve/src/pos.rs +133 -0
  79. package/crates/tish_runtime/Cargo.toml +68 -3
  80. package/crates/tish_runtime/src/http.rs +1136 -145
  81. package/crates/tish_runtime/src/http_fetch.rs +38 -27
  82. package/crates/tish_runtime/src/http_hyper.rs +418 -0
  83. package/crates/tish_runtime/src/http_prefork.rs +189 -0
  84. package/crates/tish_runtime/src/lib.rs +375 -189
  85. package/crates/tish_runtime/src/promise.rs +199 -40
  86. package/crates/tish_runtime/src/promise_io.rs +2 -1
  87. package/crates/tish_runtime/src/timers.rs +37 -1
  88. package/crates/tish_runtime/src/ws.rs +65 -42
  89. package/crates/tish_runtime/tests/fetch_readable_stream.rs +5 -4
  90. package/crates/tish_ui/src/jsx.rs +317 -27
  91. package/crates/tish_ui/src/lib.rs +5 -2
  92. package/crates/tish_ui/src/runtime/hooks.rs +406 -45
  93. package/crates/tish_ui/src/runtime/mod.rs +36 -9
  94. package/crates/tish_vm/Cargo.toml +15 -5
  95. package/crates/tish_vm/src/vm.rs +725 -281
  96. package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +11 -4
  97. package/crates/tish_wasm/src/lib.rs +55 -42
  98. package/crates/tish_wasm_runtime/Cargo.toml +2 -1
  99. package/crates/tish_wasm_runtime/src/lib.rs +1 -1
  100. package/crates/tishlang_cargo_bindgen/Cargo.toml +26 -0
  101. package/crates/tishlang_cargo_bindgen/src/classify.rs +265 -0
  102. package/crates/tishlang_cargo_bindgen/src/discover.rs +120 -0
  103. package/crates/tishlang_cargo_bindgen/src/infer.rs +372 -0
  104. package/crates/tishlang_cargo_bindgen/src/lib.rs +350 -0
  105. package/crates/tishlang_cargo_bindgen/src/main.rs +164 -0
  106. package/crates/tishlang_cargo_bindgen/src/metadata.rs +114 -0
  107. package/justfile +8 -0
  108. package/package.json +1 -1
  109. package/platform/darwin-arm64/tish +0 -0
  110. package/platform/darwin-x64/tish +0 -0
  111. package/platform/linux-arm64/tish +0 -0
  112. package/platform/linux-x64/tish +0 -0
  113. package/platform/win32-x64/tish.exe +0 -0
@@ -2,9 +2,9 @@
2
2
 
3
3
  use tishlang_ast::{
4
4
  ArrayElement, ArrowBody, BinOp, CallArg, CompoundOp, DestructElement, DestructPattern,
5
- ExportDeclaration, Expr, FunParam, ImportSpecifier, JsxAttrValue, JsxChild, JsxProp,
6
- Literal, LogicalAssignOp, MemberProp, ObjectProp, Program, Statement, TypeAnnotation,
7
- TypedParam, UnaryOp,
5
+ ExportDeclaration, Expr, FunParam, ImportSpecifier, JsxAttrValue, JsxChild, JsxProp, Literal,
6
+ LogicalAssignOp, MemberProp, ObjectProp, Program, Statement, TypeAnnotation, TypedParam,
7
+ UnaryOp,
8
8
  };
9
9
 
10
10
  /// Format Tish source. On parse error, returns the parser message.
@@ -79,7 +79,10 @@ impl Printer {
79
79
  }
80
80
  }
81
81
  Statement::VarDeclDestructure {
82
- pattern, mutable, init, ..
82
+ pattern,
83
+ mutable,
84
+ init,
85
+ ..
83
86
  } => {
84
87
  self.indent(level);
85
88
  self.buf.push_str(if *mutable { "let " } else { "const " });
@@ -267,20 +270,74 @@ impl Printer {
267
270
  self.stmt_inline_or_block(fb, level);
268
271
  }
269
272
  }
270
- Statement::Import { specifiers, from, .. } => {
273
+ Statement::Import {
274
+ specifiers, from, ..
275
+ } => {
271
276
  self.indent(level);
272
277
  self.buf.push_str("import ");
273
278
  self.import_specs(specifiers);
274
279
  self.buf.push_str(" from ");
275
280
  self.string_lit(from.as_ref());
276
281
  }
282
+ Statement::TypeAlias { name, ty, .. } => {
283
+ self.indent(level);
284
+ self.buf.push_str("type ");
285
+ self.buf.push_str(name);
286
+ self.buf.push_str(" = ");
287
+ self.type_ann(ty);
288
+ }
289
+ Statement::DeclareVar {
290
+ name,
291
+ type_ann,
292
+ const_,
293
+ ..
294
+ } => {
295
+ self.indent(level);
296
+ self.buf.push_str("declare ");
297
+ self.buf.push_str(if *const_ { "const " } else { "let " });
298
+ self.buf.push_str(name);
299
+ if let Some(t) = type_ann {
300
+ self.buf.push_str(": ");
301
+ self.type_ann(t);
302
+ }
303
+ }
304
+ Statement::DeclareFun {
305
+ async_,
306
+ name,
307
+ params,
308
+ rest_param,
309
+ return_type,
310
+ ..
311
+ } => {
312
+ self.indent(level);
313
+ self.buf.push_str("declare ");
314
+ if *async_ {
315
+ self.buf.push_str("async ");
316
+ }
317
+ self.buf.push_str("fn ");
318
+ self.buf.push_str(name);
319
+ self.buf.push('(');
320
+ self.param_list(params, rest_param);
321
+ self.buf.push(')');
322
+ if let Some(rt) = return_type {
323
+ self.buf.push_str(": ");
324
+ self.type_ann(rt);
325
+ }
326
+ }
277
327
  Statement::Export { declaration, .. } => {
278
328
  self.indent(level);
279
329
  self.buf.push_str("export ");
280
330
  match declaration.as_ref() {
281
331
  ExportDeclaration::Named(inner) => {
282
- if let Statement::FunDecl { async_, name, params, rest_param, return_type, body, .. } =
283
- inner.as_ref()
332
+ if let Statement::FunDecl {
333
+ async_,
334
+ name,
335
+ params,
336
+ rest_param,
337
+ return_type,
338
+ body,
339
+ ..
340
+ } = inner.as_ref()
284
341
  {
285
342
  if *async_ {
286
343
  self.buf.push_str("async ");
@@ -349,12 +406,12 @@ impl Printer {
349
406
  fn import_specs(&mut self, specs: &[ImportSpecifier]) {
350
407
  if specs.len() == 1 {
351
408
  match &specs[0] {
352
- ImportSpecifier::Default(n) => self.buf.push_str(n.as_ref()),
353
- ImportSpecifier::Namespace(n) => {
409
+ ImportSpecifier::Default { name, .. } => self.buf.push_str(name.as_ref()),
410
+ ImportSpecifier::Namespace { name, .. } => {
354
411
  self.buf.push_str("* as ");
355
- self.buf.push_str(n.as_ref());
412
+ self.buf.push_str(name.as_ref());
356
413
  }
357
- ImportSpecifier::Named { name, alias } => {
414
+ ImportSpecifier::Named { name, alias, .. } => {
358
415
  self.buf.push_str("{ ");
359
416
  self.buf.push_str(name.as_ref());
360
417
  if let Some(a) = alias {
@@ -372,7 +429,7 @@ impl Printer {
372
429
  self.buf.push_str(", ");
373
430
  }
374
431
  match sp {
375
- ImportSpecifier::Named { name, alias } => {
432
+ ImportSpecifier::Named { name, alias, .. } => {
376
433
  self.buf.push_str(name.as_ref());
377
434
  if let Some(a) = alias {
378
435
  self.buf.push_str(" as ");
@@ -441,9 +498,9 @@ impl Printer {
441
498
  self.buf.push_str(", ");
442
499
  }
443
500
  match e {
444
- Some(DestructElement::Ident(n)) => self.buf.push_str(n.as_ref()),
501
+ Some(DestructElement::Ident(n, _)) => self.buf.push_str(n.as_ref()),
445
502
  Some(DestructElement::Pattern(inner)) => self.destruct_pat(inner),
446
- Some(DestructElement::Rest(n)) => {
503
+ Some(DestructElement::Rest(n, _)) => {
447
504
  self.buf.push_str("...");
448
505
  self.buf.push_str(n.as_ref());
449
506
  }
@@ -460,16 +517,16 @@ impl Printer {
460
517
  }
461
518
  self.buf.push_str(pr.key.as_ref());
462
519
  match &pr.value {
463
- DestructElement::Ident(n) if n.as_ref() != pr.key.as_ref() => {
520
+ DestructElement::Ident(n, _) if n.as_ref() != pr.key.as_ref() => {
464
521
  self.buf.push_str(": ");
465
522
  self.buf.push_str(n.as_ref());
466
523
  }
467
- DestructElement::Ident(_) => {}
524
+ DestructElement::Ident(_, _) => {}
468
525
  DestructElement::Pattern(inner) => {
469
526
  self.buf.push_str(": ");
470
527
  self.destruct_pat(inner);
471
528
  }
472
- DestructElement::Rest(n) => {
529
+ DestructElement::Rest(n, _) => {
473
530
  self.buf.push_str(": ...");
474
531
  self.buf.push_str(n.as_ref());
475
532
  }
@@ -536,7 +593,9 @@ impl Printer {
536
593
  Literal::Null => self.buf.push_str("null"),
537
594
  },
538
595
  Expr::Ident { name, .. } => self.buf.push_str(name.as_ref()),
539
- Expr::Binary { left, op, right, .. } => {
596
+ Expr::Binary {
597
+ left, op, right, ..
598
+ } => {
540
599
  self.expr(left);
541
600
  self.buf.push(' ');
542
601
  self.buf.push_str(binop(*op));
@@ -603,7 +662,7 @@ impl Printer {
603
662
  self.buf.push('.');
604
663
  }
605
664
  match prop {
606
- MemberProp::Name(n) => self.buf.push_str(n.as_ref()),
665
+ MemberProp::Name { name, .. } => self.buf.push_str(name.as_ref()),
607
666
  MemberProp::Expr(ex) => {
608
667
  self.buf.push('[');
609
668
  self.expr(ex);
@@ -704,12 +763,16 @@ impl Printer {
704
763
  self.buf.push_str("--");
705
764
  self.buf.push_str(name.as_ref());
706
765
  }
707
- Expr::CompoundAssign { name, op, value, .. } => {
766
+ Expr::CompoundAssign {
767
+ name, op, value, ..
768
+ } => {
708
769
  self.buf.push_str(name.as_ref());
709
770
  self.buf.push_str(compound(*op));
710
771
  self.expr(value);
711
772
  }
712
- Expr::LogicalAssign { name, op, value, .. } => {
773
+ Expr::LogicalAssign {
774
+ name, op, value, ..
775
+ } => {
713
776
  self.buf.push_str(name.as_ref());
714
777
  self.buf.push_str(logical_assign(*op));
715
778
  self.expr(value);
@@ -799,40 +862,75 @@ impl Printer {
799
862
  if children.is_empty() {
800
863
  self.buf.push_str(" />");
801
864
  } else {
802
- self.buf.push('>');
803
- for ch in children {
804
- match ch {
805
- JsxChild::Text(t) => self.buf.push_str(t.as_ref()),
806
- JsxChild::Expr(e) => {
807
- self.buf.push('{');
808
- self.expr(e);
809
- self.buf.push('}');
865
+ let compact = children.len() == 1
866
+ && matches!(
867
+ &children[0],
868
+ JsxChild::Text(t) if !t.as_ref().contains('\n')
869
+ );
870
+ if compact {
871
+ self.buf.push('>');
872
+ if let JsxChild::Text(t) = &children[0] {
873
+ self.buf.push_str(t.as_ref());
874
+ }
875
+ self.buf.push_str("</");
876
+ self.buf.push_str(tag.as_ref());
877
+ self.buf.push('>');
878
+ } else {
879
+ self.buf.push('>');
880
+ self.buf.push('\n');
881
+ for ch in children {
882
+ self.buf.push_str(" ");
883
+ match ch {
884
+ JsxChild::Text(t) => self.buf.push_str(t.as_ref()),
885
+ JsxChild::Expr(e) => {
886
+ self.buf.push('{');
887
+ self.expr(e);
888
+ self.buf.push('}');
889
+ }
810
890
  }
891
+ self.buf.push('\n');
811
892
  }
893
+ self.buf.push_str(" </");
894
+ self.buf.push_str(tag.as_ref());
895
+ self.buf.push('>');
812
896
  }
813
- self.buf.push_str("</");
814
- self.buf.push_str(tag.as_ref());
815
- self.buf.push('>');
816
897
  }
817
898
  }
818
899
  Expr::JsxFragment { children, .. } => {
819
900
  self.buf.push_str("<>");
820
- for ch in children {
821
- match ch {
822
- JsxChild::Text(t) => self.buf.push_str(t.as_ref()),
823
- JsxChild::Expr(e) => {
824
- self.buf.push('{');
825
- self.expr(e);
826
- self.buf.push('}');
901
+ if children.is_empty() {
902
+ self.buf.push_str("</>");
903
+ } else {
904
+ let compact = children.len() == 1
905
+ && matches!(
906
+ &children[0],
907
+ JsxChild::Text(t) if !t.as_ref().contains('\n')
908
+ );
909
+ if compact {
910
+ if let JsxChild::Text(t) = &children[0] {
911
+ self.buf.push_str(t.as_ref());
912
+ }
913
+ self.buf.push_str("</>");
914
+ } else {
915
+ self.buf.push('\n');
916
+ for ch in children {
917
+ self.buf.push_str(" ");
918
+ match ch {
919
+ JsxChild::Text(t) => self.buf.push_str(t.as_ref()),
920
+ JsxChild::Expr(e) => {
921
+ self.buf.push('{');
922
+ self.expr(e);
923
+ self.buf.push('}');
924
+ }
925
+ }
926
+ self.buf.push('\n');
827
927
  }
928
+ self.buf.push_str("</>");
828
929
  }
829
930
  }
830
- self.buf.push_str("</>");
831
931
  }
832
932
  Expr::NativeModuleLoad {
833
- spec,
834
- export_name,
835
- ..
933
+ spec, export_name, ..
836
934
  } => {
837
935
  self.buf.push_str("import { ");
838
936
  self.buf.push_str(export_name.as_ref());
@@ -920,4 +1018,12 @@ mod tests {
920
1018
  let out = format_source(src).unwrap();
921
1019
  let _ = tishlang_parser::parse(&out).unwrap();
922
1020
  }
1021
+
1022
+ #[test]
1023
+ fn jsx_multiline_when_mixed_children() {
1024
+ let src = "let x = <div>a{b}</div>\n";
1025
+ let out = format_source(src).unwrap();
1026
+ assert!(out.contains('\n'), "expected line breaks in formatted JSX: {out:?}");
1027
+ let _ = tishlang_parser::parse(&out).unwrap();
1028
+ }
923
1029
  }