@tishlang/tish 1.0.12 → 1.0.14

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 (103) hide show
  1. package/crates/js_to_tish/Cargo.toml +4 -2
  2. package/crates/js_to_tish/src/span_util.rs +1 -1
  3. package/crates/js_to_tish/src/transform/expr.rs +15 -15
  4. package/crates/js_to_tish/src/transform/stmt.rs +7 -7
  5. package/crates/js_to_tish/src/transform.rs +1 -1
  6. package/crates/tish/Cargo.toml +22 -22
  7. package/crates/tish/src/main.rs +47 -46
  8. package/crates/tish/src/repl_completion.rs +4 -4
  9. package/crates/tish/tests/integration_test.rs +47 -27
  10. package/crates/tish_ast/Cargo.toml +3 -1
  11. package/crates/tish_ast/src/ast.rs +1 -1
  12. package/crates/tish_build_utils/Cargo.toml +3 -1
  13. package/crates/tish_build_utils/src/lib.rs +18 -6
  14. package/crates/tish_builtins/Cargo.toml +5 -3
  15. package/crates/tish_builtins/src/array.rs +2 -2
  16. package/crates/tish_builtins/src/globals.rs +3 -3
  17. package/crates/tish_builtins/src/helpers.rs +1 -1
  18. package/crates/tish_builtins/src/lib.rs +3 -3
  19. package/crates/tish_builtins/src/math.rs +1 -1
  20. package/crates/tish_builtins/src/object.rs +2 -2
  21. package/crates/tish_builtins/src/string.rs +1 -1
  22. package/crates/tish_bytecode/Cargo.toml +9 -7
  23. package/crates/tish_bytecode/src/chunk.rs +1 -1
  24. package/crates/tish_bytecode/src/compiler.rs +1 -1
  25. package/crates/tish_bytecode/src/encoding.rs +6 -6
  26. package/crates/tish_bytecode/tests/constant_folding.rs +7 -7
  27. package/crates/tish_bytecode/tests/shortcircuit.rs +11 -11
  28. package/crates/tish_bytecode/tests/sort_optimization.rs +3 -3
  29. package/crates/tish_compile/Cargo.toml +6 -4
  30. package/crates/tish_compile/src/codegen.rs +96 -96
  31. package/crates/tish_compile/src/lib.rs +2 -2
  32. package/crates/tish_compile/src/resolve.rs +7 -7
  33. package/crates/tish_compile/src/types.rs +1 -1
  34. package/crates/tish_compile_js/Cargo.toml +8 -6
  35. package/crates/tish_compile_js/src/codegen.rs +12 -12
  36. package/crates/tish_compile_js/src/js_intrinsics.rs +1 -1
  37. package/crates/tish_compile_js/src/lib.rs +2 -2
  38. package/crates/tish_compile_js/src/tests_jsx.rs +2 -2
  39. package/crates/tish_compiler_wasm/Cargo.toml +8 -6
  40. package/crates/tish_compiler_wasm/src/lib.rs +12 -12
  41. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +3 -3
  42. package/crates/tish_core/Cargo.toml +3 -1
  43. package/crates/tish_core/src/lib.rs +1 -1
  44. package/crates/tish_core/src/macros.rs +1 -1
  45. package/crates/tish_core/src/value.rs +1 -1
  46. package/crates/tish_cranelift/Cargo.toml +6 -4
  47. package/crates/tish_cranelift/src/lib.rs +2 -2
  48. package/crates/tish_cranelift/src/link.rs +11 -11
  49. package/crates/tish_cranelift/src/lower.rs +3 -3
  50. package/crates/tish_cranelift_runtime/Cargo.toml +9 -7
  51. package/crates/tish_cranelift_runtime/src/lib.rs +2 -2
  52. package/crates/tish_eval/Cargo.toml +10 -8
  53. package/crates/tish_eval/src/eval.rs +35 -35
  54. package/crates/tish_eval/src/http.rs +1 -1
  55. package/crates/tish_eval/src/lib.rs +3 -3
  56. package/crates/tish_eval/src/natives.rs +2 -2
  57. package/crates/tish_eval/src/regex.rs +2 -2
  58. package/crates/tish_eval/src/value.rs +7 -7
  59. package/crates/tish_eval/src/value_convert.rs +3 -3
  60. package/crates/tish_fmt/Cargo.toml +3 -3
  61. package/crates/tish_fmt/src/bin/tish-fmt.rs +1 -1
  62. package/crates/tish_fmt/src/lib.rs +3 -3
  63. package/crates/tish_jsx_web/Cargo.toml +3 -1
  64. package/crates/tish_lexer/Cargo.toml +3 -1
  65. package/crates/tish_lint/Cargo.toml +3 -3
  66. package/crates/tish_lint/src/bin/tish-lint.rs +3 -3
  67. package/crates/tish_lint/src/lib.rs +15 -15
  68. package/crates/tish_llvm/Cargo.toml +7 -5
  69. package/crates/tish_llvm/src/lib.rs +10 -10
  70. package/crates/tish_lsp/Cargo.toml +5 -5
  71. package/crates/tish_lsp/src/main.rs +35 -35
  72. package/crates/tish_native/Cargo.toml +10 -8
  73. package/crates/tish_native/src/build.rs +8 -8
  74. package/crates/tish_native/src/lib.rs +39 -39
  75. package/crates/tish_opt/Cargo.toml +5 -3
  76. package/crates/tish_opt/src/lib.rs +27 -27
  77. package/crates/tish_parser/Cargo.toml +5 -3
  78. package/crates/tish_parser/src/lib.rs +4 -4
  79. package/crates/tish_parser/src/parser.rs +2 -2
  80. package/crates/tish_runtime/Cargo.toml +7 -5
  81. package/crates/tish_runtime/src/http.rs +1 -1
  82. package/crates/tish_runtime/src/http_fetch.rs +2 -2
  83. package/crates/tish_runtime/src/lib.rs +21 -21
  84. package/crates/tish_runtime/src/native_promise.rs +1 -1
  85. package/crates/tish_runtime/src/promise.rs +2 -2
  86. package/crates/tish_runtime/src/promise_io.rs +1 -1
  87. package/crates/tish_runtime/src/timers.rs +1 -1
  88. package/crates/tish_runtime/src/ws.rs +1 -1
  89. package/crates/tish_runtime/tests/fetch_readable_stream.rs +2 -2
  90. package/crates/tish_vm/Cargo.toml +14 -12
  91. package/crates/tish_vm/src/lib.rs +2 -2
  92. package/crates/tish_vm/src/vm.rs +42 -42
  93. package/crates/tish_wasm/Cargo.toml +8 -6
  94. package/crates/tish_wasm/src/lib.rs +17 -17
  95. package/crates/tish_wasm_runtime/Cargo.toml +9 -7
  96. package/crates/tish_wasm_runtime/src/lib.rs +4 -4
  97. package/justfile +4 -4
  98. package/package.json +1 -1
  99. package/platform/darwin-arm64/tish +0 -0
  100. package/platform/darwin-x64/tish +0 -0
  101. package/platform/linux-arm64/tish +0 -0
  102. package/platform/linux-x64/tish +0 -0
  103. package/platform/win32-x64/tish.exe +0 -0
@@ -1,9 +1,11 @@
1
1
  [package]
2
- name = "js_to_tish"
2
+ name = "tishlang_js_to_tish"
3
3
  version = "0.1.0"
4
4
  edition = "2021"
5
5
  description = "Vanilla JavaScript to Tish AST converter"
6
6
 
7
+ license-file = { workspace = true }
8
+ repository = { workspace = true }
7
9
  [dependencies]
8
10
  oxc = { version = "0.121", features = ["semantic"] }
9
- tish_ast = { path = "../tish_ast" }
11
+ tishlang_ast = { path = "../tish_ast" }
@@ -1,7 +1,7 @@
1
1
  //! Span conversion from OXC offsets to Tish (line, col).
2
2
 
3
3
  use oxc::span::GetSpan;
4
- use tish_ast::Span;
4
+ use tishlang_ast::Span;
5
5
 
6
6
  /// Convert OXC span (byte start/end) to Tish Span (line, col).
7
7
  /// Uses source text to compute line/column from offsets.
@@ -4,7 +4,7 @@ use std::sync::Arc;
4
4
 
5
5
  use oxc::ast::ast::Expression as OxcExpr;
6
6
  use oxc::semantic::Semantic;
7
- use tish_ast::{
7
+ use tishlang_ast::{
8
8
  ArrayElement, ArrowBody, BinOp, CompoundOp, DestructPattern, Expr, Literal, LogicalAssignOp,
9
9
  MemberProp, ObjectProp, TypedParam,
10
10
  };
@@ -155,7 +155,7 @@ pub fn convert_expr(expr: &OxcExpr<'_>, ctx: &Ctx<'_>) -> Result<Expr, ConvertEr
155
155
  ArrowBody::Expr(Box::new(convert_expr(e, ctx)?))
156
156
  } else {
157
157
  let stmts = super::stmt::convert_statements(&arrow.body.statements, ctx.0, ctx.1)?;
158
- ArrowBody::Block(Box::new(tish_ast::Statement::Block {
158
+ ArrowBody::Block(Box::new(tishlang_ast::Statement::Block {
159
159
  statements: stmts,
160
160
  span: span_util::oxc_span_to_tish(ctx.1, &*arrow.body),
161
161
  }))
@@ -205,7 +205,7 @@ pub fn convert_expr(expr: &OxcExpr<'_>, ctx: &Ctx<'_>) -> Result<Expr, ConvertEr
205
205
  let body = match &f.body {
206
206
  Some(fb) => {
207
207
  let stmts = super::stmt::convert_statements(&fb.statements, ctx.0, ctx.1)?;
208
- ArrowBody::Block(Box::new(tish_ast::Statement::Block {
208
+ ArrowBody::Block(Box::new(tishlang_ast::Statement::Block {
209
209
  statements: stmts,
210
210
  span: span_util::oxc_span_to_tish(ctx.1, fb.as_ref()),
211
211
  }))
@@ -233,7 +233,7 @@ pub fn convert_expr(expr: &OxcExpr<'_>, ctx: &Ctx<'_>) -> Result<Expr, ConvertEr
233
233
  fn convert_chain_element(
234
234
  ce: &oxc::ast::ast::ChainElement<'_>,
235
235
  ctx: &Ctx<'_>,
236
- span: tish_ast::Span,
236
+ span: tishlang_ast::Span,
237
237
  ) -> Result<Expr, ConvertError> {
238
238
  match ce {
239
239
  oxc::ast::ast::ChainElement::StaticMemberExpression(m) => {
@@ -273,15 +273,15 @@ fn convert_chain_element(
273
273
  fn convert_call_arg(
274
274
  arg: &oxc::ast::ast::Argument<'_>,
275
275
  ctx: &Ctx<'_>,
276
- ) -> Result<tish_ast::CallArg, ConvertError> {
276
+ ) -> Result<tishlang_ast::CallArg, ConvertError> {
277
277
  if arg.is_spread() {
278
278
  if let oxc::ast::ast::Argument::SpreadElement(s) = arg {
279
- Ok(tish_ast::CallArg::Spread(convert_expr(&s.argument, ctx)?))
279
+ Ok(tishlang_ast::CallArg::Spread(convert_expr(&s.argument, ctx)?))
280
280
  } else {
281
281
  unreachable!()
282
282
  }
283
283
  } else if let Some(e) = arg.as_expression() {
284
- Ok(tish_ast::CallArg::Expr(convert_expr(e, ctx)?))
284
+ Ok(tishlang_ast::CallArg::Expr(convert_expr(e, ctx)?))
285
285
  } else {
286
286
  Err(ConvertError::new(ConvertErrorKind::Unsupported {
287
287
  what: "call argument".into(),
@@ -340,7 +340,7 @@ fn convert_object_prop(
340
340
  fn convert_assignment(
341
341
  a: &oxc::ast::ast::AssignmentExpression<'_>,
342
342
  ctx: &Ctx<'_>,
343
- span: tish_ast::Span,
343
+ span: tishlang_ast::Span,
344
344
  ) -> Result<Expr, ConvertError> {
345
345
  let (left, right) = (&a.left, &a.right);
346
346
  if let Some(oxc::ast::ast::SimpleAssignmentTarget::AssignmentTargetIdentifier(id)) =
@@ -435,7 +435,7 @@ fn convert_assignment(
435
435
  fn convert_update_expr(
436
436
  u: &oxc::ast::ast::UpdateExpression<'_>,
437
437
  _ctx: &Ctx<'_>,
438
- span: tish_ast::Span,
438
+ span: tishlang_ast::Span,
439
439
  ) -> Result<Expr, ConvertError> {
440
440
  let name: Arc<str> = match &u.argument {
441
441
  oxc::ast::ast::SimpleAssignmentTarget::AssignmentTargetIdentifier(id) => {
@@ -498,13 +498,13 @@ fn convert_bin_op(
498
498
 
499
499
  fn convert_unary_op(
500
500
  op: &oxc::ast::ast::UnaryOperator,
501
- ) -> Result<tish_ast::UnaryOp, ConvertError> {
501
+ ) -> Result<tishlang_ast::UnaryOp, ConvertError> {
502
502
  Ok(match op {
503
- oxc::ast::ast::UnaryOperator::LogicalNot => tish_ast::UnaryOp::Not,
504
- oxc::ast::ast::UnaryOperator::UnaryNegation => tish_ast::UnaryOp::Neg,
505
- oxc::ast::ast::UnaryOperator::UnaryPlus => tish_ast::UnaryOp::Pos,
506
- oxc::ast::ast::UnaryOperator::BitwiseNot => tish_ast::UnaryOp::BitNot,
507
- oxc::ast::ast::UnaryOperator::Void => tish_ast::UnaryOp::Void,
503
+ oxc::ast::ast::UnaryOperator::LogicalNot => tishlang_ast::UnaryOp::Not,
504
+ oxc::ast::ast::UnaryOperator::UnaryNegation => tishlang_ast::UnaryOp::Neg,
505
+ oxc::ast::ast::UnaryOperator::UnaryPlus => tishlang_ast::UnaryOp::Pos,
506
+ oxc::ast::ast::UnaryOperator::BitwiseNot => tishlang_ast::UnaryOp::BitNot,
507
+ oxc::ast::ast::UnaryOperator::Void => tishlang_ast::UnaryOp::Void,
508
508
  _ => {
509
509
  return Err(ConvertError::new(ConvertErrorKind::Unsupported {
510
510
  what: format!("unary operator: {op:?}"),
@@ -4,7 +4,7 @@ use std::sync::Arc;
4
4
 
5
5
  use oxc::ast::ast::Statement as OxcStmt;
6
6
  use oxc::semantic::Semantic;
7
- use tish_ast::{Statement, Span};
7
+ use tishlang_ast::{Statement, Span};
8
8
 
9
9
  use super::expr;
10
10
  use crate::error::{ConvertError, ConvertErrorKind};
@@ -406,18 +406,18 @@ fn convert_import(
406
406
  } else {
407
407
  Some(Arc::from(local_name))
408
408
  };
409
- specifiers.push(tish_ast::ImportSpecifier::Named {
409
+ specifiers.push(tishlang_ast::ImportSpecifier::Named {
410
410
  name: Arc::from(imported_name),
411
411
  alias,
412
412
  });
413
413
  }
414
414
  oxc::ast::ast::ImportDeclarationSpecifier::ImportDefaultSpecifier(ds) => {
415
- specifiers.push(tish_ast::ImportSpecifier::Default(Arc::from(
415
+ specifiers.push(tishlang_ast::ImportSpecifier::Default(Arc::from(
416
416
  ds.local.name.as_str(),
417
417
  )));
418
418
  }
419
419
  oxc::ast::ast::ImportDeclarationSpecifier::ImportNamespaceSpecifier(ns) => {
420
- specifiers.push(tish_ast::ImportSpecifier::Namespace(Arc::from(
420
+ specifiers.push(tishlang_ast::ImportSpecifier::Namespace(Arc::from(
421
421
  ns.local.name.as_str(),
422
422
  )));
423
423
  }
@@ -438,10 +438,10 @@ fn convert_export_default(
438
438
  ) -> Result<Statement, ConvertError> {
439
439
  let declaration = if let Some(expr) = e.declaration.as_expression() {
440
440
  let expr = expr::convert_expr(expr, ctx)?;
441
- tish_ast::ExportDeclaration::Default(expr)
441
+ tishlang_ast::ExportDeclaration::Default(expr)
442
442
  } else if let oxc::ast::ast::ExportDefaultDeclarationKind::FunctionDeclaration(f) = &e.declaration {
443
443
  let stmt = convert_function_decl(f.as_ref(), ctx, span_util::stub_span())?;
444
- tish_ast::ExportDeclaration::Named(Box::new(stmt))
444
+ tishlang_ast::ExportDeclaration::Named(Box::new(stmt))
445
445
  } else {
446
446
  return Err(ConvertError::new(ConvertErrorKind::Unsupported {
447
447
  what: "export default (this form)".into(),
@@ -462,7 +462,7 @@ fn convert_export_named(
462
462
  if let Some(decl) = &e.declaration {
463
463
  let stmt = convert_declaration(decl, ctx)?;
464
464
  Ok(Statement::Export {
465
- declaration: Box::new(tish_ast::ExportDeclaration::Named(Box::new(stmt))),
465
+ declaration: Box::new(tishlang_ast::ExportDeclaration::Named(Box::new(stmt))),
466
466
  span,
467
467
  })
468
468
  } else {
@@ -7,7 +7,7 @@ use oxc::allocator::Allocator;
7
7
  use oxc::parser::Parser;
8
8
  use oxc::semantic::SemanticBuilder;
9
9
  use oxc::span::SourceType;
10
- use tish_ast::Program;
10
+ use tishlang_ast::Program;
11
11
 
12
12
  use crate::error::{ConvertError, ConvertErrorKind};
13
13
  use crate::transform::stmt::convert_statements;
@@ -1,6 +1,6 @@
1
1
  [package]
2
- name = "tish"
3
- version = "0.1.0"
2
+ name = "tishlang"
3
+ version = "1.0.14"
4
4
  edition = "2021"
5
5
  description = "Tish CLI - run, REPL, compile to native"
6
6
  license-file = { workspace = true }
@@ -16,28 +16,28 @@ default = []
16
16
  # Full: all capabilities enabled (for development/trusted environments)
17
17
  full = ["http", "fs", "process", "regex", "ws"]
18
18
  # Individual capability flags
19
- http = ["tish_eval/http", "tish_runtime/http", "tish_compile/http", "tish_vm/http"]
20
- fs = ["tish_eval/fs", "tish_runtime/fs", "tish_compile/fs", "tish_vm/fs"]
21
- process = ["tish_eval/process", "tish_runtime/process", "tish_compile/process", "tish_vm/process"]
22
- regex = ["tish_eval/regex", "tish_runtime/regex", "tish_compile/regex", "tish_vm/regex"]
23
- ws = ["tish_eval/ws", "tish_runtime/ws", "tish_compile/ws", "tish_vm/ws"]
19
+ http = ["tishlang_eval/http", "tishlang_runtime/http", "tishlang_compile/http", "tishlang_vm/http"]
20
+ fs = ["tishlang_eval/fs", "tishlang_runtime/fs", "tishlang_compile/fs", "tishlang_vm/fs"]
21
+ process = ["tishlang_eval/process", "tishlang_runtime/process", "tishlang_compile/process", "tishlang_vm/process"]
22
+ regex = ["tishlang_eval/regex", "tishlang_runtime/regex", "tishlang_compile/regex", "tishlang_vm/regex"]
23
+ ws = ["tishlang_eval/ws", "tishlang_runtime/ws", "tishlang_compile/ws", "tishlang_vm/ws"]
24
24
  [dependencies]
25
25
  rustyline = { version = "17", features = ["with-file-history"] }
26
- tish_lexer = { path = "../tish_lexer" }
27
- tish_ast = { path = "../tish_ast" }
28
- tish_parser = { path = "../tish_parser" }
29
- tish_eval = { path = "../tish_eval" }
30
- tish_compile = { path = "../tish_compile" }
31
- tish_compile_js = { path = "../tish_compile_js" }
32
- tish_bytecode = { path = "../tish_bytecode" }
33
- tish_opt = { path = "../tish_opt" }
34
- tish_vm = { path = "../tish_vm" }
35
- tish_native = { path = "../tish_native" }
36
- tish_llvm = { path = "../tish_llvm" }
37
- tish_wasm = { path = "../tish_wasm" }
38
- tish_runtime = { path = "../tish_runtime" }
39
- tish_core = { path = "../tish_core" }
40
- js_to_tish = { path = "../js_to_tish" }
26
+ tishlang_lexer = { path = "../tish_lexer" }
27
+ tishlang_ast = { path = "../tish_ast" }
28
+ tishlang_parser = { path = "../tish_parser" }
29
+ tishlang_eval = { path = "../tish_eval" }
30
+ tishlang_compile = { path = "../tish_compile" }
31
+ tishlang_compile_js = { path = "../tish_compile_js" }
32
+ tishlang_bytecode = { path = "../tish_bytecode" }
33
+ tishlang_opt = { path = "../tish_opt" }
34
+ tishlang_vm = { path = "../tish_vm" }
35
+ tishlang_native = { path = "../tish_native" }
36
+ tishlang_llvm = { path = "../tish_llvm" }
37
+ tishlang_wasm = { path = "../tish_wasm" }
38
+ tishlang_runtime = { path = "../tish_runtime" }
39
+ tishlang_core = { path = "../tish_core" }
40
+ tishlang_js_to_tish = { path = "../js_to_tish" }
41
41
  clap = { version = "4.6.0", features = ["derive"] }
42
42
 
43
43
  [dev-dependencies]
@@ -14,6 +14,7 @@ use rustyline::{Behavior, ColorMode, CompletionType, Config, Editor};
14
14
  #[derive(Parser)]
15
15
  #[command(name = "tish")]
16
16
  #[command(about = "Tish - minimal TS/JS-compatible language")]
17
+ #[command(version = env!("CARGO_PKG_VERSION"))]
17
18
  #[command(after_help = "To disable optimizations: TISH_NO_OPTIMIZE=1")]
18
19
  pub(crate) struct Cli {
19
20
  #[command(subcommand)]
@@ -116,42 +117,42 @@ fn run_file(path: &str, backend: &str, _features: &[String], no_optimize: bool)
116
117
  });
117
118
 
118
119
  let program = if path.extension().map(|e| e == "js") == Some(true) {
119
- let prog = js_to_tish::convert(&fs::read_to_string(&path).map_err(|e| format!("{}", e))?)
120
+ let prog = tishlang_js_to_tish::convert(&fs::read_to_string(&path).map_err(|e| format!("{}", e))?)
120
121
  .map_err(|e| format!("{}", e))?;
121
122
  if no_optimize {
122
123
  prog
123
124
  } else {
124
- tish_opt::optimize(&prog)
125
+ tishlang_opt::optimize(&prog)
125
126
  }
126
127
  } else {
127
- let modules = tish_compile::resolve_project(&path, project_root)?;
128
- tish_compile::detect_cycles(&modules)?;
129
- let prog = tish_compile::merge_modules(modules)?;
128
+ let modules = tishlang_compile::resolve_project(&path, project_root)?;
129
+ tishlang_compile::detect_cycles(&modules)?;
130
+ let prog = tishlang_compile::merge_modules(modules)?;
130
131
  if no_optimize {
131
132
  prog
132
133
  } else {
133
- tish_opt::optimize(&prog)
134
+ tishlang_opt::optimize(&prog)
134
135
  }
135
136
  };
136
137
 
137
138
  if backend == "interp" {
138
- let mut eval = tish_eval::Evaluator::new();
139
+ let mut eval = tishlang_eval::Evaluator::new();
139
140
  let value = eval.eval_program(&program)?;
140
- if !matches!(value, tish_eval::Value::Null) {
141
- println!("{}", tish_eval::format_value_for_console(&value, tish_core::use_console_colors()));
141
+ if !matches!(value, tishlang_eval::Value::Null) {
142
+ println!("{}", tishlang_eval::format_value_for_console(&value, tishlang_core::use_console_colors()));
142
143
  }
143
144
  return Ok(());
144
145
  }
145
146
 
146
147
  // VM backend (bytecode) - supports native imports when built with fs/http/process features
147
148
  let chunk = if no_optimize {
148
- tish_bytecode::compile_unoptimized(&program).map_err(|e| e.to_string())?
149
+ tishlang_bytecode::compile_unoptimized(&program).map_err(|e| e.to_string())?
149
150
  } else {
150
- tish_bytecode::compile(&program).map_err(|e| e.to_string())?
151
+ tishlang_bytecode::compile(&program).map_err(|e| e.to_string())?
151
152
  };
152
- let value = tish_vm::run(&chunk)?;
153
- if !matches!(value, tish_core::Value::Null) {
154
- println!("{}", tish_core::format_value_styled(&value, tish_core::use_console_colors()));
153
+ let value = tishlang_vm::run(&chunk)?;
154
+ if !matches!(value, tishlang_core::Value::Null) {
155
+ println!("{}", tishlang_core::format_value_styled(&value, tishlang_core::use_console_colors()));
155
156
  }
156
157
  Ok(())
157
158
  }
@@ -161,7 +162,7 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
161
162
  let mut buffer = String::new();
162
163
 
163
164
  if backend == "interp" {
164
- let mut eval = tish_eval::Evaluator::new();
165
+ let mut eval = tishlang_eval::Evaluator::new();
165
166
  let mut multiline = String::new();
166
167
  loop {
167
168
  let prompt = repl_prompt(multiline.is_empty());
@@ -170,7 +171,7 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
170
171
  buffer.clear();
171
172
  if io::stdin().read_line(&mut buffer).map_err(|e| e.to_string())? == 0 {
172
173
  if !multiline.is_empty() {
173
- let _ = tish_parser::parse(multiline.trim());
174
+ let _ = tishlang_parser::parse(multiline.trim());
174
175
  }
175
176
  break;
176
177
  }
@@ -184,12 +185,12 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
184
185
  multiline.push('\n');
185
186
  multiline.push_str(line);
186
187
  }
187
- match tish_parser::parse(multiline.trim()) {
188
+ match tishlang_parser::parse(multiline.trim()) {
188
189
  Ok(program) => {
189
190
  match eval.eval_program(&program) {
190
191
  Ok(v) => {
191
- if !matches!(v, tish_eval::Value::Null) {
192
- println!("{}", tish_eval::format_value_for_console(&v, tish_core::use_console_colors()));
192
+ if !matches!(v, tishlang_eval::Value::Null) {
193
+ println!("{}", tishlang_eval::format_value_for_console(&v, tishlang_core::use_console_colors()));
193
194
  }
194
195
  }
195
196
  Err(e) => eprintln!("{}", e),
@@ -213,7 +214,7 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
213
214
  if !std::io::stdin().is_terminal() {
214
215
  eprintln!("Note: Tab completion and grey preview require an interactive terminal (TTY).");
215
216
  }
216
- let vm = Rc::new(RefCell::new(tish_vm::Vm::new()));
217
+ let vm = Rc::new(RefCell::new(tishlang_vm::Vm::new()));
217
218
  let completer = repl_completion::ReplCompleter {
218
219
  vm: Rc::clone(&vm),
219
220
  no_optimize,
@@ -245,12 +246,12 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
245
246
  if buffer.is_empty() {
246
247
  break;
247
248
  }
248
- match tish_parser::parse(buffer.trim()) {
249
+ match tishlang_parser::parse(buffer.trim()) {
249
250
  Ok(program) => {
250
251
  let compile_fn = if no_optimize {
251
- tish_bytecode::compile_for_repl_unoptimized
252
+ tishlang_bytecode::compile_for_repl_unoptimized
252
253
  } else {
253
- tish_bytecode::compile_for_repl
254
+ tishlang_bytecode::compile_for_repl
254
255
  };
255
256
  if let Ok(chunk) = compile_fn(&program) {
256
257
  let _ = vm.borrow_mut().run(&chunk);
@@ -276,19 +277,19 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
276
277
  buffer.push('\n');
277
278
  buffer.push_str(line);
278
279
  }
279
- match tish_parser::parse(buffer.trim()) {
280
+ match tishlang_parser::parse(buffer.trim()) {
280
281
  Ok(program) => {
281
282
  let compile_fn = if no_optimize {
282
- tish_bytecode::compile_for_repl_unoptimized
283
+ tishlang_bytecode::compile_for_repl_unoptimized
283
284
  } else {
284
- tish_bytecode::compile_for_repl
285
+ tishlang_bytecode::compile_for_repl
285
286
  };
286
287
  match compile_fn(&program) {
287
288
  Ok(chunk) => {
288
289
  match vm.borrow_mut().run(&chunk) {
289
290
  Ok(v) => {
290
- if !matches!(v, tish_core::Value::Null) {
291
- println!("{}", tish_core::format_value_styled(&v, tish_core::use_console_colors()));
291
+ if !matches!(v, tishlang_core::Value::Null) {
292
+ println!("{}", tishlang_core::format_value_styled(&v, tishlang_core::use_console_colors()));
292
293
  }
293
294
  }
294
295
  Err(e) => eprintln!("{}", e),
@@ -318,7 +319,7 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
318
319
 
319
320
  /// REPL prompt with green caret when stdout is a TTY (platform-style).
320
321
  fn repl_prompt(primary: bool) -> String {
321
- if tish_core::use_console_colors() {
322
+ if tishlang_core::use_console_colors() {
322
323
  if primary {
323
324
  "\x1b[32m> \x1b[0m".to_string()
324
325
  } else {
@@ -338,15 +339,15 @@ fn tish_history_path() -> Option<PathBuf> {
338
339
  home.map(|h| PathBuf::from(h).join(".tish_history"))
339
340
  }
340
341
 
341
- fn parse_jsx_mode(s: &str) -> Result<tish_compile_js::JsxMode, String> {
342
+ fn parse_jsx_mode(s: &str) -> Result<tishlang_compile_js::JsxMode, String> {
342
343
  match s {
343
344
  "legacy" => Err(
344
345
  "--jsx legacy was removed. Use --jsx lattish (default) with lattish merged into your \
345
346
  bundle, or --jsx vdom with Lattish's createRoot."
346
347
  .to_string(),
347
348
  ),
348
- "vdom" => Ok(tish_compile_js::JsxMode::Vdom),
349
- "lattish" => Ok(tish_compile_js::JsxMode::LattishH),
349
+ "vdom" => Ok(tishlang_compile_js::JsxMode::Vdom),
350
+ "lattish" => Ok(tishlang_compile_js::JsxMode::LattishH),
350
351
  other => Err(format!(
351
352
  "Unknown --jsx {:?}: use lattish (default) or vdom.",
352
353
  other
@@ -374,20 +375,20 @@ fn compile_to_js(
374
375
  "export fn __TishJsxRoot() {{\n return (\n{}\n )\n}}",
375
376
  source.trim()
376
377
  );
377
- let program = tish_parser::parse(&wrapped)
378
+ let program = tishlang_parser::parse(&wrapped)
378
379
  .map_err(|e| format!("JSX wrapper parse: {}", e))?;
379
380
  let p = if optimize {
380
- tish_opt::optimize(&program)
381
+ tishlang_opt::optimize(&program)
381
382
  } else {
382
383
  program
383
384
  };
384
- tish_compile_js::compile_with_jsx(&p, optimize, jsx_mode).map_err(|e| format!("{}", e))?
385
+ tishlang_compile_js::compile_with_jsx(&p, optimize, jsx_mode).map_err(|e| format!("{}", e))?
385
386
  } else if input_path.extension().map(|e| e == "js") == Some(true) {
386
387
  let source = fs::read_to_string(input_path).map_err(|e| format!("{}", e))?;
387
- let program = js_to_tish::convert(&source).map_err(|e| format!("{}", e))?;
388
- tish_compile_js::compile_with_jsx(&program, optimize, jsx_mode).map_err(|e| format!("{}", e))?
388
+ let program = tishlang_js_to_tish::convert(&source).map_err(|e| format!("{}", e))?;
389
+ tishlang_compile_js::compile_with_jsx(&program, optimize, jsx_mode).map_err(|e| format!("{}", e))?
389
390
  } else {
390
- tish_compile_js::compile_project_with_jsx(input_path, project_root, optimize, jsx_mode)
391
+ tishlang_compile_js::compile_project_with_jsx(input_path, project_root, optimize, jsx_mode)
391
392
  .map_err(|e| format!("{}", e))?
392
393
  };
393
394
 
@@ -431,8 +432,8 @@ fn compile_file(
431
432
 
432
433
  if target == "wasm" && is_js {
433
434
  let source = fs::read_to_string(&input_path).map_err(|e| format!("{}", e))?;
434
- let program = js_to_tish::convert(&source).map_err(|e| format!("{}", e))?;
435
- return tish_wasm::compile_program_to_wasm(&program, Path::new(output_path), optimize)
435
+ let program = tishlang_js_to_tish::convert(&source).map_err(|e| format!("{}", e))?;
436
+ return tishlang_wasm::compile_program_to_wasm(&program, Path::new(output_path), optimize)
436
437
  .map_err(|e| format!("{}", e));
437
438
  }
438
439
 
@@ -444,7 +445,7 @@ fn compile_file(
444
445
  Some(p)
445
446
  }
446
447
  });
447
- return tish_wasm::compile_to_wasm(&input_path, project_root, Path::new(output_path), optimize)
448
+ return tishlang_wasm::compile_to_wasm(&input_path, project_root, Path::new(output_path), optimize)
448
449
  .map_err(|e| e.to_string());
449
450
  }
450
451
 
@@ -456,7 +457,7 @@ fn compile_file(
456
457
  Some(p)
457
458
  }
458
459
  });
459
- return tish_wasm::compile_to_wasi(&input_path, project_root, Path::new(output_path), optimize)
460
+ return tishlang_wasm::compile_to_wasi(&input_path, project_root, Path::new(output_path), optimize)
460
461
  .map_err(|e| e.to_string());
461
462
  }
462
463
 
@@ -494,8 +495,8 @@ fn compile_file(
494
495
 
495
496
  if is_js {
496
497
  let source = fs::read_to_string(&input_path).map_err(|e| format!("{}", e))?;
497
- let program = js_to_tish::convert(&source).map_err(|e| format!("{}", e))?;
498
- tish_native::compile_program_to_native(
498
+ let program = tishlang_js_to_tish::convert(&source).map_err(|e| format!("{}", e))?;
499
+ tishlang_native::compile_program_to_native(
499
500
  &program,
500
501
  project_root,
501
502
  Path::new(output_path),
@@ -505,7 +506,7 @@ fn compile_file(
505
506
  )
506
507
  .map_err(|e| e.to_string())?;
507
508
  } else {
508
- tish_native::compile_to_native(
509
+ tishlang_native::compile_to_native(
509
510
  &input_path,
510
511
  project_root,
511
512
  Path::new(output_path),
@@ -579,7 +580,7 @@ mod cli_tests {
579
580
  fn dump_ast(path: &str) -> Result<(), String> {
580
581
  let source =
581
582
  fs::read_to_string(path).map_err(|e| format!("Cannot read {}: {}", path, e))?;
582
- let program = tish_parser::parse(&source)?;
583
+ let program = tishlang_parser::parse(&source)?;
583
584
  println!("{:#?}", program);
584
585
  Ok(())
585
586
  }
@@ -12,9 +12,9 @@ use rustyline::validate::Validator;
12
12
  use rustyline::Context;
13
13
  use rustyline::Helper;
14
14
 
15
- use tish_bytecode::{compile_for_repl, compile_for_repl_unoptimized};
16
- use tish_parser;
17
- use tish_vm::Vm;
15
+ use tishlang_bytecode::{compile_for_repl, compile_for_repl_unoptimized};
16
+ use tishlang_parser;
17
+ use tishlang_vm::Vm;
18
18
 
19
19
  /// Tish keywords for bare-word completion (Python-style).
20
20
  const KEYWORDS: &[&str] = &[
@@ -79,7 +79,7 @@ impl ReplCompleter {
79
79
  }
80
80
  let member_prefix = line_before_cursor[last_dot + 1..].trim();
81
81
 
82
- let program = tish_parser::parse(prefix_expr).ok()?;
82
+ let program = tishlang_parser::parse(prefix_expr).ok()?;
83
83
  let compile_fn = if self.no_optimize {
84
84
  compile_for_repl_unoptimized
85
85
  } else {