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