1pub mod core;
3pub mod lexer;
4pub mod parser;
5pub mod semantic;
6pub mod borrowck;
7pub mod mir;
8pub mod codegen;
9pub mod lexicon;
10pub mod polyglot;
11pub mod gfx;
12pub mod runtime;
13pub mod utils;
14pub mod visualize;
15#[cfg(not(target_arch = "wasm32"))]
16pub mod convert;
17
18#[cfg(not(target_arch = "wasm32"))]
19pub use ling_audio;
20
21pub use core::{LingCompiler, CompilerConfig, OptimizationLevel};
23pub use lexicon::{CanonicalToken, Lexicon, LexiconRegistry};
24pub use polyglot::{normalize_source, ScriptDetector};
25
26pub const VERSION: &str = env!("CARGO_PKG_VERSION");
28
29pub fn run(source: &str) -> Result<(), String> {
32 run_file(source, None)
33}
34
35pub fn unpack_resources(app: &str, resources: &[(&str, &[u8])]) {
42 if resources.is_empty() {
43 return;
44 }
45 let base = std::env::temp_dir().join(format!("ling-pack-{app}"));
46 for (rel, bytes) in resources {
47 let dst = base.join(rel);
48 if let Some(parent) = dst.parent() {
49 let _ = std::fs::create_dir_all(parent);
50 }
51 let _ = std::fs::write(&dst, bytes);
52 }
53 let _ = std::env::set_current_dir(&base);
54}
55
56pub fn run_file(source: &str, source_dir: Option<std::path::PathBuf>) -> Result<(), String> {
58 let program = parser::parse(source)
59 .map_err(|e| format!("parse error: {e}"))?;
60 let mut interp = runtime::Interpreter::new();
61 interp.source_dir = source_dir;
62 interp.run_program(&program)
63 .map_err(|e| format!("runtime error: {e}"))
64}
65
66pub fn detect_language(source: &str) -> &'static str {
68 let languages: &[(&[&str], &str)] = &[
69 (&["令", "灵符", "执", "函", "核", "若", "否则", "历", "于", "配", "归", "印", "格式"], "Chinese (中文)"),
70 (&["束縛", "実行", "もし", "一方", "ために", "試す", "待つ", "帰る"], "Japanese (日本語)"),
71 (&["바인드", "만약", "동안", "출력", "시작"], "Korean (한국어)"),
72 (&["связать", "сделать", "если", "иначе", "пока", "для", "вернуть", "вывести"], "Russian (русский)"),
73 (&["ผูก", "ทำ", "ถ้า", "มิฉะนั้น", "สำหรับ", "คืน", "พิมพ์", "รูปแบบ", "เริ่ม"], "Thai (ภาษาไทย)"),
74 (&["बाँधो", "करो", "अगर", "जबकि", "वापस", "सत्य"], "Hindi (हिन्दी)"),
75 (&["ربط", "افعل", "إذا", "وإلا", "بينما", "أعد"], "Arabic (العربية)"),
76 (&["enlazar", "hacer", "mientras", "retornar", "verdadero"], "Spanish (Español)"),
77 (&["lier", "faire", "sinon", "tantque", "retourner", "vrai"], "French (Français)"),
78 (&["binden", "machen", "wenn", "solange", "zurück", "wahr"], "German (Deutsch)"),
79 (&["ligar", "fazer", "enquanto", "retornar", "verdadeiro"], "Portuguese (Português)"),
80 ];
81
82 let best = languages.iter()
83 .map(|(keywords, lang)| {
84 let count = keywords.iter().filter(|&&k| source.contains(k)).count();
85 (count, *lang)
86 })
87 .max_by_key(|&(count, _)| count);
88
89 match best {
90 Some((count, lang)) if count > 0 => lang,
91 _ => "English",
92 }
93}