@tishlang/tish 1.0.6 → 1.0.10
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/Cargo.toml +43 -0
- package/LICENSE +13 -0
- package/README.md +66 -0
- package/crates/js_to_tish/Cargo.toml +9 -0
- package/crates/js_to_tish/README.md +18 -0
- package/crates/js_to_tish/src/error.rs +61 -0
- package/crates/js_to_tish/src/lib.rs +11 -0
- package/crates/js_to_tish/src/span_util.rs +35 -0
- package/crates/js_to_tish/src/transform/expr.rs +608 -0
- package/crates/js_to_tish/src/transform/stmt.rs +474 -0
- package/crates/js_to_tish/src/transform.rs +60 -0
- package/crates/tish/Cargo.toml +44 -0
- package/crates/tish/src/main.rs +585 -0
- package/crates/tish/src/repl_completion.rs +200 -0
- package/crates/tish/tests/integration_test.rs +726 -0
- package/crates/tish_ast/Cargo.toml +7 -0
- package/crates/tish_ast/src/ast.rs +494 -0
- package/crates/tish_ast/src/lib.rs +5 -0
- package/crates/tish_build_utils/Cargo.toml +5 -0
- package/crates/tish_build_utils/src/lib.rs +175 -0
- package/crates/tish_builtins/Cargo.toml +12 -0
- package/crates/tish_builtins/src/array.rs +410 -0
- package/crates/tish_builtins/src/globals.rs +197 -0
- package/crates/tish_builtins/src/helpers.rs +38 -0
- package/crates/tish_builtins/src/lib.rs +14 -0
- package/crates/tish_builtins/src/math.rs +80 -0
- package/crates/tish_builtins/src/object.rs +36 -0
- package/crates/tish_builtins/src/string.rs +253 -0
- package/crates/tish_bytecode/Cargo.toml +15 -0
- package/crates/tish_bytecode/src/chunk.rs +97 -0
- package/crates/tish_bytecode/src/compiler.rs +1361 -0
- package/crates/tish_bytecode/src/encoding.rs +100 -0
- package/crates/tish_bytecode/src/lib.rs +19 -0
- package/crates/tish_bytecode/src/opcode.rs +110 -0
- package/crates/tish_bytecode/src/peephole.rs +159 -0
- package/crates/tish_bytecode/src/serialize.rs +163 -0
- package/crates/tish_bytecode/tests/constant_folding.rs +84 -0
- package/crates/tish_bytecode/tests/shortcircuit.rs +49 -0
- package/crates/tish_bytecode/tests/sort_optimization.rs +31 -0
- package/crates/tish_compile/Cargo.toml +21 -0
- package/crates/tish_compile/src/codegen.rs +3316 -0
- package/crates/tish_compile/src/lib.rs +71 -0
- package/crates/tish_compile/src/resolve.rs +631 -0
- package/crates/tish_compile/src/types.rs +304 -0
- package/crates/tish_compile_js/Cargo.toml +16 -0
- package/crates/tish_compile_js/examples/jsx_vdom_smoke.tish +8 -0
- package/crates/tish_compile_js/src/codegen.rs +794 -0
- package/crates/tish_compile_js/src/error.rs +20 -0
- package/crates/tish_compile_js/src/js_intrinsics.rs +82 -0
- package/crates/tish_compile_js/src/lib.rs +27 -0
- package/crates/tish_compile_js/src/tests_jsx.rs +32 -0
- package/crates/tish_compiler_wasm/Cargo.toml +19 -0
- package/crates/tish_compiler_wasm/src/lib.rs +55 -0
- package/crates/tish_compiler_wasm/src/resolve_virtual.rs +462 -0
- package/crates/tish_core/Cargo.toml +11 -0
- package/crates/tish_core/src/console_style.rs +128 -0
- package/crates/tish_core/src/json.rs +327 -0
- package/crates/tish_core/src/lib.rs +15 -0
- package/crates/tish_core/src/macros.rs +37 -0
- package/crates/tish_core/src/uri.rs +115 -0
- package/crates/tish_core/src/value.rs +376 -0
- package/crates/tish_cranelift/Cargo.toml +17 -0
- package/crates/tish_cranelift/src/lib.rs +41 -0
- package/crates/tish_cranelift/src/link.rs +120 -0
- package/crates/tish_cranelift/src/lower.rs +77 -0
- package/crates/tish_cranelift_runtime/Cargo.toml +19 -0
- package/crates/tish_cranelift_runtime/src/lib.rs +43 -0
- package/crates/tish_eval/Cargo.toml +26 -0
- package/crates/tish_eval/src/eval.rs +3205 -0
- package/crates/tish_eval/src/http.rs +122 -0
- package/crates/tish_eval/src/lib.rs +59 -0
- package/crates/tish_eval/src/natives.rs +301 -0
- package/crates/tish_eval/src/promise.rs +173 -0
- package/crates/tish_eval/src/regex.rs +298 -0
- package/crates/tish_eval/src/timers.rs +111 -0
- package/crates/tish_eval/src/value.rs +224 -0
- package/crates/tish_eval/src/value_convert.rs +85 -0
- package/crates/tish_fmt/Cargo.toml +16 -0
- package/crates/tish_fmt/src/bin/tish-fmt.rs +41 -0
- package/crates/tish_fmt/src/lib.rs +884 -0
- package/crates/tish_jsx_web/Cargo.toml +7 -0
- package/crates/tish_jsx_web/README.md +18 -0
- package/crates/tish_jsx_web/src/lib.rs +157 -0
- package/crates/tish_jsx_web/vendor/Lattish.tish +347 -0
- package/crates/tish_lexer/Cargo.toml +7 -0
- package/crates/tish_lexer/src/lib.rs +430 -0
- package/crates/tish_lexer/src/token.rs +155 -0
- package/crates/tish_lint/Cargo.toml +17 -0
- package/crates/tish_lint/src/bin/tish-lint.rs +77 -0
- package/crates/tish_lint/src/lib.rs +278 -0
- package/crates/tish_llvm/Cargo.toml +11 -0
- package/crates/tish_llvm/src/lib.rs +106 -0
- package/crates/tish_lsp/Cargo.toml +22 -0
- package/crates/tish_lsp/README.md +26 -0
- package/crates/tish_lsp/src/main.rs +615 -0
- package/crates/tish_native/Cargo.toml +14 -0
- package/crates/tish_native/src/build.rs +102 -0
- package/crates/tish_native/src/lib.rs +237 -0
- package/crates/tish_opt/Cargo.toml +11 -0
- package/crates/tish_opt/src/lib.rs +896 -0
- package/crates/tish_parser/Cargo.toml +9 -0
- package/crates/tish_parser/src/lib.rs +123 -0
- package/crates/tish_parser/src/parser.rs +1714 -0
- package/crates/tish_runtime/Cargo.toml +26 -0
- package/crates/tish_runtime/src/http.rs +308 -0
- package/crates/tish_runtime/src/http_fetch.rs +453 -0
- package/crates/tish_runtime/src/lib.rs +1004 -0
- package/crates/tish_runtime/src/native_promise.rs +26 -0
- package/crates/tish_runtime/src/promise.rs +77 -0
- package/crates/tish_runtime/src/promise_io.rs +41 -0
- package/crates/tish_runtime/src/timers.rs +125 -0
- package/crates/tish_runtime/src/ws.rs +725 -0
- package/crates/tish_runtime/tests/fetch_readable_stream.rs +99 -0
- package/crates/tish_vm/Cargo.toml +31 -0
- package/crates/tish_vm/src/lib.rs +39 -0
- package/crates/tish_vm/src/vm.rs +1399 -0
- package/crates/tish_wasm/Cargo.toml +13 -0
- package/crates/tish_wasm/src/lib.rs +358 -0
- package/crates/tish_wasm_runtime/Cargo.toml +25 -0
- package/crates/tish_wasm_runtime/src/lib.rs +36 -0
- package/justfile +260 -0
- package/package.json +8 -3
- 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
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
//! Build native binary via cargo (interim path until Cranelift backend is ready).
|
|
2
|
+
|
|
3
|
+
use std::fs;
|
|
4
|
+
use std::path::Path;
|
|
5
|
+
|
|
6
|
+
use tish_compile::ResolvedNativeModule;
|
|
7
|
+
|
|
8
|
+
pub fn build_via_cargo(
|
|
9
|
+
rust_code: &str,
|
|
10
|
+
native_modules: Vec<ResolvedNativeModule>,
|
|
11
|
+
output_path: &Path,
|
|
12
|
+
features: &[String],
|
|
13
|
+
) -> Result<(), String> {
|
|
14
|
+
let out_name = output_path
|
|
15
|
+
.file_stem()
|
|
16
|
+
.and_then(|s| s.to_str())
|
|
17
|
+
.unwrap_or("tish_out");
|
|
18
|
+
let build_dir = tish_build_utils::create_build_dir("tish_build", out_name)?;
|
|
19
|
+
|
|
20
|
+
let runtime_path = tish_build_utils::find_runtime_path()?;
|
|
21
|
+
|
|
22
|
+
let runtime_features: Vec<&str> = features
|
|
23
|
+
.iter()
|
|
24
|
+
.filter(|f| ["http", "fs", "process", "regex", "ws"].contains(&f.as_str()))
|
|
25
|
+
.map(String::as_str)
|
|
26
|
+
.collect();
|
|
27
|
+
let features_str = if runtime_features.is_empty() {
|
|
28
|
+
String::new()
|
|
29
|
+
} else {
|
|
30
|
+
format!(", features = {:?}", runtime_features)
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
let needs_tokio = rust_code.contains("#[tokio::main]");
|
|
34
|
+
let tokio_dep = if needs_tokio {
|
|
35
|
+
"\ntokio = { version = \"1\", features = [\"rt-multi-thread\", \"macros\"] }\n"
|
|
36
|
+
} else {
|
|
37
|
+
""
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
let native_deps: String = native_modules
|
|
41
|
+
.iter()
|
|
42
|
+
.map(|m| {
|
|
43
|
+
let path = m.crate_path.display().to_string().replace('\\', "/");
|
|
44
|
+
format!("{} = {{ path = {:?} }}\n", m.package_name, path)
|
|
45
|
+
})
|
|
46
|
+
.collect();
|
|
47
|
+
|
|
48
|
+
let cargo_toml = format!(
|
|
49
|
+
r#"[package]
|
|
50
|
+
name = "tish_output"
|
|
51
|
+
version = "0.1.0"
|
|
52
|
+
edition = "2021"
|
|
53
|
+
|
|
54
|
+
[[bin]]
|
|
55
|
+
name = "{}"
|
|
56
|
+
path = "src/main.rs"
|
|
57
|
+
|
|
58
|
+
[profile.release]
|
|
59
|
+
# Reduce binary size: strip symbols, abort on panic (no unwinding), single codegen unit
|
|
60
|
+
strip = true
|
|
61
|
+
panic = "abort"
|
|
62
|
+
codegen-units = 1
|
|
63
|
+
lto = "thin"
|
|
64
|
+
|
|
65
|
+
[dependencies]
|
|
66
|
+
tish_runtime = {{ path = {:?}{} }}{}{}
|
|
67
|
+
"#,
|
|
68
|
+
out_name,
|
|
69
|
+
runtime_path,
|
|
70
|
+
features_str,
|
|
71
|
+
tokio_dep,
|
|
72
|
+
if native_deps.is_empty() {
|
|
73
|
+
String::new()
|
|
74
|
+
} else {
|
|
75
|
+
format!("\n{}", native_deps)
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
fs::write(build_dir.join("Cargo.toml"), cargo_toml)
|
|
80
|
+
.map_err(|e| format!("Cannot write Cargo.toml: {}", e))?;
|
|
81
|
+
fs::write(build_dir.join("src/main.rs"), rust_code)
|
|
82
|
+
.map_err(|e| format!("Cannot write main.rs: {}", e))?;
|
|
83
|
+
|
|
84
|
+
let workspace_target = Path::new(&runtime_path)
|
|
85
|
+
.parent()
|
|
86
|
+
.and_then(|p| p.parent())
|
|
87
|
+
.map(|ws| ws.join("target"));
|
|
88
|
+
let target_dir = workspace_target.filter(|p| p.exists());
|
|
89
|
+
let binary_dir = target_dir
|
|
90
|
+
.as_ref()
|
|
91
|
+
.map(|t| t.join("release"))
|
|
92
|
+
.unwrap_or_else(|| build_dir.join("target").join("release"));
|
|
93
|
+
|
|
94
|
+
tish_build_utils::run_cargo_build(&build_dir, target_dir.as_deref())?;
|
|
95
|
+
|
|
96
|
+
let binary = tish_build_utils::find_release_binary(&binary_dir, out_name)?;
|
|
97
|
+
let target = tish_build_utils::resolve_output_path(output_path, out_name);
|
|
98
|
+
tish_build_utils::copy_binary_to_output(&binary, &target)?;
|
|
99
|
+
|
|
100
|
+
Ok(())
|
|
101
|
+
}
|
|
102
|
+
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
//! Native code generation backend for Tish.
|
|
2
|
+
//!
|
|
3
|
+
//! Target architecture (per plan):
|
|
4
|
+
//! - Phase 2: Bytecode -> Cranelift IR -> .o -> link with minimal runtime
|
|
5
|
+
//! - Current: Delegates to tish_compile (Rust codegen) + cargo build as interim path
|
|
6
|
+
//!
|
|
7
|
+
//! Once Cranelift backend is implemented, this crate will:
|
|
8
|
+
//! 1. Take Chunk (bytecode) as input
|
|
9
|
+
//! 2. Lower to Cranelift IR
|
|
10
|
+
//! 3. Emit .o via cranelift-object
|
|
11
|
+
//! 4. Link against prebuilt tish_runtime staticlib
|
|
12
|
+
|
|
13
|
+
mod build;
|
|
14
|
+
|
|
15
|
+
use std::path::Path;
|
|
16
|
+
use tish_ast::Program;
|
|
17
|
+
|
|
18
|
+
/// Error from native compilation.
|
|
19
|
+
#[derive(Debug)]
|
|
20
|
+
pub struct NativeError {
|
|
21
|
+
pub message: String,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
impl std::fmt::Display for NativeError {
|
|
25
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
26
|
+
write!(f, "{}", self.message)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
impl std::error::Error for NativeError {}
|
|
31
|
+
|
|
32
|
+
/// Compile a Tish project to a native binary.
|
|
33
|
+
///
|
|
34
|
+
/// - `native_backend == "rust"`: Full Rust codegen + cargo build (supports native imports).
|
|
35
|
+
/// - `native_backend == "cranelift"`: Bytecode -> Cranelift -> native (pure Tish only).
|
|
36
|
+
/// - `native_backend == "llvm"`: Experimental LLVM backend (not implemented yet).
|
|
37
|
+
pub fn compile_to_native(
|
|
38
|
+
entry_path: &Path,
|
|
39
|
+
project_root: Option<&Path>,
|
|
40
|
+
output_path: &Path,
|
|
41
|
+
features: &[String],
|
|
42
|
+
native_backend: &str,
|
|
43
|
+
optimize: bool,
|
|
44
|
+
) -> Result<(), NativeError> {
|
|
45
|
+
let backend = match native_backend {
|
|
46
|
+
"rust" => Backend::Rust,
|
|
47
|
+
"cranelift" => Backend::Cranelift,
|
|
48
|
+
"llvm" => Backend::Llvm,
|
|
49
|
+
_ => {
|
|
50
|
+
return Err(NativeError {
|
|
51
|
+
message: format!(
|
|
52
|
+
"Invalid native backend '{}'. Use 'rust', 'cranelift', or 'llvm'.",
|
|
53
|
+
native_backend
|
|
54
|
+
),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
match backend {
|
|
60
|
+
Backend::Rust => {
|
|
61
|
+
let (rust_code, native_modules) = tish_compile::compile_project_full(
|
|
62
|
+
entry_path,
|
|
63
|
+
project_root,
|
|
64
|
+
features,
|
|
65
|
+
optimize,
|
|
66
|
+
)
|
|
67
|
+
.map_err(|e| NativeError {
|
|
68
|
+
message: e.to_string(),
|
|
69
|
+
})?;
|
|
70
|
+
|
|
71
|
+
crate::build::build_via_cargo(&rust_code, native_modules, output_path, features)
|
|
72
|
+
.map_err(|e| NativeError { message: e })
|
|
73
|
+
}
|
|
74
|
+
Backend::Cranelift => {
|
|
75
|
+
let modules = tish_compile::resolve_project(entry_path, project_root)
|
|
76
|
+
.map_err(|e| NativeError {
|
|
77
|
+
message: e.to_string(),
|
|
78
|
+
})?;
|
|
79
|
+
tish_compile::detect_cycles(&modules).map_err(|e| NativeError {
|
|
80
|
+
message: e.to_string(),
|
|
81
|
+
})?;
|
|
82
|
+
let program = {
|
|
83
|
+
let prog = tish_compile::merge_modules(modules).map_err(|e| NativeError {
|
|
84
|
+
message: e.to_string(),
|
|
85
|
+
})?;
|
|
86
|
+
if optimize {
|
|
87
|
+
tish_opt::optimize(&prog)
|
|
88
|
+
} else {
|
|
89
|
+
prog
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
if tish_compile::has_external_native_imports(&program) {
|
|
94
|
+
return Err(NativeError {
|
|
95
|
+
message: "Cranelift backend does not support external native imports (tish:egui, @scope/pkg). Built-in tish:fs, tish:http, tish:process are supported. Use --native-backend rust for external modules.".to_string(),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let chunk = if optimize {
|
|
100
|
+
tish_bytecode::compile(&program).map_err(|e| NativeError {
|
|
101
|
+
message: e.to_string(),
|
|
102
|
+
})?
|
|
103
|
+
} else {
|
|
104
|
+
tish_bytecode::compile_unoptimized(&program).map_err(|e| NativeError {
|
|
105
|
+
message: e.to_string(),
|
|
106
|
+
})?
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
let cranelift_features = tish_compile::extract_native_import_features(&program);
|
|
110
|
+
tish_cranelift::compile_chunk_to_native(&chunk, output_path, &cranelift_features)
|
|
111
|
+
.map_err(|e| NativeError {
|
|
112
|
+
message: e.to_string(),
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
Backend::Llvm => {
|
|
116
|
+
let modules = tish_compile::resolve_project(entry_path, project_root)
|
|
117
|
+
.map_err(|e| NativeError { message: e.to_string() })?;
|
|
118
|
+
tish_compile::detect_cycles(&modules).map_err(|e| NativeError { message: e.to_string() })?;
|
|
119
|
+
let program = {
|
|
120
|
+
let prog = tish_compile::merge_modules(modules).map_err(|e| NativeError {
|
|
121
|
+
message: e.to_string(),
|
|
122
|
+
})?;
|
|
123
|
+
if optimize {
|
|
124
|
+
tish_opt::optimize(&prog)
|
|
125
|
+
} else {
|
|
126
|
+
prog
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
if tish_compile::has_external_native_imports(&program) {
|
|
130
|
+
return Err(NativeError {
|
|
131
|
+
message: "LLVM backend does not support external native imports. Built-in tish:fs, tish:http, tish:process are supported.".to_string(),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
let chunk = if optimize {
|
|
135
|
+
tish_bytecode::compile(&program).map_err(|e| NativeError {
|
|
136
|
+
message: e.to_string(),
|
|
137
|
+
})?
|
|
138
|
+
} else {
|
|
139
|
+
tish_bytecode::compile_unoptimized(&program).map_err(|e| NativeError {
|
|
140
|
+
message: e.to_string(),
|
|
141
|
+
})?
|
|
142
|
+
};
|
|
143
|
+
let llvm_features = tish_compile::extract_native_import_features(&program);
|
|
144
|
+
tish_llvm::compile_chunk_to_native(&chunk, output_path, &llvm_features)
|
|
145
|
+
.map_err(|e| NativeError { message: e.message })
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/// Compile a single Program (e.g. from js_to_tish) to native.
|
|
151
|
+
pub fn compile_program_to_native(
|
|
152
|
+
program: &Program,
|
|
153
|
+
project_root: Option<&Path>,
|
|
154
|
+
output_path: &Path,
|
|
155
|
+
features: &[String],
|
|
156
|
+
native_backend: &str,
|
|
157
|
+
optimize: bool,
|
|
158
|
+
) -> Result<(), NativeError> {
|
|
159
|
+
let backend = match native_backend {
|
|
160
|
+
"rust" => Backend::Rust,
|
|
161
|
+
"cranelift" => Backend::Cranelift,
|
|
162
|
+
"llvm" => Backend::Llvm,
|
|
163
|
+
_ => {
|
|
164
|
+
return Err(NativeError {
|
|
165
|
+
message: format!(
|
|
166
|
+
"Invalid native backend '{}'. Use 'rust', 'cranelift', or 'llvm'.",
|
|
167
|
+
native_backend
|
|
168
|
+
),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
match backend {
|
|
174
|
+
Backend::Rust => {
|
|
175
|
+
let program = if optimize { tish_opt::optimize(program) } else { program.clone() };
|
|
176
|
+
let root = project_root.unwrap_or_else(|| Path::new("."));
|
|
177
|
+
let native_modules = tish_compile::resolve_native_modules(&program, root)
|
|
178
|
+
.map_err(|e| NativeError { message: e })?;
|
|
179
|
+
let mut all_features = features.to_vec();
|
|
180
|
+
for f in tish_compile::extract_native_import_features(&program) {
|
|
181
|
+
if !all_features.contains(&f) {
|
|
182
|
+
all_features.push(f);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
let rust_code = tish_compile::compile_with_native_modules(
|
|
186
|
+
&program,
|
|
187
|
+
project_root,
|
|
188
|
+
&all_features,
|
|
189
|
+
&native_modules,
|
|
190
|
+
optimize,
|
|
191
|
+
)
|
|
192
|
+
.map_err(|e| NativeError {
|
|
193
|
+
message: e.message,
|
|
194
|
+
})?;
|
|
195
|
+
crate::build::build_via_cargo(&rust_code, native_modules, output_path, &all_features)
|
|
196
|
+
.map_err(|e| NativeError { message: e })
|
|
197
|
+
}
|
|
198
|
+
Backend::Cranelift => {
|
|
199
|
+
if tish_compile::has_external_native_imports(program) {
|
|
200
|
+
return Err(NativeError {
|
|
201
|
+
message: "Cranelift backend does not support external native imports. Built-in tish:fs, tish:http, tish:process are supported.".to_string(),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
let program = if optimize { tish_opt::optimize(program) } else { program.clone() };
|
|
205
|
+
let chunk = if optimize {
|
|
206
|
+
tish_bytecode::compile(&program).map_err(|e| NativeError { message: e.to_string() })?
|
|
207
|
+
} else {
|
|
208
|
+
tish_bytecode::compile_unoptimized(&program).map_err(|e| NativeError { message: e.to_string() })?
|
|
209
|
+
};
|
|
210
|
+
let cranelift_features = tish_compile::extract_native_import_features(&program);
|
|
211
|
+
tish_cranelift::compile_chunk_to_native(&chunk, output_path, &cranelift_features)
|
|
212
|
+
.map_err(|e| NativeError { message: e.to_string() })
|
|
213
|
+
}
|
|
214
|
+
Backend::Llvm => {
|
|
215
|
+
if tish_compile::has_external_native_imports(program) {
|
|
216
|
+
return Err(NativeError {
|
|
217
|
+
message: "LLVM backend does not support external native imports.".to_string(),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
let program = if optimize { tish_opt::optimize(program) } else { program.clone() };
|
|
221
|
+
let chunk = if optimize {
|
|
222
|
+
tish_bytecode::compile(&program).map_err(|e| NativeError { message: e.to_string() })?
|
|
223
|
+
} else {
|
|
224
|
+
tish_bytecode::compile_unoptimized(&program).map_err(|e| NativeError { message: e.to_string() })?
|
|
225
|
+
};
|
|
226
|
+
let llvm_features = tish_compile::extract_native_import_features(&program);
|
|
227
|
+
tish_llvm::compile_chunk_to_native(&chunk, output_path, &llvm_features)
|
|
228
|
+
.map_err(|e| NativeError { message: e.message })
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
enum Backend {
|
|
234
|
+
Rust,
|
|
235
|
+
Cranelift,
|
|
236
|
+
Llvm,
|
|
237
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "tish_opt"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
description = "AST optimization pass for Tish (constant folding, short-circuit, etc.)"
|
|
6
|
+
|
|
7
|
+
[dependencies]
|
|
8
|
+
tish_ast = { path = "../tish_ast" }
|
|
9
|
+
|
|
10
|
+
[dev-dependencies]
|
|
11
|
+
tish_parser = { path = "../tish_parser" }
|