rename std functions

This commit is contained in:
2025-07-24 14:06:15 +02:00
parent dfec298823
commit 65bdac2fe3
26 changed files with 328 additions and 294 deletions

View File

@@ -6,6 +6,7 @@ A very cool language
* Clean indentation-based syntax * Clean indentation-based syntax
* Compiles to x86_64 Assembly * Compiles to x86_64 Assembly
* Almost works * Almost works
* Has the pipe operator
## Syntax ## Syntax
```rust ```rust

View File

@@ -1,45 +1,45 @@
func main[] : I64 func main[] : I64
// https://brainfuck.org/sierpinski.b // https://brainfuck.org/sierpinski.b
let src: String = "++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[-<<<[->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<<]>.>+[>>]>+]" let src: String = "++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[-<<<[->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<<]>.>+[>>]>+]"
let src_len: I64 = strlen(src) let src_len: I64 = c.strlen(src)
let i: I64 = 0 let i: I64 = 0
let memory: Ptr = calloc(1, 30000) let memory: Ptr = c.calloc(1, 30000)
let p: I64 = 0 let p: I64 = 0
while i < src_len while i < src_len
let op: U8 = String.nth(src, i) let op: U8 = str.nth(src, i)
if op == '>' if op == '>'
p = p + 1 p = p + 1
else if op == '<' else if op == '<'
p = p - 1 p = p - 1
else if op == '+' else if op == '+'
String.set(memory, p, String.nth(memory, p)+1) str.set(memory, p, str.nth(memory, p)+1)
else if op == '-' else if op == '-'
String.set(memory, p, String.nth(memory, p)-1) str.set(memory, p, str.nth(memory, p)-1)
else if op == '.' else if op == '.'
printf("%c", String.nth(memory, p)) c.printf("%c", str.nth(memory, p))
else if op == ',' else if op == ','
String.set(memory, p, getchar()) str.set(memory, p, c.getchar())
else if op == '[' else if op == '['
if !String.nth(memory, p) if !str.nth(memory, p)
i = i + 1 i = i + 1
let opened: I64 = 0 let opened: I64 = 0
while i < src_len && !(String.nth(src, i) == ']' && !opened) while i < src_len && !(str.nth(src, i) == ']' && !opened)
if String.nth(src, i) == '[' if str.nth(src, i) == '['
opened = opened + 1 opened = opened + 1
else if String.nth(src, i) == ']' else if str.nth(src, i) == ']'
opened = opened - 1 opened = opened - 1
i = i + 1 i = i + 1
else if op == ']' else if op == ']'
if String.nth(memory, p) if str.nth(memory, p)
i = i - 1 i = i - 1
let closed: I64 = 0 let closed: I64 = 0
while i >= 0 && !(String.nth(src, i) == '[' && !closed) while i >= 0 && !(str.nth(src, i) == '[' && !closed)
if String.nth(src, i) == ']' if str.nth(src, i) == ']'
closed = closed + 1 closed = closed + 1
else if String.nth(src, i) == '[' else if str.nth(src, i) == '['
closed = closed - 1 closed = closed - 1
i = i - 1 i = i - 1

View File

@@ -4,4 +4,4 @@ func main[] : I64
for i in 0..1000 for i in 0..1000
if i % 5 == 0 || i % 3 == 0 if i % 5 == 0 || i % 3 == 0
sum = sum + i sum = sum + i
print_i64(sum) io.print_i64(sum)

View File

@@ -2,6 +2,6 @@ func main[] : I64
let sum: I64 = 0 let sum: I64 = 0
for i in 0..2000000 for i in 0..2000000
if Math.is_prime(i) if math.is_prime(i)
sum = sum + i sum = sum + i
print_i64(sum) io.print_i64(sum)

View File

@@ -1,5 +1,5 @@
func num_divisors[n: I64] : I64 func num_divisors[n: I64] : I64
let end: I64 = Math.isqrt(n) let end: I64 = math.isqrt(n)
let out: I64 = 0 let out: I64 = 0
for i in 1..end+1 for i in 1..end+1
@@ -16,6 +16,6 @@ func main[] : I64
while true while true
n = n + i n = n + i
if num_divisors(n) > 500 if num_divisors(n) > 500
print_i64(n) io.print_i64(n)
break break
i = i + 1 i = i + 1

View File

@@ -1,5 +1,5 @@
func main[] : I64 func main[] : I64
37107287533 + 46376937677 + 74324986199 + 91942213363 + 23067588207 + 89261670696 + 28112879812 + 44274228917 + 47451445736 + 70386486105 + 62176457141 + 64906352462 + 92575867718 + 58203565325 + 80181199384 + 35398664372 + 86515506006 + 71693888707 + 54370070576 + 53282654108 + 36123272525 + 45876576172 + 17423706905 + 81142660418 + 51934325451 + 62467221648 + 15732444386 + 55037687525 + 18336384825 + 80386287592 + 78182833757 + 16726320100 + 48403098129 + 87086987551 + 59959406895 + 69793950679 + 41052684708 + 65378607361 + 35829035317 + 94953759765 + 88902802571 + 25267680276 + 36270218540 + 24074486908 + 91430288197 + 34413065578 + 23053081172 + 11487696932 + 63783299490 + 67720186971 + 95548255300 + 76085327132 + 37774242535 + 23701913275 + 29798860272 + 18495701454 + 38298203783 + 34829543829 + 40957953066 + 29746152185 + 41698116222 + 62467957194 + 23189706772 + 86188088225 + 11306739708 + 82959174767 + 97623331044 + 42846280183 + 55121603546 + 32238195734 + 75506164965 + 62177842752 + 32924185707 + 99518671430 + 73267460800 + 76841822524 + 97142617910 + 87783646182 + 10848802521 + 71329612474 + 62184073572 + 66627891981 + 60661826293 + 85786944089 + 66024396409 + 64913982680 + 16730939319 + 94809377245 + 78639167021 + 15368713711 + 40789923115 + 44889911501 + 41503128880 + 81234880673 + 82616570773 + 22918802058 + 77158542502 + 72107838435 + 20849603980 + 53503534226 37107287533 + 46376937677 + 74324986199 + 91942213363 + 23067588207 + 89261670696 + 28112879812 + 44274228917 + 47451445736 + 70386486105 + 62176457141 + 64906352462 + 92575867718 + 58203565325 + 80181199384 + 35398664372 + 86515506006 + 71693888707 + 54370070576 + 53282654108 + 36123272525 + 45876576172 + 17423706905 + 81142660418 + 51934325451 + 62467221648 + 15732444386 + 55037687525 + 18336384825 + 80386287592 + 78182833757 + 16726320100 + 48403098129 + 87086987551 + 59959406895 + 69793950679 + 41052684708 + 65378607361 + 35829035317 + 94953759765 + 88902802571 + 25267680276 + 36270218540 + 24074486908 + 91430288197 + 34413065578 + 23053081172 + 11487696932 + 63783299490 + 67720186971 + 95548255300 + 76085327132 + 37774242535 + 23701913275 + 29798860272 + 18495701454 + 38298203783 + 34829543829 + 40957953066 + 29746152185 + 41698116222 + 62467957194 + 23189706772 + 86188088225 + 11306739708 + 82959174767 + 97623331044 + 42846280183 + 55121603546 + 32238195734 + 75506164965 + 62177842752 + 32924185707 + 99518671430 + 73267460800 + 76841822524 + 97142617910 + 87783646182 + 10848802521 + 71329612474 + 62184073572 + 66627891981 + 60661826293 + 85786944089 + 66024396409 + 64913982680 + 16730939319 + 94809377245 + 78639167021 + 15368713711 + 40789923115 + 44889911501 + 41503128880 + 81234880673 + 82616570773 + 22918802058 + 77158542502 + 72107838435 + 20849603980 + 53503534226
|> I64.to_string() |> str.from_i64()
|> String.substr(0, 10) |> str.substr(0, 10)
|> print() |> io.print()

View File

@@ -19,4 +19,4 @@ func main[] : I64
if seq > max if seq > max
max = seq max = seq
max_index = i max_index = i
print_i64(max_index) io.print_i64(max_index)

View File

@@ -6,4 +6,4 @@ func main[] : I64
for i in 1..r+1 for i in 1..r+1
out = out * (n - (r - i)) / i out = out * (n - (r - i)) / i
print_i64(out) io.print_i64(out)

View File

@@ -10,4 +10,4 @@ func main[] : I64
b = a + b b = a + b
a = temp a = temp
print_i64(sum) io.print_i64(sum)

View File

@@ -8,4 +8,4 @@ func main[] : I64
else else
f = f + 1 f = f + 1
print_i64(n) io.print_i64(n)

View File

@@ -4,10 +4,10 @@ func main[] : I64
for a in 500..1000 for a in 500..1000
for b in 500..1000 for b in 500..1000
if a * b > out if a * b > out
let s: String = I64.to_string(a * b) let s: String = str.from_i64(a * b)
let s_rev: String = String.rev(s) let s_rev: String = str.reverse(s)
if strcmp(s, s_rev) == 0 if c.strcmp(s, s_rev) == 0
out = a * b out = a * b
free(s) c.free(s)
free(s_rev) c.free(s_rev)
print_i64(out) io.print_i64(out)

View File

@@ -2,5 +2,5 @@ func main[] : I64
let out: I64 = 1 let out: I64 = 1
for i in 1..21 for i in 1..21
out = Math.lcm(out, i) out = math.lcm(out, i)
print_i64(out) io.print_i64(out)

View File

@@ -8,4 +8,4 @@ func main[] : I64
square_of_sum = square_of_sum + i square_of_sum = square_of_sum + i
square_of_sum = square_of_sum * square_of_sum square_of_sum = square_of_sum * square_of_sum
print_i64(square_of_sum - sum_of_squares) io.print_i64(square_of_sum - sum_of_squares)

View File

@@ -3,9 +3,9 @@ func main[] : I64
let i: I64 = 1 let i: I64 = 1
while true while true
if Math.is_prime(i) if math.is_prime(i)
found = found + 1 found = found + 1
if found == 10001 if found == 10001
print_i64(i) io.print_i64(i)
break break
i = i + 1 i = i + 1

View File

@@ -2,13 +2,13 @@ func main[] : I64
let n: String = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450" let n: String = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"
let out: I64 = 0 let out: I64 = 0
let max: I64 = strlen(n) - 13 let max: I64 = c.strlen(n) - 13
for i in 0..max for i in 0..max
let s: I64 = 1 let s: I64 = 1
let j: I64 = 0 let j: I64 = 0
while j < 13 while j < 13
s = s * (String.nth(n, i + j) - '0') s = s * (str.nth(n, i + j) - '0')
j = j + 1 j = j + 1
if s > out if s > out
out = s out = s
print_i64(out) io.print_i64(out)

View File

@@ -3,5 +3,5 @@ func main[] : I64
for b in 1..1000 for b in 1..1000
let c: I64 = 1000 - b - a let c: I64 = 1000 - b - a
if a * a + b * b == c * c if a * a + b * b == c * c
print_i64(a * b * c) io.print_i64(a * b * c)
return 0 return 0

View File

@@ -3,7 +3,7 @@ func main[] : I64
let b: I64 = 1 let b: I64 = 1
while a < 100000 while a < 100000
print_i64(a) io.print_i64(a)
let temp: I64 = b let temp: I64 = b
b = a + b b = a + b
a = temp a = temp

View File

@@ -1,14 +1,14 @@
func main[] : I64 func main[] : I64
let answer: I64 = Math.abs(Math.urandom()) % 100 let answer: I64 = math.abs(math.urandom()) % 100
while true while true
print("Guess a number: ") io.print("Guess a number: ")
let guess: I64 = IO.read_line() |> String.trim() |> I64.parse() let guess: I64 = io.read_line() |> str.trim() |> str.parse_i64()
if guess == answer if guess == answer
print("You win!") io.print("You win!")
break break
else if guess < answer else if guess < answer
print("Too low!") io.print("Too low!")
else else
print("Too high!") io.print("Too high!")

View File

@@ -1,2 +1,2 @@
func main[] : I64 func main[] : I64
print("Hello, World!") io.print("Hello, World!")

View File

@@ -1,5 +1,5 @@
func quicksort[arr: Array] : Void func quicksort[arr: Array] : Void
do_quicksort(arr, 0, Array.size(arr)-1) do_quicksort(arr, 0, array.size(arr)-1)
func do_quicksort[arr: Array, low: I64, high: I64] : Void func do_quicksort[arr: Array, low: I64, high: I64] : Void
if low < high if low < high
@@ -14,23 +14,23 @@ func partition[arr: Array, low: I64, high: I64] : I64
if arr[j] <= pivot if arr[j] <= pivot
i = i + 1 i = i + 1
let temp: I64 = arr[i] let temp: I64 = arr[i]
Array.set(arr, i, arr[j]) array.set(arr, i, arr[j])
Array.set(arr, j, temp) array.set(arr, j, temp)
let temp: I64 = arr[i + 1] let temp: I64 = arr[i + 1]
Array.set(arr, i + 1, arr[high]) array.set(arr, i + 1, arr[high])
Array.set(arr, high, temp) array.set(arr, high, temp)
return i + 1 return i + 1
func main[] : I64 func main[] : I64
let arr: Array = [] let arr: Array = []
for i in 0..10 for i in 0..10
Array.push(arr, Math.abs(Math.urandom() % 1000)) array.push(arr, math.abs(math.urandom() % 1000))
for i in 0..Array.size(arr) for i in 0..array.size(arr)
print_i64(arr[i]) io.print_i64(arr[i])
print("------------") io.print("------------")
quicksort(arr) quicksort(arr)
for i in 0..Array.size(arr) for i in 0..array.size(arr)
print_i64(arr[i]) io.print_i64(arr[i])

View File

@@ -1,6 +1,6 @@
func rule110_step[state: Array] : Array func rule110_step[state: Array] : Array
let new_state: Array = [] let new_state: Array = []
let state_len: I64 = Array.size(state) let state_len: I64 = array.size(state)
for i in 0..state_len for i in 0..state_len
let left: Bool = false let left: Bool = false
@@ -11,17 +11,17 @@ func rule110_step[state: Array] : Array
if i + 1 < state_len if i + 1 < state_len
right = state[i+1] 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 return new_state
func to_str[state: Array]: String func to_str[state: Array]: String
let out: String = malloc(Array.size(state)) let out: String = malloc(array.size(state))
for i in 0..Array.size(state) for i in 0..array.size(state)
if state[i] if state[i]
String.set(out, i, '#') str.set(out, i, '#')
else else
String.set(out, i, ' ') str.set(out, i, ' ')
return out return out
func main[] : I64 func main[] : I64
@@ -29,10 +29,10 @@ func main[] : I64
let state: Array = [] let state: Array = []
for i in 0..SIZE for i in 0..SIZE
Array.push(state, false) array.push(state, false)
Array.push(state, true) array.push(state, true)
print(to_str(state)) io.print(to_str(state))
for i in 0..SIZE for i in 0..SIZE
state = rule110_step(state) state = rule110_step(state)
print(to_str(state)) io.print(to_str(state))

View File

@@ -1,31 +1,31 @@
func main[] : I64 func main[] : I64
let s: I64 = socket(2, 1, 0) let s: I64 = c.socket(2, 1, 0)
if s < 0 if s < 0
panic("socket() failed") dbg.panic("socket() failed")
let port: I64 = 80 let port: I64 = 80
let sa: Ptr = calloc(1, 16) let sa: Ptr = c.calloc(1, 16)
String.set(sa, 0, 2) str.set(sa, 0, 2)
String.set(sa, 1, 0) str.set(sa, 1, 0)
String.set(sa, 2, Bit.rshift(port, 8) && 255) str.set(sa, 2, bit.rshift(port, 8) && 255)
String.set(sa, 3, port && 255) str.set(sa, 3, port && 255)
// 23.192.228.80 (example.com) // 23.192.228.80 (example.com)
String.set(sa, 4, 23) str.set(sa, 4, 23)
String.set(sa, 5, 192) str.set(sa, 5, 192)
String.set(sa, 6, 228) str.set(sa, 6, 228)
String.set(sa, 7, 80) str.set(sa, 7, 80)
if connect(s, sa, 16) < 0 if c.connect(s, sa, 16) < 0
panic("connect() failed") dbg.panic("connect() failed")
free(sa) c.free(sa)
let req: String = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" let req: String = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"
send(s, req, strlen(req), 0) c.send(s, req, c.strlen(req), 0)
let resp: String = malloc(60000) let resp: String = c.malloc(60000)
let n: I64 = read(s, resp, 60000) let n: I64 = c.read(s, resp, 60000)
String.set(resp, n, 0) str.set(resp, n, 0)
print(resp) io.print(resp)
free(resp) c.free(resp)
close(s) c.close(s)

View File

@@ -1,27 +1,27 @@
func main[] : I64 func main[] : I64
let s: I64 = socket(2, 1, 0) let s: I64 = c.socket(2, 1, 0)
if s < 0 if s < 0
panic("socket() failed") dbg.panic("socket() failed")
let port: I64 = 8080 let port: I64 = 8080
let sa: Ptr = calloc(1, 16) let sa: Ptr = c.calloc(1, 16)
String.set(sa, 0, 2) str.set(sa, 0, 2)
String.set(sa, 1, 0) str.set(sa, 1, 0)
String.set(sa, 2, Bit.rshift(port, 8) && 255) str.set(sa, 2, bit.rshift(port, 8) && 255)
String.set(sa, 3, port && 255) str.set(sa, 3, port && 255)
if bind(s, sa, 16) < 0 if c.bind(s, sa, 16) < 0
panic("bind() failed") dbg.panic("bind() failed")
if listen(s, 1) < 0 if c.listen(s, 1) < 0
panic("listen() failed") dbg.panic("listen() failed")
let resp: String = malloc(60000) let resp: String = c.malloc(60000)
while true while true
let c: I64 = accept(s, 0, 0) let c: I64 = c.accept(s, 0, 0)
if c < 0 if c < 0
panic("accept() failed") dbg.panic("accept() failed")
let n: I64 = read(c, resp, 60000) let n: I64 = c.read(c, resp, 60000)
send(c, resp, n, 0) c.send(c, resp, n, 0)
close(c) c.close(c)

View File

@@ -100,44 +100,80 @@ impl CodegenX86_64 {
db 0 db 0
section .text section .text
extern stdin
extern malloc extern malloc
c.malloc equ malloc
extern calloc extern calloc
c.calloc equ calloc
extern realloc extern realloc
c.realloc equ realloc
extern free extern free
c.free equ free
extern puts
c.puts equ puts
extern printf extern printf
c.printf equ printf
extern sprintf extern sprintf
c.sprintf equ sprintf
extern strtol extern strtol
c.strtol equ strtol
extern strlen extern strlen
c.strlen equ strlen
extern strcmp extern strcmp
c.strcmp equ strcmp
extern strcat extern strcat
c.strcat equ strcat
extern strcpy extern strcpy
c.strcpy equ strcpy
extern strdup extern strdup
c.strdup equ strdup
extern strncpy extern strncpy
c.strncpy equ strncpy
extern syscall extern syscall
c.syscall equ syscall
extern fopen extern fopen
c.fopen equ fopen
extern fseek extern fseek
c.fseek equ fseek
extern ftell extern ftell
c.ftell equ ftell
extern fread extern fread
c.fread equ fread
extern fwrite extern fwrite
c.fwrite equ fwrite
extern fclose extern fclose
c.fclose equ fclose
extern rewind extern rewind
c.rewind equ rewind
extern system extern system
c.system equ system
extern opendir extern opendir
c.opendir equ opendir
extern readdir extern readdir
c.readdir equ readdir
extern closedir extern closedir
c.closedir equ closedir
extern exit extern exit
c.exit equ exit
extern gettimeofday extern gettimeofday
c.gettimeofday equ gettimeofday
extern connect extern connect
extern inet_addr c.connect equ connect
extern socket extern socket
c.socket equ socket
extern send extern send
c.send equ send
extern read extern read
c.read equ read
extern close extern close
c.close equ close
extern bind extern bind
c.bind equ bind
extern listen extern listen
c.listen equ listen
extern accept extern accept
c.accept equ accept
extern getchar extern getchar
c.getchar equ getchar
section .text._builtin_deref8 section .text._builtin_deref8
_builtin_deref8: _builtin_deref8:
@@ -418,22 +454,19 @@ _builtin_rshift:
.replace("\\033", "\x1b") .replace("\\033", "\x1b")
.replace("\\0", "\0"); .replace("\\0", "\0");
let label = format!("str_{:03}", self.data_counter);
if value.is_empty() { if value.is_empty() {
emit!(&mut self.data_section, " S{} db 0", self.data_counter); emit!(&mut self.data_section, " {} db 0", label);
} else { } else {
let charcodes = value let charcodes = value
.chars() .chars()
.map(|x| (x as u8).to_string()) .map(|x| (x as u8).to_string())
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(","); .join(",");
emit!( emit!(&mut self.data_section, " {} db {},0", label, charcodes,);
&mut self.data_section,
" S{} db {},0",
self.data_counter,
charcodes,
);
} }
emit!(&mut self.output, " mov rax, S{}", self.data_counter); emit!(&mut self.output, " mov rax, {}", label);
self.data_counter += 1; self.data_counter += 1;
} }
TokenType::True => { TokenType::True => {
@@ -512,7 +545,7 @@ _builtin_rshift:
emit!(&mut self.output, " call {}", callee); emit!(&mut self.output, " call {}", callee);
} }
Expr::ArrayLiteral(exprs) => { Expr::ArrayLiteral(exprs) => {
emit!(&mut self.output, " call Array.new"); emit!(&mut self.output, " call array.new");
emit!(&mut self.output, " push rax"); emit!(&mut self.output, " push rax");
for expr in exprs { for expr in exprs {
@@ -520,7 +553,7 @@ _builtin_rshift:
emit!(&mut self.output, " mov rsi, rax"); emit!(&mut self.output, " mov rsi, rax");
emit!(&mut self.output, " pop rdi"); emit!(&mut self.output, " pop rdi");
emit!(&mut self.output, " push rdi"); emit!(&mut self.output, " push rdi");
emit!(&mut self.output, " call Array.push"); emit!(&mut self.output, " call array.push");
} }
emit!(&mut self.output, " pop rax"); emit!(&mut self.output, " pop rax");
} }

View File

@@ -1,136 +1,136 @@
func panic[msg: String] : Void func dbg.panic[msg: String] : Void
printf("PANIC: %s\n", msg) c.printf("PANIC: %s\n", msg)
exit(1) c.exit(1)
func print[x: String] : Void func io.print[x: String] : Void
printf("%s\n", x) c.puts(x)
func print_i64[x: I64] : Void func io.print_i64[x: I64] : Void
printf("%ld\n", x) c.printf("%ld\n", x)
func String.nth[s: String, n: I64] : U8 func str.nth[s: String, n: I64] : U8
return _builtin_deref8(s + n) return _builtin_deref8(s + n)
func String.set[s: String, n: I64, c: U8] : Void func str.set[s: String, n: I64, c: U8] : Void
_builtin_set8(s+n, c) _builtin_set8(s+n, c)
func String.is_whitespace[c: U8] : Bool func str.is_whitespace[c: U8] : Bool
return c == ' ' || c == 10 || c == 13 || c == 9 return c == ' ' || c == 10 || c == 13 || c == 9
func String.concat[a: String, b: String] : String func str.concat[a: String, b: String] : String
let c: String = malloc(strlen(a) + strlen(b) + 1) let c: String = c.malloc(c.strlen(a) + c.strlen(b) + 1)
strcpy(c, a) c.strcpy(c, a)
strcat(c, b) c.strcat(c, b)
return c return c
func String.find[s: String, c: U8] : I64 func str.find[s: String, c: U8] : I64
let s_len: I64 = strlen(s) let s_len: I64 = c.strlen(s)
for i in 0..s_len for i in 0..s_len
if String.nth(s, i) == c if str.nth(s, i) == c
return i return i
return -1 return -1
func String.substr[s: String, start: I64, length: I64] : String func str.substr[s: String, start: I64, length: I64] : String
if start < 0 || length < 0 || start + length > strlen(s) if start < 0 || length < 0 || start + length > c.strlen(s)
panic("String.substr out of bounds") dbg.panic("String.substr out of bounds")
let out: String = malloc(length + 1) let out: String = c.malloc(length + 1)
strncpy(out, s + start, length) c.strncpy(out, s + start, length)
String.set(out, length, 0) str.set(out, length, 0)
return out return out
func String.trim[s: String] : String func str.trim[s: String] : String
let start: I64 = 0 let start: I64 = 0
let end: I64 = strlen(s) - 1 let end: I64 = c.strlen(s) - 1
while start <= end && String.is_whitespace(String.nth(s, start)) while start <= end && str.is_whitespace(str.nth(s, start))
start = start + 1 start = start + 1
while end >= start && String.is_whitespace(String.nth(s, end)) while end >= start && str.is_whitespace(str.nth(s, end))
end = end - 1 end = end - 1
return String.substr(s, start, end - start + 1) return str.substr(s, start, end - start + 1)
func String.rev[s: String] : String func str.reverse[s: String] : String
let len: I64 = strlen(s) let len: I64 = c.strlen(s)
let out: String = malloc(len + 1) let out: String = c.malloc(len + 1)
for i in 0..len for i in 0..len
String.set(out, i, String.nth(s, len - i - 1)) str.set(out, i, str.nth(s, len - i - 1))
String.set(out, len, 0) str.set(out, len, 0)
return out return out
func IO.read_line[]: String func io.read_line[]: String
let buffer: String = malloc(1024) let buffer: String = c.malloc(1024)
let sys_read: I64 = 0 let sys_read: I64 = 0
let stdin: I64 = 0 let stdin: I64 = 0
syscall(sys_read, stdin, buffer, 1024) c.syscall(sys_read, stdin, buffer, 1024)
return buffer return buffer
func IO.read_file[path: String]: String func io.read_file[path: String]: String
let file: Ptr = fopen(path, "rb") let file: Ptr = c.fopen(path, "rb")
if !file if !file
panic("failed to open file") dbg.panic("failed to open file")
fseek(file, 0, 2) c.fseek(file, 0, 2)
let size: I64 = ftell(file) let size: I64 = c.ftell(file)
rewind(file) c.rewind(file)
let buffer: String = malloc(size + 1) let buffer: String = c.malloc(size + 1)
let n: I64 = fread(buffer, 1, size, file) let n: I64 = c.fread(buffer, 1, size, file)
String.set(buffer, n, 0) str.set(buffer, n, 0)
fclose(file) c.fclose(file)
return buffer return buffer
func IO.write_file[path: String, content: String] : Void func io.write_file[path: String, content: String] : Void
let file: Ptr = fopen(path, "wb") let file: Ptr = c.fopen(path, "wb")
if !file if !file
panic("failed to open file") dbg.panic("failed to open file")
fwrite(content, 1, strlen(content), file) c.fwrite(content, 1, c.strlen(content), file)
fclose(file) c.fclose(file)
func I64.to_string[n: I64] : String func str.from_i64[n: I64] : String
let x: String = malloc(21) let x: String = c.malloc(21)
sprintf(x, "%ld", n) c.sprintf(x, "%ld", n)
return x return x
func I64.parse[s: String] : I64 func str.parse_i64[s: String] : I64
return strtol(s, 0, 0) return c.strtol(s, 0, 0)
func Math.gcd[a: I64, b: I64] : I64 func math.gcd[a: I64, b: I64] : I64
while b != 0 while b != 0
let tmp: I64 = b let tmp: I64 = b
b = a % b b = a % b
a = tmp a = tmp
return a return a
func Math.min[a: I64, b: I64] : I64 func math.min[a: I64, b: I64] : I64
if a < b if a < b
return a return a
return b return b
func Math.max[a: I64, b: I64] : I64 func math.max[a: I64, b: I64] : I64
if a > b if a > b
return a return a
return b return b
func Math.abs[n: I64] : I64 func math.abs[n: I64] : I64
if n < 0 if n < 0
return -n return -n
return n return n
func Math.pow[b: I64, e: I64] : I64 func math.pow[b: I64, e: I64] : I64
let out: I64 = 1 let out: I64 = 1
for i in 0..e for i in 0..e
out = out * b out = out * b
return out return out
func Math.lcm[a: I64, b: I64] : I64 func math.lcm[a: I64, b: I64] : I64
return (a * b) / Math.gcd(a, b) return (a * b) / math.gcd(a, b)
func Math.isqrt[n: I64] : I64 func math.isqrt[n: I64] : I64
if n < 0 if n < 0
return -1 return -1
if n == 0 || n == 1 if n == 0 || n == 1
@@ -145,7 +145,7 @@ func Math.isqrt[n: I64] : I64
return guess return guess
func Math.is_prime[n: I64]: Bool func math.is_prime[n: I64]: Bool
if n <= 1 if n <= 1
return false return false
if n == 2 || n == 3 if n == 2 || n == 3
@@ -160,23 +160,23 @@ func Math.is_prime[n: I64]: Bool
i = i + 6 i = i + 6
return true return true
func Math.urandom[]: I64 func math.urandom[]: I64
let buffer: Ptr = malloc(8) let buffer: Ptr = c.malloc(8)
let file: Ptr = fopen("/dev/urandom", "rb") let file: Ptr = c.fopen("/dev/urandom", "rb")
fread(buffer, 8, 1, file) c.fread(buffer, 8, 1, file)
fclose(file) c.fclose(file)
let n: I64 = _builtin_deref64(buffer) let n: I64 = _builtin_deref64(buffer)
free(buffer) c.free(buffer)
return n return n
func Array.new[] : Array func array.new[] : Array
return calloc(1, 24) return c.calloc(1, 24)
func Array.set[xs: Array, n: I64, x: I64] : Void func array.set[xs: Array, n: I64, x: I64] : Void
let data: Ptr = _builtin_deref64(xs) let data: Ptr = _builtin_deref64(xs)
_builtin_set64(data+n*8, x) _builtin_set64(data+n*8, x)
func Array.push[xs: Array, x: I64] : Void func array.push[xs: Array, x: I64] : Void
let data: Ptr = _builtin_deref64(xs) let data: Ptr = _builtin_deref64(xs)
let capacity: I64 = _builtin_deref64(xs+8) let capacity: I64 = _builtin_deref64(xs+8)
let size: I64 = _builtin_deref64(xs+16) let size: I64 = _builtin_deref64(xs+16)
@@ -185,7 +185,7 @@ func Array.push[xs: Array, x: I64] : Void
let new_capacity: I64 = 4 let new_capacity: I64 = 4
if capacity != 0 if capacity != 0
new_capacity = capacity * 2 new_capacity = capacity * 2
let new_data: Ptr = realloc(data, new_capacity * 8) let new_data: Ptr = c.realloc(data, new_capacity * 8)
_builtin_set64(xs, new_data) _builtin_set64(xs, new_data)
_builtin_set64(xs+8, new_capacity) _builtin_set64(xs+8, new_capacity)
data = new_data data = new_data
@@ -193,185 +193,185 @@ func Array.push[xs: Array, x: I64] : Void
_builtin_set64(data+size*8, x) _builtin_set64(data+size*8, x)
_builtin_set64(xs+16, size + 1) _builtin_set64(xs+16, size + 1)
func Array.size[xs: Array] : I64 func array.size[xs: Array] : I64
return _builtin_deref64(xs+16) return _builtin_deref64(xs+16)
func Array.free[xs: Array] : Void func array.free[xs: Array] : Void
free(_builtin_deref64(xs)) c.free(_builtin_deref64(xs))
free(xs) c.free(xs)
func OS.time[] : I64 func os.time[] : I64
let tv: Ptr = malloc(16) let tv: Ptr = c.malloc(16)
gettimeofday(tv, 0) c.gettimeofday(tv, 0)
let seconds: I64 = _builtin_deref64(tv) let seconds: I64 = _builtin_deref64(tv)
let microseconds: I64 = _builtin_deref64(tv+8) let microseconds: I64 = _builtin_deref64(tv+8)
free(tv) c.free(tv)
return seconds * 1000 + microseconds / 1000 return seconds * 1000 + microseconds / 1000
func OS.listdir[path: String] : Array func os.listdir[path: String] : Array
let dir: Ptr = opendir(path) let dir: Ptr = c.opendir(path)
let files: Array = [] let files: Array = []
while true while true
let entry: Ptr = readdir(dir) let entry: Ptr = c.readdir(dir)
if entry == 0 if entry == 0
break break
let skip: Bool = false let skip: Bool = false
if String.nth(entry, 19) == '.' if str.nth(entry, 19) == '.'
if String.nth(entry, 20) == 0 if str.nth(entry, 20) == 0
skip = true skip = true
else if String.nth(entry, 20) == '.' else if str.nth(entry, 20) == '.'
if String.nth(entry, 21) == 0 if str.nth(entry, 21) == 0
skip = true skip = true
if !skip if !skip
Array.push(files, strdup(entry + 19)) array.push(files, c.strdup(entry + 19))
closedir(dir) c.closedir(dir)
return files return files
func Bit.lshift[a: I64, b: I64] : I64 func bit.lshift[a: I64, b: I64] : I64
return _builtin_lshift(a, b) return _builtin_lshift(a, b)
func Bit.rshift[a: I64, b: I64] : I64 func bit.rshift[a: I64, b: I64] : I64
return _builtin_rshift(a, b) return _builtin_rshift(a, b)
func Crypto.hex_encode[s: String] : String func crypto.hex_encode[s: String] : String
let hex_chars: String = "0123456789abcdef" let hex_chars: String = "0123456789abcdef"
let s_len: I64 = strlen(s) let s_len: I64 = c.strlen(s)
let j: I64 = 0 let j: I64 = 0
let out: String = malloc(s_len*2+1) let out: String = c.malloc(s_len*2+1)
for i in 0..s_len for i in 0..s_len
let high: U8 = Bit.rshift(String.nth(s, i), 4) && 15 let high: U8 = bit.rshift(str.nth(s, i), 4) && 15
let low: U8 = String.nth(s, i) && 15 let low: U8 = str.nth(s, i) && 15
String.set(out, j, String.nth(hex_chars, high)) str.set(out, j, str.nth(hex_chars, high))
String.set(out, j+1, String.nth(hex_chars, low)) str.set(out, j+1, str.nth(hex_chars, low))
j = j + 2 j = j + 2
String.set(out, j, 0) str.set(out, j, 0)
return out return out
func Crypto.from_hex_digit[d: U8] : I64 func crypto.from_hex_digit[d: U8] : I64
if d >= 'a' && d <= 'f' if d >= 'a' && d <= 'f'
return d - 'a' + 10 return d - 'a' + 10
if d >= 'A' && d <= 'F' if d >= 'A' && d <= 'F'
return d - 'A' + 10 return d - 'A' + 10
return d - '0' return d - '0'
func Crypto.hex_decode[s: String] : String func crypto.hex_decode[s: String] : String
let s_len: I64 = strlen(s) let s_len: I64 = c.strlen(s)
let i: I64 = 0 let i: I64 = 0
let j: I64 = 0 let j: I64 = 0
let out: String = malloc(s_len/2+1) let out: String = c.malloc(s_len/2+1)
while i < s_len while i < s_len
String.set(out, j, Crypto.from_hex_digit(String.nth(s, i)) * 16 + Crypto.from_hex_digit(String.nth(s, i+1))) str.set(out, j, crypto.from_hex_digit(str.nth(s, i)) * 16 + crypto.from_hex_digit(str.nth(s, i+1)))
i = i + 2 i = i + 2
j = j + 1 j = j + 1
String.set(out, j, 0) str.set(out, j, 0)
return out return out
func Crypto.rc4[key: String, plaintext: String]: String func crypto.rc4[key: String, plaintext: String]: String
let S: String = malloc(256) let S: String = c.malloc(256)
for i in 0..256 for i in 0..256
String.set(S, i, i) str.set(S, i, i)
let j: I64 = 0 let j: I64 = 0
let key_len: I64 = strlen(key) let key_len: I64 = c.strlen(key)
for i in 0..256 for i in 0..256
j = (j + String.nth(S, i) + String.nth(key, i % key_len)) % 256 j = (j + str.nth(S, i) + str.nth(key, i % key_len)) % 256
let tmp: U8 = String.nth(S, i) let tmp: U8 = str.nth(S, i)
String.set(S, i, String.nth(S, j)) str.set(S, i, str.nth(S, j))
String.set(S, j, tmp) str.set(S, j, tmp)
let i: I64 = 0 let i: I64 = 0
j = 0 j = 0
let plaintext_len: I64 = strlen(plaintext) let plaintext_len: I64 = c.strlen(plaintext)
let ciphertext: String = malloc(plaintext_len+1) let ciphertext: String = c.malloc(plaintext_len+1)
for n in 0..plaintext_len for n in 0..plaintext_len
i = (i + 1) % 256 i = (i + 1) % 256
j = (j + String.nth(S, i)) % 256 j = (j + str.nth(S, i)) % 256
let tmp: U8 = String.nth(S, i) let tmp: U8 = str.nth(S, i)
String.set(S, i, String.nth(S, j)) str.set(S, i, str.nth(S, j))
String.set(S, j, tmp) str.set(S, j, tmp)
let r: I64 = String.nth(S, (String.nth(S, i) + String.nth(S, j)) % 256) let r: I64 = str.nth(S, (str.nth(S, i) + str.nth(S, j)) % 256)
String.set(ciphertext, n, r ^ String.nth(plaintext, n)) str.set(ciphertext, n, r ^ str.nth(plaintext, n))
String.set(ciphertext, plaintext_len, 0) str.set(ciphertext, plaintext_len, 0)
free(S) c.free(S)
return ciphertext return ciphertext
func Crypto.base64_encode[s: String] : String func crypto.base64_encode[s: String] : String
let chars: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" let chars: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
let s_len: I64 = strlen(s) let s_len: I64 = c.strlen(s)
let out: String = malloc(s_len*2) let out: String = c.malloc(s_len*2)
let i: I64 = 0 let i: I64 = 0
let j: I64 = 0 let j: I64 = 0
while i < s_len while i < s_len
let b1: U8 = String.nth(s, i) let b1: U8 = str.nth(s, i)
let b2: U8 = 0 let b2: U8 = 0
if i + 1 < s_len if i + 1 < s_len
b2 = String.nth(s, i+1) b2 = str.nth(s, i+1)
let b3: U8 = 0 let b3: U8 = 0
if i + 2 < s_len if i + 2 < s_len
b3 = String.nth(s, i+2) b3 = str.nth(s, i+2)
i = i + 3 i = i + 3
let triple: I64 = Bit.lshift(b1, 16) || Bit.lshift(b2, 8) || b3 let triple: I64 = bit.lshift(b1, 16) || bit.lshift(b2, 8) || b3
String.set(out, j, String.nth(chars, Bit.rshift(triple, 18) && 63)) str.set(out, j, str.nth(chars, bit.rshift(triple, 18) && 63))
String.set(out, j+1, String.nth(chars, Bit.rshift(triple, 12) && 63)) str.set(out, j+1, str.nth(chars, bit.rshift(triple, 12) && 63))
String.set(out, j+2, String.nth(chars, Bit.rshift(triple, 6) && 63)) str.set(out, j+2, str.nth(chars, bit.rshift(triple, 6) && 63))
String.set(out, j+3, String.nth(chars, triple && 63)) str.set(out, j+3, str.nth(chars, triple && 63))
j = j + 4 j = j + 4
let padding: I64 = s_len % 3 let padding: I64 = s_len % 3
if padding == 1 if padding == 1
String.set(out, j-2, '=') str.set(out, j-2, '=')
String.set(out, j-1, '=') str.set(out, j-1, '=')
else if padding == 2 else if padding == 2
String.set(out, j-1, '=') str.set(out, j-1, '=')
String.set(out, j, 0) str.set(out, j, 0)
return out return out
func Crypto.base64_decode[s: String] : String func crypto.base64_decode[s: String] : String
let chars: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" let chars: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
let s_len: I64 = strlen(s) let s_len: I64 = c.strlen(s)
let out: String = malloc(s_len) let out: String = c.malloc(s_len)
let i: I64 = 0 let i: I64 = 0
let j: I64 = 0 let j: I64 = 0
while String.nth(s, s_len-1) == '=' while str.nth(s, s_len-1) == '='
s_len = s_len - 1 s_len = s_len - 1
while i < s_len while i < s_len
let s1: U8 = String.find(chars, String.nth(s, i)) let s1: U8 = str.find(chars, str.nth(s, i))
let s2: U8 = 0 let s2: U8 = 0
if i + 1 < s_len if i + 1 < s_len
s2 = String.find(chars, String.nth(s, i+1)) s2 = str.find(chars, str.nth(s, i+1))
let s3: U8 = 0 let s3: U8 = 0
if i + 2 < s_len if i + 2 < s_len
s3 = String.find(chars, String.nth(s, i+2)) s3 = str.find(chars, str.nth(s, i+2))
let s4: U8 = 0 let s4: U8 = 0
if i + 3 < s_len if i + 3 < s_len
s4 = String.find(chars, String.nth(s, i+3)) s4 = str.find(chars, str.nth(s, i+3))
i = i + 4 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
String.set(out, j, Bit.rshift(triple, 16) && 255) str.set(out, j, bit.rshift(triple, 16) && 255)
j = j + 1 j = j + 1
if s3 != 64 if s3 != 64
String.set(out, j, Bit.rshift(triple, 8) && 255) str.set(out, j, bit.rshift(triple, 8) && 255)
j = j + 1 j = j + 1
if s4 != 64 if s4 != 64
String.set(out, j, triple && 255) str.set(out, j, triple && 255)
j = j + 1 j = j + 1
String.set(out, j, 0) str.set(out, j, 0)
return out return out

36
test.zr
View File

@@ -1,28 +1,28 @@
func run_test[x: String] : Void func run_test[x: String] : Void
printf("\033[93mBuilding %s...\033[0m", x) c.printf("\033[93mBuilding %s...\033[0m", x)
let cmd: String = String.concat("./target/release/zern examples/", x) let cmd: String = str.concat("./target/release/zern examples/", x)
let build_start_time: I64 = OS.time() let build_start_time: I64 = os.time()
if system(cmd) != 0 if c.system(cmd) != 0
exit(1) c.exit(1)
let build_end_time: I64 = OS.time() let build_end_time: I64 = os.time()
free(cmd) c.free(cmd)
printf(" %ldms\n", build_end_time - build_start_time) c.printf(" %ldms\n", build_end_time - build_start_time)
if strcmp(x, "guess_number.zr") == 0 || strcmp(x, "tcp_server.zr") == 0 if c.strcmp(x, "guess_number.zr") == 0 || c.strcmp(x, "tcp_server.zr") == 0
printf("\033[93mSkipping %s...\033[0m\n", x) c.printf("\033[93mSkipping %s...\033[0m\n", x)
else else
let run_start_time: I64 = OS.time() let run_start_time: I64 = os.time()
if system("./out") != 0 if c.system("./out") != 0
exit(1) c.exit(1)
let run_end_time: I64 = OS.time() let run_end_time: I64 = os.time()
printf("\033[93mRunning %s...\033[0m %ldms\n", x, run_end_time - run_start_time) c.printf("\033[93mRunning %s...\033[0m %ldms\n", x, run_end_time - run_start_time)
func main[] : I64 func main[] : I64
system("cargo build --release") c.system("cargo build --release")
let files: Array = OS.listdir("examples/") let files: Array = os.listdir("examples/")
for i in 0..Array.size(files) for i in 0..array.size(files)
run_test(files[i]) run_test(files[i])