# Standard C Types # cint, csize_t are in system/ctypes (implicitly available?) # If not, we fix it by aliasing system ones or just using int/uint. # Let's try relying on system. type cptr* = pointer # Standard POSIX-ish Wrappers (from libc_shim) proc write*(fd: cint, buf: cptr, count: csize_t): csize_t {.importc, cdecl.} proc read*(fd: cint, buf: cptr, count: csize_t): csize_t {.importc, cdecl.} proc open*(pathname: cstring, flags: cint): cint {.importc, cdecl.} proc close*(fd: cint): cint {.importc, cdecl.} proc exit*(status: cint) {.importc, cdecl.} proc list_files*(buf: pointer, len: uint64): int64 {.importc, cdecl.} # Our Custom Syscalls (Defined in libc_shim) proc nexus_syscall*(cmd: cint, arg: uint64): cint {.importc, cdecl.} proc nexus_yield*() {.importc, cdecl.} proc nexus_net_tx*(buf: cptr, len: uint64) {.importc, cdecl.} proc nexus_net_rx*(buf: cptr, max_len: uint64): uint64 {.importc, cdecl.} proc nexus_blk_read*(sector: uint64, buf: cptr, len: uint64) {.importc, cdecl.} proc nexus_blk_write*(sector: uint64, buf: cptr, len: uint64) {.importc, cdecl.} type FileArgs* = object name*: uint64 data*: uint64 len*: uint64 const CMD_FS_WRITE = 0x203 proc nexus_file_write*(name: string, data: string) = var args: FileArgs args.name = cast[uint64](cstring(name)) args.data = cast[uint64](cstring(data)) args.len = uint64(data.len) discard nexus_syscall(cint(CMD_FS_WRITE), cast[uint64](addr args)) # Helper: Print to Stdout (FD 1) proc print*(s: string) = if s.len > 0: discard write(1, unsafeAddr s[0], csize_t(s.len)) var nl = "\n" discard write(1, unsafeAddr nl[0], 1) proc print_raw*(s: string) = if s.len > 0: discard write(1, unsafeAddr s[0], csize_t(s.len)) proc print_int*(n: int) = var s = "" var v = n if v == 0: s = "0" else: while v > 0: s.add(char((v mod 10) + 48)) v = v div 10 # Reverse var r = "" var i = s.len - 1 while i >= 0: r.add(s[i]) i -= 1 print_raw(r) var read_buffer: array[512, char] var read_pos = 0 var read_len = 0 # Need to pull poll_network from somewhere? # Or just define a dummy or export proper one? # poll_network logic causes circular dep if it's in main. # Let's make my_readline simpler for now, or move poll_network here? # poll_network uses `nexus_net_rx`. # Let's move poll_network to std? # It depends on `nipbox` logic (checksums?). # Let's just do blocking read in my_readline for now without network polling for Phase 12 MVP. # Actually `libc_shim` `read(0)` is synchronous (busy wait on ring). # So poll_network inside loop was useful. # We will skip net poll in readline for this refactor to avoid complexity. proc my_readline*(out_str: var string): bool = out_str = "" while true: var c: char let n = read(0, addr c, 1) if n <= 0: return false # EOF or Error if c == '\n' or c == '\r': print_raw("\n") return true elif c == '\b' or c == char(127): # Backspace if out_str.len > 0: # Visual backspace var bs = "\b \b" discard write(1, addr bs[0], 3) out_str.setLen(out_str.len - 1) else: out_str.add(c) discard write(1, addr c, 1) # Echo