1use super::ClosureKind;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
4pub enum KernelForm {
5 Expression(ExpressionForm),
6 Definition(DefinitionForm),
7 Local,
8 Macro,
9}
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
12pub enum ExpressionForm {
13 Fn,
14 Recur,
15 Try,
16 Infer,
17 Leaf(LeafForm),
18 Borrow(ReferenceKind),
19 Deref,
20 Control(ControlForm),
21 Struct(StructForm),
22 Match,
23 Assoc,
24 MapAt,
25 SetAt,
26}
27
28#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
29pub enum LeafForm {
30 Quote,
31 Rust,
32}
33
34#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
35pub enum ControlForm {
36 Do,
37 If,
38}
39
40#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
41pub enum StructForm {
42 New,
43 Field,
44}
45
46#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
47pub enum DefinitionForm {
48 Def,
49 Type,
50 Struct,
51 Enum,
52 Derive,
53 RustTrait,
54 RustType,
55 Trait,
56 Impl,
57 Use,
58 Export,
59}
60
61struct KernelFormRow {
62 form: KernelForm,
63 name: &'static str,
64 shape: &'static str,
65}
66
67impl KernelForm {
68 const ROWS: [KernelFormRow; 30] = [
69 KernelFormRow {
70 form: KernelForm::Expression(ExpressionForm::Fn),
71 name: "fn",
72 shape: "(fn (parameter ...) body ...)",
73 },
74 KernelFormRow {
75 form: KernelForm::Definition(DefinitionForm::Def),
76 name: "def",
77 shape: "(def name value)",
78 },
79 KernelFormRow {
80 form: KernelForm::Local,
81 name: "local",
82 shape: "(local name value)",
83 },
84 KernelFormRow {
85 form: KernelForm::Expression(ExpressionForm::Control(ControlForm::Do)),
86 name: "do",
87 shape: "(do form ...)",
88 },
89 KernelFormRow {
90 form: KernelForm::Expression(ExpressionForm::Control(ControlForm::If)),
91 name: "if",
92 shape: "(if test then else)",
93 },
94 KernelFormRow {
95 form: KernelForm::Definition(DefinitionForm::Type),
96 name: "type",
97 shape: "(type name type)",
98 },
99 KernelFormRow {
100 form: KernelForm::Definition(DefinitionForm::Struct),
101 name: "struct",
102 shape: "(struct (name parameter ...) (field type) ...)",
103 },
104 KernelFormRow {
105 form: KernelForm::Definition(DefinitionForm::Enum),
106 name: "enum",
107 shape: "(enum (name parameter ...) (rust \"Path\")? variant ...)",
108 },
109 KernelFormRow {
110 form: KernelForm::Definition(DefinitionForm::Derive),
111 name: "derive",
112 shape: "(derive type trait ...)",
113 },
114 KernelFormRow {
115 form: KernelForm::Expression(ExpressionForm::Match),
116 name: "match",
117 shape: "(match value (pattern body ...) ...)",
118 },
119 KernelFormRow {
120 form: KernelForm::Expression(ExpressionForm::Assoc),
121 name: "assoc-at",
122 shape: "(assoc-at value (key ...) item)",
123 },
124 KernelFormRow {
125 form: KernelForm::Expression(ExpressionForm::MapAt),
126 name: "map-at",
127 shape: "(map-at operation value argument ...)",
128 },
129 KernelFormRow {
130 form: KernelForm::Expression(ExpressionForm::SetAt),
131 name: "set-at",
132 shape: "(set-at value (key ...) item)",
133 },
134 KernelFormRow {
135 form: KernelForm::Expression(ExpressionForm::Struct(StructForm::New)),
136 name: "new",
137 shape: "(new name (field value) ...) or (new _ base (field value) ...)",
138 },
139 KernelFormRow {
140 form: KernelForm::Expression(ExpressionForm::Struct(StructForm::Field)),
141 name: "field",
142 shape: "(field value name)",
143 },
144 KernelFormRow {
145 form: KernelForm::Expression(ExpressionForm::Borrow(ReferenceKind::Shared)),
146 name: "ref",
147 shape: "(ref value)",
148 },
149 KernelFormRow {
150 form: KernelForm::Expression(ExpressionForm::Borrow(ReferenceKind::Mutable)),
151 name: "mut",
152 shape: "(mut place)",
153 },
154 KernelFormRow {
155 form: KernelForm::Expression(ExpressionForm::Deref),
156 name: "deref",
157 shape: "(deref value)",
158 },
159 KernelFormRow {
160 form: KernelForm::Expression(ExpressionForm::Leaf(LeafForm::Quote)),
161 name: "quote",
162 shape: "(quote form)",
163 },
164 KernelFormRow {
165 form: KernelForm::Macro,
166 name: "macro",
167 shape: "(macro (form) body ...)",
168 },
169 KernelFormRow {
170 form: KernelForm::Expression(ExpressionForm::Leaf(LeafForm::Rust)),
171 name: "rust",
172 shape: "(rust \"template\" type (target \"template\") ...)",
173 },
174 KernelFormRow {
175 form: KernelForm::Definition(DefinitionForm::RustTrait),
176 name: "rust-trait",
177 shape: "(rust-trait name \"Path\" (requires trait ...)? (method name type)? (help \"text\")? type ...)",
178 },
179 KernelFormRow {
180 form: KernelForm::Definition(DefinitionForm::RustType),
181 name: "rust-type",
182 shape: "(rust-type (name parameter ...) \"template\" (type \"template\") ...)",
183 },
184 KernelFormRow {
185 form: KernelForm::Expression(ExpressionForm::Recur),
186 name: "recur",
187 shape: "(recur argument ...)",
188 },
189 KernelFormRow {
190 form: KernelForm::Expression(ExpressionForm::Try),
191 name: "try",
192 shape: "(try expression)",
193 },
194 KernelFormRow {
195 form: KernelForm::Expression(ExpressionForm::Infer),
196 name: "infer",
197 shape: "(infer expression)",
198 },
199 KernelFormRow {
200 form: KernelForm::Definition(DefinitionForm::Trait),
201 name: "trait",
202 shape: "(trait name (method type) ...)",
203 },
204 KernelFormRow {
205 form: KernelForm::Definition(DefinitionForm::Impl),
206 name: "impl",
207 shape: "(impl trait type (method (parameter ...) body ...) ...)",
208 },
209 KernelFormRow {
210 form: KernelForm::Definition(DefinitionForm::Use),
211 name: "use",
212 shape: "(use module name ...)",
213 },
214 KernelFormRow {
215 form: KernelForm::Definition(DefinitionForm::Export),
216 name: "export",
217 shape: "(export name ...)",
218 },
219 ];
220
221 pub fn all() -> impl Iterator<Item = KernelForm> {
222 Self::ROWS.iter().map(|row| row.form)
223 }
224
225 pub fn name(self) -> &'static str {
226 self.row().name
227 }
228
229 pub fn shape(self) -> &'static str {
230 self.row().shape
231 }
232
233 fn row(self) -> &'static KernelFormRow {
234 Self::ROWS
235 .iter()
236 .find(|row| row.form == self)
237 .expect("every kernel form has a row in the kernel form table")
238 }
239}
240
241#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
242pub enum PrimitiveType {
243 Bool,
244 Char,
245 Str,
246 String,
247 Unit,
248 I8,
249 I16,
250 I32,
251 I64,
252 I128,
253 Isize,
254 U8,
255 U16,
256 U32,
257 U64,
258 U128,
259 Usize,
260 F32,
261 F64,
262}
263
264struct PrimitiveRow {
265 primitive: PrimitiveType,
266 name: &'static str,
267 integer_range: Option<(i128, i128)>,
268}
269
270impl PrimitiveType {
271 const ROWS: [PrimitiveRow; 19] = [
272 PrimitiveRow {
273 primitive: PrimitiveType::Bool,
274 name: "bool",
275 integer_range: None,
276 },
277 PrimitiveRow {
278 primitive: PrimitiveType::Char,
279 name: "char",
280 integer_range: None,
281 },
282 PrimitiveRow {
283 primitive: PrimitiveType::Str,
284 name: "str",
285 integer_range: None,
286 },
287 PrimitiveRow {
288 primitive: PrimitiveType::String,
289 name: "string",
290 integer_range: None,
291 },
292 PrimitiveRow {
293 primitive: PrimitiveType::Unit,
294 name: "unit",
295 integer_range: None,
296 },
297 PrimitiveRow {
298 primitive: PrimitiveType::I8,
299 name: "i8",
300 integer_range: Some((i8::MIN as i128, i8::MAX as i128)),
301 },
302 PrimitiveRow {
303 primitive: PrimitiveType::I16,
304 name: "i16",
305 integer_range: Some((i16::MIN as i128, i16::MAX as i128)),
306 },
307 PrimitiveRow {
308 primitive: PrimitiveType::I32,
309 name: "i32",
310 integer_range: Some((i32::MIN as i128, i32::MAX as i128)),
311 },
312 PrimitiveRow {
313 primitive: PrimitiveType::I64,
314 name: "i64",
315 integer_range: Some((i64::MIN as i128, i64::MAX as i128)),
316 },
317 PrimitiveRow {
318 primitive: PrimitiveType::I128,
319 name: "i128",
320 integer_range: Some((i128::MIN, i128::MAX)),
321 },
322 PrimitiveRow {
323 primitive: PrimitiveType::Isize,
324 name: "isize",
325 integer_range: Some((i64::MIN as i128, i64::MAX as i128)),
326 },
327 PrimitiveRow {
328 primitive: PrimitiveType::U8,
329 name: "u8",
330 integer_range: Some((0, u8::MAX as i128)),
331 },
332 PrimitiveRow {
333 primitive: PrimitiveType::U16,
334 name: "u16",
335 integer_range: Some((0, u16::MAX as i128)),
336 },
337 PrimitiveRow {
338 primitive: PrimitiveType::U32,
339 name: "u32",
340 integer_range: Some((0, u32::MAX as i128)),
341 },
342 PrimitiveRow {
343 primitive: PrimitiveType::U64,
344 name: "u64",
345 integer_range: Some((0, u64::MAX as i128)),
346 },
347 PrimitiveRow {
348 primitive: PrimitiveType::U128,
349 name: "u128",
350 integer_range: Some((0, i128::MAX)),
351 },
352 PrimitiveRow {
353 primitive: PrimitiveType::Usize,
354 name: "usize",
355 integer_range: Some((0, u64::MAX as i128)),
356 },
357 PrimitiveRow {
358 primitive: PrimitiveType::F32,
359 name: "f32",
360 integer_range: None,
361 },
362 PrimitiveRow {
363 primitive: PrimitiveType::F64,
364 name: "f64",
365 integer_range: None,
366 },
367 ];
368
369 pub fn all() -> impl Iterator<Item = PrimitiveType> {
370 Self::ROWS.iter().map(|row| row.primitive)
371 }
372
373 pub fn name(self) -> &'static str {
374 self.row().name
375 }
376
377 pub fn integer_range(self) -> Option<(i128, i128)> {
378 self.row().integer_range
379 }
380
381 pub fn is_integer(self) -> bool {
382 self.integer_range().is_some()
383 }
384
385 pub fn is_float(self) -> bool {
386 matches!(self, PrimitiveType::F32 | PrimitiveType::F64)
387 }
388
389 fn row(self) -> &'static PrimitiveRow {
390 Self::ROWS
391 .iter()
392 .find(|row| row.primitive == self)
393 .expect("every primitive type has a row in the primitive table")
394 }
395}
396
397#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
398pub enum KernelType {
399 Function(ClosureKind),
400 Reference(ReferenceKind),
401 Where,
402 With,
403 Hole,
404 Primitive(PrimitiveType),
405}
406
407#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
408pub enum ReferenceKind {
409 Shared,
410 Mutable,
411}
412
413impl ReferenceKind {
414 pub fn keyword(self) -> &'static str {
415 match self {
416 ReferenceKind::Shared => "ref",
417 ReferenceKind::Mutable => "mut",
418 }
419 }
420}
421
422impl KernelType {
423 pub fn all() -> impl Iterator<Item = KernelType> {
424 [
425 KernelType::Function(ClosureKind::Fn),
426 KernelType::Function(ClosureKind::FnMut),
427 KernelType::Function(ClosureKind::FnOnce),
428 KernelType::Reference(ReferenceKind::Shared),
429 KernelType::Reference(ReferenceKind::Mutable),
430 KernelType::Where,
431 KernelType::With,
432 KernelType::Hole,
433 ]
434 .into_iter()
435 .chain(PrimitiveType::all().map(KernelType::Primitive))
436 }
437
438 pub fn shape(self) -> &'static str {
439 match self {
440 KernelType::Function(kind) => kind.shape(),
441 KernelType::Reference(ReferenceKind::Shared) => "(ref type)",
442 KernelType::Reference(ReferenceKind::Mutable) => "(mut type)",
443 KernelType::Where => "(where (variable (variable trait ...) ...) type)",
444 KernelType::With => "(with type type)",
445 KernelType::Hole | KernelType::Primitive(_) => self.name(),
446 }
447 }
448
449 pub fn name(self) -> &'static str {
450 match self {
451 KernelType::Function(kind) => kind.name(),
452 KernelType::Reference(kind) => kind.keyword(),
453 KernelType::Where => "where",
454 KernelType::With => "with",
455 KernelType::Hole => "_",
456 KernelType::Primitive(primitive) => primitive.name(),
457 }
458 }
459}
460
461pub struct KernelConstants;
462
463impl KernelConstants {
464 pub const BOOLEANS: [(&'static str, bool); 2] = [("true", true), ("false", false)];
465}
466
467pub struct CopyTrait;
468
469impl CopyTrait {
470 pub const PATH: &'static str = "Copy";
471}
472
473pub struct OrderTrait;
474
475impl OrderTrait {
476 pub const PATH: &'static str = "Ord";
477}
478
479pub struct FunctionFieldTraits;
480
481impl FunctionFieldTraits {
482 pub const ALLOWED: [&'static str; 3] = ["Clone", "Copy", "Debug"];
483}
484
485pub struct StructDerives;
486
487impl StructDerives {
488 pub const COPY: &'static str = "Copy";
489 pub const INFERRED: [&'static str; 5] = ["Clone", "Copy", "PartialEq", "Eq", "Hash"];
490 pub const DERIVABLE: [&'static str; 8] = [
491 "Clone",
492 "Copy",
493 "Debug",
494 "PartialEq",
495 "Eq",
496 "PartialOrd",
497 "Ord",
498 "Hash",
499 ];
500 const REQUIRED: [(&'static str, &'static str); 5] = [
501 ("Copy", "Clone"),
502 ("Eq", "PartialEq"),
503 ("PartialOrd", "PartialEq"),
504 ("Ord", "Eq"),
505 ("Ord", "PartialOrd"),
506 ];
507
508 pub fn derive_name(path: &str) -> &str {
509 path.rsplit("::").next().unwrap_or(path)
510 }
511
512 pub fn brings(listed: &str, derived: &str) -> bool {
513 listed == derived
514 || Self::REQUIRED
515 .iter()
516 .any(|(requirer, required)| *requirer == listed && Self::brings(required, derived))
517 }
518}