array indexing, nested array literals
This commit is contained in:
@@ -1,10 +1,5 @@
|
||||
func main[] : I64
|
||||
let xs: Array = [5849, 3869, 2859]
|
||||
Array.push(xs, 5242)
|
||||
Array.push(xs, 6533)
|
||||
Array.push(xs, 4574)
|
||||
|
||||
for i in 0..Array.size(xs)
|
||||
xs
|
||||
|> Array.nth(i)
|
||||
|> print_i64()
|
||||
let xs: Array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
||||
for x in 0..3
|
||||
for y in 0..3
|
||||
print_i64(xs[y][x])
|
||||
@@ -8,16 +8,16 @@ func do_quicksort[arr: Array, low: I64, high: I64] : I64
|
||||
do_quicksort(arr, i + 1, high)
|
||||
|
||||
func partition[arr: Array, low: I64, high: I64] : I64
|
||||
let pivot: I64 = Array.nth(arr, high)
|
||||
let pivot: I64 = arr[high]
|
||||
let i: I64 = low - 1
|
||||
for j in (low)..high
|
||||
if Array.nth(arr, j) <= pivot
|
||||
if arr[j] <= pivot
|
||||
i = i + 1
|
||||
let temp: I64 = Array.nth(arr, i)
|
||||
Array.set(arr, i, Array.nth(arr, j))
|
||||
let temp: I64 = arr[i]
|
||||
Array.set(arr, i, arr[j])
|
||||
Array.set(arr, j, temp)
|
||||
let temp: I64 = Array.nth(arr, i + 1)
|
||||
Array.set(arr, i + 1, Array.nth(arr, high))
|
||||
let temp: I64 = arr[i + 1]
|
||||
Array.set(arr, i + 1, arr[high])
|
||||
Array.set(arr, high, temp)
|
||||
return i + 1
|
||||
|
||||
@@ -25,10 +25,10 @@ func main[] : I64
|
||||
let arr: Array = [340, 252, 352, 117, 650, 652, 322, 175, 714, 268, 725, 664]
|
||||
|
||||
for i in 0..Array.size(arr)
|
||||
print_i64(Array.nth(arr, i))
|
||||
print_i64(arr[i])
|
||||
print("------------")
|
||||
|
||||
quicksort(arr)
|
||||
|
||||
for i in 0..Array.size(arr)
|
||||
print_i64(Array.nth(arr, i))
|
||||
print_i64(arr[i])
|
||||
@@ -1,14 +1,15 @@
|
||||
func rule110_step[state: Array] : Array
|
||||
let new_state: Array = []
|
||||
let state_len: I64 = Array.size(state)
|
||||
|
||||
for i in 0..Array.size(state)
|
||||
for i in 0..state_len
|
||||
let left: Bool = false
|
||||
if i - 1 >= 0
|
||||
left = Array.nth(state, i-1)
|
||||
let center: Bool = Array.nth(state, i)
|
||||
left = state[i-1]
|
||||
let center: Bool = state[i]
|
||||
let right: Bool = false
|
||||
if i + 1 < Array.size(state)
|
||||
right = Array.nth(state, i+1)
|
||||
if i + 1 < state_len
|
||||
right = state[i+1]
|
||||
|
||||
Array.push(new_state, !((!left && !center && !right) || (left && !center && !right) || (left && center && right)))
|
||||
|
||||
@@ -17,7 +18,7 @@ func rule110_step[state: Array] : Array
|
||||
func to_str[state: Array]: String
|
||||
let out: String = malloc(Array.size(state))
|
||||
for i in 0..Array.size(state)
|
||||
if Array.nth(state, i)
|
||||
if state[i]
|
||||
String.set(out, i, '#')
|
||||
else
|
||||
String.set(out, i, ' ')
|
||||
|
||||
@@ -58,8 +58,6 @@ macro_rules! emit {
|
||||
}
|
||||
|
||||
static REGISTERS: [&str; 6] = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"];
|
||||
// TODO: currently they are all just 8 byte values
|
||||
static TYPES: [&str; 6] = ["U8", "I64", "String", "Bool", "Ptr", "Array"];
|
||||
|
||||
pub struct CodegenX86_64 {
|
||||
output: String,
|
||||
@@ -234,12 +232,6 @@ OS.listdir:
|
||||
pop r14
|
||||
ret
|
||||
|
||||
section .text.Array.nth
|
||||
Array.nth:
|
||||
mov rax, [rdi]
|
||||
mov rax, [rax + rsi*8]
|
||||
ret
|
||||
|
||||
section .text.Array.set
|
||||
Array.set:
|
||||
mov rax, [rdi]
|
||||
@@ -302,11 +294,6 @@ Array.free:
|
||||
var_type,
|
||||
initializer,
|
||||
} => {
|
||||
// TODO: types
|
||||
if !TYPES.contains(&var_type.lexeme.as_str()) {
|
||||
return error!(&name.loc, format!("unknown type: {}", var_type.lexeme));
|
||||
}
|
||||
|
||||
self.compile_expr(env, initializer)?;
|
||||
let offset = env.define_var(name.lexeme.clone(), var_type.lexeme);
|
||||
emit!(&mut self.output, " mov QWORD [rbp-{}], rax", offset);
|
||||
@@ -353,10 +340,6 @@ Array.free:
|
||||
return_type,
|
||||
body,
|
||||
} => {
|
||||
if !TYPES.contains(&return_type.lexeme.as_str()) {
|
||||
return error!(&name.loc, format!("unknown type: {}", return_type.lexeme));
|
||||
}
|
||||
|
||||
// TODO
|
||||
if name.lexeme == "main" {
|
||||
emit!(&mut self.output, "global {}", name.lexeme);
|
||||
@@ -377,7 +360,7 @@ Array.free:
|
||||
Some(x) => x,
|
||||
None => return error!(&name.loc, "only up to 6 params allowed"),
|
||||
};
|
||||
emit!(&mut self.output, " mov QWORD [rbp-{}], {}", offset, reg,);
|
||||
emit!(&mut self.output, " mov QWORD [rbp-{}], {}", offset, reg);
|
||||
}
|
||||
|
||||
self.compile_stmt(env, *body)?;
|
||||
@@ -625,16 +608,24 @@ Array.free:
|
||||
}
|
||||
Expr::ArrayLiteral(exprs) => {
|
||||
emit!(&mut self.output, " call Array.new");
|
||||
emit!(&mut self.output, " mov r12, rax");
|
||||
emit!(&mut self.output, " push rax");
|
||||
|
||||
// TODO: nested array literals probably dont work
|
||||
for expr in exprs {
|
||||
self.compile_expr(env, expr)?;
|
||||
emit!(&mut self.output, " mov rsi, rax");
|
||||
emit!(&mut self.output, " mov rdi, r12");
|
||||
emit!(&mut self.output, " pop rdi");
|
||||
emit!(&mut self.output, " push rdi");
|
||||
emit!(&mut self.output, " call Array.push");
|
||||
}
|
||||
emit!(&mut self.output, " mov rax, r12");
|
||||
emit!(&mut self.output, " pop rax");
|
||||
}
|
||||
Expr::Index { expr, index } => {
|
||||
self.compile_expr(env, *expr)?;
|
||||
emit!(&mut self.output, " push rax");
|
||||
self.compile_expr(env, *index)?;
|
||||
emit!(&mut self.output, " pop rbx");
|
||||
emit!(&mut self.output, " mov rbx, [rbx]");
|
||||
emit!(&mut self.output, " mov rax, [rbx + rax*8]");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -67,8 +67,15 @@ pub enum Expr {
|
||||
args: Vec<Expr>,
|
||||
},
|
||||
ArrayLiteral(Vec<Expr>),
|
||||
Index {
|
||||
expr: Box<Expr>,
|
||||
index: Box<Expr>,
|
||||
},
|
||||
}
|
||||
|
||||
// TODO: currently they are all just 8 byte values
|
||||
static TYPES: [&str; 6] = ["U8", "I64", "String", "Bool", "Ptr", "Array"];
|
||||
|
||||
pub struct Parser {
|
||||
tokens: Vec<Token>,
|
||||
current: usize,
|
||||
@@ -120,7 +127,12 @@ impl Parser {
|
||||
loop {
|
||||
let var_name = self.consume(TokenType::Identifier, "expected parameter name")?;
|
||||
self.consume(TokenType::Colon, "expected ':' after parameter name")?;
|
||||
|
||||
let var_type = self.consume(TokenType::Identifier, "expected parameter type")?;
|
||||
if !TYPES.contains(&var_type.lexeme.as_str()) {
|
||||
return error!(&name.loc, format!("unknown type: {}", var_type.lexeme));
|
||||
}
|
||||
|
||||
params.push(Param { var_type, var_name });
|
||||
if !self.match_token(&[TokenType::Comma]) {
|
||||
break;
|
||||
@@ -131,6 +143,9 @@ impl Parser {
|
||||
self.consume(TokenType::RightBracket, "expected ']' after arguments")?;
|
||||
self.consume(TokenType::Colon, "expected ':' after '['")?;
|
||||
let return_type = self.consume(TokenType::Identifier, "expected return type")?;
|
||||
if !TYPES.contains(&return_type.lexeme.as_str()) {
|
||||
return error!(&name.loc, format!("unknown type: {}", return_type.lexeme));
|
||||
}
|
||||
|
||||
self.is_inside_function = true;
|
||||
let body = Box::new(self.block()?);
|
||||
@@ -147,7 +162,12 @@ impl Parser {
|
||||
fn let_declaration(&mut self) -> Result<Stmt, ZernError> {
|
||||
let name = self.consume(TokenType::Identifier, "expected variable name")?;
|
||||
self.consume(TokenType::Colon, "expected ':' after variable name")?;
|
||||
|
||||
let var_type = self.consume(TokenType::Identifier, "expected variable type")?;
|
||||
if !TYPES.contains(&var_type.lexeme.as_str()) {
|
||||
return error!(&name.loc, format!("unknown type: {}", var_type.lexeme));
|
||||
}
|
||||
|
||||
self.consume(TokenType::Equal, "expected '=' after variable type")?;
|
||||
let initializer = self.expression()?;
|
||||
Ok(Stmt::Let {
|
||||
@@ -401,7 +421,8 @@ impl Parser {
|
||||
fn call(&mut self) -> Result<Expr, ZernError> {
|
||||
let mut expr = self.primary()?;
|
||||
|
||||
while self.match_token(&[TokenType::LeftParen]) {
|
||||
loop {
|
||||
if self.match_token(&[TokenType::LeftParen]) {
|
||||
let mut args = vec![];
|
||||
if !self.check(&TokenType::RightParen) {
|
||||
loop {
|
||||
@@ -419,6 +440,16 @@ impl Parser {
|
||||
paren,
|
||||
args,
|
||||
};
|
||||
} else if self.match_token(&[TokenType::LeftBracket]) {
|
||||
let index = self.expression()?;
|
||||
self.consume(TokenType::RightBracket, "expected ']' after index")?;
|
||||
expr = Expr::Index {
|
||||
expr: Box::new(expr),
|
||||
index: Box::new(index),
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(expr)
|
||||
|
||||
Reference in New Issue
Block a user