rename std functions
This commit is contained in:
@@ -100,44 +100,80 @@ impl CodegenX86_64 {
|
||||
db 0
|
||||
|
||||
section .text
|
||||
extern stdin
|
||||
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
|
||||
extern inet_addr
|
||||
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
|
||||
|
||||
section .text._builtin_deref8
|
||||
_builtin_deref8:
|
||||
@@ -418,22 +454,19 @@ _builtin_rshift:
|
||||
.replace("\\033", "\x1b")
|
||||
.replace("\\0", "\0");
|
||||
|
||||
let label = format!("str_{:03}", self.data_counter);
|
||||
|
||||
if value.is_empty() {
|
||||
emit!(&mut self.data_section, " S{} db 0", self.data_counter);
|
||||
emit!(&mut self.data_section, " {} db 0", label);
|
||||
} else {
|
||||
let charcodes = value
|
||||
.chars()
|
||||
.map(|x| (x as u8).to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(",");
|
||||
emit!(
|
||||
&mut self.data_section,
|
||||
" S{} db {},0",
|
||||
self.data_counter,
|
||||
charcodes,
|
||||
);
|
||||
emit!(&mut self.data_section, " {} db {},0", label, charcodes,);
|
||||
}
|
||||
emit!(&mut self.output, " mov rax, S{}", self.data_counter);
|
||||
emit!(&mut self.output, " mov rax, {}", label);
|
||||
self.data_counter += 1;
|
||||
}
|
||||
TokenType::True => {
|
||||
@@ -512,7 +545,7 @@ _builtin_rshift:
|
||||
emit!(&mut self.output, " call {}", callee);
|
||||
}
|
||||
Expr::ArrayLiteral(exprs) => {
|
||||
emit!(&mut self.output, " call Array.new");
|
||||
emit!(&mut self.output, " call array.new");
|
||||
emit!(&mut self.output, " push rax");
|
||||
|
||||
for expr in exprs {
|
||||
@@ -520,7 +553,7 @@ _builtin_rshift:
|
||||
emit!(&mut self.output, " mov rsi, rax");
|
||||
emit!(&mut self.output, " pop 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");
|
||||
}
|
||||
|
||||
310
src/std.zr
310
src/std.zr
@@ -1,136 +1,136 @@
|
||||
func panic[msg: String] : Void
|
||||
printf("PANIC: %s\n", msg)
|
||||
exit(1)
|
||||
func dbg.panic[msg: String] : Void
|
||||
c.printf("PANIC: %s\n", msg)
|
||||
c.exit(1)
|
||||
|
||||
func print[x: String] : Void
|
||||
printf("%s\n", x)
|
||||
func io.print[x: String] : Void
|
||||
c.puts(x)
|
||||
|
||||
func print_i64[x: I64] : Void
|
||||
printf("%ld\n", x)
|
||||
func io.print_i64[x: I64] : Void
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
func String.is_whitespace[c: U8] : Bool
|
||||
func str.is_whitespace[c: U8] : Bool
|
||||
return c == ' ' || c == 10 || c == 13 || c == 9
|
||||
|
||||
func String.concat[a: String, b: String] : String
|
||||
let c: String = malloc(strlen(a) + strlen(b) + 1)
|
||||
strcpy(c, a)
|
||||
strcat(c, b)
|
||||
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
|
||||
|
||||
func String.find[s: String, c: U8] : I64
|
||||
let s_len: I64 = strlen(s)
|
||||
func str.find[s: String, c: U8] : I64
|
||||
let s_len: I64 = c.strlen(s)
|
||||
for i in 0..s_len
|
||||
if String.nth(s, i) == c
|
||||
if str.nth(s, i) == c
|
||||
return i
|
||||
return -1
|
||||
|
||||
func String.substr[s: String, start: I64, length: I64] : String
|
||||
if start < 0 || length < 0 || start + length > strlen(s)
|
||||
panic("String.substr out of bounds")
|
||||
func str.substr[s: String, start: I64, length: I64] : String
|
||||
if start < 0 || length < 0 || start + length > c.strlen(s)
|
||||
dbg.panic("String.substr out of bounds")
|
||||
|
||||
let out: String = malloc(length + 1)
|
||||
strncpy(out, s + start, length)
|
||||
String.set(out, length, 0)
|
||||
let out: String = c.malloc(length + 1)
|
||||
c.strncpy(out, s + start, length)
|
||||
str.set(out, length, 0)
|
||||
return out
|
||||
|
||||
func String.trim[s: String] : String
|
||||
func str.trim[s: String] : String
|
||||
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
|
||||
|
||||
while end >= start && String.is_whitespace(String.nth(s, end))
|
||||
while end >= start && str.is_whitespace(str.nth(s, end))
|
||||
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
|
||||
let len: I64 = strlen(s)
|
||||
let out: String = malloc(len + 1)
|
||||
func str.reverse[s: String] : String
|
||||
let len: I64 = c.strlen(s)
|
||||
let out: String = c.malloc(len + 1)
|
||||
|
||||
for i in 0..len
|
||||
String.set(out, i, String.nth(s, len - i - 1))
|
||||
String.set(out, len, 0)
|
||||
str.set(out, i, str.nth(s, len - i - 1))
|
||||
str.set(out, len, 0)
|
||||
return out
|
||||
|
||||
func IO.read_line[]: String
|
||||
let buffer: String = malloc(1024)
|
||||
func io.read_line[]: String
|
||||
let buffer: String = c.malloc(1024)
|
||||
let sys_read: I64 = 0
|
||||
let stdin: I64 = 0
|
||||
syscall(sys_read, stdin, buffer, 1024)
|
||||
c.syscall(sys_read, stdin, buffer, 1024)
|
||||
return buffer
|
||||
|
||||
func IO.read_file[path: String]: String
|
||||
let file: Ptr = fopen(path, "rb")
|
||||
func io.read_file[path: String]: String
|
||||
let file: Ptr = c.fopen(path, "rb")
|
||||
if !file
|
||||
panic("failed to open file")
|
||||
dbg.panic("failed to open file")
|
||||
|
||||
fseek(file, 0, 2)
|
||||
let size: I64 = ftell(file)
|
||||
rewind(file)
|
||||
c.fseek(file, 0, 2)
|
||||
let size: I64 = c.ftell(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)
|
||||
String.set(buffer, n, 0)
|
||||
fclose(file)
|
||||
let n: I64 = c.fread(buffer, 1, size, file)
|
||||
str.set(buffer, n, 0)
|
||||
c.fclose(file)
|
||||
return buffer
|
||||
|
||||
func IO.write_file[path: String, content: String] : Void
|
||||
let file: Ptr = fopen(path, "wb")
|
||||
func io.write_file[path: String, content: String] : Void
|
||||
let file: Ptr = c.fopen(path, "wb")
|
||||
if !file
|
||||
panic("failed to open file")
|
||||
dbg.panic("failed to open file")
|
||||
|
||||
fwrite(content, 1, strlen(content), file)
|
||||
fclose(file)
|
||||
c.fwrite(content, 1, c.strlen(content), file)
|
||||
c.fclose(file)
|
||||
|
||||
func I64.to_string[n: I64] : String
|
||||
let x: String = malloc(21)
|
||||
sprintf(x, "%ld", n)
|
||||
func str.from_i64[n: I64] : String
|
||||
let x: String = c.malloc(21)
|
||||
c.sprintf(x, "%ld", n)
|
||||
return x
|
||||
|
||||
func I64.parse[s: String] : I64
|
||||
return strtol(s, 0, 0)
|
||||
func str.parse_i64[s: String] : I64
|
||||
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
|
||||
let tmp: I64 = b
|
||||
b = a % b
|
||||
a = tmp
|
||||
return a
|
||||
|
||||
func Math.min[a: I64, b: I64] : I64
|
||||
func math.min[a: I64, b: I64] : I64
|
||||
if a < b
|
||||
return a
|
||||
return b
|
||||
|
||||
func Math.max[a: I64, b: I64] : I64
|
||||
func math.max[a: I64, b: I64] : I64
|
||||
if a > b
|
||||
return a
|
||||
return b
|
||||
|
||||
func Math.abs[n: I64] : I64
|
||||
func math.abs[n: I64] : I64
|
||||
if n < 0
|
||||
return -n
|
||||
return n
|
||||
|
||||
func Math.pow[b: I64, e: I64] : I64
|
||||
func math.pow[b: I64, e: I64] : I64
|
||||
let out: I64 = 1
|
||||
for i in 0..e
|
||||
out = out * b
|
||||
return out
|
||||
|
||||
func Math.lcm[a: I64, b: I64] : I64
|
||||
return (a * b) / Math.gcd(a, b)
|
||||
func math.lcm[a: I64, b: I64] : I64
|
||||
return (a * b) / math.gcd(a, b)
|
||||
|
||||
func Math.isqrt[n: I64] : I64
|
||||
func math.isqrt[n: I64] : I64
|
||||
if n < 0
|
||||
return -1
|
||||
if n == 0 || n == 1
|
||||
@@ -145,7 +145,7 @@ func Math.isqrt[n: I64] : I64
|
||||
|
||||
return guess
|
||||
|
||||
func Math.is_prime[n: I64]: Bool
|
||||
func math.is_prime[n: I64]: Bool
|
||||
if n <= 1
|
||||
return false
|
||||
if n == 2 || n == 3
|
||||
@@ -160,23 +160,23 @@ func Math.is_prime[n: I64]: Bool
|
||||
i = i + 6
|
||||
return true
|
||||
|
||||
func Math.urandom[]: I64
|
||||
let buffer: Ptr = malloc(8)
|
||||
let file: Ptr = fopen("/dev/urandom", "rb")
|
||||
fread(buffer, 8, 1, file)
|
||||
fclose(file)
|
||||
func math.urandom[]: I64
|
||||
let buffer: Ptr = c.malloc(8)
|
||||
let file: Ptr = c.fopen("/dev/urandom", "rb")
|
||||
c.fread(buffer, 8, 1, file)
|
||||
c.fclose(file)
|
||||
let n: I64 = _builtin_deref64(buffer)
|
||||
free(buffer)
|
||||
c.free(buffer)
|
||||
return n
|
||||
|
||||
func Array.new[] : Array
|
||||
return calloc(1, 24)
|
||||
func array.new[] : Array
|
||||
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)
|
||||
_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 capacity: I64 = _builtin_deref64(xs+8)
|
||||
let size: I64 = _builtin_deref64(xs+16)
|
||||
@@ -185,7 +185,7 @@ func Array.push[xs: Array, x: I64] : Void
|
||||
let new_capacity: I64 = 4
|
||||
if capacity != 0
|
||||
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+8, new_capacity)
|
||||
data = new_data
|
||||
@@ -193,185 +193,185 @@ func Array.push[xs: Array, x: I64] : Void
|
||||
_builtin_set64(data+size*8, x)
|
||||
_builtin_set64(xs+16, size + 1)
|
||||
|
||||
func Array.size[xs: Array] : I64
|
||||
func array.size[xs: Array] : I64
|
||||
return _builtin_deref64(xs+16)
|
||||
|
||||
func Array.free[xs: Array] : Void
|
||||
free(_builtin_deref64(xs))
|
||||
free(xs)
|
||||
func array.free[xs: Array] : Void
|
||||
c.free(_builtin_deref64(xs))
|
||||
c.free(xs)
|
||||
|
||||
func OS.time[] : I64
|
||||
let tv: Ptr = malloc(16)
|
||||
gettimeofday(tv, 0)
|
||||
func os.time[] : I64
|
||||
let tv: Ptr = c.malloc(16)
|
||||
c.gettimeofday(tv, 0)
|
||||
let seconds: I64 = _builtin_deref64(tv)
|
||||
let microseconds: I64 = _builtin_deref64(tv+8)
|
||||
free(tv)
|
||||
c.free(tv)
|
||||
return seconds * 1000 + microseconds / 1000
|
||||
|
||||
func OS.listdir[path: String] : Array
|
||||
let dir: Ptr = opendir(path)
|
||||
func os.listdir[path: String] : Array
|
||||
let dir: Ptr = c.opendir(path)
|
||||
let files: Array = []
|
||||
|
||||
while true
|
||||
let entry: Ptr = readdir(dir)
|
||||
let entry: Ptr = c.readdir(dir)
|
||||
if entry == 0
|
||||
break
|
||||
|
||||
let skip: Bool = false
|
||||
if String.nth(entry, 19) == '.'
|
||||
if String.nth(entry, 20) == 0
|
||||
if str.nth(entry, 19) == '.'
|
||||
if str.nth(entry, 20) == 0
|
||||
skip = true
|
||||
else if String.nth(entry, 20) == '.'
|
||||
if String.nth(entry, 21) == 0
|
||||
else if str.nth(entry, 20) == '.'
|
||||
if str.nth(entry, 21) == 0
|
||||
skip = true
|
||||
|
||||
if !skip
|
||||
Array.push(files, strdup(entry + 19))
|
||||
closedir(dir)
|
||||
array.push(files, c.strdup(entry + 19))
|
||||
c.closedir(dir)
|
||||
return files
|
||||
|
||||
func Bit.lshift[a: I64, b: I64] : I64
|
||||
func bit.lshift[a: I64, b: I64] : I64
|
||||
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)
|
||||
|
||||
func Crypto.hex_encode[s: String] : String
|
||||
func crypto.hex_encode[s: String] : String
|
||||
let hex_chars: String = "0123456789abcdef"
|
||||
let s_len: I64 = strlen(s)
|
||||
let s_len: I64 = c.strlen(s)
|
||||
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
|
||||
let high: U8 = Bit.rshift(String.nth(s, i), 4) && 15
|
||||
let low: U8 = String.nth(s, i) && 15
|
||||
String.set(out, j, String.nth(hex_chars, high))
|
||||
String.set(out, j+1, String.nth(hex_chars, low))
|
||||
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
|
||||
|
||||
String.set(out, j, 0)
|
||||
str.set(out, j, 0)
|
||||
return out
|
||||
|
||||
func Crypto.from_hex_digit[d: U8] : I64
|
||||
func crypto.from_hex_digit[d: U8] : I64
|
||||
if d >= 'a' && d <= 'f'
|
||||
return d - 'a' + 10
|
||||
if d >= 'A' && d <= 'F'
|
||||
return d - 'A' + 10
|
||||
return d - '0'
|
||||
|
||||
func Crypto.hex_decode[s: String] : String
|
||||
let s_len: I64 = strlen(s)
|
||||
func crypto.hex_decode[s: String] : String
|
||||
let s_len: I64 = c.strlen(s)
|
||||
let i: 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
|
||||
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
|
||||
j = j + 1
|
||||
|
||||
String.set(out, j, 0)
|
||||
str.set(out, j, 0)
|
||||
return out
|
||||
|
||||
func Crypto.rc4[key: String, plaintext: String]: String
|
||||
let S: String = malloc(256)
|
||||
func crypto.rc4[key: String, plaintext: String]: String
|
||||
let S: String = c.malloc(256)
|
||||
for i in 0..256
|
||||
String.set(S, i, i)
|
||||
str.set(S, i, i)
|
||||
|
||||
let j: I64 = 0
|
||||
let key_len: I64 = strlen(key)
|
||||
let key_len: I64 = c.strlen(key)
|
||||
for i in 0..256
|
||||
j = (j + String.nth(S, i) + String.nth(key, i % key_len)) % 256
|
||||
let tmp: U8 = String.nth(S, i)
|
||||
String.set(S, i, String.nth(S, j))
|
||||
String.set(S, j, tmp)
|
||||
j = (j + str.nth(S, i) + str.nth(key, i % key_len)) % 256
|
||||
let tmp: U8 = str.nth(S, i)
|
||||
str.set(S, i, str.nth(S, j))
|
||||
str.set(S, j, tmp)
|
||||
|
||||
let i: I64 = 0
|
||||
j = 0
|
||||
let plaintext_len: I64 = strlen(plaintext)
|
||||
let ciphertext: String = malloc(plaintext_len+1)
|
||||
let plaintext_len: I64 = c.strlen(plaintext)
|
||||
let ciphertext: String = c.malloc(plaintext_len+1)
|
||||
for n in 0..plaintext_len
|
||||
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)
|
||||
String.set(S, i, String.nth(S, j))
|
||||
String.set(S, j, tmp)
|
||||
let tmp: U8 = str.nth(S, i)
|
||||
str.set(S, i, str.nth(S, j))
|
||||
str.set(S, j, tmp)
|
||||
|
||||
let r: I64 = String.nth(S, (String.nth(S, i) + String.nth(S, j)) % 256)
|
||||
String.set(ciphertext, n, r ^ String.nth(plaintext, n))
|
||||
let r: I64 = str.nth(S, (str.nth(S, i) + str.nth(S, j)) % 256)
|
||||
str.set(ciphertext, n, r ^ str.nth(plaintext, n))
|
||||
|
||||
String.set(ciphertext, plaintext_len, 0)
|
||||
free(S)
|
||||
str.set(ciphertext, plaintext_len, 0)
|
||||
c.free(S)
|
||||
return ciphertext
|
||||
|
||||
func Crypto.base64_encode[s: String] : String
|
||||
func crypto.base64_encode[s: String] : String
|
||||
let chars: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
let s_len: I64 = strlen(s)
|
||||
let out: String = malloc(s_len*2)
|
||||
let s_len: I64 = c.strlen(s)
|
||||
let out: String = c.malloc(s_len*2)
|
||||
let i: I64 = 0
|
||||
let j: I64 = 0
|
||||
|
||||
while i < s_len
|
||||
let b1: U8 = String.nth(s, i)
|
||||
let b1: U8 = str.nth(s, i)
|
||||
let b2: U8 = 0
|
||||
if i + 1 < s_len
|
||||
b2 = String.nth(s, i+1)
|
||||
b2 = str.nth(s, i+1)
|
||||
let b3: U8 = 0
|
||||
if i + 2 < s_len
|
||||
b3 = String.nth(s, i+2)
|
||||
b3 = str.nth(s, i+2)
|
||||
i = i + 3
|
||||
|
||||
let triple: I64 = Bit.lshift(b1, 16) || Bit.lshift(b2, 8) || b3
|
||||
String.set(out, j, String.nth(chars, Bit.rshift(triple, 18) && 63))
|
||||
String.set(out, j+1, String.nth(chars, Bit.rshift(triple, 12) && 63))
|
||||
String.set(out, j+2, String.nth(chars, Bit.rshift(triple, 6) && 63))
|
||||
String.set(out, j+3, String.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
|
||||
if padding == 1
|
||||
String.set(out, j-2, '=')
|
||||
String.set(out, j-1, '=')
|
||||
str.set(out, j-2, '=')
|
||||
str.set(out, j-1, '=')
|
||||
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
|
||||
|
||||
func Crypto.base64_decode[s: String] : String
|
||||
func crypto.base64_decode[s: String] : String
|
||||
let chars: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
let s_len: I64 = strlen(s)
|
||||
let out: String = malloc(s_len)
|
||||
let s_len: I64 = c.strlen(s)
|
||||
let out: String = c.malloc(s_len)
|
||||
let i: 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
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
if s3 != 64
|
||||
String.set(out, j, Bit.rshift(triple, 8) && 255)
|
||||
str.set(out, j, bit.rshift(triple, 8) && 255)
|
||||
j = j + 1
|
||||
if s4 != 64
|
||||
String.set(out, j, triple && 255)
|
||||
str.set(out, j, triple && 255)
|
||||
j = j + 1
|
||||
|
||||
String.set(out, j, 0)
|
||||
str.set(out, j, 0)
|
||||
return out
|
||||
Reference in New Issue
Block a user