1use crate::lcnf::*;
6
7use super::functions::OXILEAN_SWIFT_RUNTIME;
8
9use super::functions::*;
10use std::collections::{HashMap, HashSet, VecDeque};
11
12#[allow(dead_code)]
13#[derive(Debug, Clone)]
14pub struct SwiftDominatorTree {
15 pub idom: Vec<Option<u32>>,
16 pub dom_children: Vec<Vec<u32>>,
17 pub dom_depth: Vec<u32>,
18}
19impl SwiftDominatorTree {
20 #[allow(dead_code)]
21 pub fn new(size: usize) -> Self {
22 SwiftDominatorTree {
23 idom: vec![None; size],
24 dom_children: vec![Vec::new(); size],
25 dom_depth: vec![0; size],
26 }
27 }
28 #[allow(dead_code)]
29 pub fn set_idom(&mut self, node: usize, idom: u32) {
30 self.idom[node] = Some(idom);
31 }
32 #[allow(dead_code)]
33 pub fn dominates(&self, a: usize, b: usize) -> bool {
34 if a == b {
35 return true;
36 }
37 let mut cur = b;
38 loop {
39 match self.idom[cur] {
40 Some(parent) if parent as usize == a => return true,
41 Some(parent) if parent as usize == cur => return false,
42 Some(parent) => cur = parent as usize,
43 None => return false,
44 }
45 }
46 }
47 #[allow(dead_code)]
48 pub fn depth(&self, node: usize) -> u32 {
49 self.dom_depth.get(node).copied().unwrap_or(0)
50 }
51}
52#[derive(Debug, Clone, PartialEq)]
54pub struct SwiftStructDecl {
55 pub name: String,
57 pub fields: Vec<SwiftField>,
59 pub methods: Vec<SwiftFunc>,
61 pub conformances: Vec<SwiftConformance>,
63 pub is_public: bool,
65 pub generic_params: Vec<String>,
67}
68impl SwiftStructDecl {
69 pub fn new(name: impl Into<String>) -> Self {
71 SwiftStructDecl {
72 name: name.into(),
73 fields: Vec::new(),
74 methods: Vec::new(),
75 conformances: Vec::new(),
76 is_public: false,
77 generic_params: Vec::new(),
78 }
79 }
80 pub fn codegen(&self) -> String {
82 let vis = if self.is_public { "public " } else { "" };
83 let generics = if self.generic_params.is_empty() {
84 String::new()
85 } else {
86 format!("<{}>", self.generic_params.join(", "))
87 };
88 let conformances = if self.conformances.is_empty() {
89 String::new()
90 } else {
91 format!(
92 ": {}",
93 self.conformances
94 .iter()
95 .map(|c| c.0.as_str())
96 .collect::<Vec<_>>()
97 .join(", ")
98 )
99 };
100 let mut out = format!(
101 "{}struct {}{}{} {{\n",
102 vis, self.name, generics, conformances
103 );
104 for field in &self.fields {
105 out += &field.codegen();
106 out += "\n";
107 }
108 for method in &self.methods {
109 for line in method.codegen().lines() {
110 out += " ";
111 out += line;
112 out += "\n";
113 }
114 }
115 out += "}\n";
116 out
117 }
118}
119#[derive(Debug, Clone, PartialEq)]
121pub struct SwiftFunc {
122 pub name: String,
124 pub params: Vec<SwiftParam>,
126 pub return_type: SwiftType,
128 pub body: Vec<SwiftStmt>,
130 pub is_public: bool,
132 pub is_private: bool,
134 pub throws: bool,
136 pub is_async: bool,
138 pub is_static: bool,
140 pub is_mutating: bool,
142 pub generic_params: Vec<String>,
144 pub where_clause: Option<String>,
146}
147impl SwiftFunc {
148 pub fn new(name: impl Into<String>, return_type: SwiftType) -> Self {
150 SwiftFunc {
151 name: name.into(),
152 params: Vec::new(),
153 return_type,
154 body: Vec::new(),
155 is_public: false,
156 is_private: false,
157 throws: false,
158 is_async: false,
159 is_static: false,
160 is_mutating: false,
161 generic_params: Vec::new(),
162 where_clause: None,
163 }
164 }
165 pub fn codegen(&self) -> String {
167 let mut out = String::new();
168 if self.is_public {
169 out += "public ";
170 } else if self.is_private {
171 out += "private ";
172 }
173 if self.is_static {
174 out += "static ";
175 }
176 if self.is_mutating {
177 out += "mutating ";
178 }
179 out += "func ";
180 out += &self.name;
181 if !self.generic_params.is_empty() {
182 out += "<";
183 out += &self.generic_params.join(", ");
184 out += ">";
185 }
186 out += "(";
187 for (i, p) in self.params.iter().enumerate() {
188 if i > 0 {
189 out += ", ";
190 }
191 out += &p.to_string();
192 }
193 out += ")";
194 if self.is_async {
195 out += " async";
196 }
197 if self.throws {
198 out += " throws";
199 }
200 if self.return_type != SwiftType::SwiftVoid {
201 out += &format!(" -> {}", self.return_type);
202 }
203 if let Some(ref wh) = self.where_clause {
204 out += &format!(" where {}", wh);
205 }
206 out += " {\n";
207 out += &emit_block(&self.body, 4);
208 if !self.body.is_empty() {
209 out += "\n";
210 }
211 out += "}\n";
212 out
213 }
214}
215#[derive(Debug, Clone, PartialEq)]
217pub struct SwiftConformance(pub String);
218#[allow(dead_code)]
219pub struct SwiftPassRegistry {
220 pub(super) configs: Vec<SwiftPassConfig>,
221 pub(super) stats: std::collections::HashMap<String, SwiftPassStats>,
222}
223impl SwiftPassRegistry {
224 #[allow(dead_code)]
225 pub fn new() -> Self {
226 SwiftPassRegistry {
227 configs: Vec::new(),
228 stats: std::collections::HashMap::new(),
229 }
230 }
231 #[allow(dead_code)]
232 pub fn register(&mut self, config: SwiftPassConfig) {
233 self.stats
234 .insert(config.pass_name.clone(), SwiftPassStats::new());
235 self.configs.push(config);
236 }
237 #[allow(dead_code)]
238 pub fn enabled_passes(&self) -> Vec<&SwiftPassConfig> {
239 self.configs.iter().filter(|c| c.enabled).collect()
240 }
241 #[allow(dead_code)]
242 pub fn get_stats(&self, name: &str) -> Option<&SwiftPassStats> {
243 self.stats.get(name)
244 }
245 #[allow(dead_code)]
246 pub fn total_passes(&self) -> usize {
247 self.configs.len()
248 }
249 #[allow(dead_code)]
250 pub fn enabled_count(&self) -> usize {
251 self.enabled_passes().len()
252 }
253 #[allow(dead_code)]
254 pub fn update_stats(&mut self, name: &str, changes: u64, time_ms: u64, iter: u32) {
255 if let Some(stats) = self.stats.get_mut(name) {
256 stats.record_run(changes, time_ms, iter);
257 }
258 }
259}
260#[allow(dead_code)]
261#[derive(Debug, Clone)]
262pub struct SwiftCacheEntry {
263 pub key: String,
264 pub data: Vec<u8>,
265 pub timestamp: u64,
266 pub valid: bool,
267}
268#[derive(Debug, Clone, PartialEq)]
270pub struct SwiftModule {
271 pub name: String,
273 pub imports: Vec<String>,
275 pub types: Vec<SwiftTypeDecl>,
277 pub funcs: Vec<SwiftFunc>,
279 pub extensions: Vec<SwiftExtension>,
281 pub globals: Vec<SwiftStmt>,
283}
284impl SwiftModule {
285 pub fn new(name: impl Into<String>) -> Self {
287 SwiftModule {
288 name: name.into(),
289 imports: Vec::new(),
290 types: Vec::new(),
291 funcs: Vec::new(),
292 extensions: Vec::new(),
293 globals: Vec::new(),
294 }
295 }
296 pub fn add_import(&mut self, module: impl Into<String>) {
298 let m = module.into();
299 if !self.imports.contains(&m) {
300 self.imports.push(m);
301 }
302 }
303 pub fn codegen(&self) -> String {
305 let mut out = String::new();
306 out += &format!("// OxiLean-generated Swift module: {}\n", self.name);
307 out += OXILEAN_SWIFT_RUNTIME;
308 out += "\n";
309 for imp in &self.imports {
310 out += &format!("import {}\n", imp);
311 }
312 if !self.imports.is_empty() {
313 out += "\n";
314 }
315 for g in &self.globals {
316 out += &format!("{}\n", emit_stmt(g, 0));
317 }
318 if !self.globals.is_empty() {
319 out += "\n";
320 }
321 for ty in &self.types {
322 out += &ty.codegen();
323 out += "\n";
324 }
325 for func in &self.funcs {
326 out += &func.codegen();
327 out += "\n";
328 }
329 for ext in &self.extensions {
330 out += &ext.codegen();
331 out += "\n";
332 }
333 out
334 }
335}
336#[derive(Debug, Clone, PartialEq)]
338pub struct SwiftCase {
339 pub pattern: String,
341 pub body: Vec<SwiftStmt>,
343}
344#[allow(dead_code)]
345pub struct SwiftConstantFoldingHelper;
346impl SwiftConstantFoldingHelper {
347 #[allow(dead_code)]
348 pub fn fold_add_i64(a: i64, b: i64) -> Option<i64> {
349 a.checked_add(b)
350 }
351 #[allow(dead_code)]
352 pub fn fold_sub_i64(a: i64, b: i64) -> Option<i64> {
353 a.checked_sub(b)
354 }
355 #[allow(dead_code)]
356 pub fn fold_mul_i64(a: i64, b: i64) -> Option<i64> {
357 a.checked_mul(b)
358 }
359 #[allow(dead_code)]
360 pub fn fold_div_i64(a: i64, b: i64) -> Option<i64> {
361 if b == 0 {
362 None
363 } else {
364 a.checked_div(b)
365 }
366 }
367 #[allow(dead_code)]
368 pub fn fold_add_f64(a: f64, b: f64) -> f64 {
369 a + b
370 }
371 #[allow(dead_code)]
372 pub fn fold_mul_f64(a: f64, b: f64) -> f64 {
373 a * b
374 }
375 #[allow(dead_code)]
376 pub fn fold_neg_i64(a: i64) -> Option<i64> {
377 a.checked_neg()
378 }
379 #[allow(dead_code)]
380 pub fn fold_not_bool(a: bool) -> bool {
381 !a
382 }
383 #[allow(dead_code)]
384 pub fn fold_and_bool(a: bool, b: bool) -> bool {
385 a && b
386 }
387 #[allow(dead_code)]
388 pub fn fold_or_bool(a: bool, b: bool) -> bool {
389 a || b
390 }
391 #[allow(dead_code)]
392 pub fn fold_shl_i64(a: i64, b: u32) -> Option<i64> {
393 a.checked_shl(b)
394 }
395 #[allow(dead_code)]
396 pub fn fold_shr_i64(a: i64, b: u32) -> Option<i64> {
397 a.checked_shr(b)
398 }
399 #[allow(dead_code)]
400 pub fn fold_rem_i64(a: i64, b: i64) -> Option<i64> {
401 if b == 0 {
402 None
403 } else {
404 Some(a % b)
405 }
406 }
407 #[allow(dead_code)]
408 pub fn fold_bitand_i64(a: i64, b: i64) -> i64 {
409 a & b
410 }
411 #[allow(dead_code)]
412 pub fn fold_bitor_i64(a: i64, b: i64) -> i64 {
413 a | b
414 }
415 #[allow(dead_code)]
416 pub fn fold_bitxor_i64(a: i64, b: i64) -> i64 {
417 a ^ b
418 }
419 #[allow(dead_code)]
420 pub fn fold_bitnot_i64(a: i64) -> i64 {
421 !a
422 }
423}
424#[derive(Debug, Clone, PartialEq)]
426pub enum SwiftExpr {
427 SwiftLitExpr(SwiftLit),
429 SwiftVar(String),
431 SwiftCall {
433 callee: Box<SwiftExpr>,
435 args: Vec<(String, SwiftExpr)>,
437 },
438 SwiftBinOp {
440 op: String,
441 lhs: Box<SwiftExpr>,
442 rhs: Box<SwiftExpr>,
443 },
444 SwiftMember(Box<SwiftExpr>, String),
446 SwiftSubscript(Box<SwiftExpr>, Box<SwiftExpr>),
448 SwiftUnary(String, Box<SwiftExpr>),
450 SwiftTernary(Box<SwiftExpr>, Box<SwiftExpr>, Box<SwiftExpr>),
452 SwiftClosure {
454 params: Vec<(String, Option<SwiftType>)>,
456 return_type: Option<SwiftType>,
458 body: Vec<SwiftStmt>,
460 },
461 SwiftSwitchExpr {
463 subject: Box<SwiftExpr>,
465 arms: Vec<(String, SwiftExpr)>,
467 },
468 SwiftOptionalChain(Box<SwiftExpr>, String),
470 SwiftForceUnwrap(Box<SwiftExpr>),
472 SwiftArrayLit(Vec<SwiftExpr>),
474 SwiftDictLit(Vec<(SwiftExpr, SwiftExpr)>),
476 SwiftTupleLit(Vec<SwiftExpr>),
478 SwiftAs(Box<SwiftExpr>, SwiftType),
480 SwiftTry(Box<SwiftExpr>),
482 SwiftAwait(Box<SwiftExpr>),
484 SwiftSelf,
486 SwiftSuper,
488}
489#[allow(dead_code)]
490#[derive(Debug, Clone)]
491pub struct SwiftWorklist {
492 pub(super) items: std::collections::VecDeque<u32>,
493 pub(super) in_worklist: std::collections::HashSet<u32>,
494}
495impl SwiftWorklist {
496 #[allow(dead_code)]
497 pub fn new() -> Self {
498 SwiftWorklist {
499 items: std::collections::VecDeque::new(),
500 in_worklist: std::collections::HashSet::new(),
501 }
502 }
503 #[allow(dead_code)]
504 pub fn push(&mut self, item: u32) -> bool {
505 if self.in_worklist.insert(item) {
506 self.items.push_back(item);
507 true
508 } else {
509 false
510 }
511 }
512 #[allow(dead_code)]
513 pub fn pop(&mut self) -> Option<u32> {
514 let item = self.items.pop_front()?;
515 self.in_worklist.remove(&item);
516 Some(item)
517 }
518 #[allow(dead_code)]
519 pub fn is_empty(&self) -> bool {
520 self.items.is_empty()
521 }
522 #[allow(dead_code)]
523 pub fn len(&self) -> usize {
524 self.items.len()
525 }
526 #[allow(dead_code)]
527 pub fn contains(&self, item: u32) -> bool {
528 self.in_worklist.contains(&item)
529 }
530}
531#[derive(Debug, Clone, PartialEq)]
533pub enum SwiftLit {
534 Int(i64),
536 Bool(bool),
538 Str(String),
540 Nil,
542 Float(f64),
544}
545#[derive(Debug, Clone, PartialEq)]
547pub struct SwiftClassDecl {
548 pub name: String,
550 pub superclass: Option<String>,
552 pub fields: Vec<SwiftField>,
554 pub methods: Vec<SwiftFunc>,
556 pub conformances: Vec<SwiftConformance>,
558 pub is_public: bool,
560 pub is_final: bool,
562 pub generic_params: Vec<String>,
564}
565impl SwiftClassDecl {
566 pub fn new(name: impl Into<String>) -> Self {
568 SwiftClassDecl {
569 name: name.into(),
570 superclass: None,
571 fields: Vec::new(),
572 methods: Vec::new(),
573 conformances: Vec::new(),
574 is_public: false,
575 is_final: false,
576 generic_params: Vec::new(),
577 }
578 }
579 pub fn codegen(&self) -> String {
581 let vis = if self.is_public { "public " } else { "" };
582 let final_ = if self.is_final { "final " } else { "" };
583 let generics = if self.generic_params.is_empty() {
584 String::new()
585 } else {
586 format!("<{}>", self.generic_params.join(", "))
587 };
588 let mut inherit = Vec::new();
589 if let Some(ref sc) = self.superclass {
590 inherit.push(sc.clone());
591 }
592 for c in &self.conformances {
593 inherit.push(c.0.clone());
594 }
595 let inherit_str = if inherit.is_empty() {
596 String::new()
597 } else {
598 format!(": {}", inherit.join(", "))
599 };
600 let mut out = format!(
601 "{}{}class {}{}{} {{\n",
602 vis, final_, self.name, generics, inherit_str
603 );
604 for field in &self.fields {
605 out += &field.codegen();
606 out += "\n";
607 }
608 for method in &self.methods {
609 for line in method.codegen().lines() {
610 out += " ";
611 out += line;
612 out += "\n";
613 }
614 }
615 out += "}\n";
616 out
617 }
618}
619#[allow(dead_code)]
620#[derive(Debug, Clone)]
621pub struct SwiftLivenessInfo {
622 pub live_in: Vec<std::collections::HashSet<u32>>,
623 pub live_out: Vec<std::collections::HashSet<u32>>,
624 pub defs: Vec<std::collections::HashSet<u32>>,
625 pub uses: Vec<std::collections::HashSet<u32>>,
626}
627impl SwiftLivenessInfo {
628 #[allow(dead_code)]
629 pub fn new(block_count: usize) -> Self {
630 SwiftLivenessInfo {
631 live_in: vec![std::collections::HashSet::new(); block_count],
632 live_out: vec![std::collections::HashSet::new(); block_count],
633 defs: vec![std::collections::HashSet::new(); block_count],
634 uses: vec![std::collections::HashSet::new(); block_count],
635 }
636 }
637 #[allow(dead_code)]
638 pub fn add_def(&mut self, block: usize, var: u32) {
639 if block < self.defs.len() {
640 self.defs[block].insert(var);
641 }
642 }
643 #[allow(dead_code)]
644 pub fn add_use(&mut self, block: usize, var: u32) {
645 if block < self.uses.len() {
646 self.uses[block].insert(var);
647 }
648 }
649 #[allow(dead_code)]
650 pub fn is_live_in(&self, block: usize, var: u32) -> bool {
651 self.live_in
652 .get(block)
653 .map(|s| s.contains(&var))
654 .unwrap_or(false)
655 }
656 #[allow(dead_code)]
657 pub fn is_live_out(&self, block: usize, var: u32) -> bool {
658 self.live_out
659 .get(block)
660 .map(|s| s.contains(&var))
661 .unwrap_or(false)
662 }
663}
664#[derive(Debug, Clone, PartialEq, Eq, Hash)]
666pub enum SwiftType {
667 SwiftInt,
669 SwiftBool,
671 SwiftString,
673 SwiftDouble,
675 SwiftFloat,
677 SwiftVoid,
679 SwiftArray(Box<SwiftType>),
681 SwiftDict(Box<SwiftType>, Box<SwiftType>),
683 SwiftOptional(Box<SwiftType>),
685 SwiftTuple(Vec<SwiftType>),
687 SwiftFunc(Vec<SwiftType>, Box<SwiftType>),
689 SwiftEnum(String),
691 SwiftStruct(String),
693 SwiftClass(String),
695 SwiftProtocol(String),
697 SwiftGeneric(String, Vec<SwiftType>),
699 SwiftAny,
701 SwiftAnyObject,
703 SwiftNever,
705 SwiftNamed(String),
707}
708#[derive(Debug, Clone, PartialEq)]
710pub struct SwiftEnumCase {
711 pub name: String,
713 pub associated: Vec<SwiftType>,
715 pub raw_value: Option<SwiftLit>,
717}
718impl SwiftEnumCase {
719 pub fn bare(name: impl Into<String>) -> Self {
721 SwiftEnumCase {
722 name: name.into(),
723 associated: Vec::new(),
724 raw_value: None,
725 }
726 }
727 pub fn with_values(name: impl Into<String>, values: Vec<SwiftType>) -> Self {
729 SwiftEnumCase {
730 name: name.into(),
731 associated: values,
732 raw_value: None,
733 }
734 }
735 pub fn codegen(&self) -> String {
737 let mut out = format!(" case {}", self.name);
738 if !self.associated.is_empty() {
739 out += "(";
740 for (i, t) in self.associated.iter().enumerate() {
741 if i > 0 {
742 out += ", ";
743 }
744 out += &t.to_string();
745 }
746 out += ")";
747 }
748 if let Some(ref rv) = self.raw_value {
749 out += &format!(" = {}", rv);
750 }
751 out
752 }
753}
754#[derive(Debug, Clone, PartialEq)]
756pub struct SwiftField {
757 pub name: String,
759 pub ty: SwiftType,
761 pub mutable: bool,
763 pub is_public: bool,
765 pub default: Option<SwiftExpr>,
767}
768impl SwiftField {
769 pub fn new_let(name: impl Into<String>, ty: SwiftType) -> Self {
771 SwiftField {
772 name: name.into(),
773 ty,
774 mutable: false,
775 is_public: false,
776 default: None,
777 }
778 }
779 pub fn new_var(name: impl Into<String>, ty: SwiftType) -> Self {
781 SwiftField {
782 name: name.into(),
783 ty,
784 mutable: true,
785 is_public: false,
786 default: None,
787 }
788 }
789 pub fn codegen(&self) -> String {
791 let vis = if self.is_public { "public " } else { "" };
792 let kw = if self.mutable { "var" } else { "let" };
793 let default = self
794 .default
795 .as_ref()
796 .map(|v| format!(" = {}", v))
797 .unwrap_or_default();
798 format!(" {}{} {}: {}{}", vis, kw, self.name, self.ty, default)
799 }
800}
801#[derive(Debug, Clone, PartialEq)]
803pub struct SwiftParam {
804 pub label: String,
806 pub name: String,
808 pub ty: SwiftType,
810 pub default: Option<SwiftExpr>,
812 pub variadic: bool,
814 pub inout: bool,
816}
817impl SwiftParam {
818 pub fn new(name: impl Into<String>, ty: SwiftType) -> Self {
820 SwiftParam {
821 label: String::new(),
822 name: name.into(),
823 ty,
824 default: None,
825 variadic: false,
826 inout: false,
827 }
828 }
829 pub fn labeled(label: impl Into<String>, name: impl Into<String>, ty: SwiftType) -> Self {
831 SwiftParam {
832 label: label.into(),
833 name: name.into(),
834 ty,
835 default: None,
836 variadic: false,
837 inout: false,
838 }
839 }
840}
841#[derive(Debug, Clone, PartialEq)]
843pub enum SwiftStmt {
844 Let {
846 name: String,
847 ty: Option<SwiftType>,
848 value: SwiftExpr,
849 },
850 Var {
852 name: String,
853 ty: Option<SwiftType>,
854 value: Option<SwiftExpr>,
855 },
856 Assign { target: SwiftExpr, value: SwiftExpr },
858 Return(Option<SwiftExpr>),
860 If {
862 cond: SwiftExpr,
863 then_body: Vec<SwiftStmt>,
864 else_body: Vec<SwiftStmt>,
865 },
866 IfLet {
868 name: String,
869 value: SwiftExpr,
870 then_body: Vec<SwiftStmt>,
871 else_body: Vec<SwiftStmt>,
872 },
873 Guard {
875 cond: SwiftExpr,
876 else_body: Vec<SwiftStmt>,
877 },
878 Switch {
880 subject: SwiftExpr,
881 cases: Vec<SwiftCase>,
882 },
883 For {
885 name: String,
886 collection: SwiftExpr,
887 body: Vec<SwiftStmt>,
888 },
889 While {
891 cond: SwiftExpr,
892 body: Vec<SwiftStmt>,
893 },
894 Throw(SwiftExpr),
896 Break,
898 Continue,
900 ExprStmt(SwiftExpr),
902 Block(Vec<SwiftStmt>),
904 Raw(String),
906}
907#[derive(Debug, Clone, PartialEq)]
909pub enum SwiftTypeDecl {
910 Enum(SwiftEnumDecl),
911 Struct(SwiftStructDecl),
912 Class(SwiftClassDecl),
913}
914impl SwiftTypeDecl {
915 pub fn codegen(&self) -> String {
917 match self {
918 SwiftTypeDecl::Enum(e) => e.codegen(),
919 SwiftTypeDecl::Struct(s) => s.codegen(),
920 SwiftTypeDecl::Class(c) => c.codegen(),
921 }
922 }
923}
924#[allow(dead_code)]
925#[derive(Debug, Clone, Default)]
926pub struct SwiftPassStats {
927 pub total_runs: u32,
928 pub successful_runs: u32,
929 pub total_changes: u64,
930 pub time_ms: u64,
931 pub iterations_used: u32,
932}
933impl SwiftPassStats {
934 #[allow(dead_code)]
935 pub fn new() -> Self {
936 Self::default()
937 }
938 #[allow(dead_code)]
939 pub fn record_run(&mut self, changes: u64, time_ms: u64, iterations: u32) {
940 self.total_runs += 1;
941 self.successful_runs += 1;
942 self.total_changes += changes;
943 self.time_ms += time_ms;
944 self.iterations_used = iterations;
945 }
946 #[allow(dead_code)]
947 pub fn average_changes_per_run(&self) -> f64 {
948 if self.total_runs == 0 {
949 return 0.0;
950 }
951 self.total_changes as f64 / self.total_runs as f64
952 }
953 #[allow(dead_code)]
954 pub fn success_rate(&self) -> f64 {
955 if self.total_runs == 0 {
956 return 0.0;
957 }
958 self.successful_runs as f64 / self.total_runs as f64
959 }
960 #[allow(dead_code)]
961 pub fn format_summary(&self) -> String {
962 format!(
963 "Runs: {}/{}, Changes: {}, Time: {}ms",
964 self.successful_runs, self.total_runs, self.total_changes, self.time_ms
965 )
966 }
967}
968#[allow(dead_code)]
969#[derive(Debug, Clone)]
970pub struct SwiftAnalysisCache {
971 pub(super) entries: std::collections::HashMap<String, SwiftCacheEntry>,
972 pub(super) max_size: usize,
973 pub(super) hits: u64,
974 pub(super) misses: u64,
975}
976impl SwiftAnalysisCache {
977 #[allow(dead_code)]
978 pub fn new(max_size: usize) -> Self {
979 SwiftAnalysisCache {
980 entries: std::collections::HashMap::new(),
981 max_size,
982 hits: 0,
983 misses: 0,
984 }
985 }
986 #[allow(dead_code)]
987 pub fn get(&mut self, key: &str) -> Option<&SwiftCacheEntry> {
988 if self.entries.contains_key(key) {
989 self.hits += 1;
990 self.entries.get(key)
991 } else {
992 self.misses += 1;
993 None
994 }
995 }
996 #[allow(dead_code)]
997 pub fn insert(&mut self, key: String, data: Vec<u8>) {
998 if self.entries.len() >= self.max_size {
999 if let Some(oldest) = self.entries.keys().next().cloned() {
1000 self.entries.remove(&oldest);
1001 }
1002 }
1003 self.entries.insert(
1004 key.clone(),
1005 SwiftCacheEntry {
1006 key,
1007 data,
1008 timestamp: 0,
1009 valid: true,
1010 },
1011 );
1012 }
1013 #[allow(dead_code)]
1014 pub fn invalidate(&mut self, key: &str) {
1015 if let Some(entry) = self.entries.get_mut(key) {
1016 entry.valid = false;
1017 }
1018 }
1019 #[allow(dead_code)]
1020 pub fn clear(&mut self) {
1021 self.entries.clear();
1022 }
1023 #[allow(dead_code)]
1024 pub fn hit_rate(&self) -> f64 {
1025 let total = self.hits + self.misses;
1026 if total == 0 {
1027 return 0.0;
1028 }
1029 self.hits as f64 / total as f64
1030 }
1031 #[allow(dead_code)]
1032 pub fn size(&self) -> usize {
1033 self.entries.len()
1034 }
1035}
1036#[derive(Debug, Clone, PartialEq)]
1038pub struct SwiftExtension {
1039 pub target: String,
1041 pub conformances: Vec<SwiftConformance>,
1043 pub methods: Vec<SwiftFunc>,
1045 pub where_clause: Option<String>,
1047}
1048impl SwiftExtension {
1049 pub fn new(target: impl Into<String>) -> Self {
1051 SwiftExtension {
1052 target: target.into(),
1053 conformances: Vec::new(),
1054 methods: Vec::new(),
1055 where_clause: None,
1056 }
1057 }
1058 pub fn codegen(&self) -> String {
1060 let conformances = if self.conformances.is_empty() {
1061 String::new()
1062 } else {
1063 format!(
1064 ": {}",
1065 self.conformances
1066 .iter()
1067 .map(|c| c.0.as_str())
1068 .collect::<Vec<_>>()
1069 .join(", ")
1070 )
1071 };
1072 let where_str = self
1073 .where_clause
1074 .as_ref()
1075 .map(|w| format!(" where {}", w))
1076 .unwrap_or_default();
1077 let mut out = format!(
1078 "extension {}{}{} {{\n",
1079 self.target, conformances, where_str
1080 );
1081 for method in &self.methods {
1082 for line in method.codegen().lines() {
1083 out += " ";
1084 out += line;
1085 out += "\n";
1086 }
1087 }
1088 out += "}\n";
1089 out
1090 }
1091}
1092pub struct SwiftBackend {
1101 pub(super) var_counter: u64,
1103 pub emit_public: bool,
1105 pub emit_comments: bool,
1107}
1108impl SwiftBackend {
1109 pub fn new() -> Self {
1111 SwiftBackend {
1112 var_counter: 0,
1113 emit_public: true,
1114 emit_comments: true,
1115 }
1116 }
1117 pub fn fresh_var(&mut self) -> String {
1119 let n = self.var_counter;
1120 self.var_counter += 1;
1121 format!("_ox{}", n)
1122 }
1123 pub fn mangle_name(name: &str) -> String {
1131 if name.is_empty() {
1132 return "ox_empty".to_string();
1133 }
1134 let sanitized: String = name
1135 .chars()
1136 .map(|c| {
1137 if c.is_alphanumeric() || c == '_' {
1138 c
1139 } else {
1140 '_'
1141 }
1142 })
1143 .collect();
1144 let sanitized = if sanitized.starts_with(|c: char| c.is_ascii_digit()) {
1145 format!("ox_{}", sanitized)
1146 } else {
1147 sanitized
1148 };
1149 if is_swift_keyword(&sanitized) {
1150 format!("ox_{}", sanitized)
1151 } else {
1152 sanitized
1153 }
1154 }
1155 pub fn compile_arg(&self, arg: &LcnfArg) -> SwiftExpr {
1157 match arg {
1158 LcnfArg::Var(id) => SwiftExpr::SwiftVar(format!("{}", id)),
1159 LcnfArg::Lit(lit) => self.compile_lit(lit),
1160 LcnfArg::Erased => SwiftExpr::SwiftMember(
1161 Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1162 "erased".to_string(),
1163 ),
1164 LcnfArg::Type(_) => SwiftExpr::SwiftMember(
1165 Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1166 "erased".to_string(),
1167 ),
1168 }
1169 }
1170 pub fn compile_lit(&self, lit: &LcnfLit) -> SwiftExpr {
1172 match lit {
1173 LcnfLit::Nat(n) => SwiftExpr::SwiftLitExpr(SwiftLit::Int(*n as i64)),
1174 LcnfLit::Str(s) => SwiftExpr::SwiftLitExpr(SwiftLit::Str(s.clone())),
1175 }
1176 }
1177 pub fn compile_expr(&self, expr: &LcnfExpr) -> Vec<SwiftStmt> {
1181 match expr {
1182 LcnfExpr::Return(arg) => vec![SwiftStmt::Return(Some(self.compile_arg(arg)))],
1183 LcnfExpr::Unreachable => {
1184 vec![SwiftStmt::ExprStmt(SwiftExpr::SwiftCall {
1185 callee: Box::new(SwiftExpr::SwiftVar("ox_unreachable".to_string())),
1186 args: Vec::new(),
1187 })]
1188 }
1189 LcnfExpr::TailCall(func, args) => {
1190 let callee = Box::new(self.compile_arg(func));
1191 let call_args = args
1192 .iter()
1193 .map(|a| (String::new(), self.compile_arg(a)))
1194 .collect();
1195 vec![SwiftStmt::Return(Some(SwiftExpr::SwiftCall {
1196 callee,
1197 args: call_args,
1198 }))]
1199 }
1200 LcnfExpr::Let {
1201 id, value, body, ..
1202 } => {
1203 let var_name = format!("{}", id);
1204 let rhs = self.compile_let_value(value);
1205 let mut stmts = vec![SwiftStmt::Let {
1206 name: var_name,
1207 ty: None,
1208 value: rhs,
1209 }];
1210 stmts.extend(self.compile_expr(body));
1211 stmts
1212 }
1213 LcnfExpr::Case {
1214 scrutinee,
1215 alts,
1216 default,
1217 ..
1218 } => {
1219 let subject = SwiftExpr::SwiftVar(format!("{}", scrutinee));
1220 let mut cases: Vec<SwiftCase> = alts
1221 .iter()
1222 .map(|alt| {
1223 let pattern = format!(".ctor(tag: {}, _)", alt.ctor_tag);
1224 let body = self.compile_expr(&alt.body);
1225 SwiftCase { pattern, body }
1226 })
1227 .collect();
1228 if let Some(def) = default {
1229 let def_body = self.compile_expr(def);
1230 cases.push(SwiftCase {
1231 pattern: "default".to_string(),
1232 body: def_body,
1233 });
1234 } else {
1235 cases.push(SwiftCase {
1236 pattern: "default".to_string(),
1237 body: vec![SwiftStmt::ExprStmt(SwiftExpr::SwiftCall {
1238 callee: Box::new(SwiftExpr::SwiftVar("ox_unreachable".to_string())),
1239 args: Vec::new(),
1240 })],
1241 });
1242 }
1243 vec![SwiftStmt::Switch { subject, cases }]
1244 }
1245 }
1246 }
1247 pub fn compile_let_value(&self, value: &LcnfLetValue) -> SwiftExpr {
1249 match value {
1250 LcnfLetValue::Lit(lit) => self.compile_lit(lit),
1251 LcnfLetValue::Erased => SwiftExpr::SwiftMember(
1252 Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1253 "erased".to_string(),
1254 ),
1255 LcnfLetValue::FVar(id) => SwiftExpr::SwiftVar(format!("{}", id)),
1256 LcnfLetValue::App(func, args) => {
1257 let callee = Box::new(self.compile_arg(func));
1258 let call_args = args
1259 .iter()
1260 .map(|a| (String::new(), self.compile_arg(a)))
1261 .collect();
1262 SwiftExpr::SwiftCall {
1263 callee,
1264 args: call_args,
1265 }
1266 }
1267 LcnfLetValue::Ctor(name, tag, args) => {
1268 let tag_pair = (
1269 "tag".to_string(),
1270 SwiftExpr::SwiftLitExpr(SwiftLit::Int(*tag as i64)),
1271 );
1272 let field_exprs: Vec<SwiftExpr> =
1273 args.iter().map(|a| self.compile_arg(a)).collect();
1274 let fields_array = SwiftExpr::SwiftArrayLit(field_exprs);
1275 let _ = name;
1276 SwiftExpr::SwiftCall {
1277 callee: Box::new(SwiftExpr::SwiftMember(
1278 Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1279 "ctor".to_string(),
1280 )),
1281 args: vec![tag_pair, ("fields".to_string(), fields_array)],
1282 }
1283 }
1284 LcnfLetValue::Proj(_, idx, var) => {
1285 let base = SwiftExpr::SwiftMember(
1286 Box::new(SwiftExpr::SwiftVar(format!("{}", var))),
1287 "fields".to_string(),
1288 );
1289 SwiftExpr::SwiftSubscript(
1290 Box::new(base),
1291 Box::new(SwiftExpr::SwiftLitExpr(SwiftLit::Int(*idx as i64))),
1292 )
1293 }
1294 LcnfLetValue::Reset(var) => SwiftExpr::SwiftVar(format!("{}", var)),
1295 LcnfLetValue::Reuse(_, name, tag, args) => {
1296 let tag_pair = (
1297 "tag".to_string(),
1298 SwiftExpr::SwiftLitExpr(SwiftLit::Int(*tag as i64)),
1299 );
1300 let field_exprs: Vec<SwiftExpr> =
1301 args.iter().map(|a| self.compile_arg(a)).collect();
1302 let fields_array = SwiftExpr::SwiftArrayLit(field_exprs);
1303 let _ = name;
1304 SwiftExpr::SwiftCall {
1305 callee: Box::new(SwiftExpr::SwiftMember(
1306 Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1307 "ctor".to_string(),
1308 )),
1309 args: vec![tag_pair, ("fields".to_string(), fields_array)],
1310 }
1311 }
1312 }
1313 }
1314 pub fn compile_decl(&self, decl: &LcnfFunDecl) -> SwiftFunc {
1316 let safe_name = Self::mangle_name(&decl.name.to_string());
1317 let params: Vec<SwiftParam> = decl
1318 .params
1319 .iter()
1320 .map(|p| {
1321 let pname = Self::mangle_name(&p.name);
1322 SwiftParam {
1323 label: "_".to_string(),
1324 name: pname,
1325 ty: self.compile_lcnf_type(&p.ty),
1326 default: None,
1327 variadic: false,
1328 inout: false,
1329 }
1330 })
1331 .collect();
1332 let body = self.compile_expr(&decl.body);
1333 let mut func = SwiftFunc::new(safe_name, SwiftType::SwiftNamed("OxValue".to_string()));
1334 func.params = params;
1335 func.body = body;
1336 func.is_public = self.emit_public;
1337 func
1338 }
1339 pub fn compile_lcnf_type(&self, ty: &LcnfType) -> SwiftType {
1341 match ty {
1342 LcnfType::Nat | LcnfType::Unit | LcnfType::Erased | LcnfType::Irrelevant => {
1343 SwiftType::SwiftNamed("OxValue".to_string())
1344 }
1345 LcnfType::LcnfString => SwiftType::SwiftNamed("OxValue".to_string()),
1346 LcnfType::Object => SwiftType::SwiftNamed("OxValue".to_string()),
1347 LcnfType::Var(_) => SwiftType::SwiftNamed("OxValue".to_string()),
1348 LcnfType::Fun(params, ret) => {
1349 let p: Vec<SwiftType> = params.iter().map(|p| self.compile_lcnf_type(p)).collect();
1350 let r = Box::new(self.compile_lcnf_type(ret));
1351 SwiftType::SwiftFunc(p, r)
1352 }
1353 LcnfType::Ctor(_, _) => SwiftType::SwiftNamed("OxValue".to_string()),
1354 }
1355 }
1356 pub fn compile_module(&self, name: &str, decls: &[LcnfFunDecl]) -> SwiftModule {
1358 let mut module = SwiftModule::new(name);
1359 module.add_import("Foundation");
1360 for decl in decls {
1361 let func = self.compile_decl(decl);
1362 module.funcs.push(func);
1363 }
1364 module
1365 }
1366 pub fn emit_module(&self, module: &SwiftModule) -> String {
1368 module.codegen()
1369 }
1370 pub fn emit_func(&self, func: &SwiftFunc) -> String {
1372 func.codegen()
1373 }
1374 pub fn emit_type_decl(&self, decl: &SwiftTypeDecl) -> String {
1376 decl.codegen()
1377 }
1378}
1379#[allow(dead_code)]
1380#[derive(Debug, Clone)]
1381pub struct SwiftPassConfig {
1382 pub phase: SwiftPassPhase,
1383 pub enabled: bool,
1384 pub max_iterations: u32,
1385 pub debug_output: bool,
1386 pub pass_name: String,
1387}
1388impl SwiftPassConfig {
1389 #[allow(dead_code)]
1390 pub fn new(name: impl Into<String>, phase: SwiftPassPhase) -> Self {
1391 SwiftPassConfig {
1392 phase,
1393 enabled: true,
1394 max_iterations: 10,
1395 debug_output: false,
1396 pass_name: name.into(),
1397 }
1398 }
1399 #[allow(dead_code)]
1400 pub fn disabled(mut self) -> Self {
1401 self.enabled = false;
1402 self
1403 }
1404 #[allow(dead_code)]
1405 pub fn with_debug(mut self) -> Self {
1406 self.debug_output = true;
1407 self
1408 }
1409 #[allow(dead_code)]
1410 pub fn max_iter(mut self, n: u32) -> Self {
1411 self.max_iterations = n;
1412 self
1413 }
1414}
1415#[derive(Debug, Clone, PartialEq)]
1417pub struct SwiftEnumDecl {
1418 pub name: String,
1420 pub cases: Vec<SwiftEnumCase>,
1422 pub methods: Vec<SwiftFunc>,
1424 pub conformances: Vec<SwiftConformance>,
1426 pub is_public: bool,
1428 pub generic_params: Vec<String>,
1430}
1431impl SwiftEnumDecl {
1432 pub fn new(name: impl Into<String>) -> Self {
1434 SwiftEnumDecl {
1435 name: name.into(),
1436 cases: Vec::new(),
1437 methods: Vec::new(),
1438 conformances: Vec::new(),
1439 is_public: false,
1440 generic_params: Vec::new(),
1441 }
1442 }
1443 pub fn codegen(&self) -> String {
1445 let vis = if self.is_public { "public " } else { "" };
1446 let generics = if self.generic_params.is_empty() {
1447 String::new()
1448 } else {
1449 format!("<{}>", self.generic_params.join(", "))
1450 };
1451 let conformances = if self.conformances.is_empty() {
1452 String::new()
1453 } else {
1454 format!(
1455 ": {}",
1456 self.conformances
1457 .iter()
1458 .map(|c| c.0.as_str())
1459 .collect::<Vec<_>>()
1460 .join(", ")
1461 )
1462 };
1463 let mut out = format!("{}enum {}{}{} {{\n", vis, self.name, generics, conformances);
1464 for case in &self.cases {
1465 out += &case.codegen();
1466 out += "\n";
1467 }
1468 for method in &self.methods {
1469 for line in method.codegen().lines() {
1470 out += " ";
1471 out += line;
1472 out += "\n";
1473 }
1474 }
1475 out += "}\n";
1476 out
1477 }
1478}
1479#[allow(dead_code)]
1480#[derive(Debug, Clone, PartialEq)]
1481pub enum SwiftPassPhase {
1482 Analysis,
1483 Transformation,
1484 Verification,
1485 Cleanup,
1486}
1487impl SwiftPassPhase {
1488 #[allow(dead_code)]
1489 pub fn name(&self) -> &str {
1490 match self {
1491 SwiftPassPhase::Analysis => "analysis",
1492 SwiftPassPhase::Transformation => "transformation",
1493 SwiftPassPhase::Verification => "verification",
1494 SwiftPassPhase::Cleanup => "cleanup",
1495 }
1496 }
1497 #[allow(dead_code)]
1498 pub fn is_modifying(&self) -> bool {
1499 matches!(
1500 self,
1501 SwiftPassPhase::Transformation | SwiftPassPhase::Cleanup
1502 )
1503 }
1504}
1505#[allow(dead_code)]
1506#[derive(Debug, Clone)]
1507pub struct SwiftDepGraph {
1508 pub(super) nodes: Vec<u32>,
1509 pub(super) edges: Vec<(u32, u32)>,
1510}
1511impl SwiftDepGraph {
1512 #[allow(dead_code)]
1513 pub fn new() -> Self {
1514 SwiftDepGraph {
1515 nodes: Vec::new(),
1516 edges: Vec::new(),
1517 }
1518 }
1519 #[allow(dead_code)]
1520 pub fn add_node(&mut self, id: u32) {
1521 if !self.nodes.contains(&id) {
1522 self.nodes.push(id);
1523 }
1524 }
1525 #[allow(dead_code)]
1526 pub fn add_dep(&mut self, dep: u32, dependent: u32) {
1527 self.add_node(dep);
1528 self.add_node(dependent);
1529 self.edges.push((dep, dependent));
1530 }
1531 #[allow(dead_code)]
1532 pub fn dependents_of(&self, node: u32) -> Vec<u32> {
1533 self.edges
1534 .iter()
1535 .filter(|(d, _)| *d == node)
1536 .map(|(_, dep)| *dep)
1537 .collect()
1538 }
1539 #[allow(dead_code)]
1540 pub fn dependencies_of(&self, node: u32) -> Vec<u32> {
1541 self.edges
1542 .iter()
1543 .filter(|(_, dep)| *dep == node)
1544 .map(|(d, _)| *d)
1545 .collect()
1546 }
1547 #[allow(dead_code)]
1548 pub fn topological_sort(&self) -> Vec<u32> {
1549 let mut in_degree: std::collections::HashMap<u32, u32> = std::collections::HashMap::new();
1550 for &n in &self.nodes {
1551 in_degree.insert(n, 0);
1552 }
1553 for (_, dep) in &self.edges {
1554 *in_degree.entry(*dep).or_insert(0) += 1;
1555 }
1556 let mut queue: std::collections::VecDeque<u32> = self
1557 .nodes
1558 .iter()
1559 .filter(|&&n| in_degree[&n] == 0)
1560 .copied()
1561 .collect();
1562 let mut result = Vec::new();
1563 while let Some(node) = queue.pop_front() {
1564 result.push(node);
1565 for dep in self.dependents_of(node) {
1566 let cnt = in_degree.entry(dep).or_insert(0);
1567 *cnt = cnt.saturating_sub(1);
1568 if *cnt == 0 {
1569 queue.push_back(dep);
1570 }
1571 }
1572 }
1573 result
1574 }
1575 #[allow(dead_code)]
1576 pub fn has_cycle(&self) -> bool {
1577 self.topological_sort().len() < self.nodes.len()
1578 }
1579}