Skip to main content

kain/codegen/
rust.rs

1//! Rust Code Generation - Transpiles KAIN AST to Rust source code
2//!
3//! This module generates valid Rust code from a typed KAIN program.
4//! The generated Rust can be compiled with `rustc` directly or integrated
5//! into a Cargo project.
6
7use crate::types::{TypedProgram, TypedItem};
8use crate::error::{KainResult, KainError};
9use crate::ast::{
10    Type, Expr, Stmt, Block, BinaryOp, UnaryOp, Pattern, Function, Struct, Enum,
11    Field, Variant, VariantFields, Impl, Param, MatchArm, CallArg, ElseBranch,
12    VariantPatternFields, EnumVariantFields,
13};
14use crate::span::Span;
15
16/// Generate Rust source code from a typed program
17pub fn generate(program: &TypedProgram) -> KainResult<String> {
18    let mut gen = RustGen::new();
19    Ok(gen.gen_program(program))
20}
21
22// StringBuilder helper for accumulated output
23struct StringBuilder {
24    lines: Vec<String>,
25}
26
27impl StringBuilder {
28    fn new() -> Self {
29        Self { lines: Vec::new() }
30    }
31
32    fn push(&mut self, text: &str) {
33        self.lines.push(text.to_string());
34    }
35
36    fn push_line(&mut self, text: &str) {
37        self.lines.push(format!("{}\n", text));
38    }
39
40    fn build(&self) -> String {
41        self.lines.join("")
42    }
43}
44
45// Main Rust code generator
46struct RustGen {
47    output: StringBuilder,
48    indent: usize,
49}
50
51impl RustGen {
52    fn new() -> Self {
53        Self {
54            output: StringBuilder::new(),
55            indent: 0,
56        }
57    }
58
59    fn push_indent(&mut self) {
60        self.indent += 1;
61    }
62
63    fn pop_indent(&mut self) {
64        if self.indent > 0 {
65            self.indent -= 1;
66        }
67    }
68
69    fn indent_str(&self) -> String {
70        "    ".repeat(self.indent)
71    }
72
73    fn write_line(&mut self, line: &str) {
74        let indented = format!("{}{}", self.indent_str(), line);
75        self.output.push_line(&indented);
76    }
77
78    fn write_blank(&mut self) {
79        self.output.push_line("");
80    }
81
82    // Generate Rust code for an entire program
83    fn gen_program(&mut self, program: &TypedProgram) -> String {
84        // Header
85        self.write_line("// Generated by KAIN Compiler (Project Ouroboros)");
86        self.write_line("// Do not edit - regenerate from .kn source");
87        self.write_blank();
88        self.write_line("#![allow(unused_variables)]");
89        self.write_line("#![allow(unused_mut)]");
90        self.write_line("#![allow(dead_code)]");
91        self.write_line("#![allow(unused_parens)]");
92        self.write_blank();
93
94        // Standard imports
95        self.write_line("use std::collections::HashMap;");
96        self.write_line("use std::rc::Rc;");
97        self.write_line("use std::cell::RefCell;");
98        self.write_blank();
99
100        // Generate each item
101        for item in &program.items {
102            self.gen_item(item);
103            self.write_blank();
104        }
105
106        self.output.build()
107    }
108
109    fn gen_item(&mut self, item: &TypedItem) {
110        match item {
111            TypedItem::Function(fn_typed) => self.gen_function(&fn_typed.ast),
112            TypedItem::Struct(st) => self.gen_struct(&st.ast),
113            TypedItem::Enum(en) => self.gen_enum(&en.ast),
114            TypedItem::Impl(im) => self.gen_impl(&im.ast),
115            _ => {} // Skip shaders, actors, components, traits, etc. for Rust output
116        }
117    }
118
119    // Generate a function definition
120    fn gen_function(&mut self, func: &Function) {
121        let vis = match func.visibility {
122            crate::ast::Visibility::Public => "pub ",
123            _ => "",
124        };
125
126        // Parameters
127        let params = self.gen_params(&func.params);
128
129        // Return type
130        let ret = if let Some(ty) = &func.return_type {
131            format!(" -> {}", self.map_type(ty))
132        } else {
133            String::new()
134        };
135
136        // Function signature
137        self.write_line(&format!("{}fn {}({}){} {{", vis, func.name, params, ret));
138        self.push_indent();
139
140        // Body
141        self.gen_block(&func.body);
142
143        self.pop_indent();
144        self.write_line("}");
145    }
146
147    fn gen_params(&self, params: &[Param]) -> String {
148        let parts: Vec<String> = params
149            .iter()
150            .map(|p| {
151                let ty_str = self.map_type(&p.ty);
152                if p.mutable {
153                    format!("mut {}: {}", p.name, ty_str)
154                } else {
155                    format!("{}: {}", p.name, ty_str)
156                }
157            })
158            .collect();
159        parts.join(", ")
160    }
161
162    fn gen_struct(&mut self, struct_def: &Struct) {
163        let vis = match struct_def.visibility {
164            crate::ast::Visibility::Public => "pub ",
165            _ => "",
166        };
167
168        self.write_line("#[derive(Debug, Clone)]");
169        self.write_line(&format!("{}struct {} {{", vis, struct_def.name));
170        self.push_indent();
171
172        for field in &struct_def.fields {
173            self.write_line(&format!("pub {}: {},", field.name, self.map_type(&field.ty)));
174        }
175
176        self.pop_indent();
177        self.write_line("}");
178    }
179
180    fn gen_enum(&mut self, enum_def: &Enum) {
181        self.write_line("#[derive(Debug, Clone, PartialEq)]");
182        self.write_line(&format!("pub enum {} {{", enum_def.name));
183        self.push_indent();
184
185        for variant in &enum_def.variants {
186            match &variant.fields {
187                VariantFields::Unit => {
188                    self.write_line(&format!("{},", variant.name));
189                }
190                VariantFields::Tuple(types) => {
191                    let fields: Vec<String> = types.iter().map(|t| self.map_type(t)).collect();
192                    self.write_line(&format!("{}({}),", variant.name, fields.join(", ")));
193                }
194                VariantFields::Struct(fields) => {
195                    self.write_line(&format!("{} {{", variant.name));
196                    self.push_indent();
197                    for f in fields {
198                        self.write_line(&format!("{}: {},", f.name, self.map_type(&f.ty)));
199                    }
200                    self.pop_indent();
201                    self.write_line("},");
202                }
203            }
204        }
205
206        self.pop_indent();
207        self.write_line("}");
208    }
209
210    fn gen_impl(&mut self, impl_def: &Impl) {
211        let target = self.map_type(&impl_def.target_type);
212        
213        if let Some(trait_name) = &impl_def.trait_name {
214            self.write_line(&format!("impl {} for {} {{", trait_name, target));
215        } else {
216            self.write_line(&format!("impl {} {{", target));
217        }
218        self.push_indent();
219
220        for method in &impl_def.methods {
221            self.gen_function(method);
222            self.write_blank();
223        }
224
225        self.pop_indent();
226        self.write_line("}");
227    }
228
229    fn gen_block(&mut self, block: &Block) {
230        for stmt in &block.stmts {
231            self.gen_stmt(stmt);
232        }
233    }
234
235    fn gen_stmt(&mut self, stmt: &Stmt) {
236        match stmt {
237            Stmt::Let { pattern, ty, value, .. } => {
238                let pat_str = self.gen_pattern(pattern);
239                let ty_str = ty.as_ref().map(|t| format!(": {}", self.map_type(t))).unwrap_or_default();
240                if let Some(val) = value {
241                    self.write_line(&format!("let {}{} = {};", pat_str, ty_str, self.gen_expr(val)));
242                } else {
243                    self.write_line(&format!("let {}{};", pat_str, ty_str));
244                }
245            }
246
247            Stmt::Return(maybe_expr, _) => {
248                if let Some(expr) = maybe_expr {
249                    self.write_line(&format!("return {};", self.gen_expr(expr)));
250                } else {
251                    self.write_line("return;");
252                }
253            }
254
255            Stmt::Break(maybe_expr, _) => {
256                if let Some(expr) = maybe_expr {
257                    self.write_line(&format!("break {};", self.gen_expr(expr)));
258                } else {
259                    self.write_line("break;");
260                }
261            }
262
263            Stmt::Continue(_) => {
264                self.write_line("continue;");
265            }
266
267            Stmt::For { binding, iter, body, .. } => {
268                let pat = self.gen_pattern(binding);
269                self.write_line(&format!("for {} in {} {{", pat, self.gen_expr(iter)));
270                self.push_indent();
271                self.gen_block(body);
272                self.pop_indent();
273                self.write_line("}");
274            }
275
276            Stmt::While { condition, body, .. } => {
277                self.write_line(&format!("while {} {{", self.gen_expr(condition)));
278                self.push_indent();
279                self.gen_block(body);
280                self.pop_indent();
281                self.write_line("}");
282            }
283
284            Stmt::Loop { body, .. } => {
285                self.write_line("loop {");
286                self.push_indent();
287                self.gen_block(body);
288                self.pop_indent();
289                self.write_line("}");
290            }
291
292            Stmt::Expr(expr) => {
293                // Check for assignment expression
294                if let Expr::Assign { target, value, .. } = expr {
295                    self.write_line(&format!("{} = {};", self.gen_expr(target), self.gen_expr(value)));
296                } else {
297                    self.write_line(&format!("{};", self.gen_expr(expr)));
298                }
299            }
300
301            Stmt::Item(item) => {
302                // Nested items - convert to TypedItem and generate
303                // For now, skip nested items in Rust output
304            }
305        }
306    }
307
308    fn gen_expr(&self, expr: &Expr) -> String {
309        match expr {
310            Expr::Int(n, _) => n.to_string(),
311            Expr::Float(f, _) => format!("{:.1}", f),
312            Expr::String(s, _) => format!("\"{}\".to_string()", self.escape_string(s)),
313            Expr::Bool(b, _) => if *b { "true".to_string() } else { "false".to_string() },
314            Expr::None(_) => "None".to_string(),
315            Expr::Ident(name, _) => name.clone(),
316
317            Expr::Binary { left, op, right, .. } => {
318                let l = self.gen_expr(left);
319                let r = self.gen_expr(right);
320                let rust_op = self.map_binop(op);
321                format!("({} {} {})", l, rust_op, r)
322            }
323
324            Expr::Unary { op, operand, .. } => {
325                let o = self.gen_expr(operand);
326                let rust_op = self.map_unaryop(op);
327                format!("({}{})", rust_op, o)
328            }
329
330            Expr::Call { callee, args, .. } => {
331                let fn_name = self.gen_expr(callee);
332
333                // Handle KAIN builtins
334                if fn_name == "println" || fn_name == "print" {
335                    let arg_strs: Vec<String> = args.iter().map(|a| self.gen_expr(&a.value)).collect();
336                    let placeholders: Vec<&str> = arg_strs.iter().map(|_| "{}").collect();
337                    let format_str = format!("\"{}\"", placeholders.join(" "));
338                    if !arg_strs.is_empty() {
339                        return format!("{}!({}, {})", fn_name, format_str, arg_strs.join(", "));
340                    }
341                    return format!("{}!()", fn_name);
342                }
343
344                let arg_strs: Vec<String> = args.iter().map(|a| {
345                    if let Some(name) = &a.name {
346                        format!("{}: {}", name, self.gen_expr(&a.value))
347                    } else {
348                        self.gen_expr(&a.value)
349                    }
350                }).collect();
351                format!("{}({})", fn_name, arg_strs.join(", "))
352            }
353
354            Expr::MethodCall { receiver, method, args, .. } => {
355                let recv = self.gen_expr(receiver);
356                let arg_strs: Vec<String> = args.iter().map(|a| self.gen_expr(&a.value)).collect();
357                format!("{}.{}({})", recv, method, arg_strs.join(", "))
358            }
359
360            Expr::Field { object, field, .. } => {
361                format!("{}.{}", self.gen_expr(object), field)
362            }
363
364            Expr::Index { object, index, .. } => {
365                format!("{}[{}]", self.gen_expr(object), self.gen_expr(index))
366            }
367
368            Expr::Array(elements, _) => {
369                let elems: Vec<String> = elements.iter().map(|e| self.gen_expr(e)).collect();
370                format!("vec![{}]", elems.join(", "))
371            }
372
373            Expr::Tuple(elements, _) => {
374                let elems: Vec<String> = elements.iter().map(|e| self.gen_expr(e)).collect();
375                if elems.len() == 1 {
376                    format!("({},)", elems[0])
377                } else {
378                    format!("({})", elems.join(", "))
379                }
380            }
381
382            Expr::Struct { name, fields, .. } => {
383                let field_strs: Vec<String> = fields
384                    .iter()
385                    .map(|(fname, fval)| format!("{}: {}", fname, self.gen_expr(fval)))
386                    .collect();
387                format!("{} {{ {} }}", name, field_strs.join(", "))
388            }
389
390            Expr::EnumVariant { enum_name, variant, fields, .. } => {
391                match fields {
392                    EnumVariantFields::Unit => format!("{}::{}", enum_name, variant),
393                    EnumVariantFields::Tuple(args) => {
394                        let arg_strs: Vec<String> = args.iter().map(|a| self.gen_expr(a)).collect();
395                        format!("{}::{}({})", enum_name, variant, arg_strs.join(", "))
396                    }
397                    EnumVariantFields::Struct(fields) => {
398                        let field_strs: Vec<String> = fields
399                            .iter()
400                            .map(|(n, v)| format!("{}: {}", n, self.gen_expr(v)))
401                            .collect();
402                        format!("{}::{} {{ {} }}", enum_name, variant, field_strs.join(", "))
403                    }
404                }
405            }
406
407            Expr::If { condition, then_branch, else_branch, .. } => {
408                let cond = self.gen_expr(condition);
409                let then_str = self.gen_block_expr(then_branch);
410                if let Some(else_b) = else_branch {
411                    let else_str = self.gen_else_branch(else_b);
412                    format!("if {} {{ {} }} else {}", cond, then_str, else_str)
413                } else {
414                    format!("if {} {{ {} }}", cond, then_str)
415                }
416            }
417
418            Expr::Match { scrutinee, arms, .. } => {
419                let scrut = self.gen_expr(scrutinee);
420                let mut result = format!("match {} {{\n", scrut);
421                for arm in arms {
422                    let pat = self.gen_pattern(&arm.pattern);
423                    let body = self.gen_expr(&arm.body);
424                    result.push_str(&format!("    {} => {{ {} }}\n", pat, body));
425                }
426                result.push_str("}");
427                result
428            }
429
430            Expr::Lambda { params, body, .. } => {
431                let param_strs: Vec<String> = params.iter().map(|p| p.name.clone()).collect();
432                format!("|{}| {}", param_strs.join(", "), self.gen_expr(body))
433            }
434
435            Expr::Await(future, _) => {
436                format!("{}.await", self.gen_expr(future))
437            }
438
439            Expr::Ref { mutable, value, .. } => {
440                if *mutable {
441                    format!("&mut {}", self.gen_expr(value))
442                } else {
443                    format!("&{}", self.gen_expr(value))
444                }
445            }
446
447            Expr::Deref(inner, _) => {
448                format!("*{}", self.gen_expr(inner))
449            }
450
451            Expr::Cast { value, target, .. } => {
452                format!("{} as {}", self.gen_expr(value), self.map_type(target))
453            }
454
455            Expr::Try(inner, _) => {
456                format!("{}?", self.gen_expr(inner))
457            }
458
459            Expr::Range { start, end, inclusive, .. } => {
460                let s = start.as_ref().map(|e| self.gen_expr(e)).unwrap_or_default();
461                let e = end.as_ref().map(|e| self.gen_expr(e)).unwrap_or_default();
462                if *inclusive {
463                    format!("{}..={}", s, e)
464                } else {
465                    format!("{}..{}", s, e)
466                }
467            }
468
469            Expr::Block(block, _) => {
470                format!("{{ {} }}", self.gen_block_expr(block))
471            }
472
473            Expr::Paren(inner, _) => {
474                format!("({})", self.gen_expr(inner))
475            }
476
477            Expr::Return(maybe_expr, _) => {
478                if let Some(expr) = maybe_expr {
479                    format!("return {}", self.gen_expr(expr))
480                } else {
481                    "return".to_string()
482                }
483            }
484
485            Expr::Break(maybe_expr, _) => {
486                if let Some(expr) = maybe_expr {
487                    format!("break {}", self.gen_expr(expr))
488                } else {
489                    "break".to_string()
490                }
491            }
492
493            Expr::Continue(_) => "continue".to_string(),
494
495            // FString - format string with interpolation
496            Expr::FString(parts, _) => {
497                let mut format_str = String::new();
498                let mut args = Vec::new();
499                for part in parts {
500                    if let Expr::String(s, _) = part {
501                        format_str.push_str(s);
502                    } else {
503                        format_str.push_str("{}");
504                        args.push(self.gen_expr(part));
505                    }
506                }
507                if args.is_empty() {
508                    format!("format!(\"{}\")", format_str)
509                } else {
510                    format!("format!(\"{}\", {})", format_str, args.join(", "))
511                }
512            }
513
514            // Fallback for unhandled expressions
515            _ => "/* unhandled expr */".to_string(),
516        }
517    }
518
519    fn gen_block_expr(&self, block: &Block) -> String {
520        // For expression context, return the last expression value
521        if block.stmts.is_empty() {
522            return "()".to_string();
523        }
524        
525        let mut parts = Vec::new();
526        for stmt in &block.stmts {
527            match stmt {
528                Stmt::Expr(e) => parts.push(self.gen_expr(e)),
529                Stmt::Return(Some(e), _) => parts.push(format!("return {}", self.gen_expr(e))),
530                Stmt::Return(None, _) => parts.push("return".to_string()),
531                _ => {} // Skip other statements in expression context
532            }
533        }
534        parts.join("; ")
535    }
536
537    fn gen_else_branch(&self, branch: &ElseBranch) -> String {
538        match branch {
539            ElseBranch::Else(block) => {
540                format!("{{ {} }}", self.gen_block_expr(block))
541            }
542            ElseBranch::ElseIf(cond, block, maybe_else) => {
543                let cond_str = self.gen_expr(cond);
544                let then_str = self.gen_block_expr(block);
545                if let Some(else_b) = maybe_else {
546                    format!("if {} {{ {} }} else {}", cond_str, then_str, self.gen_else_branch(else_b))
547                } else {
548                    format!("if {} {{ {} }}", cond_str, then_str)
549                }
550            }
551        }
552    }
553
554    fn gen_pattern(&self, pattern: &Pattern) -> String {
555        match pattern {
556            Pattern::Wildcard(_) => "_".to_string(),
557            Pattern::Literal(expr) => self.gen_expr(expr),
558            Pattern::Binding { name, mutable, .. } => {
559                if *mutable {
560                    format!("mut {}", name)
561                } else {
562                    name.clone()
563                }
564            }
565            Pattern::Struct { name, fields, rest, .. } => {
566                let field_pats: Vec<String> = fields
567                    .iter()
568                    .map(|(n, p)| format!("{}: {}", n, self.gen_pattern(p)))
569                    .collect();
570                if *rest {
571                    format!("{} {{ {}, .. }}", name, field_pats.join(", "))
572                } else {
573                    format!("{} {{ {} }}", name, field_pats.join(", "))
574                }
575            }
576            Pattern::Tuple(pats, _) => {
577                let pat_strs: Vec<String> = pats.iter().map(|p| self.gen_pattern(p)).collect();
578                format!("({})", pat_strs.join(", "))
579            }
580            Pattern::Variant { enum_name, variant, fields, .. } => {
581                let full_name = if let Some(en) = enum_name {
582                    format!("{}::{}", en, variant)
583                } else {
584                    variant.clone()
585                };
586
587                match fields {
588                    VariantPatternFields::Unit => full_name,
589                    VariantPatternFields::Tuple(pats) => {
590                        let pat_strs: Vec<String> = pats.iter().map(|p| self.gen_pattern(p)).collect();
591                        format!("{}({})", full_name, pat_strs.join(", "))
592                    }
593                    VariantPatternFields::Struct(field_pats) => {
594                        let field_strs: Vec<String> = field_pats
595                            .iter()
596                            .map(|(n, p)| format!("{}: {}", n, self.gen_pattern(p)))
597                            .collect();
598                        format!("{} {{ {} }}", full_name, field_strs.join(", "))
599                    }
600                }
601            }
602            Pattern::Slice { patterns, rest, .. } => {
603                let mut pat_strs: Vec<String> = patterns.iter().map(|p| self.gen_pattern(p)).collect();
604                if let Some(rest_name) = rest {
605                    pat_strs.push(format!("{} @ ..", rest_name));
606                }
607                format!("[{}]", pat_strs.join(", "))
608            }
609            Pattern::Or(pats, _) => {
610                let pat_strs: Vec<String> = pats.iter().map(|p| self.gen_pattern(p)).collect();
611                pat_strs.join(" | ")
612            }
613            Pattern::Range { start, end, inclusive, .. } => {
614                let s = start.as_ref().map(|e| self.gen_expr(e)).unwrap_or_default();
615                let e = end.as_ref().map(|e| self.gen_expr(e)).unwrap_or_default();
616                if *inclusive {
617                    format!("{}..={}", s, e)
618                } else {
619                    format!("{}..{}", s, e)
620                }
621            }
622        }
623    }
624
625    // Type mapping from KAIN to Rust
626    fn map_type(&self, ty: &Type) -> String {
627        match ty {
628            Type::Named { name, generics, .. } => {
629                let rust_name = match name.as_str() {
630                    "Int" => "i64",
631                    "Float" => "f64",
632                    "Bool" => "bool",
633                    "String" => "String",
634                    "Unit" => "()",
635                    "Array" => "Vec",
636                    _ => name,
637                };
638
639                if generics.is_empty() {
640                    rust_name.to_string()
641                } else {
642                    let gen_strs: Vec<String> = generics.iter().map(|g| self.map_type(g)).collect();
643                    format!("{}<{}>", rust_name, gen_strs.join(", "))
644                }
645            }
646            Type::Tuple(types, _) => {
647                let type_strs: Vec<String> = types.iter().map(|t| self.map_type(t)).collect();
648                format!("({})", type_strs.join(", "))
649            }
650            Type::Array(inner, size, _) => {
651                format!("[{}; {}]", self.map_type(inner), size)
652            }
653            Type::Slice(inner, _) => {
654                format!("[{}]", self.map_type(inner))
655            }
656            Type::Ref { mutable, inner, .. } => {
657                if *mutable {
658                    format!("&mut {}", self.map_type(inner))
659                } else {
660                    format!("&{}", self.map_type(inner))
661                }
662            }
663            Type::Function { params, return_type, .. } => {
664                let param_strs: Vec<String> = params.iter().map(|p| self.map_type(p)).collect();
665                format!("fn({}) -> {}", param_strs.join(", "), self.map_type(return_type))
666            }
667            Type::Option(inner, _) => {
668                format!("Option<{}>", self.map_type(inner))
669            }
670            Type::Result(ok, err, _) => {
671                format!("Result<{}, {}>", self.map_type(ok), self.map_type(err))
672            }
673            Type::Infer(_) => "_".to_string(),
674            Type::Never(_) => "!".to_string(),
675            Type::Unit(_) => "()".to_string(),
676            Type::Impl { trait_name, generics, .. } => {
677                if generics.is_empty() {
678                    format!("impl {}", trait_name)
679                } else {
680                    let gen_strs: Vec<String> = generics.iter().map(|g| self.map_type(g)).collect();
681                    format!("impl {}<{}>", trait_name, gen_strs.join(", "))
682                }
683            }
684        }
685    }
686
687    fn map_binop(&self, op: &BinaryOp) -> &'static str {
688        match op {
689            BinaryOp::Add => "+",
690            BinaryOp::Sub => "-",
691            BinaryOp::Mul => "*",
692            BinaryOp::Div => "/",
693            BinaryOp::Mod => "%",
694            BinaryOp::Pow => ".pow", // Rust uses method call, but we approximate
695            BinaryOp::And => "&&",
696            BinaryOp::Or => "||",
697            BinaryOp::Eq => "==",
698            BinaryOp::Ne => "!=",
699            BinaryOp::Lt => "<",
700            BinaryOp::Le => "<=",
701            BinaryOp::Gt => ">",
702            BinaryOp::Ge => ">=",
703            BinaryOp::BitAnd => "&",
704            BinaryOp::BitOr => "|",
705            BinaryOp::BitXor => "^",
706            BinaryOp::Shl => "<<",
707            BinaryOp::Shr => ">>",
708            BinaryOp::Assign => "=",
709            BinaryOp::AddAssign => "+=",
710            BinaryOp::SubAssign => "-=",
711            BinaryOp::MulAssign => "*=",
712            BinaryOp::DivAssign => "/=",
713            BinaryOp::Range => "..",
714            BinaryOp::RangeInclusive => "..=",
715        }
716    }
717
718    fn map_unaryop(&self, op: &UnaryOp) -> &'static str {
719        match op {
720            UnaryOp::Not => "!",
721            UnaryOp::Neg => "-",
722            UnaryOp::Ref => "&",
723            UnaryOp::RefMut => "&mut ",
724            UnaryOp::BitNot => "!", // Rust uses ! for bitwise not too
725            UnaryOp::Deref => "*",
726        }
727    }
728
729    fn escape_string(&self, s: &str) -> String {
730        let mut result = String::new();
731        for c in s.chars() {
732            match c {
733                '\n' => result.push_str("\\n"),
734                '\t' => result.push_str("\\t"),
735                '\\' => result.push_str("\\\\"),
736                '"' => result.push_str("\\\""),
737                _ => result.push(c),
738            }
739        }
740        result
741    }
742}
743
744/// Generate a Cargo.toml for the transpiled Rust project
745pub fn gen_cargo_toml(name: &str, deps: &[&str]) -> String {
746    let mut sb = StringBuilder::new();
747
748    sb.push_line("[package]");
749    sb.push_line(&format!("name = \"{}\"", name));
750    sb.push_line("version = \"0.1.0\"");
751    sb.push_line("edition = \"2021\"");
752    sb.push_line("");
753    sb.push_line("# Generated by KAIN Compiler");
754    sb.push_line("");
755    sb.push_line("[dependencies]");
756
757    for dep in deps {
758        sb.push_line(&format!("{} = \"*\"", dep));
759    }
760
761    sb.build()
762}
763
764#[cfg(test)]
765mod tests {
766    use super::*;
767
768    #[test]
769    fn test_type_mapping() {
770        let gen = RustGen::new();
771        let int_ty = Type::Named {
772            name: "Int".to_string(),
773            generics: vec![],
774            span: Span::default(),
775        };
776        assert_eq!(gen.map_type(&int_ty), "i64");
777    }
778}