From bb7bbcc03386089dce1353e98c071c15c45aa82f Mon Sep 17 00:00:00 2001
From: Kyle Gunger <kgunger12@gmail.com>
Date: Sat, 30 Mar 2024 04:15:10 -0400
Subject: copy file example

---
 tnslc/c_wrap_linux.tnsl         | 228 --------------------------------
 tnslc/c_wrap_windows.tnsl       | 284 ----------------------------------------
 tnslc/compile/generator.tnsl    |  19 +--
 tnslc/tnslc.tnsl                |   8 --
 tnslc/utils/c_wrap_linux.tnsl   | 228 ++++++++++++++++++++++++++++++++
 tnslc/utils/c_wrap_windows.tnsl | 284 ++++++++++++++++++++++++++++++++++++++++
 tnslc/utils/file.tnsl           |  17 ++-
 tnslc/utils/utils.tnsl          |   2 +
 8 files changed, 539 insertions(+), 531 deletions(-)
 delete mode 100644 tnslc/c_wrap_linux.tnsl
 delete mode 100644 tnslc/c_wrap_windows.tnsl
 create mode 100644 tnslc/utils/c_wrap_linux.tnsl
 create mode 100644 tnslc/utils/c_wrap_windows.tnsl

diff --git a/tnslc/c_wrap_linux.tnsl b/tnslc/c_wrap_linux.tnsl
deleted file mode 100644
index 814ec1c..0000000
--- a/tnslc/c_wrap_linux.tnsl
+++ /dev/null
@@ -1,228 +0,0 @@
-# Must be included at the top of the file
-asm "extern malloc, realloc, free, printf, open, close, read, write"
-
-{}uint8 _alert = "Alert!\n\0"
-{}uint8 _dec = "%d\n\0"
-{}uint8 _ptr = "%p\n\0"
-
-~void NULL = 0
-
-/; _alloc (uint size) [~void]
-    ~void out
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 16"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 128"
-    
-    # Mov size into proper register, and set all extras to zero
-    asm "mov rdi, r10"
-    asm "mov rsi, 0"
-    asm "xor rax, rax"
-    
-    # Do call
-    asm "call malloc wrt ..plt"
-
-    # Set out to the returned value
-    # (The compiler assignes spaces sequentially, and we have a uint in r10)
-    asm "mov r11, rax"
-
-    return out
-;/
-
-/; _realloc (~void ptr, uint new_size) [~void]
-    ~void out
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 16"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 128"
-    
-    # Mov ptr and new size into proper registers, and set all extras to zero
-    asm "mov rdi, r10"
-    asm "mov rsi, r11"
-    asm "xor rax, rax"
-
-    # Do call
-    asm "call realloc wrt ..plt"
-    
-    # Set out to the returned value
-    # (The compiler assignes spaces sequentially. We have a ptr in r10, and a uint in r11)
-    asm "mov r12, rax"
-
-    return out
-;/
-
-/; _delete (~void ptr)
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 16"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 128"
-    
-    # setup call by clearing most values
-    asm "mov rdi, r10"
-    asm "mov rsi, 0"
-    asm "xor rax, rax"
-
-    # do call
-    asm "call free wrt ..plt"
-
-    # there's no more to do 'cause free returns nothing 
-;/
-
-/; _printf (~void str)
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 16"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 128"
-    
-    # setup call by clearing most values
-    asm "mov rdi, r10"
-    asm "xor rsi, rsi"
-    asm "xor rax, rax"
-    
-    # do call
-    asm "call printf wrt ..plt"
-    
-    # there's no more to do 'cause printf returns nothing 
-;/
-
-/; _print_num (~void str, int num)
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 16"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 128"
-    
-    # setup call by clearing most values
-    asm "mov rdi, r10"
-    asm "mov rsi, r11"
-    asm "xor rax, rax"
-    
-    # do call
-    asm "call printf wrt ..plt"
-    
-    # there's no more to do 'cause printf returns nothing 
-;/
-
-
-# Create file for writing (overwrite)
-/; _create_file (~void name) [~void]
-    ~void out
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 16"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 128"
-
-    # Do call
-    asm "mov rdi, r10"
-    asm "mov rsi, 0q1102"
-    asm "mov rdx, 0q700"
-    asm "call open wrt ..plt"
-
-    # Set out to the returned value
-    # (The compiler assignes spaces sequentially. We have a ptr in r8)
-    asm "mov r11, rax"
-
-    return out
-;/
-
-# Open file for reading or writing (no overwrite)
-/; _open_file (~void name) [~void]
-    ~void out
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 16"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 128"
-
-    # Do syscall
-    asm "mov rdi, r10"
-    asm "mov rsi, 2"
-    asm "mov rdx, 0q700"
-    asm "call open wrt ..plt"
-
-    # Set out to the returned value
-    # (The compiler assignes spaces sequentially. We have a ptr in r8, and a uint in r9)
-    asm "mov r11, rax"
-
-    return out
-;/
-
-/; _close_file (~void handle)
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 16"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 128"
-
-    # Do syscall
-    asm "mov rdi, r10"
-    asm "call close wrt ..plt"
-;/
-
-/; _read_byte (~void handle, ~uint8 byte) [int]
-    int out
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 16"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 128"
-
-    # Do syscall
-    asm "mov rdi, r10"  # handle
-    asm "mov rsi, r11"  # buffer
-    asm "mov rdx, 1"   # one byte
-    asm "call read wrt ..plt"
-
-    # return number of bytes read
-    asm "mov r12, rax"
-
-    return out
-;/
-
-/; _write_byte (~void handle, ~uint8 byte) [int]
-    int out
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 16"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 128"
-
-    # Do syscall
-    asm "mov rdi, r10"  # handle
-    asm "mov rsi, r11"  # buffer
-    asm "mov rdx, 1"   # one byte
-    asm "call write wrt ..plt"
-
-    asm "mov r12, rax"
-
-    return out
-;/
-
-/; print_alert
-    _printf(~_alert{0})
-;/
diff --git a/tnslc/c_wrap_windows.tnsl b/tnslc/c_wrap_windows.tnsl
deleted file mode 100644
index 577ca25..0000000
--- a/tnslc/c_wrap_windows.tnsl
+++ /dev/null
@@ -1,284 +0,0 @@
-# Must be included at the top of the file
-asm "extern malloc"
-asm "extern realloc"
-asm "extern free"
-
-asm "extern printf"
-
-asm "extern CreateFileA"
-asm "extern ReadFile"
-asm "extern WriteFile"
-asm "extern CloseHandle"
-
-{}uint8 _alert = "Alert!\n\0"
-{}uint8 _dec = "%d\n\0"
-{}uint8 _ptr = "%p\n\0"
-
-/; _alloc (uint size) [~void]
-    ~void out
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 32"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 32"
-    
-    # Mov size into proper register, and set all extras to zero
-    asm "mov rcx, r8"
-    asm "mov rdx, 0"
-    asm "mov r8, 0"
-    asm "mov r9, 0"
-    
-    asm "call malloc"
-    # Set out to the returned value
-    # (The compiler assignes spaces sequentially, and we have a uint in r8)
-    asm "mov r9, rax"
-    return out
-;/
-
-/; _realloc (~void ptr, uint new_size) [~void]
-    ~void out
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 32"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 32"
-    
-    # Mov ptr and new size into proper registers, and set all extras to zero
-    asm "mov rcx, r8"
-    asm "mov rdx, r9"
-    asm "mov r8, 0"
-    asm "mov r9, 0"
-    # Do call
-    asm "call realloc"
-    # Set out to the returned value
-    # (The compiler assignes spaces sequentially. We have a ptr in r8, and a uint in r9)
-    asm "mov r10, rax"
-    return out
-;/
-
-/; _delete (~void ptr)
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 32"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "sub rsp, 32"
-    
-    # setup call by clearing most values
-    asm "mov rcx, r8"
-    asm "mov rdx, 0"
-    asm "mov r8, 0"
-    asm "mov r9, 0"
-    # do call
-    asm "call free"
-    # there's no more to do 'cause free returns nothing 
-;/
-
-/; _printf (~void str)
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 32"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "push qword 0"
-    asm "push qword 0"
-    asm "push qword 0"
-    asm "push qword 0"
-    
-    # setup call by clearing most values
-    asm "mov rcx, r8"
-    asm "mov rdx, 0"
-    asm "mov r8, 0"
-    asm "mov r9, 0"
-    # do call
-    asm "call printf"
-    # there's no more to do 'cause printf returns nothing 
-;/
-
-/; _print_num (~void str, int num)
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 32"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-    asm "push qword 0"
-    asm "push qword 0"
-    asm "push qword 0"
-    asm "push qword 0"
-    
-    # setup call by clearing most values
-    asm "mov rcx, r8"
-    asm "mov rdx, r9"
-    asm "mov rdi, 0"
-    asm "mov rsi, 0"
-    asm "mov r8, 0"
-    asm "mov r9, 0"
-    # do call
-    asm "call printf"
-    # there's no more to do 'cause printf returns nothing 
-;/
-
-
-# Create file for writing (overwrite)
-/; _create_file (~void name) [~void]
-    ~void out
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 32"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-
-    asm "mov rcx, r8" # lpFileName
-    asm "mov rdx, 1"  # dwDesiredAccess
-    asm "shl rdx, 28" # (GENERIC_READ 1 << 31 | GENERIC_WRITE 1 << 30)
-    asm "mov r8, 3"   # dwShareMode
-    asm "mov r9, 0"   # lpSecurityAttributes
-
-    asm "push qword 0"   # hTemplateFile
-    asm "push qword 128" # dwFlagsAndAttributes (NORMAL_FILE = 128)
-    asm "push qword 2"   # dwCreationDisposition (CREATE_ALWAYS = 2)
-
-    # Shadow space
-    asm "push r9"
-    asm "push r8"
-    asm "push rdx"
-    asm "push rcx"
-
-    # Do call
-    asm "call CreateFileA"
-
-    # Set out to the returned value
-    # (The compiler assignes spaces sequentially. We have a ptr in r8)
-    asm "mov r9, rax"
-
-    return out
-;/
-
-# Open file for reading or writing (no overwrite)
-/; _open_file (~void name) [~void]
-    ~void out
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 32"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-
-    asm "mov rcx, r8" # lpFileName
-    asm "mov rdx, 1"  # dwDesiredAccess
-    asm "shl rdx, 28" # (GENERIC_READ 1 << 31 | GENERIC_WRITE 1 << 30)
-    asm "mov r8, 3"   # dwShareMode
-    asm "mov r9, 0"   # lpSecurityAttributes
-
-    asm "push qword 0"   # hTemplateFile
-    asm "push qword 128" # dwFlagsAndAttributes (NORMAL_FILE = 128)
-    asm "push qword 3"   # dwCreationDisposition (OPEN_EXISTING = 3)
-
-    # Shadow space
-    asm "push r9"
-    asm "push r8"
-    asm "push rdx"
-    asm "push rcx"
-
-    # Do call
-    asm "call CreateFileA"
-
-    # Set out to the returned value
-    # (The compiler assignes spaces sequentially. We have a ptr in r8, and a uint in r9)
-    asm "mov r9, rax"
-
-    return out
-;/
-
-/; _close_file (~void handle)
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 32"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-
-    asm "mov rcx, r8" # handle
-    asm "mov rdx, 0"
-    asm "mov r8, 0"
-    asm "mov r9, 0"
-
-    # Shadow space
-    asm "push r9"
-    asm "push r8"
-    asm "push rdx"
-    asm "push rcx"
-
-    asm "call CloseHandle"
-
-    asm "add rsp, 32"
-;/
-
-/; _read_byte (~void handle, ~uint8 byte) [int]
-    ~int out
-    int i = 0
-    out = ~i
-
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 32"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-
-    asm "mov rcx, r8" # handle
-    asm "mov rdx, r9" # buffer
-    asm "mov r8, 1"   # one byte
-    asm "mov r9, r10" # read bytes buffer
-    asm "push qword 0"
-
-    # Shadow space
-    asm "push r9"
-    asm "push r8"
-    asm "push rdx"
-    asm "push rcx"
-
-    asm "call ReadFile"
-
-    return out`
-;/
-
-/; _write_byte (~void handle, ~uint8 byte) [int]
-    ~int out
-    int i = 0
-    out = ~i
-
-    asm "mov rax, rsp"
-    asm "xor rdx, rdx"
-    asm "mov rcx, 32"
-    asm "div rcx"
-    asm "sub rsp, rdx"
-
-    asm "mov rcx, r8" # handle
-    asm "mov rdx, r9" # buffer
-    asm "mov r8, 1"   # one byte
-    asm "mov r9, 0"
-    asm "push qword 0"
-
-    # Shadow space
-    asm "push r9"
-    asm "push r8"
-    asm "push rdx"
-    asm "push rcx"
-
-    asm "call WriteFile"
-
-    return out`
-;/
-
-/; print_alert
-    _printf(~_alert{0})
-;/
diff --git a/tnslc/compile/generator.tnsl b/tnslc/compile/generator.tnsl
index 5d71a05..28a834d 100644
--- a/tnslc/compile/generator.tnsl
+++ b/tnslc/compile/generator.tnsl
@@ -1,13 +1,16 @@
 /; generate (utils.File fin, fout)
-	~uint8 fa = fin.path.to_cstr('/')
-	~uint8 fb = fout.path.to_cstr('/')
 
-	_printf(fa)
-	_printf(newline)
-	_printf(fb)
-	_printf(newline)
+	fin.open()
+	fout.create()
+
+	uint8 buf = fin.read()
+	/; loop (fin.at_end == false && fout.at_end == false)
+		fout.write(buf)
+		buf = fin.read()
+	;/
+
+	fin.close()
+	fout.close()
 
-	_delete(fa)
-	_delete(fb)
 ;/
 
diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl
index 0123430..84fbdb5 100644
--- a/tnslc/tnslc.tnsl
+++ b/tnslc/tnslc.tnsl
@@ -1,5 +1,3 @@
-:import "c_wrap_linux.tnsl"
-
 :import "utils/utils.tnsl"
 :import "compile/compile.tnsl"
 
@@ -17,8 +15,6 @@ usage:
 
 ~uint8 char_str = "%c\0"
 ~uint8 newline = "\n\0"
-~uint8 scratch = "asd,efg\0"
-~uint8 test = "asd\0"
 
 /; main (int argc, ~~uint8 argv) [int]
 	asm "mov r10, rdi"
@@ -29,10 +25,6 @@ usage:
 		return 1
 	;/
 	
-	/; if (compile._in_csv(scratch, test))
-		_printf(test)
-		_printf(newline)
-	;/
 
 	utils.File fin, fout
 	fin.init(argv{1})
diff --git a/tnslc/utils/c_wrap_linux.tnsl b/tnslc/utils/c_wrap_linux.tnsl
new file mode 100644
index 0000000..814ec1c
--- /dev/null
+++ b/tnslc/utils/c_wrap_linux.tnsl
@@ -0,0 +1,228 @@
+# Must be included at the top of the file
+asm "extern malloc, realloc, free, printf, open, close, read, write"
+
+{}uint8 _alert = "Alert!\n\0"
+{}uint8 _dec = "%d\n\0"
+{}uint8 _ptr = "%p\n\0"
+
+~void NULL = 0
+
+/; _alloc (uint size) [~void]
+    ~void out
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 16"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 128"
+    
+    # Mov size into proper register, and set all extras to zero
+    asm "mov rdi, r10"
+    asm "mov rsi, 0"
+    asm "xor rax, rax"
+    
+    # Do call
+    asm "call malloc wrt ..plt"
+
+    # Set out to the returned value
+    # (The compiler assignes spaces sequentially, and we have a uint in r10)
+    asm "mov r11, rax"
+
+    return out
+;/
+
+/; _realloc (~void ptr, uint new_size) [~void]
+    ~void out
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 16"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 128"
+    
+    # Mov ptr and new size into proper registers, and set all extras to zero
+    asm "mov rdi, r10"
+    asm "mov rsi, r11"
+    asm "xor rax, rax"
+
+    # Do call
+    asm "call realloc wrt ..plt"
+    
+    # Set out to the returned value
+    # (The compiler assignes spaces sequentially. We have a ptr in r10, and a uint in r11)
+    asm "mov r12, rax"
+
+    return out
+;/
+
+/; _delete (~void ptr)
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 16"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 128"
+    
+    # setup call by clearing most values
+    asm "mov rdi, r10"
+    asm "mov rsi, 0"
+    asm "xor rax, rax"
+
+    # do call
+    asm "call free wrt ..plt"
+
+    # there's no more to do 'cause free returns nothing 
+;/
+
+/; _printf (~void str)
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 16"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 128"
+    
+    # setup call by clearing most values
+    asm "mov rdi, r10"
+    asm "xor rsi, rsi"
+    asm "xor rax, rax"
+    
+    # do call
+    asm "call printf wrt ..plt"
+    
+    # there's no more to do 'cause printf returns nothing 
+;/
+
+/; _print_num (~void str, int num)
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 16"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 128"
+    
+    # setup call by clearing most values
+    asm "mov rdi, r10"
+    asm "mov rsi, r11"
+    asm "xor rax, rax"
+    
+    # do call
+    asm "call printf wrt ..plt"
+    
+    # there's no more to do 'cause printf returns nothing 
+;/
+
+
+# Create file for writing (overwrite)
+/; _create_file (~void name) [~void]
+    ~void out
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 16"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 128"
+
+    # Do call
+    asm "mov rdi, r10"
+    asm "mov rsi, 0q1102"
+    asm "mov rdx, 0q700"
+    asm "call open wrt ..plt"
+
+    # Set out to the returned value
+    # (The compiler assignes spaces sequentially. We have a ptr in r8)
+    asm "mov r11, rax"
+
+    return out
+;/
+
+# Open file for reading or writing (no overwrite)
+/; _open_file (~void name) [~void]
+    ~void out
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 16"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 128"
+
+    # Do syscall
+    asm "mov rdi, r10"
+    asm "mov rsi, 2"
+    asm "mov rdx, 0q700"
+    asm "call open wrt ..plt"
+
+    # Set out to the returned value
+    # (The compiler assignes spaces sequentially. We have a ptr in r8, and a uint in r9)
+    asm "mov r11, rax"
+
+    return out
+;/
+
+/; _close_file (~void handle)
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 16"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 128"
+
+    # Do syscall
+    asm "mov rdi, r10"
+    asm "call close wrt ..plt"
+;/
+
+/; _read_byte (~void handle, ~uint8 byte) [int]
+    int out
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 16"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 128"
+
+    # Do syscall
+    asm "mov rdi, r10"  # handle
+    asm "mov rsi, r11"  # buffer
+    asm "mov rdx, 1"   # one byte
+    asm "call read wrt ..plt"
+
+    # return number of bytes read
+    asm "mov r12, rax"
+
+    return out
+;/
+
+/; _write_byte (~void handle, ~uint8 byte) [int]
+    int out
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 16"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 128"
+
+    # Do syscall
+    asm "mov rdi, r10"  # handle
+    asm "mov rsi, r11"  # buffer
+    asm "mov rdx, 1"   # one byte
+    asm "call write wrt ..plt"
+
+    asm "mov r12, rax"
+
+    return out
+;/
+
+/; print_alert
+    _printf(~_alert{0})
+;/
diff --git a/tnslc/utils/c_wrap_windows.tnsl b/tnslc/utils/c_wrap_windows.tnsl
new file mode 100644
index 0000000..577ca25
--- /dev/null
+++ b/tnslc/utils/c_wrap_windows.tnsl
@@ -0,0 +1,284 @@
+# Must be included at the top of the file
+asm "extern malloc"
+asm "extern realloc"
+asm "extern free"
+
+asm "extern printf"
+
+asm "extern CreateFileA"
+asm "extern ReadFile"
+asm "extern WriteFile"
+asm "extern CloseHandle"
+
+{}uint8 _alert = "Alert!\n\0"
+{}uint8 _dec = "%d\n\0"
+{}uint8 _ptr = "%p\n\0"
+
+/; _alloc (uint size) [~void]
+    ~void out
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 32"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 32"
+    
+    # Mov size into proper register, and set all extras to zero
+    asm "mov rcx, r8"
+    asm "mov rdx, 0"
+    asm "mov r8, 0"
+    asm "mov r9, 0"
+    
+    asm "call malloc"
+    # Set out to the returned value
+    # (The compiler assignes spaces sequentially, and we have a uint in r8)
+    asm "mov r9, rax"
+    return out
+;/
+
+/; _realloc (~void ptr, uint new_size) [~void]
+    ~void out
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 32"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 32"
+    
+    # Mov ptr and new size into proper registers, and set all extras to zero
+    asm "mov rcx, r8"
+    asm "mov rdx, r9"
+    asm "mov r8, 0"
+    asm "mov r9, 0"
+    # Do call
+    asm "call realloc"
+    # Set out to the returned value
+    # (The compiler assignes spaces sequentially. We have a ptr in r8, and a uint in r9)
+    asm "mov r10, rax"
+    return out
+;/
+
+/; _delete (~void ptr)
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 32"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "sub rsp, 32"
+    
+    # setup call by clearing most values
+    asm "mov rcx, r8"
+    asm "mov rdx, 0"
+    asm "mov r8, 0"
+    asm "mov r9, 0"
+    # do call
+    asm "call free"
+    # there's no more to do 'cause free returns nothing 
+;/
+
+/; _printf (~void str)
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 32"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "push qword 0"
+    asm "push qword 0"
+    asm "push qword 0"
+    asm "push qword 0"
+    
+    # setup call by clearing most values
+    asm "mov rcx, r8"
+    asm "mov rdx, 0"
+    asm "mov r8, 0"
+    asm "mov r9, 0"
+    # do call
+    asm "call printf"
+    # there's no more to do 'cause printf returns nothing 
+;/
+
+/; _print_num (~void str, int num)
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 32"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+    asm "push qword 0"
+    asm "push qword 0"
+    asm "push qword 0"
+    asm "push qword 0"
+    
+    # setup call by clearing most values
+    asm "mov rcx, r8"
+    asm "mov rdx, r9"
+    asm "mov rdi, 0"
+    asm "mov rsi, 0"
+    asm "mov r8, 0"
+    asm "mov r9, 0"
+    # do call
+    asm "call printf"
+    # there's no more to do 'cause printf returns nothing 
+;/
+
+
+# Create file for writing (overwrite)
+/; _create_file (~void name) [~void]
+    ~void out
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 32"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+
+    asm "mov rcx, r8" # lpFileName
+    asm "mov rdx, 1"  # dwDesiredAccess
+    asm "shl rdx, 28" # (GENERIC_READ 1 << 31 | GENERIC_WRITE 1 << 30)
+    asm "mov r8, 3"   # dwShareMode
+    asm "mov r9, 0"   # lpSecurityAttributes
+
+    asm "push qword 0"   # hTemplateFile
+    asm "push qword 128" # dwFlagsAndAttributes (NORMAL_FILE = 128)
+    asm "push qword 2"   # dwCreationDisposition (CREATE_ALWAYS = 2)
+
+    # Shadow space
+    asm "push r9"
+    asm "push r8"
+    asm "push rdx"
+    asm "push rcx"
+
+    # Do call
+    asm "call CreateFileA"
+
+    # Set out to the returned value
+    # (The compiler assignes spaces sequentially. We have a ptr in r8)
+    asm "mov r9, rax"
+
+    return out
+;/
+
+# Open file for reading or writing (no overwrite)
+/; _open_file (~void name) [~void]
+    ~void out
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 32"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+
+    asm "mov rcx, r8" # lpFileName
+    asm "mov rdx, 1"  # dwDesiredAccess
+    asm "shl rdx, 28" # (GENERIC_READ 1 << 31 | GENERIC_WRITE 1 << 30)
+    asm "mov r8, 3"   # dwShareMode
+    asm "mov r9, 0"   # lpSecurityAttributes
+
+    asm "push qword 0"   # hTemplateFile
+    asm "push qword 128" # dwFlagsAndAttributes (NORMAL_FILE = 128)
+    asm "push qword 3"   # dwCreationDisposition (OPEN_EXISTING = 3)
+
+    # Shadow space
+    asm "push r9"
+    asm "push r8"
+    asm "push rdx"
+    asm "push rcx"
+
+    # Do call
+    asm "call CreateFileA"
+
+    # Set out to the returned value
+    # (The compiler assignes spaces sequentially. We have a ptr in r8, and a uint in r9)
+    asm "mov r9, rax"
+
+    return out
+;/
+
+/; _close_file (~void handle)
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 32"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+
+    asm "mov rcx, r8" # handle
+    asm "mov rdx, 0"
+    asm "mov r8, 0"
+    asm "mov r9, 0"
+
+    # Shadow space
+    asm "push r9"
+    asm "push r8"
+    asm "push rdx"
+    asm "push rcx"
+
+    asm "call CloseHandle"
+
+    asm "add rsp, 32"
+;/
+
+/; _read_byte (~void handle, ~uint8 byte) [int]
+    ~int out
+    int i = 0
+    out = ~i
+
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 32"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+
+    asm "mov rcx, r8" # handle
+    asm "mov rdx, r9" # buffer
+    asm "mov r8, 1"   # one byte
+    asm "mov r9, r10" # read bytes buffer
+    asm "push qword 0"
+
+    # Shadow space
+    asm "push r9"
+    asm "push r8"
+    asm "push rdx"
+    asm "push rcx"
+
+    asm "call ReadFile"
+
+    return out`
+;/
+
+/; _write_byte (~void handle, ~uint8 byte) [int]
+    ~int out
+    int i = 0
+    out = ~i
+
+    asm "mov rax, rsp"
+    asm "xor rdx, rdx"
+    asm "mov rcx, 32"
+    asm "div rcx"
+    asm "sub rsp, rdx"
+
+    asm "mov rcx, r8" # handle
+    asm "mov rdx, r9" # buffer
+    asm "mov r8, 1"   # one byte
+    asm "mov r9, 0"
+    asm "push qword 0"
+
+    # Shadow space
+    asm "push r9"
+    asm "push r8"
+    asm "push rdx"
+    asm "push rcx"
+
+    asm "call WriteFile"
+
+    return out`
+;/
+
+/; print_alert
+    _printf(~_alert{0})
+;/
diff --git a/tnslc/utils/file.tnsl b/tnslc/utils/file.tnsl
index a33e30c..978f31b 100644
--- a/tnslc/utils/file.tnsl
+++ b/tnslc/utils/file.tnsl
@@ -5,7 +5,6 @@ struct File {
 }
 
 ~uint8 PT_HANDLE = "Handle: %p\n\0"
-uint INVALID_HANDLE = 0xffffffff
 ~uint8 PARENT_DIR = ".."
 ~uint8 CURRENT_DIR = "."
 
@@ -43,7 +42,7 @@ uint INVALID_HANDLE = 0xffffffff
 
 	/; end
 		self.path.end()
-		/; if (self.handle < INVALID_HANDLE && self.handle != NULL)
+		/; if (self.handle + 1 !== 0)
 			_close_file(self.handle)
 			self.handle = NULL
 		;/
@@ -52,17 +51,23 @@ uint INVALID_HANDLE = 0xffffffff
 	/; open
 		~uint8 p = self.path.to_cstr('/')
 		self.handle = _open_file(p)
+		/; if (self.handle + 1 == 0)
+			self.at_end = true
+		;/
 		_delete(p)
 	;/
 
 	/; create
 		~uint8 p = self.path.to_cstr('/')
 		self.handle = _create_file(p)
+		/; if (self.handle + 1 == 0)
+			self.at_end = true
+		;/
 		_delete(p)
 	;/
 
 	/; close
-		/; if (self.handle !== INVALID_HANDLE && self.handle !== NULL)
+		/; if (self.handle + 1 !== 0)
 			_close_file(self.handle)
 			self.handle = NULL
 			self.at_end = false
@@ -86,4 +91,10 @@ uint INVALID_HANDLE = 0xffffffff
 		;/
 	;/
 
+	/; write_cstr (~uint8 str)
+		/; loop (self.at_end == false && str` !== 0) [str++]
+			self.write(str`)
+		;/
+	;/
+
 ;/
diff --git a/tnslc/utils/utils.tnsl b/tnslc/utils/utils.tnsl
index fece1da..eab2f8c 100644
--- a/tnslc/utils/utils.tnsl
+++ b/tnslc/utils/utils.tnsl
@@ -1,3 +1,5 @@
+:import "c_wrap_linux.tnsl"
+
 /; module utils
 
 	:import "vector.tnsl"
-- 
cgit v1.2.3