some std wrappers around libc

This commit is contained in:
2025-08-03 10:37:18 +02:00
parent 6fc80626dc
commit 3fd62c6083
8 changed files with 101 additions and 56 deletions

View File

@@ -1,7 +1,7 @@
func main[] : I64
// https://brainfuck.org/sierpinski.b
let src: String = "++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[-<<<[->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<<]>.>+[>>]>+]"
let src_len: I64 = c.strlen(src)
let src_len: I64 = str.len(src)
let i: I64 = 0
let memory: Ptr = c.calloc(1, 30000)
@@ -45,4 +45,4 @@ func main[] : I64
i = i + 1
c.free(memory)
mem.free(memory)

View File

@@ -7,7 +7,7 @@ func main[argc: I64, argv: Ptr] : I64
if c.strncmp(url, "http://", 7) != 0
dbg.panic("invalid url scheme")
let url_len: I64 = c.strlen(url)
let url_len: I64 = str.len(url)
let host_start: I64 = 7
let i: I64 = host_start
while i < url_len
@@ -24,12 +24,12 @@ func main[argc: I64, argv: Ptr] : I64
if s < 0
dbg.panic("failed to connect")
let req: String = c.malloc(2048)
let req: String = mem.alloc(2048)
c.snprintf(req, 2048, "GET %s HTTP/1.0\r\nHost: %s\r\nConnection: close\r\n\r\n", path, host)
c.send(s, req, c.strlen(req), 0)
c.free(req)
c.send(s, req, str.len(req), 0)
mem.free(req)
let header_buf: Ptr = c.malloc(8192)
let header_buf: Ptr = mem.alloc(8192)
let header_size: I64 = 0
let found: Bool = false
let end_index: I64 = -1
@@ -51,14 +51,14 @@ func main[argc: I64, argv: Ptr] : I64
if end_index < header_size
c.write(1, header_buf + end_index, header_size - end_index)
c.free(header_buf)
mem.free(header_buf)
let buffer: Ptr = c.malloc(4096)
let buffer: Ptr = mem.alloc(4096)
while true
let n: I64 = c.read(s, buffer, 4096)
if n <= 0
break
c.write(1, buffer, n)
c.free(buffer)
mem.free(buffer)
c.close(s)

View File

@@ -6,8 +6,8 @@ func main[] : I64
if a * b > out
let s: String = str.from_i64(a * b)
let s_rev: String = str.reverse(s)
if c.strcmp(s, s_rev) == 0
if str.equal(s, s_rev)
out = a * b
c.free(s)
c.free(s_rev)
mem.free(s)
mem.free(s_rev)
io.print_i64(out)

View File

@@ -2,7 +2,7 @@ func main[] : I64
let n: String = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"
let out: I64 = 0
let max: I64 = c.strlen(n) - 13
let max: I64 = str.len(n) - 13
for i in 0..max
let s: I64 = 1
let j: I64 = 0

View File

@@ -1,12 +1,12 @@
func main[] : I64
let s: I64 = net.listen(8000)
let resp: String = c.malloc(60000)
let resp: String = mem.alloc(60000)
while true
let c: I64 = c.accept(s, 0, 0)
if c < 0
let conn: I64 = c.accept(s, 0, 0)
if conn < 0
continue
let n: I64 = c.read(c, resp, 60000)
c.send(c, resp, n, 0)
c.close(c)
let n: I64 = c.read(conn, resp, 60000)
c.send(conn, resp, n, 0)
c.close(conn)

View File

@@ -225,10 +225,8 @@ _builtin_set64:
self.compile_stmt(env, *body)?;
if name.lexeme == "main" {
emit!(&mut self.output, " mov rax, 0");
}
// fallback to returning null
emit!(&mut self.output, " mov rax, 0");
emit!(&mut self.output, " mov rsp, rbp");
emit!(&mut self.output, " pop rbp");
emit!(&mut self.output, " ret");

View File

@@ -2,6 +2,12 @@ func dbg.panic[msg: String] : Void
c.printf("PANIC: %s\n", msg)
c.exit(1)
func mem.alloc[x: I64] : Ptr
return c.malloc(x)
func mem.free[x: I64] : Ptr
return c.free(x)
func mem.deref8[x: Ptr] : I64
return _builtin_deref8(x)
@@ -15,7 +21,7 @@ func io.print_i64[x: I64] : Void
c.printf("%ld\n", x)
func io.read_stdin[]: String
let buffer: String = c.malloc(1025)
let buffer: String = mem.alloc(1025)
let n: I64 = c.syscall(0, 0, buffer, 1024)
str.set(buffer, n, 0)
return buffer
@@ -29,7 +35,7 @@ func io.read_file[path: String]: String
let size: I64 = c.ftell(file)
c.rewind(file)
let buffer: String = c.malloc(size + 1)
let buffer: String = mem.alloc(size + 1)
let n: I64 = c.fread(buffer, 1, size, file)
str.set(buffer, n, 0)
@@ -41,43 +47,49 @@ func io.write_file[path: String, content: String] : Void
if !file
dbg.panic("failed to open file")
c.fwrite(content, 1, c.strlen(content), file)
c.fwrite(content, 1, str.len(content), file)
c.fclose(file)
func str.len[s: String] : I64
return c.strlen(s)
func str.nth[s: String, n: I64] : U8
return mem.deref8(s + n)
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
func str.equal[a: String, b: String] : Bool
return c.strcmp(a, b) == 0
func str.is_whitespace[x: U8] : Bool
return x == ' ' | x == 10 | x == 13 | x == 9
func str.concat[a: String, b: String] : String
let c: String = c.malloc(c.strlen(a) + c.strlen(b) + 1)
c.strcpy(c, a)
c.strcat(c, b)
return c
let out: String = mem.alloc(str.len(a) + str.len(b) + 1)
c.strcpy(out, a)
c.strcat(out, b)
return out
func str.find[s: String, c: U8] : I64
let s_len: I64 = c.strlen(s)
let s_len: I64 = str.len(s)
for i in 0..s_len
if str.nth(s, i) == c
return i
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 > str.len(s)
dbg.panic("String.substr out of bounds")
let out: String = c.malloc(length + 1)
let out: String = mem.alloc(length + 1)
c.strncpy(out, s + start, length)
str.set(out, length, 0)
return out
func str.trim[s: String] : String
let start: I64 = 0
let end: I64 = c.strlen(s) - 1
let end: I64 = str.len(s) - 1
while start <= end & str.is_whitespace(str.nth(s, start))
start = start + 1
@@ -87,9 +99,41 @@ func str.trim[s: String] : String
return str.substr(s, start, end - start + 1)
func str.split[haystack: String, needle: String]: Array
let haystack_len: I64 = str.len(haystack)
let needle_len: I64 = str.len(needle)
let result: Array = []
if !needle_len
if !haystack_len
return result
else
for i in 0..haystack_len
array.push(result, str.substr(haystack, i, 1))
return result
let start: I64 = 0
let i: I64 = 0
while i < haystack_len
if i <= haystack_len - needle_len
let match: Bool = true
for j in 0..needle_len
if str.nth(haystack, i+j) != str.nth(needle, j)
match = false
break
if match
array.push(result, str.substr(haystack, start, i - start))
start = i + needle_len
i = i + needle_len
continue
i = i + 1
array.push(result, str.substr(haystack, start, haystack_len - start))
return result
func str.reverse[s: String] : String
let len: I64 = c.strlen(s)
let out: String = c.malloc(len + 1)
let len: I64 = str.len(s)
let out: String = mem.alloc(len + 1)
for i in 0..len
str.set(out, i, str.nth(s, len - i - 1))
@@ -97,7 +141,7 @@ func str.reverse[s: String] : String
return out
func str.from_i64[n: I64] : String
let x: String = c.malloc(21)
let x: String = mem.alloc(21)
c.sprintf(x, "%ld", n)
return x
@@ -106,9 +150,9 @@ func str.parse_i64[s: String] : I64
func str.hex_encode[s: String] : String
let hex_chars: String = "0123456789abcdef"
let s_len: I64 = c.strlen(s)
let s_len: I64 = str.len(s)
let j: I64 = 0
let out: String = c.malloc(s_len*2+1)
let out: String = mem.alloc(s_len*2+1)
for i in 0..s_len
let high: U8 = (str.nth(s, i) >> 4) & 15
@@ -128,10 +172,10 @@ func str.from_hex_digit[d: U8] : I64
return d - '0'
func str.hex_decode[s: String] : String
let s_len: I64 = c.strlen(s)
let s_len: I64 = str.len(s)
let i: I64 = 0
let j: I64 = 0
let out: String = c.malloc(s_len/2+1)
let out: String = mem.alloc(s_len/2+1)
while i < s_len
str.set(out, j, str.from_hex_digit(str.nth(s, i)) * 16 + str.from_hex_digit(str.nth(s, i+1)))
@@ -203,17 +247,20 @@ func math.is_prime[n: I64]: Bool
return true
func math.urandom[]: I64
let buffer: Ptr = c.malloc(8)
let buffer: Ptr = mem.alloc(8)
let file: Ptr = c.fopen("/dev/urandom", "rb")
c.fread(buffer, 8, 1, file)
c.fclose(file)
let n: I64 = mem.deref64(buffer)
c.free(buffer)
mem.free(buffer)
return n
func array.new[] : Array
return c.calloc(1, 24)
func array.nth[xs: Array, n: I64] : I64
return xs[n]
func array.set[xs: Array, n: I64, x: I64] : Void
let data: Ptr = mem.deref64(xs)
_builtin_set64(data+n*8, x)
@@ -239,15 +286,15 @@ func array.size[xs: Array] : I64
return mem.deref64(xs+16)
func array.free[xs: Array] : Void
c.free(mem.deref64(xs))
c.free(xs)
mem.free(mem.deref64(xs))
mem.free(xs)
func os.time[] : I64
let tv: Ptr = c.malloc(16)
let tv: Ptr = mem.alloc(16)
c.gettimeofday(tv, 0)
let seconds: I64 = mem.deref64(tv)
let microseconds: I64 = mem.deref64(tv+8)
c.free(tv)
mem.free(tv)
return seconds * 1000 + microseconds / 1000
func os.listdir[path: String] : Array
@@ -286,7 +333,7 @@ func net.listen[port: I64] : I64
if c.bind(s, sa, 16) < 0
c.close(s)
return -1
c.free(sa)
mem.free(sa)
if c.listen(s, 1) < 0
c.close(s)
@@ -315,9 +362,9 @@ func net.connect[host: String, port: I64] : I64
str.set(sa, 7, mem.deref8(ip_ptr + 3))
if c.connect(s, sa, 16) < 0
c.free(sa)
mem.free(sa)
c.close(s)
return -1
c.free(sa)
mem.free(sa)
return s

View File

@@ -7,14 +7,14 @@ func run_test[x: String] : Void
c.exit(1)
let build_end_time: I64 = os.time()
c.free(cmd)
mem.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 str.equal(x, "guess_number.zr") | str.equal(x, "tcp_server.zr")
c.printf("\033[93mSkipping %s...\033[0m\n", x)
else
let run_start_time: I64 = os.time()
if c.strcmp(x, "curl.zr") == 0
if str.equal(x, "curl.zr")
if c.system("./out http://devernay.free.fr/hacks/chip8/C8TECH10.HTM") != 0
c.exit(1)
else