diff --git a/README.md b/README.md index b796fd8..b4f25ac 100644 --- a/README.md +++ b/README.md @@ -17,5 +17,5 @@ func fib[n: I64] : I64 func main[] : I64 for i in 0..20 - fib(i) |> I64.to_string() |> print() + fib(i) |> str.from_i64() |> io.print() ``` \ No newline at end of file diff --git a/examples/brainfuck.zr b/examples/brainfuck.zr index 96a2eed..b679f77 100644 --- a/examples/brainfuck.zr +++ b/examples/brainfuck.zr @@ -26,7 +26,7 @@ func main[] : I64 if !str.nth(memory, p) i = i + 1 let opened: I64 = 0 - while i < src_len && !(str.nth(src, i) == ']' && !opened) + while i < src_len & !(str.nth(src, i) == ']' & !opened) if str.nth(src, i) == '[' opened = opened + 1 else if str.nth(src, i) == ']' @@ -36,7 +36,7 @@ func main[] : I64 if str.nth(memory, p) i = i - 1 let closed: I64 = 0 - while i >= 0 && !(str.nth(src, i) == '[' && !closed) + while i >= 0 & !(str.nth(src, i) == '[' & !closed) if str.nth(src, i) == ']' closed = closed + 1 else if str.nth(src, i) == '[' diff --git a/examples/euler1.zr b/examples/euler1.zr index dfc09cf..4a5d1ef 100644 --- a/examples/euler1.zr +++ b/examples/euler1.zr @@ -2,6 +2,6 @@ func main[] : I64 let sum: I64 = 0 for i in 0..1000 - if i % 5 == 0 || i % 3 == 0 + if i % 5 == 0 | i % 3 == 0 sum = sum + i io.print_i64(sum) \ No newline at end of file diff --git a/examples/rule110.zr b/examples/rule110.zr index 4915389..a9a751c 100644 --- a/examples/rule110.zr +++ b/examples/rule110.zr @@ -11,7 +11,7 @@ func rule110_step[state: Array] : Array if i + 1 < state_len right = 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 diff --git a/examples/tcp_client.zr b/examples/tcp_client.zr index 5f966ee..c3905e5 100644 --- a/examples/tcp_client.zr +++ b/examples/tcp_client.zr @@ -1,25 +1,7 @@ func main[] : I64 - let s: I64 = c.socket(2, 1, 0) - if s < 0 - dbg.panic("socket() failed") + let s: I64 = net.connect("devernay.free.fr", 80) - let port: I64 = 80 - let sa: Ptr = c.calloc(1, 16) - str.set(sa, 0, 2) - str.set(sa, 1, 0) - str.set(sa, 2, bit.rshift(port, 8) && 255) - str.set(sa, 3, port && 255) - // 23.192.228.80 (example.com) - str.set(sa, 4, 23) - str.set(sa, 5, 192) - str.set(sa, 6, 228) - str.set(sa, 7, 80) - - if c.connect(s, sa, 16) < 0 - dbg.panic("connect() failed") - c.free(sa) - - let req: String = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" + let req: String = "GET /hacks/chip8/C8TECH10.HTM HTTP/1.0\r\nHost: devernay.free.fr\r\nConnection: close\r\n\r\n" c.send(s, req, c.strlen(req), 0) let resp: String = c.malloc(60000) diff --git a/examples/tcp_server.zr b/examples/tcp_server.zr index ee847a9..7ff8a48 100644 --- a/examples/tcp_server.zr +++ b/examples/tcp_server.zr @@ -1,26 +1,11 @@ func main[] : I64 - let s: I64 = c.socket(2, 1, 0) - if s < 0 - dbg.panic("socket() failed") - - let port: I64 = 8080 - let sa: Ptr = c.calloc(1, 16) - str.set(sa, 0, 2) - str.set(sa, 1, 0) - str.set(sa, 2, bit.rshift(port, 8) && 255) - str.set(sa, 3, port && 255) - - if c.bind(s, sa, 16) < 0 - dbg.panic("bind() failed") - - if c.listen(s, 1) < 0 - dbg.panic("listen() failed") + let s: I64 = net.listen(8000) let resp: String = c.malloc(60000) while true let c: I64 = c.accept(s, 0, 0) if c < 0 - dbg.panic("accept() failed") + continue let n: I64 = c.read(c, resp, 60000) c.send(c, resp, n, 0) diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index 1ecc4e7..4d33805 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -100,81 +100,19 @@ impl CodegenX86_64 { db 0 section .text -extern malloc -c.malloc equ malloc -extern calloc -c.calloc equ calloc -extern realloc -c.realloc equ realloc -extern free -c.free equ free -extern puts -c.puts equ puts -extern printf -c.printf equ printf -extern sprintf -c.sprintf equ sprintf -extern strtol -c.strtol equ strtol -extern strlen -c.strlen equ strlen -extern strcmp -c.strcmp equ strcmp -extern strcat -c.strcat equ strcat -extern strcpy -c.strcpy equ strcpy -extern strdup -c.strdup equ strdup -extern strncpy -c.strncpy equ strncpy -extern syscall -c.syscall equ syscall -extern fopen -c.fopen equ fopen -extern fseek -c.fseek equ fseek -extern ftell -c.ftell equ ftell -extern fread -c.fread equ fread -extern fwrite -c.fwrite equ fwrite -extern fclose -c.fclose equ fclose -extern rewind -c.rewind equ rewind -extern system -c.system equ system -extern opendir -c.opendir equ opendir -extern readdir -c.readdir equ readdir -extern closedir -c.closedir equ closedir -extern exit -c.exit equ exit -extern gettimeofday -c.gettimeofday equ gettimeofday -extern connect -c.connect equ connect -extern socket -c.socket equ socket -extern send -c.send equ send -extern read -c.read equ read -extern close -c.close equ close -extern bind -c.bind equ bind -extern listen -c.listen equ listen -extern accept -c.accept equ accept -extern getchar -c.getchar equ getchar +" + ); + // take that rustfmt + for name in "malloc,calloc,realloc,free,puts,printf,sprintf,strtol,strlen,strcmp,strcat,strcpy,strdup,strncpy,syscall,fopen,fseek,ftell,fread,fwrite,fclose,rewind,system,opendir,readdir,closedir,exit,gettimeofday,connect,socket,send,read,close,bind,listen,accept,getchar,gethostbyname".split(",") + { + emit!(&mut self.output, "extern {}", name); + emit!(&mut self.output, "c.{} equ {}", name, name); + } + + emit!( + &mut self.output, + " section .text._builtin_deref8 _builtin_deref8: xor rax, rax diff --git a/src/std.zr b/src/std.zr index 54c6e84..8060029 100644 --- a/src/std.zr +++ b/src/std.zr @@ -15,7 +15,7 @@ func str.set[s: String, n: I64, c: U8] : Void _builtin_set8(s+n, c) func str.is_whitespace[c: U8] : Bool - return c == ' ' || c == 10 || c == 13 || c == 9 + return c == ' ' | c == 10 | c == 13 | c == 9 func str.concat[a: String, b: String] : String let c: String = c.malloc(c.strlen(a) + c.strlen(b) + 1) @@ -31,7 +31,7 @@ func str.find[s: String, c: U8] : I64 return -1 func str.substr[s: String, start: I64, length: I64] : String - if start < 0 || length < 0 || start + length > c.strlen(s) + if start < 0 | length < 0 | start + length > c.strlen(s) dbg.panic("String.substr out of bounds") let out: String = c.malloc(length + 1) @@ -43,10 +43,10 @@ func str.trim[s: String] : String let start: I64 = 0 let end: I64 = c.strlen(s) - 1 - while start <= end && str.is_whitespace(str.nth(s, start)) + while start <= end & str.is_whitespace(str.nth(s, start)) start = start + 1 - while end >= start && str.is_whitespace(str.nth(s, end)) + while end >= start & str.is_whitespace(str.nth(s, end)) end = end - 1 return str.substr(s, start, end - start + 1) @@ -133,7 +133,7 @@ func math.lcm[a: I64, b: I64] : I64 func math.isqrt[n: I64] : I64 if n < 0 return -1 - if n == 0 || n == 1 + if n == 0 | n == 1 return n let guess: I64 = n @@ -148,14 +148,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: I64 = 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 @@ -243,8 +243,8 @@ func crypto.hex_encode[s: String] : String let out: String = c.malloc(s_len*2+1) for i in 0..s_len - let high: U8 = bit.rshift(str.nth(s, i), 4) && 15 - let low: U8 = str.nth(s, i) && 15 + let high: U8 = bit.rshift(str.nth(s, i), 4) & 15 + let low: U8 = str.nth(s, i) & 15 str.set(out, j, str.nth(hex_chars, high)) str.set(out, j+1, str.nth(hex_chars, low)) j = j + 2 @@ -253,9 +253,9 @@ func crypto.hex_encode[s: String] : String return out func crypto.from_hex_digit[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' @@ -322,11 +322,11 @@ func crypto.base64_encode[s: String] : String b3 = str.nth(s, i+2) i = i + 3 - let triple: I64 = bit.lshift(b1, 16) || bit.lshift(b2, 8) || b3 - str.set(out, j, str.nth(chars, bit.rshift(triple, 18) && 63)) - str.set(out, j+1, str.nth(chars, bit.rshift(triple, 12) && 63)) - str.set(out, j+2, str.nth(chars, bit.rshift(triple, 6) && 63)) - str.set(out, j+3, str.nth(chars, triple && 63)) + let triple: I64 = bit.lshift(b1, 16) | bit.lshift(b2, 8) | b3 + str.set(out, j, str.nth(chars, bit.rshift(triple, 18) & 63)) + str.set(out, j+1, str.nth(chars, bit.rshift(triple, 12) & 63)) + str.set(out, j+2, str.nth(chars, bit.rshift(triple, 6) & 63)) + str.set(out, j+3, str.nth(chars, triple & 63)) j = j + 4 let padding: I64 = s_len % 3 @@ -362,16 +362,66 @@ func crypto.base64_decode[s: String] : String s4 = str.find(chars, str.nth(s, i+3)) i = i + 4 - let triple: I64 = bit.lshift(s1, 18) || bit.lshift(s2, 12) || bit.lshift(s3, 6) || s4 + let triple: I64 = bit.lshift(s1, 18) | bit.lshift(s2, 12) | bit.lshift(s3, 6) | s4 - str.set(out, j, bit.rshift(triple, 16) && 255) + str.set(out, j, bit.rshift(triple, 16) & 255) j = j + 1 if s3 != 64 - str.set(out, j, bit.rshift(triple, 8) && 255) + str.set(out, j, bit.rshift(triple, 8) & 255) j = j + 1 if s4 != 64 - str.set(out, j, triple && 255) + str.set(out, j, triple & 255) j = j + 1 str.set(out, j, 0) - return out \ No newline at end of file + return out + +func net.listen[port: I64] : I64 + let s: I64 = c.socket(2, 1, 0) + if s < 0 + return -1 + + let sa: Ptr = c.calloc(1, 16) + str.set(sa, 0, 2) + str.set(sa, 1, 0) + str.set(sa, 2, bit.rshift(port, 8) & 255) + str.set(sa, 3, port & 255) + + if c.bind(s, sa, 16) < 0 + c.close(s) + return -1 + c.free(sa) + + if c.listen(s, 1) < 0 + c.close(s) + return -1 + + return s + +func net.connect[host: String, port: I64] : I64 + let he: Ptr = c.gethostbyname(host) + if he == 0 + return -1 + + let ip_ptr: Ptr = _builtin_deref64(_builtin_deref64(he + 24)) + + let s: I64 = c.socket(2, 1, 0) + if s < 0 + return -1 + + let sa: Ptr = c.calloc(1, 16) + str.set(sa, 0, 2) + str.set(sa, 2, bit.rshift(port, 8) & 255) + str.set(sa, 3, port & 255) + str.set(sa, 4, _builtin_deref8(ip_ptr + 0)) + str.set(sa, 5, _builtin_deref8(ip_ptr + 1)) + str.set(sa, 6, _builtin_deref8(ip_ptr + 2)) + str.set(sa, 7, _builtin_deref8(ip_ptr + 3)) + + if c.connect(s, sa, 16) < 0 + c.free(sa) + c.close(s) + return -1 + + c.free(sa) + return s \ No newline at end of file diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 7791385..85e861c 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -166,20 +166,12 @@ impl Tokenizer { self.add_token(TokenType::Slash) } } - '&' => { - if self.match_char('&') { - self.add_token(TokenType::And); - } else { - return error!(self.loc, "expected '&' after '&'"); - } - } + '&' => self.add_token(TokenType::And), '|' => { - if self.match_char('|') { - self.add_token(TokenType::Or); - } else if self.match_char('>') { + if self.match_char('>') { self.add_token(TokenType::Pipe); } else { - return error!(self.loc, "expected '>' or '|' after '|'"); + self.add_token(TokenType::Or); } } '!' => { diff --git a/test.zr b/test.zr index ea9dbea..2b6236a 100644 --- a/test.zr +++ b/test.zr @@ -10,7 +10,7 @@ func run_test[x: String] : Void c.free(cmd) c.printf(" %ldms\n", build_end_time - build_start_time) - if c.strcmp(x, "guess_number.zr") == 0 || c.strcmp(x, "tcp_server.zr") == 0 + if c.strcmp(x, "guess_number.zr") == 0 | c.strcmp(x, "tcp_server.zr") == 0 c.printf("\033[93mSkipping %s...\033[0m\n", x) else let run_start_time: I64 = os.time()