parse var types
This commit is contained in:
@@ -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(())
|
||||||
|
|||||||
@@ -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>> {
|
||||||
|
|||||||
Reference in New Issue
Block a user