swamp_core/
lib.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5pub mod text;
6
7use swamp_modules::prelude::{Module, SymbolTable};
8use swamp_modules::symtbl::AliasType;
9use swamp_semantic::prelude::{IntrinsicFunction, IntrinsicFunctionDefinition};
10use swamp_types::prelude::{Signature, TypeCache, TypeForParameter};
11use tiny_ver::TinyVersion;
12
13pub const PACKAGE_NAME: &str = "core";
14fn add_intrinsic_types(core_ns: &mut SymbolTable, cache: &mut TypeCache) {
15    let byte_alias = AliasType {
16        name: None,
17        assigned_name: "Byte".to_string(),
18        ty: cache.byte(),
19    };
20    core_ns.add_alias(byte_alias).unwrap();
21
22    let char_alias = AliasType {
23        name: None,
24        assigned_name: "Char".to_string(),
25        ty: cache.codepoint(),
26    };
27    core_ns.add_alias(char_alias).unwrap();
28
29    let int_alias = AliasType {
30        name: None,
31        assigned_name: "Int".to_string(),
32        ty: cache.int(),
33    };
34    core_ns.add_alias(int_alias).unwrap();
35
36    let float_alias = AliasType {
37        name: None,
38        assigned_name: "Float".to_string(),
39        ty: cache.float(),
40    };
41    core_ns.add_alias(float_alias).unwrap();
42
43    let string_alias = AliasType {
44        name: None,
45        assigned_name: "String".to_string(),
46        ty: cache.string(),
47    };
48    core_ns.add_alias(string_alias).unwrap();
49
50    let bool_alias = AliasType {
51        name: None,
52        assigned_name: "Bool".to_string(),
53        ty: cache.bool(),
54    };
55    core_ns.add_alias(bool_alias).unwrap();
56}
57
58#[allow(clippy::too_many_lines)]
59fn add_intrinsic_functions(core_ns: &mut SymbolTable, type_cache: &mut TypeCache) {
60    add_intrinsic_byte_functions(core_ns, type_cache);
61    add_intrinsic_char_functions(core_ns, type_cache);
62    add_intrinsic_bool_functions(core_ns, type_cache);
63    add_intrinsic_float_functions(core_ns, type_cache);
64    add_intrinsic_int_functions(core_ns, type_cache);
65    add_intrinsic_string_functions(core_ns, type_cache);
66    add_intrinsic_debug_functions(core_ns, type_cache);
67    // These are generated (generic)
68    //add_intrinsic_grid_functions(core_ns);
69    //add_intrinsic_vec_functions(core_ns);
70    //add_intrinsic_map_functions(core_ns);
71    //add_intrinsic_map2_functions(core_ns);
72    //add_intrinsic_sparse_functions(core_ns);
73}
74
75fn add_intrinsic_debug_functions(core_ns: &mut SymbolTable, type_cache: &mut TypeCache) {
76    let string_type = type_cache.string();
77    let unit_type = type_cache.unit();
78
79    let string_unit = Signature {
80        parameters: [TypeForParameter {
81            name: "v".to_string(),
82            resolved_type: string_type,
83            is_mutable: false,
84            node: None,
85        }]
86            .into(),
87        return_type: unit_type.clone(),
88    };
89    let string_unit_functions = [IntrinsicFunction::RuntimePanic];
90    for intrinsic_fn in string_unit_functions {
91        let name = intrinsic_fn.to_string();
92        core_ns
93            .add_intrinsic_function(IntrinsicFunctionDefinition {
94                name,
95                intrinsic: intrinsic_fn,
96                signature: string_unit.clone(),
97            })
98            .unwrap();
99    }
100
101    let nothing_unit = Signature {
102        parameters: [].into(),
103        return_type: unit_type,
104    };
105    let nothing_unit_functions = [
106        IntrinsicFunction::RuntimeHalt,
107        IntrinsicFunction::RuntimeStep,
108    ];
109    for intrinsic_fn in nothing_unit_functions {
110        let name = intrinsic_fn.to_string();
111        core_ns
112            .add_intrinsic_function(IntrinsicFunctionDefinition {
113                name,
114                intrinsic: intrinsic_fn,
115                signature: nothing_unit.clone(),
116            })
117            .unwrap();
118    }
119}
120
121#[allow(clippy::too_many_lines)]
122fn add_intrinsic_string_functions(core_ns: &mut SymbolTable, type_cache: &mut TypeCache) {
123    let string_type = type_cache.string();
124    let int_type = type_cache.int();
125
126    let string_to_int = Signature {
127        parameters: [TypeForParameter {
128            name: "self".into(),
129            resolved_type: string_type.clone(),
130            is_mutable: false,
131            node: None,
132        }]
133            .into(),
134        return_type: int_type,
135    };
136
137    let string_to_int_functions = [IntrinsicFunction::StringLen];
138
139    for intrinsic_fn in string_to_int_functions {
140        let name = intrinsic_fn.to_string();
141        core_ns
142            .add_intrinsic_function(IntrinsicFunctionDefinition {
143                name,
144                intrinsic: intrinsic_fn,
145                signature: string_to_int.clone(),
146            })
147            .unwrap();
148    }
149
150    let string_to_string = Signature {
151        parameters: [TypeForParameter {
152            name: "self".into(),
153            resolved_type: string_type.clone(),
154            is_mutable: false,
155            node: None,
156        }]
157            .into(),
158        return_type: string_type,
159    };
160
161    let string_to_string_functions = [IntrinsicFunction::StringToString];
162
163    for intrinsic_fn in string_to_string_functions {
164        let name = intrinsic_fn.to_string();
165        core_ns
166            .add_intrinsic_function(IntrinsicFunctionDefinition {
167                name,
168                intrinsic: intrinsic_fn,
169                signature: string_to_string.clone(),
170            })
171            .unwrap();
172    }
173}
174
175fn add_intrinsic_bool_functions(core_ns: &mut SymbolTable, type_cache: &mut TypeCache) {
176    let string_type = type_cache.string();
177    let bool_type = type_cache.bool();
178
179    let self_to_string = Signature {
180        parameters: [TypeForParameter {
181            name: "self".into(),
182            resolved_type: bool_type,
183            is_mutable: false,
184            node: None,
185        }]
186            .into(),
187        return_type: string_type,
188    };
189    let self_to_string_functions = [IntrinsicFunction::BoolToString];
190    for intrinsic_fn in self_to_string_functions {
191        let name = intrinsic_fn.to_string();
192        core_ns
193            .add_intrinsic_function(IntrinsicFunctionDefinition {
194                name,
195                intrinsic: intrinsic_fn,
196                signature: self_to_string.clone(),
197            })
198            .unwrap();
199    }
200}
201
202fn add_intrinsic_byte_functions(core_ns: &mut SymbolTable, type_cache: &mut TypeCache) {
203    let string_type = type_cache.string();
204    let byte_type = type_cache.byte();
205
206    let self_to_string = Signature {
207        parameters: [TypeForParameter {
208            name: "self".into(),
209            resolved_type: byte_type,
210            is_mutable: false,
211            node: None,
212        }]
213            .into(),
214        return_type: string_type,
215    };
216    let self_to_string_functions = [IntrinsicFunction::ByteToString];
217    for intrinsic_fn in self_to_string_functions {
218        let name = intrinsic_fn.to_string();
219        core_ns
220            .add_intrinsic_function(IntrinsicFunctionDefinition {
221                name,
222                intrinsic: intrinsic_fn,
223                signature: self_to_string.clone(),
224            })
225            .unwrap();
226    }
227}
228
229fn add_intrinsic_char_functions(core_ns: &mut SymbolTable, type_cache: &mut TypeCache) {
230    let string_type = type_cache.string();
231    let char_type = type_cache.codepoint();
232    let int_type = type_cache.int();
233
234    let self_to_string = Signature {
235        parameters: [TypeForParameter {
236            name: "self".into(),
237            resolved_type: char_type.clone(),
238            is_mutable: false,
239            node: None,
240        }]
241            .into(),
242        return_type: string_type,
243    };
244    let self_to_string_functions = [IntrinsicFunction::CodepointToString];
245    for intrinsic_fn in self_to_string_functions {
246        let name = intrinsic_fn.to_string();
247        core_ns
248            .add_intrinsic_function(IntrinsicFunctionDefinition {
249                name,
250                intrinsic: intrinsic_fn,
251                signature: self_to_string.clone(),
252            })
253            .unwrap();
254    }
255
256    let self_to_int = Signature {
257        parameters: [TypeForParameter {
258            name: "self".into(),
259            resolved_type: char_type,
260            is_mutable: false,
261            node: None,
262        }]
263            .into(),
264        return_type: int_type,
265    };
266    let self_to_int_functions = [IntrinsicFunction::CodepointToInt];
267    for intrinsic_fn in self_to_int_functions {
268        let name = intrinsic_fn.to_string();
269        core_ns
270            .add_intrinsic_function(IntrinsicFunctionDefinition {
271                name,
272                intrinsic: intrinsic_fn,
273                signature: self_to_int.clone(),
274            })
275            .unwrap();
276    }
277}
278
279#[allow(clippy::too_many_lines)]
280fn add_intrinsic_int_functions(core_ns: &mut SymbolTable, type_cache: &mut TypeCache) {
281    let string_type = type_cache.string();
282    let int_type = type_cache.int();
283    let float_type = type_cache.float();
284    let int_to_int = Signature {
285        parameters: [TypeForParameter {
286            name: "self".into(),
287            resolved_type: int_type.clone(),
288            is_mutable: false,
289            node: None,
290        }]
291            .into(),
292        return_type: int_type.clone(),
293    };
294    let int_to_int_functions = [IntrinsicFunction::IntAbs, IntrinsicFunction::IntRnd];
295    for intrinsic_fn in int_to_int_functions {
296        let name = intrinsic_fn.to_string();
297        core_ns
298            .add_intrinsic_function(IntrinsicFunctionDefinition {
299                name,
300                intrinsic: intrinsic_fn,
301                signature: int_to_int.clone(),
302            })
303            .unwrap();
304    }
305
306    let self_to_string = Signature {
307        parameters: [TypeForParameter {
308            name: "self".into(),
309            resolved_type: int_type.clone(),
310            is_mutable: false,
311            node: None,
312        }]
313            .into(),
314        return_type: string_type,
315    };
316    let self_to_string_functions = [IntrinsicFunction::IntToString];
317    for intrinsic_fn in self_to_string_functions {
318        let name = intrinsic_fn.to_string();
319        core_ns
320            .add_intrinsic_function(IntrinsicFunctionDefinition {
321                name,
322                intrinsic: intrinsic_fn,
323                signature: self_to_string.clone(),
324            })
325            .unwrap();
326    }
327
328    let int_int_to_int = Signature {
329        parameters: [
330            TypeForParameter {
331                name: "self".into(),
332                resolved_type: int_type.clone(),
333                is_mutable: false,
334                node: None,
335            },
336            TypeForParameter {
337                name: "b".into(),
338                resolved_type: int_type.clone(),
339                is_mutable: false,
340                node: None,
341            },
342        ]
343            .into(),
344        return_type: int_type.clone(),
345    };
346    let int_int_to_int_functions = [IntrinsicFunction::IntMax, IntrinsicFunction::IntMin];
347
348    for intrinsic_fn in int_int_to_int_functions {
349        let name = intrinsic_fn.to_string();
350        core_ns
351            .add_intrinsic_function(IntrinsicFunctionDefinition {
352                name,
353                intrinsic: intrinsic_fn,
354                signature: int_int_to_int.clone(),
355            })
356            .unwrap();
357    }
358
359    let int_int_int_to_int = Signature {
360        parameters: [
361            TypeForParameter {
362                name: "self".into(),
363                resolved_type: int_type.clone(),
364                is_mutable: false,
365                node: None,
366            },
367            TypeForParameter {
368                name: "a".into(),
369                resolved_type: int_type.clone(),
370                is_mutable: false,
371                node: None,
372            },
373            TypeForParameter {
374                name: "b".into(),
375                resolved_type: int_type.clone(),
376                is_mutable: false,
377                node: None,
378            },
379        ]
380            .into(),
381        return_type: int_type.clone(),
382    };
383    let int_int_int_to_int_functions = [IntrinsicFunction::IntClamp];
384    for intrinsic_fn in int_int_int_to_int_functions {
385        let name = intrinsic_fn.to_string();
386        core_ns
387            .add_intrinsic_function(IntrinsicFunctionDefinition {
388                name,
389                intrinsic: intrinsic_fn,
390                signature: int_int_int_to_int.clone(),
391            })
392            .unwrap();
393    }
394
395    let int_to_float = Signature {
396        parameters: [TypeForParameter {
397            name: "self".into(),
398            resolved_type: int_type,
399            is_mutable: false,
400            node: None,
401        }]
402            .into(),
403        return_type: float_type,
404    };
405
406    core_ns
407        .add_intrinsic_function(IntrinsicFunctionDefinition {
408            name: IntrinsicFunction::IntToFloat.to_string(),
409            intrinsic: IntrinsicFunction::IntToFloat,
410            signature: int_to_float,
411        })
412        .unwrap();
413}
414
415#[allow(clippy::too_many_lines)]
416fn add_intrinsic_float_functions(core_ns: &mut SymbolTable, type_cache: &mut TypeCache) {
417    let string_type = type_cache.string();
418    let int_type = type_cache.int();
419    let float_type = type_cache.float();
420
421    let float_to_float = Signature {
422        parameters: [TypeForParameter {
423            name: "self".into(),
424            resolved_type: float_type.clone(),
425            is_mutable: false,
426            node: None,
427        }]
428            .into(),
429        return_type: float_type.clone(),
430    };
431
432    let float_to_float_functions = [
433        IntrinsicFunction::FloatSqrt,
434        IntrinsicFunction::FloatSign,
435        IntrinsicFunction::FloatAbs,
436        IntrinsicFunction::FloatRnd,
437        IntrinsicFunction::FloatCos,
438        IntrinsicFunction::FloatSin,
439        IntrinsicFunction::FloatAcos,
440        IntrinsicFunction::FloatAsin,
441    ];
442    for intrinsic_fn in float_to_float_functions {
443        let name = intrinsic_fn.to_string();
444        core_ns
445            .add_intrinsic_function(IntrinsicFunctionDefinition {
446                name,
447                intrinsic: intrinsic_fn,
448                signature: float_to_float.clone(),
449            })
450            .unwrap();
451    }
452
453    let float_to_int = Signature {
454        parameters: [TypeForParameter {
455            name: "self".into(),
456            resolved_type: float_type.clone(),
457            is_mutable: false,
458            node: None,
459        }]
460            .into(),
461        return_type: int_type,
462    };
463    let float_to_int_functions = [IntrinsicFunction::FloatRound, IntrinsicFunction::FloatFloor];
464    for intrinsic_fn in float_to_int_functions {
465        let name = intrinsic_fn.to_string();
466        core_ns
467            .add_intrinsic_function(IntrinsicFunctionDefinition {
468                name,
469                intrinsic: intrinsic_fn,
470                signature: float_to_int.clone(),
471            })
472            .unwrap();
473    }
474
475    let self_to_string = Signature {
476        parameters: [TypeForParameter {
477            name: "self".into(),
478            resolved_type: float_type.clone(),
479            is_mutable: false,
480            node: None,
481        }]
482            .into(),
483        return_type: string_type,
484    };
485    let self_to_string_functions = [IntrinsicFunction::FloatToString];
486    for intrinsic_fn in self_to_string_functions {
487        let name = intrinsic_fn.to_string();
488        core_ns
489            .add_intrinsic_function(IntrinsicFunctionDefinition {
490                name,
491                intrinsic: intrinsic_fn,
492                signature: self_to_string.clone(),
493            })
494            .unwrap();
495    }
496
497    let float_float_to_float = Signature {
498        parameters: [
499            TypeForParameter {
500                name: "self".into(),
501                resolved_type: float_type.clone(),
502                is_mutable: false,
503                node: None,
504            },
505            TypeForParameter {
506                name: "other".into(),
507                resolved_type: float_type.clone(),
508                is_mutable: false,
509                node: None,
510            },
511        ]
512            .into(),
513        return_type: float_type.clone(),
514    };
515
516    let float_float_to_float_functions = [
517        IntrinsicFunction::FloatAtan2,
518        IntrinsicFunction::FloatMin,
519        IntrinsicFunction::FloatMax,
520        IntrinsicFunction::Float2Magnitude,
521    ];
522    for intrinsic_fn in float_float_to_float_functions {
523        let name = intrinsic_fn.to_string();
524        core_ns
525            .add_intrinsic_function(IntrinsicFunctionDefinition {
526                name,
527                intrinsic: intrinsic_fn,
528                signature: float_float_to_float.clone(),
529            })
530            .unwrap();
531    }
532
533    let float_float_float_to_float = Signature {
534        parameters: [
535            TypeForParameter {
536                name: "self".into(),
537                resolved_type: float_type.clone(),
538                is_mutable: false,
539                node: None,
540            },
541            TypeForParameter {
542                name: "a".into(),
543                resolved_type: float_type.clone(),
544                is_mutable: false,
545                node: None,
546            },
547            TypeForParameter {
548                name: "b".into(),
549                resolved_type: float_type.clone(),
550                is_mutable: false,
551                node: None,
552            },
553        ]
554            .into(),
555        return_type: float_type,
556    };
557
558    core_ns
559        .add_intrinsic_function(IntrinsicFunctionDefinition {
560            name: IntrinsicFunction::FloatClamp.to_string(),
561            intrinsic: IntrinsicFunction::FloatClamp,
562            signature: float_float_float_to_float,
563        })
564        .unwrap();
565}
566
567/// # Panics
568/// if `versioned_name` is wrong
569#[must_use]
570pub fn create_module(tiny_version: &TinyVersion, type_cache: &mut TypeCache) -> Module {
571    let canonical_core_path = [tiny_version.versioned_name(PACKAGE_NAME).unwrap()];
572    let mut intrinsic_types_symbol_table = SymbolTable::new(&canonical_core_path);
573    add_intrinsic_types(&mut intrinsic_types_symbol_table, type_cache);
574    add_intrinsic_functions(&mut intrinsic_types_symbol_table, type_cache);
575
576    Module::new(intrinsic_types_symbol_table, Vec::new(), None)
577}
578
579/// # Panics
580/// if `versioned_name` is wrong
581#[must_use]
582pub fn create_module_with_name(path: &[String]) -> Module {
583    let intrinsic_types_symbol_table = SymbolTable::new(path);
584
585    Module::new(intrinsic_types_symbol_table, Vec::new(), None)
586}