finally add real logical operators
This commit is contained in:
@@ -27,7 +27,7 @@ func main[] : i64
|
||||
if !memory[p]
|
||||
i = i + 1
|
||||
let opened = 0
|
||||
while i < src_len & !(src[i] == ']' & !opened)
|
||||
while i < src_len && !(src[i] == ']' && !opened)
|
||||
if src[i] == '['
|
||||
opened = opened + 1
|
||||
else if src[i] == ']'
|
||||
@@ -37,7 +37,7 @@ func main[] : i64
|
||||
if memory[p]
|
||||
i = i - 1
|
||||
let closed = 0
|
||||
while i >= 0 & !(src[i] == '[' & !closed)
|
||||
while i >= 0 && !(src[i] == '[' && !closed)
|
||||
if src[i] == ']'
|
||||
closed = closed + 1
|
||||
else if src[i] == '['
|
||||
|
||||
@@ -41,14 +41,14 @@ func main[argc: i64, argv: ptr] : i64
|
||||
let found: bool = false
|
||||
let end_index: i64 = -1
|
||||
|
||||
while !found & header_size < 8192
|
||||
while !found && header_size < 8192
|
||||
let n: i64 = net.read(s, header_buf + header_size, 8192 - header_size)
|
||||
if n <= 0
|
||||
break
|
||||
let current_size: i64 = header_size + n
|
||||
i = 0
|
||||
while i <= current_size - 4
|
||||
if header_buf[i] == 13 & header_buf[i + 1] == 10 & header_buf[i + 2] == 13 & header_buf[i + 3] == 10
|
||||
if header_buf[i] == 13 && header_buf[i + 1] == 10 && header_buf[i + 2] == 13 && header_buf[i + 3] == 10
|
||||
found = true
|
||||
end_index = i + 4
|
||||
break
|
||||
|
||||
@@ -2,13 +2,13 @@ func check[report: array] : bool
|
||||
let increasing: bool = array.nth(report, 0) < array.nth(report, 1)
|
||||
|
||||
for i in 0..array.size(report)-1
|
||||
if array.nth(report, i) > array.nth(report, i + 1) & increasing
|
||||
if array.nth(report, i) > array.nth(report, i + 1) && increasing
|
||||
return false
|
||||
if array.nth(report, i) < array.nth(report, i + 1) & !increasing
|
||||
if array.nth(report, i) < array.nth(report, i + 1) && !increasing
|
||||
return false
|
||||
|
||||
let diff: i64 = math.abs(array.nth(report, i) - array.nth(report, i + 1))
|
||||
if diff < 1 | diff > 3
|
||||
if diff < 1 || diff > 3
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
func check[lines: array, x: i64, y: i64, dx: i64, dy: i64] : bool
|
||||
if x + dx * 3 < 0 | x + dx * 3 >= array.size(lines) | y + dy * 3 < 0 | y + dy * 3 >= str.len(array.nth(lines, 0))
|
||||
if x + dx * 3 < 0 || x + dx * 3 >= array.size(lines) || y + dy * 3 < 0 || y + dy * 3 >= str.len(array.nth(lines, 0))
|
||||
return false
|
||||
|
||||
if array.nth(lines, x)[y] != 'X'
|
||||
@@ -50,7 +50,7 @@ func part2[lines: array] : void
|
||||
str.set(s, 3, array.nth(lines, x - 1)[y + 1])
|
||||
str.set(s, 4, 0)
|
||||
|
||||
if str.equal(s, "MSSM") | str.equal(s, "SMMS") | str.equal(s, "MMSS") | str.equal(s, "SSMM")
|
||||
if str.equal(s, "MSSM") || str.equal(s, "SMMS") || str.equal(s, "MMSS") || str.equal(s, "SSMM")
|
||||
out = out + 1
|
||||
|
||||
io.println_i64(out)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
func rule_exists[rules_left: array, rules_right: array, a: i64, b: i64] : bool
|
||||
for k in 0..array.size(rules_left)
|
||||
if array.nth(rules_left, k) == a & array.nth(rules_right, k) == b
|
||||
if array.nth(rules_left, k) == a && array.nth(rules_right, k) == b
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@ func main[] : i64
|
||||
let sum = 0
|
||||
|
||||
for i in 0..1000
|
||||
if i % 5 == 0 | i % 3 == 0
|
||||
if i % 5 == 0 || i % 3 == 0
|
||||
sum = sum + i
|
||||
io.println_i64(sum)
|
||||
@@ -1,10 +1,10 @@
|
||||
func days[y: i64, m: i64] : i64
|
||||
if m == 2
|
||||
if (((y % 4 == 0) & (y % 100 != 0)) | (y % 400 == 0))
|
||||
if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
|
||||
return 29
|
||||
else
|
||||
return 28
|
||||
else if (m == 4) | (m == 6) | (m == 9) | (m == 11)
|
||||
else if (m == 4) || (m == 6) || (m == 9) || (m == 11)
|
||||
return 30
|
||||
else
|
||||
return 31
|
||||
|
||||
@@ -15,7 +15,7 @@ func main[] : i64
|
||||
|
||||
for i in 2..10000
|
||||
let d: i64 = divisors_sum(i)
|
||||
if i < d & i == divisors_sum(d)
|
||||
if i < d && i == divisors_sum(d)
|
||||
sum = sum + i + d
|
||||
|
||||
io.println_i64(sum)
|
||||
@@ -11,7 +11,7 @@ func rule110_step[state: array] : array
|
||||
if i + 1 < state_len
|
||||
right = array.nth(state, i + 1)
|
||||
|
||||
array.push(new_state, !((!left & !center & !right) | (left & !center & !right) | (left & center & right)))
|
||||
array.push(new_state, !((!left && !center && !right) || (left && !center && !right) || (left && center && right)))
|
||||
|
||||
return new_state
|
||||
|
||||
|
||||
@@ -50,11 +50,11 @@ func handle_indentation[tokens: array, current: ptr, column: ptr, line: i64, sou
|
||||
array.push(indent_stack, new_indent)
|
||||
add_token_with_lexeme("Indent", tokens, "", line, mem.read64(column))
|
||||
else if new_indent < mem.read64(current_indent)
|
||||
while array.size(indent_stack) > 1 & array.nth(indent_stack, array.size(indent_stack) - 1) > new_indent
|
||||
while array.size(indent_stack) > 1 && array.nth(indent_stack, array.size(indent_stack) - 1) > new_indent
|
||||
array.pop(indent_stack)
|
||||
add_token_with_lexeme("Dedent", tokens, "", line, mem.read64(column))
|
||||
|
||||
if array.size(indent_stack) == 0 | array.nth(indent_stack, array.size(indent_stack) - 1) != new_indent
|
||||
if array.size(indent_stack) == 0 || array.nth(indent_stack, array.size(indent_stack) - 1) != new_indent
|
||||
zern_error(filename, line, mem.read64(column), "invalid indentation")
|
||||
|
||||
mem.write64(current_indent, new_indent)
|
||||
@@ -75,14 +75,14 @@ func scan_number[current: ptr, column: ptr, source: str, source_len: i64] : void
|
||||
while str.is_hex_digit(peek(mem.read64(current), source, source_len))
|
||||
advance(current, column, source, source_len)
|
||||
else if match_char('o', current, column, source, source_len)
|
||||
while peek(mem.read64(current), source, source_len) >= '0' & peek(mem.read64(current), source, source_len) <= '7'
|
||||
while peek(mem.read64(current), source, source_len) >= '0' && peek(mem.read64(current), source, source_len) <= '7'
|
||||
advance(current, column, source, source_len)
|
||||
else
|
||||
while str.is_digit(peek(mem.read64(current), source, source_len))
|
||||
advance(current, column, source, source_len)
|
||||
|
||||
func scan_identifier[tokens: array, current: ptr, column: ptr, start: i64, line: i64, source: str, source_len: i64] : void
|
||||
while str.is_alphanumeric(peek(mem.read64(current), source, source_len)) | peek(mem.read64(current), source, source_len) == '_' | peek(mem.read64(current), source, source_len) == '.'
|
||||
while str.is_alphanumeric(peek(mem.read64(current), source, source_len)) || peek(mem.read64(current), source, source_len) == '_' || peek(mem.read64(current), source, source_len) == '.'
|
||||
advance(current, column, source, source_len)
|
||||
|
||||
let len: i64 = mem.read64(current) - start
|
||||
@@ -216,7 +216,7 @@ func scan_token[tokens: array, current: ptr, line: ptr, column: ptr, source: str
|
||||
zern_error(filename, mem.read64(line), mem.read64(column), "unterminated string")
|
||||
advance(current, column, source, source_len)
|
||||
add_token("String", tokens, source, start, mem.read64(current), mem.read64(line), mem.read64(column))
|
||||
else if c == ' ' | c == 13 // \r
|
||||
else if c == ' ' || c == 13 // \r
|
||||
return 0
|
||||
else if c == 10 // \n
|
||||
mem.write64(line, mem.read64(line) + 1)
|
||||
@@ -225,7 +225,7 @@ func scan_token[tokens: array, current: ptr, line: ptr, column: ptr, source: str
|
||||
else if str.is_digit(c)
|
||||
scan_number(current, column, source, source_len)
|
||||
add_token("Number", tokens, source, start, mem.read64(current), mem.read64(line), mem.read64(column))
|
||||
else if str.is_letter(c) | c == '_'
|
||||
else if str.is_letter(c) || c == '_'
|
||||
scan_identifier(tokens, current, column, start, mem.read64(line), source, source_len)
|
||||
else
|
||||
zern_error(filename, mem.read64(line), mem.read64(column), "unexpected character")
|
||||
|
||||
@@ -120,6 +120,10 @@ impl Analyzer {
|
||||
self.analyze_expr(left)?;
|
||||
self.analyze_expr(right)?;
|
||||
}
|
||||
Expr::Logical { left, op: _, right } => {
|
||||
self.analyze_expr(left)?;
|
||||
self.analyze_expr(right)?;
|
||||
}
|
||||
Expr::Grouping(expr) => self.analyze_expr(expr)?,
|
||||
Expr::Literal(_) => {}
|
||||
Expr::Unary { op: _, right } => {
|
||||
|
||||
@@ -395,6 +395,25 @@ _builtin_environ:
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
Expr::Logical { left, op, right } => {
|
||||
let end_label = self.label();
|
||||
match op.token_type {
|
||||
TokenType::LogicalAnd => {
|
||||
self.compile_expr(env, *left)?;
|
||||
emit!(&mut self.output, " test rax, rax");
|
||||
emit!(&mut self.output, " je {}", end_label);
|
||||
self.compile_expr(env, *right)?;
|
||||
}
|
||||
TokenType::LogicalOr => {
|
||||
self.compile_expr(env, *left)?;
|
||||
emit!(&mut self.output, " test rax, rax");
|
||||
emit!(&mut self.output, " jne {}", end_label);
|
||||
self.compile_expr(env, *right)?;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
emit!(&mut self.output, "{}:", end_label);
|
||||
}
|
||||
Expr::Grouping(expr) => self.compile_expr(env, *expr)?,
|
||||
Expr::Literal(token) => match token.token_type {
|
||||
TokenType::Number => {
|
||||
|
||||
@@ -54,6 +54,11 @@ pub enum Expr {
|
||||
op: Token,
|
||||
right: Box<Expr>,
|
||||
},
|
||||
Logical {
|
||||
left: Box<Expr>,
|
||||
op: Token,
|
||||
right: Box<Expr>,
|
||||
},
|
||||
Grouping(Box<Expr>),
|
||||
Literal(Token),
|
||||
Unary {
|
||||
@@ -341,10 +346,10 @@ impl Parser {
|
||||
fn or_and(&mut self) -> Result<Expr, ZernError> {
|
||||
let mut expr = self.equality()?;
|
||||
|
||||
while self.match_token(&[TokenType::BitOr, TokenType::BitAnd]) {
|
||||
while self.match_token(&[TokenType::LogicalOr, TokenType::LogicalAnd]) {
|
||||
let op = self.previous().clone();
|
||||
let right = self.equality()?;
|
||||
expr = Expr::Binary {
|
||||
expr = Expr::Logical {
|
||||
left: Box::new(expr),
|
||||
op,
|
||||
right: Box::new(right),
|
||||
@@ -394,7 +399,13 @@ impl Parser {
|
||||
fn term(&mut self) -> Result<Expr, ZernError> {
|
||||
let mut expr = self.factor()?;
|
||||
|
||||
while self.match_token(&[TokenType::Plus, TokenType::Minus, TokenType::Xor]) {
|
||||
while self.match_token(&[
|
||||
TokenType::Plus,
|
||||
TokenType::Minus,
|
||||
TokenType::Xor,
|
||||
TokenType::BitAnd,
|
||||
TokenType::BitOr,
|
||||
]) {
|
||||
let op = self.previous().clone();
|
||||
let right = self.factor()?;
|
||||
expr = Expr::Binary {
|
||||
|
||||
44
src/std.zr
44
src/std.zr
@@ -113,32 +113,32 @@ func str.set[s: str, n: i64, c: u8] : void
|
||||
|
||||
func str.equal[a: str, b: str] : bool
|
||||
let i = 0
|
||||
while a[i] != 0 & b[i] != 0
|
||||
while a[i] != 0 && b[i] != 0
|
||||
if a[i] != b[i]
|
||||
return false
|
||||
i = i + 1
|
||||
return a[i] == b[i]
|
||||
|
||||
func str.is_whitespace[x: u8] : bool
|
||||
return x == ' ' | x == 10 | x == 13 | x == 9
|
||||
return x == ' ' || x == 10 || x == 13 || x == 9
|
||||
|
||||
func str.is_digit[x: u8] : bool
|
||||
return x >= '0' & x <= '9'
|
||||
return x >= '0' && x <= '9'
|
||||
|
||||
func str.is_hex_digit[x: u8] : bool
|
||||
return (x >= '0' & x <= '9') | (x >= 'a' & x <= 'f') | (x >= 'A' & x <= 'F')
|
||||
return (x >= '0' && x <= '9') || (x >= 'a' && x <= 'f') || (x >= 'A' && x <= 'F')
|
||||
|
||||
func str.is_lowercase[x: u8] : bool
|
||||
return x >= 'a' & x <= 'z'
|
||||
return x >= 'a' && x <= 'z'
|
||||
|
||||
func str.is_uppercase[x: u8] : bool
|
||||
return x >= 'A' & x <= 'Z'
|
||||
return x >= 'A' && x <= 'Z'
|
||||
|
||||
func str.is_letter[x: u8] : bool
|
||||
return str.is_uppercase(x) | str.is_lowercase(x)
|
||||
return str.is_uppercase(x) || str.is_lowercase(x)
|
||||
|
||||
func str.is_alphanumeric[x: u8] : bool
|
||||
return str.is_letter(x) | str.is_digit(x)
|
||||
return str.is_letter(x) || str.is_digit(x)
|
||||
|
||||
func str.concat[a: str, b: str] : str
|
||||
let a_len: i64 = str.len(a)
|
||||
@@ -169,7 +169,7 @@ func str.find[haystack: str, needle: str] : i64
|
||||
return -1
|
||||
|
||||
func str.substr[s: str, start: i64, length: i64] : str
|
||||
if start < 0 | length < 0 | start + length > str.len(s)
|
||||
if start < 0 || length < 0 || start + length > str.len(s)
|
||||
dbg.panic("str.substr out of bounds")
|
||||
|
||||
let out: str = mem.alloc(length + 1)
|
||||
@@ -186,10 +186,10 @@ func str.trim[s: str] : str
|
||||
let start = 0
|
||||
let end: i64 = len - 1
|
||||
|
||||
while start <= end & str.is_whitespace(s[start])
|
||||
while start <= end && str.is_whitespace(s[start])
|
||||
start = start + 1
|
||||
|
||||
while end >= start & str.is_whitespace(s[end])
|
||||
while end >= start && str.is_whitespace(s[end])
|
||||
end = end - 1
|
||||
|
||||
return str.substr(s, start, end - start + 1)
|
||||
@@ -269,14 +269,14 @@ func str.parse_i64[s: str] : i64
|
||||
let i = 0
|
||||
|
||||
let sign = 1
|
||||
if i < len & s[i] == '-'
|
||||
if i < len && s[i] == '-'
|
||||
sign = -1
|
||||
i = i + 1
|
||||
|
||||
let num = 0
|
||||
while i < len
|
||||
let d: u8 = s[i]
|
||||
if d < '0' | d > '9'
|
||||
if d < '0' || d > '9'
|
||||
break
|
||||
num = num * 10 + (d - '0')
|
||||
i = i + 1
|
||||
@@ -299,9 +299,9 @@ func str.hex_encode[s: str] : str
|
||||
return out
|
||||
|
||||
func str._hex_digit_to_int[d: u8] : i64
|
||||
if d >= 'a' & d <= 'f'
|
||||
if d >= 'a' && d <= 'f'
|
||||
return d - 'a' + 10
|
||||
if d >= 'A' & d <= 'F'
|
||||
if d >= 'A' && d <= 'F'
|
||||
return d - 'A' + 10
|
||||
return d - '0'
|
||||
|
||||
@@ -353,7 +353,7 @@ func math.lcm[a: i64, b: i64] : i64
|
||||
func math.isqrt[n: i64] : i64
|
||||
if n < 0
|
||||
dbg.panic("negative number passed to math.isqrt")
|
||||
if n == 0 | n == 1
|
||||
if n == 0 || n == 1
|
||||
return n
|
||||
|
||||
let guess: i64 = n
|
||||
@@ -368,14 +368,14 @@ func math.isqrt[n: i64] : i64
|
||||
func math.is_prime[n: i64]: bool
|
||||
if n <= 1
|
||||
return false
|
||||
if n == 2 | n == 3
|
||||
if n == 2 || n == 3
|
||||
return true
|
||||
if n % 2 == 0 | n % 3 == 0
|
||||
if n % 2 == 0 || n % 3 == 0
|
||||
return false
|
||||
|
||||
let i = 5
|
||||
while i * i <= n
|
||||
if n % i == 0 | n % (i + 2) == 0
|
||||
if n % i == 0 || n % (i + 2) == 0
|
||||
return false
|
||||
i = i + 6
|
||||
return true
|
||||
@@ -387,13 +387,13 @@ func array.new[] : array
|
||||
return arr
|
||||
|
||||
func array.nth[xs: array, n: i64] : i64
|
||||
if n < 0 | n >= array.size(xs)
|
||||
if n < 0 || n >= array.size(xs)
|
||||
dbg.panic("array.nth out of bounds")
|
||||
let data: ptr = mem.read64(xs)
|
||||
return mem.read64(data + n * 8)
|
||||
|
||||
func array.set[xs: array, n: i64, x: i64] : void
|
||||
if n < 0 | n >= array.size(xs)
|
||||
if n < 0 || n >= array.size(xs)
|
||||
dbg.panic("array.set out of bounds")
|
||||
let data: ptr = mem.read64(xs)
|
||||
mem.write64(data + n * 8, x)
|
||||
@@ -433,7 +433,7 @@ func array.pop[xs: array] : i64
|
||||
return x
|
||||
|
||||
func array.slice[xs: array, start: i64, length: i64] : array
|
||||
if start < 0 | length < 0 | start + length > array.size(xs)
|
||||
if start < 0 || length < 0 || start + length > array.size(xs)
|
||||
dbg.panic("array.slice out of bounds")
|
||||
|
||||
let new_array: array = []
|
||||
|
||||
@@ -17,6 +17,8 @@ pub enum TokenType {
|
||||
Colon,
|
||||
BitAnd,
|
||||
BitOr,
|
||||
LogicalAnd,
|
||||
LogicalOr,
|
||||
Pipe,
|
||||
At,
|
||||
DoubleDot,
|
||||
@@ -173,10 +175,18 @@ impl Tokenizer {
|
||||
self.add_token(TokenType::Slash)
|
||||
}
|
||||
}
|
||||
'&' => self.add_token(TokenType::BitAnd),
|
||||
'&' => {
|
||||
if self.match_char('&') {
|
||||
self.add_token(TokenType::LogicalAnd)
|
||||
} else {
|
||||
self.add_token(TokenType::BitAnd)
|
||||
}
|
||||
}
|
||||
'|' => {
|
||||
if self.match_char('>') {
|
||||
self.add_token(TokenType::Pipe);
|
||||
} else if self.match_char('|') {
|
||||
self.add_token(TokenType::LogicalOr);
|
||||
} else {
|
||||
self.add_token(TokenType::BitOr);
|
||||
}
|
||||
|
||||
7
test.zr
7
test.zr
@@ -1,5 +1,5 @@
|
||||
func run_test[x: str] : void
|
||||
if str.equal(x, "puzzles") | 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")
|
||||
@@ -19,7 +19,7 @@ func run_test[x: str] : void
|
||||
io.print_i64(build_end_time - build_start_time)
|
||||
io.println("ms")
|
||||
|
||||
if str.find(x, "/aoc") != -1 | str.equal(x, "guess_number.zr") | str.equal(x, "tcp_server.zr")
|
||||
if str.find(x, "/aoc") != -1 || str.equal(x, "guess_number.zr") || str.equal(x, "tcp_server.zr")
|
||||
io.print("\033[93mSkipping ")
|
||||
io.print(x)
|
||||
io.println("...\033[0m")
|
||||
@@ -33,6 +33,9 @@ func run_test[x: str] : void
|
||||
if str.equal(x, "curl.zr")
|
||||
if os.shell("./out http://example.com") != 0
|
||||
os.exit(1)
|
||||
else if str.equal(x, "tokenizer.zr")
|
||||
if os.shell("./out examples/tokenizer.zr") != 0
|
||||
os.exit(1)
|
||||
else
|
||||
if os.shell("./out") != 0
|
||||
os.exit(1)
|
||||
|
||||
Reference in New Issue
Block a user