addr-of operator
This commit is contained in:
@@ -160,6 +160,9 @@ impl Analyzer {
|
||||
self.analyze_expr(expr)?;
|
||||
self.analyze_expr(index)?;
|
||||
}
|
||||
Expr::AddrOf { op: _, expr } => {
|
||||
self.analyze_expr(expr)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -548,6 +548,31 @@ _builtin_environ:
|
||||
emit!(&mut self.output, " add rdi, rax");
|
||||
emit!(&mut self.output, " call _builtin_read8");
|
||||
}
|
||||
Expr::AddrOf { op, expr } => match *expr {
|
||||
Expr::Variable(name) => {
|
||||
if self.analyzer.functions.contains_key(&name.lexeme) {
|
||||
emit!(&mut self.output, " mov rax, {}", name.lexeme);
|
||||
} else {
|
||||
let var = match env.get_var(&name.lexeme) {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
return error!(
|
||||
name.loc,
|
||||
format!("undefined variable: {}", &name.lexeme)
|
||||
);
|
||||
}
|
||||
};
|
||||
emit!(
|
||||
&mut self.output,
|
||||
" lea rax, QWORD [rbp-{}]",
|
||||
var.stack_offset,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return error!(&op.loc, "can only take address of variables and functions");
|
||||
}
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -71,6 +71,10 @@ pub enum Expr {
|
||||
expr: Box<Expr>,
|
||||
index: Box<Expr>,
|
||||
},
|
||||
AddrOf {
|
||||
op: Token,
|
||||
expr: Box<Expr>,
|
||||
},
|
||||
}
|
||||
|
||||
// TODO: currently they are all just 8 byte values
|
||||
@@ -408,6 +412,14 @@ impl Parser {
|
||||
}
|
||||
|
||||
fn unary(&mut self) -> Result<Expr, ZernError> {
|
||||
if self.match_token(&[TokenType::At]) {
|
||||
let op = self.previous().clone();
|
||||
let right = self.unary()?;
|
||||
return Ok(Expr::AddrOf {
|
||||
op,
|
||||
expr: Box::new(right),
|
||||
});
|
||||
}
|
||||
if self.match_token(&[TokenType::Bang, TokenType::Minus]) {
|
||||
let op = self.previous().clone();
|
||||
let right = self.unary()?;
|
||||
|
||||
@@ -18,6 +18,7 @@ pub enum TokenType {
|
||||
BitAnd,
|
||||
BitOr,
|
||||
Pipe,
|
||||
At,
|
||||
DoubleDot,
|
||||
ShiftLeft,
|
||||
ShiftRight,
|
||||
@@ -154,6 +155,7 @@ impl Tokenizer {
|
||||
'%' => self.add_token(TokenType::Mod),
|
||||
'^' => self.add_token(TokenType::Xor),
|
||||
':' => self.add_token(TokenType::Colon),
|
||||
'@' => self.add_token(TokenType::At),
|
||||
'.' => {
|
||||
if self.match_char('.') {
|
||||
self.add_token(TokenType::DoubleDot)
|
||||
|
||||
2
test.zr
2
test.zr
@@ -1,5 +1,5 @@
|
||||
func run_test[x: String] : Void
|
||||
if str.equal(x, "raylib.zr") | str.equal(x, "x11.zr") | str.equal(x, "sqlite_todo.zr")
|
||||
if str.equal(x, "puzzles") | str.equal(x, "raylib.zr") | str.equal(x, "x11.zr") | str.equal(x, "sqlite_todo.zr")
|
||||
io.print("\033[93mSkipping ")
|
||||
io.print(x)
|
||||
io.println("...\033[0m")
|
||||
|
||||
Reference in New Issue
Block a user