expand stdlib

This commit is contained in:
2025-11-12 11:57:34 +01:00
parent 2b316cbc16
commit d9819476f8
8 changed files with 94 additions and 64 deletions

View File

@@ -4,7 +4,8 @@ func main[] : I64
let src_len: I64 = str.len(src)
let i: I64 = 0
let memory: Ptr = c.calloc(1, 30000)
let memory: Ptr = mem.alloc(30000)
mem.zero(memory, 30000)
let p: I64 = 0
while i < src_len

View File

@@ -4,7 +4,10 @@ func main[argc: I64, argv: Ptr] : I64
let url: String = mem.read64(argv + 8)
if c.strncmp(url, "http://", 7) != 0
if str.len(url) <= 7
dbg.panic("missing url scheme")
if !str.equal(str.substr(url, 0, 7), "http://")
dbg.panic("invalid url scheme")
let url_len: I64 = str.len(url)

View File

@@ -1,26 +1,3 @@
func quicksort[arr: Array] : Void
do_quicksort(arr, 0, array.size(arr)-1)
func do_quicksort[arr: Array, low: I64, high: I64] : Void
if low < high
let i: I64 = partition(arr, low, high)
do_quicksort(arr, low, i - 1)
do_quicksort(arr, i + 1, high)
func partition[arr: Array, low: I64, high: I64] : I64
let pivot: I64 = arr[high]
let i: I64 = low - 1
for j in (low)..high
if arr[j] <= pivot
i = i + 1
let temp: I64 = arr[i]
array.set(arr, i, arr[j])
array.set(arr, j, temp)
let temp: I64 = arr[i + 1]
array.set(arr, i + 1, arr[high])
array.set(arr, high, temp)
return i + 1
func main[] : I64
let arr: Array = []
for i in 0..10
@@ -30,7 +7,7 @@ func main[] : I64
io.print_i64(arr[i])
io.print("------------")
quicksort(arr)
alg.quicksort(arr)
for i in 0..array.size(arr)
io.print_i64(arr[i])

View File

@@ -106,7 +106,7 @@ section .text
);
// take that rustfmt
for name in "malloc,calloc,realloc,free,puts,putchar,printf,sprintf,snprintf,strtol,strlen,strcmp,strncmp,strcat,strcpy,strdup,strncpy,syscall,fopen,fseek,ftell,fread,fwrite,fclose,rewind,system,opendir,readdir,closedir,exit,gettimeofday,connect,socket,send,write,read,close,bind,listen,accept,getchar,gethostbyname,dlopen,dlsym,dlerror".split(",")
for name in "malloc,memset,realloc,free,puts,putchar,printf,snprintf,strtol,strlen,strcmp,strcat,strcpy,strncpy,fopen,fseek,ftell,fread,fwrite,fclose,rewind,system,opendir,readdir,closedir,exit,gettimeofday,connect,socket,send,write,read,close,bind,listen,accept,getchar,gethostbyname,dlopen,dlsym".split(",")
{
emit!(&mut self.output, "extern {}", name);
emit!(&mut self.output, "c.{} equ {}", name, name);
@@ -316,10 +316,10 @@ _builtin_set64:
TokenType::Xor => {
emit!(&mut self.output, " xor rax, rbx");
}
TokenType::And => {
TokenType::BitAnd => {
emit!(&mut self.output, " and rax, rbx");
}
TokenType::Or => {
TokenType::BitOr => {
emit!(&mut self.output, " or rax, rbx");
}
TokenType::DoubleEqual => {

View File

@@ -115,7 +115,6 @@ impl Parser {
}
}
// TOOD: parse return type
fn func_declaration(&mut self) -> Result<Stmt, ZernError> {
let name = self.consume(TokenType::Identifier, "expected function name")?;
self.consume(TokenType::LeftBracket, "expected '[' after function name")?;
@@ -304,7 +303,7 @@ impl Parser {
fn logical_or(&mut self) -> Result<Expr, ZernError> {
let mut expr = self.logical_and()?;
while self.match_token(&[TokenType::Or]) {
while self.match_token(&[TokenType::BitOr]) {
let op = self.previous().clone();
let right = self.logical_and()?;
expr = Expr::Binary {
@@ -320,7 +319,7 @@ impl Parser {
fn logical_and(&mut self) -> Result<Expr, ZernError> {
let mut expr = self.equality()?;
while self.match_token(&[TokenType::And]) {
while self.match_token(&[TokenType::BitAnd]) {
let op = self.previous().clone();
let right = self.equality()?;
expr = Expr::Binary {

View File

@@ -8,12 +8,21 @@ func mem.alloc[x: I64] : Ptr
func mem.free[x: Ptr] : Void
c.free(x)
func mem.zero[x: I64, size: I64] : Void
c.memset(x, 0, size)
func mem.read8[x: Ptr] : U8
return _builtin_read8(x)
func mem.read64[x: Ptr] : I64
return _builtin_read64(x)
func mem.write8[x: Ptr, d: U8] : Void
_builtin_set8(x, d)
func mem.write64[x: Ptr, d: I64] : Void
_builtin_set64(x, d)
func io.print[x: String] : Void
c.puts(x)
@@ -22,7 +31,9 @@ func io.print_i64[x: I64] : Void
func io.read_stdin[]: String
let buffer: String = mem.alloc(1025)
let n: I64 = c.syscall(0, 0, buffer, 1024)
let n: I64 = c.read(0, buffer, 1024)
if n < 0
return ""
str.set(buffer, n, 0)
return buffer
@@ -57,8 +68,15 @@ func str.len[s: String] : I64
func str.nth[s: String, n: I64] : U8
return mem.read8(s + n)
func str.copy[s: String] : String
let size: I64 = str.len(s) + 1
let dup: String = mem.alloc(size)
for i in 0..size+1
str.set(dup, i, str.nth(s, i))
return dup
func str.set[s: String, n: I64, c: U8] : Void
_builtin_set8(s+n, c)
mem.write8(s+n, c)
func str.equal[a: String, b: String] : Bool
return c.strcmp(a, b) == 0
@@ -143,7 +161,7 @@ func str.reverse[s: String] : String
func str.from_i64[n: I64] : String
let x: String = mem.alloc(21)
c.sprintf(x, "%ld", n)
c.snprintf(x, 21, "%ld", n)
return x
func str.parse_i64[s: String] : I64
@@ -257,7 +275,9 @@ func math.urandom[]: I64
return n
func array.new[] : Array
return c.calloc(1, 24)
let arr: Ptr = mem.alloc(24)
mem.zero(arr, 24)
return arr
func array.nth[xs: Array, n: I64] : I64
// this probably should be implemented in the codegen
@@ -267,7 +287,7 @@ func array.nth[xs: Array, n: I64] : I64
func array.set[xs: Array, n: I64, x: I64] : Void
let data: Ptr = mem.read64(xs)
_builtin_set64(data+n*8, x)
mem.write64(data+n*8, x)
func array.push[xs: Array, x: I64] : Void
let data: Ptr = mem.read64(xs)
@@ -279,20 +299,48 @@ func array.push[xs: Array, x: I64] : Void
if capacity != 0
new_capacity = capacity * 2
let new_data: Ptr = c.realloc(data, new_capacity * 8)
_builtin_set64(xs, new_data)
_builtin_set64(xs+8, new_capacity)
mem.write64(xs, new_data)
mem.write64(xs+8, new_capacity)
data = new_data
_builtin_set64(data+size*8, x)
_builtin_set64(xs+16, size + 1)
mem.write64(data+size*8, x)
mem.write64(xs+16, size + 1)
func array.size[xs: Array] : I64
return mem.read64(xs+16)
func array.free[xs: Array] : Void
mem.free(mem.read64(xs))
let data: Ptr = mem.read64(xs)
if data != 0
mem.free(data)
mem.free(xs)
func alg.quicksort[arr: Array] : Void
alg._do_quicksort(arr, 0, array.size(arr)-1)
func alg._do_quicksort[arr: Array, low: I64, high: I64] : Void
if low < high
let i: I64 = alg._partition(arr, low, high)
alg._do_quicksort(arr, low, i - 1)
alg._do_quicksort(arr, i + 1, high)
func alg._partition[arr: Array, low: I64, high: I64] : I64
let pivot: I64 = arr[high]
let i: I64 = low - 1
for j in (low)..high
if arr[j] <= pivot
i = i + 1
let temp: I64 = arr[i]
array.set(arr, i, arr[j])
array.set(arr, j, temp)
let temp: I64 = arr[i + 1]
array.set(arr, i + 1, arr[high])
array.set(arr, high, temp)
return i + 1
func os.exit[code: I64] : Void
c.exit(code)
func os.time[] : I64
let tv: Ptr = mem.alloc(16)
c.gettimeofday(tv, 0)
@@ -319,7 +367,7 @@ func os.listdir[path: String] : Array
skip = true
if !skip
array.push(files, c.strdup(entry + 19))
array.push(files, str.copy(entry + 19))
c.closedir(dir)
return files
@@ -328,11 +376,12 @@ func net.listen[port: I64] : I64
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, (port >> 8) & 255)
str.set(sa, 3, port & 255)
let sa: Ptr = mem.alloc(16)
mem.zero(sa, 16)
mem.write8(sa + 0, 2)
mem.write8(sa + 1, 0)
mem.write8(sa + 2, (port >> 8) & 255)
mem.write8(sa + 3, port & 255)
if c.bind(s, sa, 16) < 0
c.close(s)
@@ -356,14 +405,15 @@ func net.connect[host: String, port: I64] : I64
if s < 0
return -1
let sa: Ptr = c.calloc(1, 16)
str.set(sa, 0, 2)
str.set(sa, 2, (port >> 8) & 255)
str.set(sa, 3, port & 255)
str.set(sa, 4, mem.read8(ip_ptr + 0))
str.set(sa, 5, mem.read8(ip_ptr + 1))
str.set(sa, 6, mem.read8(ip_ptr + 2))
str.set(sa, 7, mem.read8(ip_ptr + 3))
let sa: Ptr = mem.alloc(16)
mem.zero(sa, 16)
mem.write8(sa + 0, 2)
mem.write8(sa + 2, (port >> 8) & 255)
mem.write8(sa + 3, port & 255)
mem.write8(sa + 4, mem.read8(ip_ptr + 0))
mem.write8(sa + 5, mem.read8(ip_ptr + 1))
mem.write8(sa + 6, mem.read8(ip_ptr + 2))
mem.write8(sa + 7, mem.read8(ip_ptr + 3))
if c.connect(s, sa, 16) < 0
mem.free(sa)

View File

@@ -15,8 +15,8 @@ pub enum TokenType {
Xor,
Bang,
Colon,
And,
Or,
BitAnd,
BitOr,
Pipe,
DoubleDot,
ShiftLeft,
@@ -168,12 +168,12 @@ impl Tokenizer {
self.add_token(TokenType::Slash)
}
}
'&' => self.add_token(TokenType::And),
'&' => self.add_token(TokenType::BitAnd),
'|' => {
if self.match_char('>') {
self.add_token(TokenType::Pipe);
} else {
self.add_token(TokenType::Or);
self.add_token(TokenType::BitOr);
}
}
'!' => {

View File

@@ -4,22 +4,22 @@ func run_test[x: String] : Void
let build_start_time: I64 = os.time()
if c.system(cmd) != 0
c.exit(1)
os.exit(1)
let build_end_time: I64 = os.time()
mem.free(cmd)
c.printf(" %ldms\n", build_end_time - build_start_time)
if str.equal(x, "guess_number.zr") | str.equal(x, "tcp_server.zr")
if str.equal(x, "guess_number.zr") | str.equal(x, "tcp_server.zr") | str.equal(x, "raylib.zr")
c.printf("\033[93mSkipping %s...\033[0m\n", x)
else
let run_start_time: I64 = os.time()
if str.equal(x, "curl.zr")
if c.system("./out http://example.com") != 0
c.exit(1)
os.exit(1)
else
if c.system("./out") != 0
c.exit(1)
os.exit(1)
let run_end_time: I64 = os.time()
c.printf("\033[93mRunning %s...\033[0m %ldms\n", x, run_end_time - run_start_time)