basic One2C code gen
This commit is contained in:
132
generator.v
Normal file
132
generator.v
Normal file
@@ -0,0 +1,132 @@
|
||||
module main
|
||||
|
||||
import strings
|
||||
import os
|
||||
|
||||
struct Generator {
|
||||
mut:
|
||||
out strings.Builder
|
||||
}
|
||||
|
||||
fn (mut g Generator) get_c_type(typ string) string {
|
||||
c_type := if typ == 'real' { 'double' } else { typ }
|
||||
return c_type
|
||||
}
|
||||
|
||||
fn (mut g Generator) gen_stmt(stmt Stmt) {
|
||||
match stmt {
|
||||
VarDecl {
|
||||
c_type := g.get_c_type(stmt.type)
|
||||
g.out.write_string('${c_type} ${stmt.name} = ')
|
||||
g.gen_expr(stmt.value)
|
||||
g.out.writeln(';')
|
||||
}
|
||||
ExprStmt {
|
||||
g.gen_expr(stmt.expr)
|
||||
g.out.writeln(';')
|
||||
}
|
||||
ReturnStmt {
|
||||
g.out.write_string('return ')
|
||||
g.gen_expr(stmt.expr)
|
||||
g.out.writeln(';')
|
||||
}
|
||||
Block {
|
||||
g.out.writeln('{')
|
||||
for inner_stmt in stmt.stmts {
|
||||
g.gen_stmt(inner_stmt)
|
||||
}
|
||||
g.out.writeln('}')
|
||||
}
|
||||
FuncDecl {
|
||||
c_type := g.get_c_type(stmt.ret_type)
|
||||
g.out.write_string('${c_type} ${stmt.name}() ')
|
||||
g.gen_stmt(stmt.block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Generator) gen_expr(expr Expr) {
|
||||
match expr {
|
||||
RealLiteral {
|
||||
g.out.write_string(expr.val.str())
|
||||
}
|
||||
IntegerLiteral {
|
||||
g.out.write_string(expr.val.str())
|
||||
}
|
||||
BoolLiteral {
|
||||
g.out.write_string(expr.val.str())
|
||||
}
|
||||
Variable {
|
||||
g.out.write_string(expr.name)
|
||||
}
|
||||
UnaryExpr {
|
||||
// Handle postfix/prefix logic if necessary
|
||||
g.out.write_string('${expr.ident}${expr.op}')
|
||||
}
|
||||
BinaryExpr {
|
||||
g.out.write_string('(')
|
||||
g.gen_expr(expr.left)
|
||||
g.out.write_string(' ${expr.op} ')
|
||||
g.gen_expr(expr.right)
|
||||
g.out.write_string(')')
|
||||
}
|
||||
PrintExpr {
|
||||
g.out.write_string('printf(\"%')
|
||||
format := match expr.type {
|
||||
'int' {'d'}
|
||||
'real' {'lf'}
|
||||
'bool' {'d'}
|
||||
else {panic("Tried printing illegal type")}
|
||||
}
|
||||
g.out.write_string('${format}\\n\", ')
|
||||
g.gen_expr(expr.expr)
|
||||
g.out.write_string(')')
|
||||
}
|
||||
TypeCast {
|
||||
c_type := g.get_c_type(expr.type)
|
||||
g.out.write_string('(${c_type})')
|
||||
g.gen_expr(expr.expr)
|
||||
}
|
||||
else {panic('unimplemented ${expr}')}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Generator) gen_c(program []Stmt) string {
|
||||
g.out.writeln('#include <stdio.h>')
|
||||
g.out.writeln('#include <stdbool.h>') // For your 'bool' types [cite: 4]
|
||||
for stmt in program {
|
||||
g.gen_stmt(stmt)
|
||||
}
|
||||
|
||||
return g.out.str()
|
||||
|
||||
}
|
||||
|
||||
fn compile_with_clang(c_code string, output_name string, keep_c bool) {
|
||||
// 1. Write the C code to a temporary file
|
||||
c_file := 'middle_c.c'
|
||||
os.write_file(c_file, c_code) or {
|
||||
eprintln('Failed to write C file: $err')
|
||||
return
|
||||
}
|
||||
|
||||
// 2. Construct the clang command
|
||||
// We'll use -O2 for optimization and -o to specify the output binary
|
||||
clang_cmd := 'clang ${c_file} -o ${output_name} -O2'
|
||||
|
||||
println('Executing: ${clang_cmd}')
|
||||
|
||||
// 3. Run the command
|
||||
result := os.execute(clang_cmd)
|
||||
|
||||
if result.exit_code != 0 {
|
||||
eprintln('Clang Compilation Failed:')
|
||||
eprintln(result.output)
|
||||
} else {
|
||||
println('Compilation successful! Binary created: $output_name')
|
||||
// Optional: Remove the temporary C file
|
||||
if !keep_c {
|
||||
os.rm(c_file) or { }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user