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},
};
struct Var {
var_type: String,
stack_offset: usize,
}
pub struct Env {
locals: HashMap<String, usize>,
locals: HashMap<String, Var>,
}
impl Env {
@@ -77,10 +82,20 @@ section .note.GNU-stack
call printf"
)?;
}
Stmt::Var { name, initializer } => {
Stmt::Var {
name,
var_type,
initializer,
} => {
// TODO
assert!(var_type.lexeme == "I64");
self.compile_expr(env, initializer)?;
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)?;
}
Stmt::Block(statements) => {
@@ -151,23 +166,31 @@ section .note.GNU-stack
}
}
Expr::Variable(name) => {
let offset = match env.locals.get(&name.lexeme) {
let var = match env.locals.get(&name.lexeme) {
Some(x) => x,
None => {
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 } => {
self.compile_expr(env, *value)?;
let offset = match env.locals.get(&name.lexeme) {
let var = match env.locals.get(&name.lexeme) {
Some(x) => x,
None => {
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(())

View File

@@ -8,6 +8,7 @@ pub enum Stmt {
Print(Expr),
Var {
name: Token,
var_type: Token,
initializer: Expr,
},
Block(Vec<Stmt>),
@@ -71,9 +72,15 @@ impl Parser {
fn let_declaration(&mut self) -> Result<Stmt, Box<dyn Error>> {
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()?;
Ok(Stmt::Var { name, initializer })
Ok(Stmt::Var {
name,
var_type,
initializer,
})
}
fn block(&mut self) -> Result<Stmt, Box<dyn Error>> {

View File

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