string example

This commit is contained in:
2025-06-01 17:30:26 +02:00
parent 35f0823432
commit 781280060c
12 changed files with 47 additions and 38 deletions

View File

@@ -1,4 +1,4 @@
func print_i64[x : I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func main[] : I64 func main[] : I64

View File

@@ -1,4 +1,4 @@
func print_i64[x : I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func is_prime[n: I64]: I64 func is_prime[n: I64]: I64

View File

@@ -1,4 +1,4 @@
func print_i64[x : I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func collatz_num[n: I64] : I64 func collatz_num[n: I64] : I64

View File

@@ -1,4 +1,4 @@
func print_i64[x : I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func main[] : I64 func main[] : I64

View File

@@ -1,4 +1,4 @@
func print_i64[x : I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func main[] : I64 func main[] : I64

View File

@@ -1,4 +1,4 @@
func print_i64[x : I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func gcd[a: I64, b: I64] : I64 func gcd[a: I64, b: I64] : I64

View File

@@ -1,4 +1,4 @@
func print_i64[x : I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func main[] : I64 func main[] : I64

View File

@@ -1,4 +1,4 @@
func print_i64[x : I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func is_prime[n: I64]: I64 func is_prime[n: I64]: I64

View File

@@ -1,4 +1,4 @@
func print_i64[x : I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func main[] : I64 func main[] : I64

View File

@@ -1,4 +1,4 @@
func print_i64[x : I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func main[] : I64 func main[] : I64

12
examples/strings.zr Normal file
View File

@@ -0,0 +1,12 @@
func print_i64[x: I64] : I64
printf("%ld\n", x)
func i64_to_string[n: I64] : String
let x: I64 = malloc(21)
sprintf(x, "%d", n)
return x
func main[] : I64
let s: String = i64_to_string(58394)
print_i64(strlen(s))
free(s)

View File

@@ -57,6 +57,9 @@ macro_rules! emit {
}; };
} }
static REGISTERS: [&str; 6] = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"];
static TYPES: [&str; 2] = ["I64", "String"];
pub struct CodegenX86_64 { pub struct CodegenX86_64 {
output: String, output: String,
data_section: String, data_section: String,
@@ -74,18 +77,6 @@ impl CodegenX86_64 {
} }
} }
fn nth_register(n: usize) -> &'static str {
match n {
0 => "rdi",
1 => "rsi",
2 => "rdx",
3 => "rcx",
4 => "r8",
5 => "r9",
_ => todo!("only up to 6 arguments supported"),
}
}
fn label(&mut self) -> String { fn label(&mut self) -> String {
self.label_counter += 1; self.label_counter += 1;
format!(".L{}", self.label_counter) format!(".L{}", self.label_counter)
@@ -94,8 +85,7 @@ impl CodegenX86_64 {
pub fn get_output(&self) -> String { pub fn get_output(&self) -> String {
format!( format!(
"section .data "section .data
{} {}{}",
{}",
self.data_section, self.output self.data_section, self.output
) )
} }
@@ -105,7 +95,11 @@ impl CodegenX86_64 {
&mut self.output, &mut self.output,
" "
section .text section .text
extern malloc
extern free
extern printf extern printf
extern sprintf
extern strlen
extern puts extern puts
print equ puts print equ puts
", ",
@@ -128,7 +122,9 @@ print equ puts
initializer, initializer,
} => { } => {
// TODO: types // TODO: types
assert!(var_type.lexeme == "I64"); if !TYPES.contains(&var_type.lexeme.as_str()) {
return error!(&name.loc, format!("unknown type: {}", var_type.lexeme));
}
self.compile_expr(env, initializer)?; self.compile_expr(env, initializer)?;
let offset = env.define_var(name.lexeme.clone(), var_type.lexeme); let offset = env.define_var(name.lexeme.clone(), var_type.lexeme);
@@ -176,7 +172,9 @@ print equ puts
return_type, return_type,
body, body,
} => { } => {
assert!(return_type.lexeme == "I64"); // TODO if !TYPES.contains(&return_type.lexeme.as_str()) {
return error!(&name.loc, format!("unknown type: {}", return_type.lexeme));
}
emit!(&mut self.output, "global {}", name.lexeme); emit!(&mut self.output, "global {}", name.lexeme);
emit!(&mut self.output, "{}:", name.lexeme); emit!(&mut self.output, "{}:", name.lexeme);
@@ -187,12 +185,11 @@ print equ puts
for (i, param) in params.iter().enumerate() { for (i, param) in params.iter().enumerate() {
let offset = env let offset = env
.define_var(param.var_name.lexeme.clone(), param.var_type.lexeme.clone()); .define_var(param.var_name.lexeme.clone(), param.var_type.lexeme.clone());
emit!( let reg = match REGISTERS.get(i) {
&mut self.output, Some(x) => x,
" mov QWORD [rbp-{}], {}", None => return error!(&name.loc, "only up to 6 params allowed"),
offset, };
CodegenX86_64::nth_register(i), emit!(&mut self.output, " mov QWORD [rbp-{}], {}", offset, reg,);
);
} }
self.compile_stmt(env, *body)?; self.compile_stmt(env, *body)?;
@@ -350,7 +347,7 @@ print equ puts
} }
Expr::Call { Expr::Call {
callee, callee,
paren: _, paren,
args, args,
} => { } => {
let callee = match *callee { let callee = match *callee {
@@ -360,11 +357,11 @@ print equ puts
for (i, arg) in args.iter().enumerate() { for (i, arg) in args.iter().enumerate() {
self.compile_expr(env, arg.clone())?; self.compile_expr(env, arg.clone())?;
emit!( let reg = match REGISTERS.get(i) {
&mut self.output, Some(x) => x,
" mov {}, rax", None => return error!(&paren.loc, "only up to 6 args allowed"),
CodegenX86_64::nth_register(i), };
); emit!(&mut self.output, " mov {}, rax", reg,);
} }
emit!(&mut self.output, " call {}", callee); emit!(&mut self.output, " call {}", callee);