@tishlang/tish 1.0.13 → 1.0.15
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.
- package/crates/js_to_tish/Cargo.toml +4 -2
- package/crates/js_to_tish/src/span_util.rs +1 -1
- package/crates/js_to_tish/src/transform/expr.rs +15 -15
- package/crates/js_to_tish/src/transform/stmt.rs +7 -7
- package/crates/js_to_tish/src/transform.rs +1 -1
- package/crates/tish/Cargo.toml +22 -22
- package/crates/tish/src/main.rs +46 -46
- package/crates/tish/src/repl_completion.rs +4 -4
- package/crates/tish/tests/integration_test.rs +28 -28
- package/crates/tish_ast/Cargo.toml +3 -1
- package/crates/tish_ast/src/ast.rs +1 -1
- package/crates/tish_build_utils/Cargo.toml +3 -1
- package/crates/tish_build_utils/src/lib.rs +18 -6
- package/crates/tish_builtins/Cargo.toml +5 -3
- package/crates/tish_builtins/src/array.rs +2 -2
- package/crates/tish_builtins/src/globals.rs +3 -3
- package/crates/tish_builtins/src/helpers.rs +1 -1
- package/crates/tish_builtins/src/lib.rs +3 -3
- package/crates/tish_builtins/src/math.rs +1 -1
- package/crates/tish_builtins/src/object.rs +2 -2
- package/crates/tish_builtins/src/string.rs +1 -1
- package/crates/tish_bytecode/Cargo.toml +9 -7
- package/crates/tish_bytecode/src/chunk.rs +1 -1
- package/crates/tish_bytecode/src/compiler.rs +1 -1
- package/crates/tish_bytecode/src/encoding.rs +6 -6
- package/crates/tish_bytecode/tests/constant_folding.rs +7 -7
- package/crates/tish_bytecode/tests/shortcircuit.rs +11 -11
- package/crates/tish_bytecode/tests/sort_optimization.rs +3 -3
- package/crates/tish_compile/Cargo.toml +6 -4
- package/crates/tish_compile/src/codegen.rs +96 -96
- package/crates/tish_compile/src/lib.rs +2 -2
- package/crates/tish_compile/src/resolve.rs +7 -7
- package/crates/tish_compile/src/types.rs +1 -1
- package/crates/tish_compile_js/Cargo.toml +8 -6
- package/crates/tish_compile_js/src/codegen.rs +12 -12
- package/crates/tish_compile_js/src/js_intrinsics.rs +1 -1
- package/crates/tish_compile_js/src/lib.rs +2 -2
- package/crates/tish_compile_js/src/tests_jsx.rs +2 -2
- package/crates/tish_compiler_wasm/Cargo.toml +8 -6
- package/crates/tish_compiler_wasm/src/lib.rs +12 -12
- package/crates/tish_compiler_wasm/src/resolve_virtual.rs +3 -3
- package/crates/tish_core/Cargo.toml +3 -1
- package/crates/tish_core/src/lib.rs +1 -1
- package/crates/tish_core/src/macros.rs +1 -1
- package/crates/tish_core/src/value.rs +1 -1
- package/crates/tish_cranelift/Cargo.toml +6 -4
- package/crates/tish_cranelift/src/lib.rs +2 -2
- package/crates/tish_cranelift/src/link.rs +11 -11
- package/crates/tish_cranelift/src/lower.rs +3 -3
- package/crates/tish_cranelift_runtime/Cargo.toml +9 -7
- package/crates/tish_cranelift_runtime/src/lib.rs +2 -2
- package/crates/tish_eval/Cargo.toml +10 -8
- package/crates/tish_eval/src/eval.rs +35 -35
- package/crates/tish_eval/src/http.rs +1 -1
- package/crates/tish_eval/src/lib.rs +3 -3
- package/crates/tish_eval/src/natives.rs +2 -2
- package/crates/tish_eval/src/regex.rs +2 -2
- package/crates/tish_eval/src/value.rs +7 -7
- package/crates/tish_eval/src/value_convert.rs +3 -3
- package/crates/tish_fmt/Cargo.toml +3 -3
- package/crates/tish_fmt/src/bin/tish-fmt.rs +1 -1
- package/crates/tish_fmt/src/lib.rs +3 -3
- package/crates/tish_jsx_web/Cargo.toml +3 -1
- package/crates/tish_lexer/Cargo.toml +3 -1
- package/crates/tish_lint/Cargo.toml +3 -3
- package/crates/tish_lint/src/bin/tish-lint.rs +3 -3
- package/crates/tish_lint/src/lib.rs +15 -15
- package/crates/tish_llvm/Cargo.toml +7 -5
- package/crates/tish_llvm/src/lib.rs +10 -10
- package/crates/tish_lsp/Cargo.toml +5 -5
- package/crates/tish_lsp/src/main.rs +35 -35
- package/crates/tish_native/Cargo.toml +10 -8
- package/crates/tish_native/src/build.rs +8 -8
- package/crates/tish_native/src/lib.rs +39 -39
- package/crates/tish_opt/Cargo.toml +5 -3
- package/crates/tish_opt/src/lib.rs +27 -27
- package/crates/tish_parser/Cargo.toml +5 -3
- package/crates/tish_parser/src/lib.rs +4 -4
- package/crates/tish_parser/src/parser.rs +2 -2
- package/crates/tish_runtime/Cargo.toml +7 -5
- package/crates/tish_runtime/src/http.rs +1 -1
- package/crates/tish_runtime/src/http_fetch.rs +2 -2
- package/crates/tish_runtime/src/lib.rs +21 -21
- package/crates/tish_runtime/src/native_promise.rs +1 -1
- package/crates/tish_runtime/src/promise.rs +2 -2
- package/crates/tish_runtime/src/promise_io.rs +1 -1
- package/crates/tish_runtime/src/timers.rs +1 -1
- package/crates/tish_runtime/src/ws.rs +1 -1
- package/crates/tish_runtime/tests/fetch_readable_stream.rs +2 -2
- package/crates/tish_vm/Cargo.toml +14 -12
- package/crates/tish_vm/src/lib.rs +2 -2
- package/crates/tish_vm/src/vm.rs +42 -42
- package/crates/tish_wasm/Cargo.toml +8 -6
- package/crates/tish_wasm/src/lib.rs +17 -17
- package/crates/tish_wasm_runtime/Cargo.toml +9 -7
- package/crates/tish_wasm_runtime/src/lib.rs +4 -4
- package/justfile +4 -4
- package/package.json +1 -1
- package/platform/darwin-arm64/tish +0 -0
- package/platform/darwin-x64/tish +0 -0
- package/platform/linux-arm64/tish +0 -0
- package/platform/linux-x64/tish +0 -0
- package/platform/win32-x64/tish.exe +0 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
[package]
|
|
2
|
-
name = "
|
|
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
|
-
|
|
11
|
+
tishlang_ast = { path = "../tish_ast" }
|
|
@@ -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
|
|
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(
|
|
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(
|
|
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:
|
|
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<
|
|
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(
|
|
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(
|
|
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:
|
|
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:
|
|
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<
|
|
501
|
+
) -> Result<tishlang_ast::UnaryOp, ConvertError> {
|
|
502
502
|
Ok(match op {
|
|
503
|
-
oxc::ast::ast::UnaryOperator::LogicalNot =>
|
|
504
|
-
oxc::ast::ast::UnaryOperator::UnaryNegation =>
|
|
505
|
-
oxc::ast::ast::UnaryOperator::UnaryPlus =>
|
|
506
|
-
oxc::ast::ast::UnaryOperator::BitwiseNot =>
|
|
507
|
-
oxc::ast::ast::UnaryOperator::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
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
10
|
+
use tishlang_ast::Program;
|
|
11
11
|
|
|
12
12
|
use crate::error::{ConvertError, ConvertErrorKind};
|
|
13
13
|
use crate::transform::stmt::convert_statements;
|
package/crates/tish/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
|
-
name = "
|
|
3
|
-
version = "1.0.
|
|
2
|
+
name = "tishlang"
|
|
3
|
+
version = "1.0.15"
|
|
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 = ["
|
|
20
|
-
fs = ["
|
|
21
|
-
process = ["
|
|
22
|
-
regex = ["
|
|
23
|
-
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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]
|
package/crates/tish/src/main.rs
CHANGED
|
@@ -117,42 +117,42 @@ fn run_file(path: &str, backend: &str, _features: &[String], no_optimize: bool)
|
|
|
117
117
|
});
|
|
118
118
|
|
|
119
119
|
let program = if path.extension().map(|e| e == "js") == Some(true) {
|
|
120
|
-
let prog =
|
|
120
|
+
let prog = tishlang_js_to_tish::convert(&fs::read_to_string(&path).map_err(|e| format!("{}", e))?)
|
|
121
121
|
.map_err(|e| format!("{}", e))?;
|
|
122
122
|
if no_optimize {
|
|
123
123
|
prog
|
|
124
124
|
} else {
|
|
125
|
-
|
|
125
|
+
tishlang_opt::optimize(&prog)
|
|
126
126
|
}
|
|
127
127
|
} else {
|
|
128
|
-
let modules =
|
|
129
|
-
|
|
130
|
-
let prog =
|
|
128
|
+
let modules = tishlang_compile::resolve_project(&path, project_root)?;
|
|
129
|
+
tishlang_compile::detect_cycles(&modules)?;
|
|
130
|
+
let prog = tishlang_compile::merge_modules(modules)?;
|
|
131
131
|
if no_optimize {
|
|
132
132
|
prog
|
|
133
133
|
} else {
|
|
134
|
-
|
|
134
|
+
tishlang_opt::optimize(&prog)
|
|
135
135
|
}
|
|
136
136
|
};
|
|
137
137
|
|
|
138
138
|
if backend == "interp" {
|
|
139
|
-
let mut eval =
|
|
139
|
+
let mut eval = tishlang_eval::Evaluator::new();
|
|
140
140
|
let value = eval.eval_program(&program)?;
|
|
141
|
-
if !matches!(value,
|
|
142
|
-
println!("{}",
|
|
141
|
+
if !matches!(value, tishlang_eval::Value::Null) {
|
|
142
|
+
println!("{}", tishlang_eval::format_value_for_console(&value, tishlang_core::use_console_colors()));
|
|
143
143
|
}
|
|
144
144
|
return Ok(());
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
// VM backend (bytecode) - supports native imports when built with fs/http/process features
|
|
148
148
|
let chunk = if no_optimize {
|
|
149
|
-
|
|
149
|
+
tishlang_bytecode::compile_unoptimized(&program).map_err(|e| e.to_string())?
|
|
150
150
|
} else {
|
|
151
|
-
|
|
151
|
+
tishlang_bytecode::compile(&program).map_err(|e| e.to_string())?
|
|
152
152
|
};
|
|
153
|
-
let value =
|
|
154
|
-
if !matches!(value,
|
|
155
|
-
println!("{}",
|
|
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()));
|
|
156
156
|
}
|
|
157
157
|
Ok(())
|
|
158
158
|
}
|
|
@@ -162,7 +162,7 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
|
|
|
162
162
|
let mut buffer = String::new();
|
|
163
163
|
|
|
164
164
|
if backend == "interp" {
|
|
165
|
-
let mut eval =
|
|
165
|
+
let mut eval = tishlang_eval::Evaluator::new();
|
|
166
166
|
let mut multiline = String::new();
|
|
167
167
|
loop {
|
|
168
168
|
let prompt = repl_prompt(multiline.is_empty());
|
|
@@ -171,7 +171,7 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
|
|
|
171
171
|
buffer.clear();
|
|
172
172
|
if io::stdin().read_line(&mut buffer).map_err(|e| e.to_string())? == 0 {
|
|
173
173
|
if !multiline.is_empty() {
|
|
174
|
-
let _ =
|
|
174
|
+
let _ = tishlang_parser::parse(multiline.trim());
|
|
175
175
|
}
|
|
176
176
|
break;
|
|
177
177
|
}
|
|
@@ -185,12 +185,12 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
|
|
|
185
185
|
multiline.push('\n');
|
|
186
186
|
multiline.push_str(line);
|
|
187
187
|
}
|
|
188
|
-
match
|
|
188
|
+
match tishlang_parser::parse(multiline.trim()) {
|
|
189
189
|
Ok(program) => {
|
|
190
190
|
match eval.eval_program(&program) {
|
|
191
191
|
Ok(v) => {
|
|
192
|
-
if !matches!(v,
|
|
193
|
-
println!("{}",
|
|
192
|
+
if !matches!(v, tishlang_eval::Value::Null) {
|
|
193
|
+
println!("{}", tishlang_eval::format_value_for_console(&v, tishlang_core::use_console_colors()));
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
Err(e) => eprintln!("{}", e),
|
|
@@ -214,7 +214,7 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
|
|
|
214
214
|
if !std::io::stdin().is_terminal() {
|
|
215
215
|
eprintln!("Note: Tab completion and grey preview require an interactive terminal (TTY).");
|
|
216
216
|
}
|
|
217
|
-
let vm = Rc::new(RefCell::new(
|
|
217
|
+
let vm = Rc::new(RefCell::new(tishlang_vm::Vm::new()));
|
|
218
218
|
let completer = repl_completion::ReplCompleter {
|
|
219
219
|
vm: Rc::clone(&vm),
|
|
220
220
|
no_optimize,
|
|
@@ -246,12 +246,12 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
|
|
|
246
246
|
if buffer.is_empty() {
|
|
247
247
|
break;
|
|
248
248
|
}
|
|
249
|
-
match
|
|
249
|
+
match tishlang_parser::parse(buffer.trim()) {
|
|
250
250
|
Ok(program) => {
|
|
251
251
|
let compile_fn = if no_optimize {
|
|
252
|
-
|
|
252
|
+
tishlang_bytecode::compile_for_repl_unoptimized
|
|
253
253
|
} else {
|
|
254
|
-
|
|
254
|
+
tishlang_bytecode::compile_for_repl
|
|
255
255
|
};
|
|
256
256
|
if let Ok(chunk) = compile_fn(&program) {
|
|
257
257
|
let _ = vm.borrow_mut().run(&chunk);
|
|
@@ -277,19 +277,19 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
|
|
|
277
277
|
buffer.push('\n');
|
|
278
278
|
buffer.push_str(line);
|
|
279
279
|
}
|
|
280
|
-
match
|
|
280
|
+
match tishlang_parser::parse(buffer.trim()) {
|
|
281
281
|
Ok(program) => {
|
|
282
282
|
let compile_fn = if no_optimize {
|
|
283
|
-
|
|
283
|
+
tishlang_bytecode::compile_for_repl_unoptimized
|
|
284
284
|
} else {
|
|
285
|
-
|
|
285
|
+
tishlang_bytecode::compile_for_repl
|
|
286
286
|
};
|
|
287
287
|
match compile_fn(&program) {
|
|
288
288
|
Ok(chunk) => {
|
|
289
289
|
match vm.borrow_mut().run(&chunk) {
|
|
290
290
|
Ok(v) => {
|
|
291
|
-
if !matches!(v,
|
|
292
|
-
println!("{}",
|
|
291
|
+
if !matches!(v, tishlang_core::Value::Null) {
|
|
292
|
+
println!("{}", tishlang_core::format_value_styled(&v, tishlang_core::use_console_colors()));
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
Err(e) => eprintln!("{}", e),
|
|
@@ -319,7 +319,7 @@ fn run_repl(backend: &str, no_optimize: bool) -> Result<(), String> {
|
|
|
319
319
|
|
|
320
320
|
/// REPL prompt with green caret when stdout is a TTY (platform-style).
|
|
321
321
|
fn repl_prompt(primary: bool) -> String {
|
|
322
|
-
if
|
|
322
|
+
if tishlang_core::use_console_colors() {
|
|
323
323
|
if primary {
|
|
324
324
|
"\x1b[32m> \x1b[0m".to_string()
|
|
325
325
|
} else {
|
|
@@ -339,15 +339,15 @@ fn tish_history_path() -> Option<PathBuf> {
|
|
|
339
339
|
home.map(|h| PathBuf::from(h).join(".tish_history"))
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
-
fn parse_jsx_mode(s: &str) -> Result<
|
|
342
|
+
fn parse_jsx_mode(s: &str) -> Result<tishlang_compile_js::JsxMode, String> {
|
|
343
343
|
match s {
|
|
344
344
|
"legacy" => Err(
|
|
345
345
|
"--jsx legacy was removed. Use --jsx lattish (default) with lattish merged into your \
|
|
346
346
|
bundle, or --jsx vdom with Lattish's createRoot."
|
|
347
347
|
.to_string(),
|
|
348
348
|
),
|
|
349
|
-
"vdom" => Ok(
|
|
350
|
-
"lattish" => Ok(
|
|
349
|
+
"vdom" => Ok(tishlang_compile_js::JsxMode::Vdom),
|
|
350
|
+
"lattish" => Ok(tishlang_compile_js::JsxMode::LattishH),
|
|
351
351
|
other => Err(format!(
|
|
352
352
|
"Unknown --jsx {:?}: use lattish (default) or vdom.",
|
|
353
353
|
other
|
|
@@ -375,20 +375,20 @@ fn compile_to_js(
|
|
|
375
375
|
"export fn __TishJsxRoot() {{\n return (\n{}\n )\n}}",
|
|
376
376
|
source.trim()
|
|
377
377
|
);
|
|
378
|
-
let program =
|
|
378
|
+
let program = tishlang_parser::parse(&wrapped)
|
|
379
379
|
.map_err(|e| format!("JSX wrapper parse: {}", e))?;
|
|
380
380
|
let p = if optimize {
|
|
381
|
-
|
|
381
|
+
tishlang_opt::optimize(&program)
|
|
382
382
|
} else {
|
|
383
383
|
program
|
|
384
384
|
};
|
|
385
|
-
|
|
385
|
+
tishlang_compile_js::compile_with_jsx(&p, optimize, jsx_mode).map_err(|e| format!("{}", e))?
|
|
386
386
|
} else if input_path.extension().map(|e| e == "js") == Some(true) {
|
|
387
387
|
let source = fs::read_to_string(input_path).map_err(|e| format!("{}", e))?;
|
|
388
|
-
let program =
|
|
389
|
-
|
|
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))?
|
|
390
390
|
} else {
|
|
391
|
-
|
|
391
|
+
tishlang_compile_js::compile_project_with_jsx(input_path, project_root, optimize, jsx_mode)
|
|
392
392
|
.map_err(|e| format!("{}", e))?
|
|
393
393
|
};
|
|
394
394
|
|
|
@@ -432,8 +432,8 @@ fn compile_file(
|
|
|
432
432
|
|
|
433
433
|
if target == "wasm" && is_js {
|
|
434
434
|
let source = fs::read_to_string(&input_path).map_err(|e| format!("{}", e))?;
|
|
435
|
-
let program =
|
|
436
|
-
return
|
|
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)
|
|
437
437
|
.map_err(|e| format!("{}", e));
|
|
438
438
|
}
|
|
439
439
|
|
|
@@ -445,7 +445,7 @@ fn compile_file(
|
|
|
445
445
|
Some(p)
|
|
446
446
|
}
|
|
447
447
|
});
|
|
448
|
-
return
|
|
448
|
+
return tishlang_wasm::compile_to_wasm(&input_path, project_root, Path::new(output_path), optimize)
|
|
449
449
|
.map_err(|e| e.to_string());
|
|
450
450
|
}
|
|
451
451
|
|
|
@@ -457,7 +457,7 @@ fn compile_file(
|
|
|
457
457
|
Some(p)
|
|
458
458
|
}
|
|
459
459
|
});
|
|
460
|
-
return
|
|
460
|
+
return tishlang_wasm::compile_to_wasi(&input_path, project_root, Path::new(output_path), optimize)
|
|
461
461
|
.map_err(|e| e.to_string());
|
|
462
462
|
}
|
|
463
463
|
|
|
@@ -495,8 +495,8 @@ fn compile_file(
|
|
|
495
495
|
|
|
496
496
|
if is_js {
|
|
497
497
|
let source = fs::read_to_string(&input_path).map_err(|e| format!("{}", e))?;
|
|
498
|
-
let program =
|
|
499
|
-
|
|
498
|
+
let program = tishlang_js_to_tish::convert(&source).map_err(|e| format!("{}", e))?;
|
|
499
|
+
tishlang_native::compile_program_to_native(
|
|
500
500
|
&program,
|
|
501
501
|
project_root,
|
|
502
502
|
Path::new(output_path),
|
|
@@ -506,7 +506,7 @@ fn compile_file(
|
|
|
506
506
|
)
|
|
507
507
|
.map_err(|e| e.to_string())?;
|
|
508
508
|
} else {
|
|
509
|
-
|
|
509
|
+
tishlang_native::compile_to_native(
|
|
510
510
|
&input_path,
|
|
511
511
|
project_root,
|
|
512
512
|
Path::new(output_path),
|
|
@@ -580,7 +580,7 @@ mod cli_tests {
|
|
|
580
580
|
fn dump_ast(path: &str) -> Result<(), String> {
|
|
581
581
|
let source =
|
|
582
582
|
fs::read_to_string(path).map_err(|e| format!("Cannot read {}: {}", path, e))?;
|
|
583
|
-
let program =
|
|
583
|
+
let program = tishlang_parser::parse(&source)?;
|
|
584
584
|
println!("{:#?}", program);
|
|
585
585
|
Ok(())
|
|
586
586
|
}
|
|
@@ -12,9 +12,9 @@ use rustyline::validate::Validator;
|
|
|
12
12
|
use rustyline::Context;
|
|
13
13
|
use rustyline::Helper;
|
|
14
14
|
|
|
15
|
-
use
|
|
16
|
-
use
|
|
17
|
-
use
|
|
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 =
|
|
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 {
|