drop some libc functions, octal numerals, io.println, mem.read32

This commit is contained in:
2025-11-22 17:31:36 +01:00
parent 5a41163ca1
commit 7cffd73406
28 changed files with 165 additions and 126 deletions

View File

@@ -106,7 +106,7 @@ section .text
);
// take that rustfmt
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(",")
for name in "syscall,malloc,realloc,free,snprintf,strtol,system,opendir,readdir,closedir,gettimeofday,send,write,read,close,getchar,gethostbyname".split(",")
{
emit!(&mut self.output, "extern {}", name);
emit!(&mut self.output, "c.{} equ {}", name, name);
@@ -121,6 +121,11 @@ _builtin_read8:
mov al, byte [rdi]
ret
section .text._builtin_read32
_builtin_read32:
mov eax, dword [rdi]
ret
section .text._builtin_read64
_builtin_read64:
mov rax, qword [rdi]

View File

@@ -276,7 +276,7 @@ impl Parser {
}
fn pipe(&mut self) -> Result<Expr, ZernError> {
let mut expr = self.logical_or()?;
let mut expr = self.or_and()?;
while self.match_token(&[TokenType::Pipe]) {
let pipe = self.previous().clone();
@@ -305,26 +305,10 @@ impl Parser {
Ok(expr)
}
fn logical_or(&mut self) -> Result<Expr, ZernError> {
let mut expr = self.logical_and()?;
while self.match_token(&[TokenType::BitOr]) {
let op = self.previous().clone();
let right = self.logical_and()?;
expr = Expr::Binary {
left: Box::new(expr),
op,
right: Box::new(right),
}
}
Ok(expr)
}
fn logical_and(&mut self) -> Result<Expr, ZernError> {
fn or_and(&mut self) -> Result<Expr, ZernError> {
let mut expr = self.equality()?;
while self.match_token(&[TokenType::BitAnd]) {
while self.match_token(&[TokenType::BitOr, TokenType::BitAnd]) {
let op = self.previous().clone();
let right = self.equality()?;
expr = Expr::Binary {

View File

@@ -1,6 +1,7 @@
func dbg.panic[msg: String] : Void
c.printf("PANIC: %s\n", msg)
c.exit(1)
io.print("PANIC:")
io.println(msg)
os.exit(1)
func mem.alloc[x: I64] : Ptr
return c.malloc(x)
@@ -9,11 +10,15 @@ func mem.free[x: Ptr] : Void
c.free(x)
func mem.zero[x: I64, size: I64] : Void
c.memset(x, 0, size)
for i in 0..size
mem.write8(x + i, 0)
func mem.read8[x: Ptr] : U8
return _builtin_read8(x)
func mem.read32[x: Ptr] : I64
return _builtin_read32(x)
func mem.read64[x: Ptr] : I64
return _builtin_read64(x)
@@ -24,46 +29,63 @@ func mem.write64[x: Ptr, d: I64] : Void
_builtin_set64(x, d)
func io.print[x: String] : Void
c.puts(x)
c.syscall(1, 1, x, str.len(x))
func io.println[x: String] : Void
io.print(x)
io.print("\n")
func io.print_char[x: U8] : Void
let s: String = mem.alloc(1)
str.set(s, 0, x)
c.syscall(1, 1, s, 1)
mem.free(s)
func io.print_i64[x: I64] : Void
c.printf("%ld\n", x)
let s: String = str.from_i64(x)
io.print(s)
mem.free(s)
func io.println_i64[x: I64] : Void
let s: String = str.from_i64(x)
io.println(s)
mem.free(s)
func io.read_stdin[]: String
let buffer: String = mem.alloc(1025)
let n: I64 = c.read(0, buffer, 1024)
let n: I64 = c.syscall(0, 0, buffer, 1024)
if n < 0
return ""
str.set(buffer, n, 0)
return buffer
func io.read_file[path: String]: String
let file: Ptr = c.fopen(path, "rb")
if !file
let fd: I64 = c.syscall(2, path, 0, 0) // open
if fd <= 0
dbg.panic("failed to open file")
c.fseek(file, 0, 2)
let size: I64 = c.ftell(file)
c.rewind(file)
let size: I64 = c.syscall(8, fd, 0, 2) // lseek to the end
c.syscall(8, fd, 0, 0) // lseek back to start
let buffer: String = mem.alloc(size + 1)
// TODO: check if works with huge files
let n: I64 = c.fread(buffer, 1, size, file)
let n: I64 = c.syscall(0, fd, buffer, size) // read
str.set(buffer, n, 0)
c.fclose(file)
c.syscall(3, fd) // close
return buffer
func io.write_file[path: String, content: String] : Void
let file: Ptr = c.fopen(path, "wb")
if !file
let fd: Ptr = c.syscall(2, path, 0x241, 0o644) // open
if fd < 0
dbg.panic("failed to open file")
c.fwrite(content, 1, str.len(content), file)
c.fclose(file)
c.syscall(1, fd, content, str.len(content)) // write
c.syscall(3, fd) // close
func str.len[s: String] : I64
return c.strlen(s)
let i: I64 = 0
while mem.read8(s + i)
i = i + 1
return i
func str.copy[s: String] : String
let size: I64 = str.len(s) + 1
@@ -76,15 +98,25 @@ func str.set[s: String, n: I64, c: U8] : Void
mem.write8(s+n, c)
func str.equal[a: String, b: String] : Bool
return c.strcmp(a, b) == 0
let i: I64 = 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
func str.concat[a: String, b: String] : String
let out: String = mem.alloc(str.len(a) + str.len(b) + 1)
c.strcpy(out, a)
c.strcat(out, b)
let a_len: I64 = str.len(a)
let b_len: I64 = str.len(b)
let out: String = mem.alloc(a_len + b_len + 1)
for i in 0..a_len
str.set(out, i, a[i])
for i in 0..b_len
str.set(out, a_len + i, b[i])
str.set(out, a_len + b_len, 0)
return out
func str.find[s: String, c: U8] : I64
@@ -99,7 +131,8 @@ func str.substr[s: String, start: I64, length: I64] : String
dbg.panic("str.substr out of bounds")
let out: String = mem.alloc(length + 1)
c.strncpy(out, s + start, length)
for i in 0..length
str.set(out, i, s[start + i])
str.set(out, length, 0)
return out
@@ -264,9 +297,9 @@ func math.is_prime[n: I64]: Bool
func math.urandom[]: I64
let buffer: Ptr = mem.alloc(8)
let file: Ptr = c.fopen("/dev/urandom", "rb")
c.fread(buffer, 8, 1, file)
c.fclose(file)
let fd: I64 = c.syscall(2, "/dev/urandom", 0, 0) // open
c.syscall(0, fd, buffer, 8) // read
c.syscall(3, fd) // close
let n: I64 = mem.read64(buffer)
mem.free(buffer)
return n
@@ -337,7 +370,7 @@ func alg._partition[arr: Array, low: I64, high: I64] : I64
return i + 1
func os.exit[code: I64] : Void
c.exit(code)
c.syscall(60, code)
func os.time[] : I64
let tv: Ptr = mem.alloc(16)
@@ -370,7 +403,7 @@ func os.listdir[path: String] : Array
return files
func net.listen[port: I64] : I64
let s: I64 = c.socket(2, 1, 0)
let s: I64 = c.syscall(41, 2, 1, 0) // socket
if s < 0
return -1
@@ -381,13 +414,13 @@ func net.listen[port: I64] : I64
mem.write8(sa + 2, (port >> 8) & 255)
mem.write8(sa + 3, port & 255)
if c.bind(s, sa, 16) < 0
c.close(s)
if c.syscall(49, s, sa, 16) < 0 // bind
c.syscall(3, s) // close
return -1
mem.free(sa)
if c.listen(s, 1) < 0
c.close(s)
if c.syscall(50, s, 1) < 0 // listen
c.syscall(3, s) // close
return -1
return s
@@ -399,7 +432,7 @@ func net.connect[host: String, port: I64] : I64
let ip_ptr: Ptr = mem.read64(mem.read64(he + 24))
let s: I64 = c.socket(2, 1, 0)
let s: I64 = c.syscall(41, 2, 1, 0) // socket
if s < 0
return -1
@@ -413,9 +446,9 @@ func net.connect[host: String, port: I64] : I64
mem.write8(sa + 6, ip_ptr[2])
mem.write8(sa + 7, ip_ptr[3])
if c.connect(s, sa, 16) < 0
if c.syscall(42, s, sa, 16) < 0 // connect
mem.free(sa)
c.close(s)
c.syscall(3, s) // close
return -1
mem.free(sa)

View File

@@ -299,6 +299,10 @@ impl Tokenizer {
while self.peek().is_ascii_hexdigit() {
self.advance();
}
} else if self.match_char('o') {
while matches!(self.peek(), '0'..='7') {
self.advance();
}
} else {
while self.peek().is_ascii_digit() {
self.advance();