1#![feature(fn_traits)]
2#![feature(trait_alias)]
3#![feature(concat_idents)]
4#![feature(macro_metavar_expr)]
5#![feature(get_mut_unchecked)]
6#![feature(impl_trait_in_bindings)]
7#![feature(unboxed_closures)]
8
9use std::{collections::HashMap, process, sync::Arc, time::Instant};
10
11pub use paste::paste;
12
13#[macro_use]
14pub mod macros;
15
16pub mod runtime;
17pub use runtime::RuntimeValue;
18
19#[cfg(feature = "parser")]
20pub mod parser;
21
22#[cfg(feature = "phf")]
23pub use phf;
24
25mod parallel_ipreter;
26
27pub use tokio;
28
29#[macro_use]
30pub mod package;
31pub mod types;
32pub mod val;
33
34pub(crate) use package::*;
35use tokio::runtime::{Builder, Runtime};
36use types::ExtendsInternal;
37pub use types::{Extends, Heap, LanguagePackages, MethodRes, PrototypeDocs};
38pub use val::*;
39
40pub use lealang_chalk_rs::Chalk;
41
42pub static VERSION_INT: u16 = 10;
43
44pub trait Package: Sync {
45 fn name(&self) -> &'static [u8];
46
47 fn doc(&self) -> HashMap<&'static str, &'static [&'static str; 3]> {
48 HashMap::new()
49 }
50
51 fn prototype_docs(&self) -> PrototypeDocs {
52 PrototypeDocs::default()
53 }
54
55 fn prototype(&self) -> Extends {
56 Extends::default()
57 }
58
59 fn methods(&self) -> MethodRes {
60 &[]
61 }
62}
63
64pub struct RespPackage {
65 pub methods: MethodRes,
66 pub extends: Option<Extends>,
67}
68
69pub struct Application<'a> {
70 code: Arc<Structure>,
71 pub(crate) pkg: LanguagePackages<'a>,
72 pkg_resolver: Box<dyn FnMut(&str, bool) -> Vec<RespPackage>>,
74 log_info: Box<dyn FnMut(&str) -> ()>,
76}
77
78unsafe impl Send for Application<'_> {}
79unsafe impl Sync for Application<'_> {}
80
81pub type Args = &'static [&'static str];
82
83pub type ModuleArgs = &'static [&'static str];
84
85pub type StaticLeadModule = Arc<HashMap<&'static str, (ModuleArgs, &'static [Args])>>;
86
87#[derive(Debug)]
88pub enum LeadCode {
89 LeadModule(StaticLeadModule),
91 Code(&'static [Args]),
93}
94
95pub type Structure = HashMap<
96 &'static str,
98 LeadCode,
100>;
101
102impl<'a> Application<'a> {
103 pub fn new<
104 T: FnOnce() -> Structure,
105 F: FnMut(&str, bool) -> Vec<RespPackage> + 'static,
106 R: FnMut(&str) -> () + 'static,
107 >(
108 dll_resolver: F,
109 requested_perm: R,
110 structure: T,
111 ) -> Self {
112 let code = Arc::new(structure());
113
114 Self {
115 code,
116 pkg: LanguagePackages::new(),
117 pkg_resolver: Box::new(dll_resolver),
118 log_info: Box::new(requested_perm),
119 }
120 }
121
122 pub fn add_pkg<T: Package + 'static>(&mut self, package: T) -> &mut Self {
123 self.pkg.import(package);
124 self
125 }
126
127 pub fn add_pkg_static(&mut self, package: &'static dyn Package) -> &mut Self {
128 self.pkg.import_static(package);
129 self
130 }
131
132 pub fn add_pkg_box(&mut self, package: Box<dyn Package>) -> &mut Self {
133 self.pkg.import_dyn(package);
134 self
135 }
136
137 pub fn add_pkg_raw(&mut self, name: &'static [u8], methods: MethodRes) -> &mut Self {
138 let pkg = ImplPackage { name, methods };
139
140 self.pkg.import(pkg);
141
142 self
143 }
144
145 pub fn list_cmds(&mut self) -> &mut Self {
146 let mut chalk = Chalk::new();
147 chalk.red().bold();
148 chalk.println(&"The Lead Programming Language");
149
150 chalk.reset_weight().yellow().println(&"Interpreter");
151
152 self.pkg.list(&mut chalk);
153 self
154 }
155
156 pub fn run_non(mut self, runtime: Runtime) {
158 parallel_ipreter::schedule(runtime, &mut self)
159 }
160
161 pub fn run(self, time: bool) -> ! {
162 if time {
163 println!("⚒️ Building execution Runtime...");
164 }
165
166 let inst = Instant::now();
168
169 let runtime = Builder::new_multi_thread()
170 .enable_all()
171 .build()
172 .expect("Unable to build async runtime");
173
174 let dur = inst.elapsed();
175
176 if time {
177 println!("✅ Runtime Ready in {:?}", dur);
178 println!("⚒️ Executing...");
179 }
180
181 let inst = Instant::now();
183
184 self.run_non(runtime);
185
186 let dur = inst.elapsed();
187
188 if time {
189 println!("✅ Runtime Time Elasped: {:?}", dur);
190 }
191
192 process::exit(0)
193 }
194}