module main import strings import os struct Generator { mut: symbols SymbolTable out strings.Builder } fn mangle_var(name string) string { return 'one_var_${name}' } fn mangle_func(name string, class_name ?string) string { if name == 'main' {return 'main'} mut mangled_name := 'one_func_${name}' if class_name != none { mangled_name += '_${class_name}' } return mangled_name } fn mangle_struct(name string) string { return 'one_class_${name}' } fn get_type_format(type string) string { if type.contains('*') { return 'p' } return match type { 'int', 'bool' {'d'} 'real' {'f'} 'string' {'s'} else {panic("invalid type to print")} } } fn (mut g Generator) get_print_label(expr Expr) string { return match expr { Variable { expr.name } MemberAccess { "${g.get_print_label(expr.from)}.${expr.member}" } else { "" } } } fn (mut g Generator) get_c_type(typ string) string { astkcount := typ.count('*') clean := typ.replace('*', '') return match clean { 'real' {'float'} 'int' {'int32_t'} 'string' {'OneString'} else {clean} } + '*'.repeat(astkcount) } fn (mut g Generator) mangle_if_class(name string) string { astkcount := name.count('*') noptr := name.replace('*', '') if g.symbols.lookup_class(noptr) != none { return 'struct ${mangle_struct(noptr)}' + '*'.repeat(astkcount) } return name } // thank google gemini for this one, I genuinely did not have the mental strength to // think this at 9pm fn (mut g Generator) gen_class_print_func(stmt ClassDecl) { struct_name := mangle_struct(stmt.name) g.out.writeln('void print_${struct_name}(struct ${struct_name} s, int indent) {') g.out.writeln('printf("${stmt.name} {\\n");') for member in stmt.members { g.out.writeln('for(int i=0; i 0 { g.out.write_string(', ') } for arg in expr.args { g.gen_expr(arg) if arg != expr.args[expr.args.len-1]{ g.out.write_string(', ') } } g.out.write_string(')') } ClassMember { c_type := g.mangle_if_class(g.get_c_type(expr.type)) g.out.write_string('${c_type} ${expr.name}') } ClassInstantiation { g.out.write_string('(struct ${mangle_struct(expr.name)}){') for m_expr in expr.member_values { g.gen_expr(m_expr) if m_expr != expr.member_values[expr.member_values.len - 1] { g.out.write_string(', ') } } g.out.write_string('}') } MemberAccess { g.gen_expr(expr.from) match expr.from_type.count('*') { 0 {g.out.write_string('.')} 1 {g.out.write_string('->')} else {panic("Tried accessing member from an object of type ${expr.from_type}")} } g.out.write_string('${expr.member}') } else {panic("Unimplemented expression")} } } fn (mut g Generator) gen_c(program []Stmt) string { g.out.writeln('#include ') g.out.writeln('#include ') g.out.writeln('#include ') g.out.writeln('typedef struct {\nchar* string;\nint len;\n} OneString;') for stmt in program { g.gen_stmt(stmt) } return g.out.str() } fn compile(c_code string, output_name string, keep_c bool, compiler string) { c_file := 'middle_c.c' os.write_file(c_file, c_code) or { eprintln('Failed to write C file: $err') return } cmd := match compiler { 'clang' {'clang ${c_file} -o ${output_name} -O2'} 'gcc' {'gcc ${c_file} -o ${output_name} -O2'} else {panic("Invalid compiler")} } println('Executing: ${cmd}') result := os.execute(cmd) if result.exit_code != 0 { eprintln('${compiler} Compilation Failed:') eprintln(result.output) } else { println('Compilation successful! Binary created: $output_name') if !keep_c { os.rm(c_file) or { } } } }