#extern(vm) fn vm_fopen(path: *any, mode: *any): *any; #extern(vm) fn vm_fclose(f: *any): i32; #extern(vm) fn vm_fread(buf: *any, sz: usize, n: usize, f: *any): usize; #extern(vm) fn vm_fwrite(buf: *any, sz: usize, n: usize, f: *any): usize; #extern(vm) fn vm_fsize(f: *any): usize; #extern(vm) fn vm_stdin(): *any; #extern(vm) fn vm_stdout(): *any; #extern(vm) fn vm_stderr(): *any; #extern(vm) fn vm_putchar(c: i32): i32; #extern(vm) fn vm_getchar(): i32; handle: *any, type File = @self; fn stdin(): File { ret File { .handle = vm_stdin() }; } fn stdout(): File { ret File { .handle = vm_stdout() }; } fn stderr(): File { ret File { .handle = vm_stderr() }; } fn open(path: *u8, mode: *u8): File { ret File { .handle = vm_fopen(path as *any, mode as *any) }; } fn valid(f: *File): bool { ret f.handle != null; } fn write(f: *File, data: *u8, n: u64): u64 { if f.handle == null { ret 0; } ret vm_fwrite(data as *any, 1, n, f.handle); } fn write_byte(f: *File, b: u8): u64 { var tmp: u8 = b; ret write(f, &tmp, 1); } fn read(f: *File, buf: *u8, n: usize): usize { if f.handle == null { ret 0; } ret vm_fread(buf as *any, 1, n, f.handle); } fn size(f: *File): usize { if f.handle == null { ret 0; } ret vm_fsize(f.handle); } fn close(f: *File): i32 { if f.handle == null { ret -1; } var r = vm_fclose(f.handle); f.handle = null; ret r; } fn putchar(c: u8) { vm_putchar(c as i32); } fn getchar(): i32 { ret vm_getchar(); } fn main(): void { var out = stdout(); @assert(out.handle != null, "stdout"); var msg = "file: ok\n"; var n = write(&out, msg.ptr, msg.len); @assert(n == msg.len, "write"); putchar(46 as u8); putchar(10 as u8); }