parse var types

This commit is contained in:
2025-05-29 20:57:07 +02:00
parent 47fd9a36a4
commit da1102714a
3 changed files with 42 additions and 12 deletions

View File

@@ -5,8 +5,13 @@ use crate::{
tokenizer::{MotError, TokenType, error}, tokenizer::{MotError, TokenType, error},
}; };
struct Var {
var_type: String,
stack_offset: usize,
}
pub struct Env { pub struct Env {
locals: HashMap<String, usize>, locals: HashMap<String, Var>,
} }
impl Env { impl Env {
@@ -77,10 +82,20 @@ section .note.GNU-stack
call printf" call printf"
)?; )?;
} }
Stmt::Var { name, initializer } => { Stmt::Var {
name,
var_type,
initializer,
} => {
// TODO
assert!(var_type.lexeme == "I64");
self.compile_expr(env, initializer)?; self.compile_expr(env, initializer)?;
let offset = (env.locals.len() + 1) * 8; let offset = (env.locals.len() + 1) * 8;
env.locals.insert(name.lexeme, offset); env.locals.insert(name.lexeme, Var {
var_type: var_type.lexeme,
stack_offset: offset,
});
writeln!(&mut self.output, " mov QWORD [rbp-{}], rax", offset)?; writeln!(&mut self.output, " mov QWORD [rbp-{}], rax", offset)?;
} }
Stmt::Block(statements) => { Stmt::Block(statements) => {
@@ -151,23 +166,31 @@ section .note.GNU-stack
} }
} }
Expr::Variable(name) => { Expr::Variable(name) => {
let offset = match env.locals.get(&name.lexeme) { let var = match env.locals.get(&name.lexeme) {
Some(x) => x, Some(x) => x,
None => { None => {
return error!(name.loc, format!("undefined variable: {}", &name.lexeme)); return error!(name.loc, format!("undefined variable: {}", &name.lexeme));
} }
}; };
writeln!(&mut self.output, " mov rax, QWORD [rbp-{}]", offset)? writeln!(
&mut self.output,
" mov rax, QWORD [rbp-{}]",
var.stack_offset
)?
} }
Expr::Assign { name, value } => { Expr::Assign { name, value } => {
self.compile_expr(env, *value)?; self.compile_expr(env, *value)?;
let offset = match env.locals.get(&name.lexeme) { let var = match env.locals.get(&name.lexeme) {
Some(x) => x, Some(x) => x,
None => { None => {
return error!(name.loc, format!("undefined variable: {}", &name.lexeme)); return error!(name.loc, format!("undefined variable: {}", &name.lexeme));
} }
}; };
writeln!(&mut self.output, " mov QWORD [rbp-{}], rax", offset)?; writeln!(
&mut self.output,
" mov QWORD [rbp-{}], rax",
var.stack_offset
)?;
} }
} }
Ok(()) Ok(())

View File

@@ -8,6 +8,7 @@ pub enum Stmt {
Print(Expr), Print(Expr),
Var { Var {
name: Token, name: Token,
var_type: Token,
initializer: Expr, initializer: Expr,
}, },
Block(Vec<Stmt>), Block(Vec<Stmt>),
@@ -71,9 +72,15 @@ impl Parser {
fn let_declaration(&mut self) -> Result<Stmt, Box<dyn Error>> { fn let_declaration(&mut self) -> Result<Stmt, Box<dyn Error>> {
let name = self.consume(TokenType::Identifier, "expected variable name")?; let name = self.consume(TokenType::Identifier, "expected variable name")?;
self.consume(TokenType::Equal, "expected '=' after variable name")?; self.consume(TokenType::Colon, "expected ':' after variable name")?;
let var_type = self.consume(TokenType::Identifier, "expected variable type")?;
self.consume(TokenType::Equal, "expected '=' after variable type")?;
let initializer = self.expression()?; let initializer = self.expression()?;
Ok(Stmt::Var { name, initializer }) Ok(Stmt::Var {
name,
var_type,
initializer,
})
} }
fn block(&mut self) -> Result<Stmt, Box<dyn Error>> { fn block(&mut self) -> Result<Stmt, Box<dyn Error>> {

View File

@@ -1,6 +1,6 @@
let a = 0 let a: I64 = 0
let b = 1 let b: I64 = 1
let temp = 0 let temp: I64 = 0
while a < 10000 while a < 10000
print a print a