// Port of cmd/w6a/main.c. // // w6a_ww -o file.o file.s package main; import os; import strings; fn cstreq(a: *u8, lit: str) bool = { let n: u64 = lit.len: u64; let i: u64 = 0u64; for (i < n) { let li: i32 = i: i32; if (a[i] != lit[li]) { return false; }; i += 1u64; }; if (a[i] != 0u8) { return false; }; return true; }; fn cstrlen(p: *u8) u64 = { let n: u64 = 0u64; for (p[n] != 0u8) { n += 1u64; }; return n; }; // Bridges argv-style callers to lib/os entrypoints (str post-task-#23). fn pathstr(p: *u8) str = { let r: str; r.ptr = p; r.len = cstrlen(p): i32; return r; }; fn slurp(path: *u8) (*u8, u64) = { let fd: i32 = os.open(pathstr(path), os.flag.RDONLY, 0i32); if (fd < 0) { return nil, 0u64; }; let szr: (i64 | os.oserror) = os.filesize(fd); let n: i64 = 0i64; match (szr) { case let v: i64 => n = v; case let e: os.oserror => { os.close(fd); return nil, 0u64; }; }; let nz: u64 = n: u64; let buf: []u8 = alloc([], nz + 1u64)!; buf.len = (nz + 1u64): i32; let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, nz); os.close(fd); let got: i64 = 0i64; match (rr) { case let v: i64 => got = v; case let e: os.oserror => return nil, 0u64; }; if (got != n) { return nil, 0u64; }; buf[nz] = 0u8; return buf.ptr, nz; }; export fn main(argc: i32, argv: **u8) i32 = { let src: *u8 = nil; let out: *u8 = nil; let i: i32 = 1; for (i < argc) { let a: *u8 = argv[i]; if (cstreq(a, "-o")) { i += 1; if (i >= argc) { let wm1: str = "w6a: -o requires arg\n"; os.write(2, wm1.ptr, wm1.len: u64); return 2; }; out = argv[i]; } else { if (a[0u64] == 45u8) { let wm2: str = "w6a: unknown flag\n"; os.write(2, wm2.ptr, wm2.len: u64); return 2; } else { if (src != nil) { let wm3: str = "w6a: only one input\n"; os.write(2, wm3.ptr, wm3.len: u64); return 2; }; src = a; }; }; i += 1; }; if (src == nil) { let wm4: str = "usage: w6a_ww -o file.o file.s\n"; os.write(2, wm4.ptr, wm4.len: u64); return 2; }; if (out == nil) { let wm5: str = "w6a: missing -o\n"; os.write(2, wm5.ptr, wm5.len: u64); return 2; }; let buf: *u8; let blen: u64; buf, blen = slurp(src); if (buf == nil) { let wm6: str = "w6a: cannot read input\n"; os.write(2, wm6.ptr, wm6.len: u64); return 1; }; let s: asm_; let nlen: u64 = cstrlen(src); let view: str; view.ptr = src; view.len = nlen: i32; let fname: str = strings.dup(view); init(&s, fname, buf, blen); if (parse(&s) != 0) { return 1; }; if (encode(&s) != 0) { return 1; }; let fd: i32 = os.open(pathstr(out), os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC, 420i32); // 0o644 if (fd < 0) { let wm7: str = "w6a: cannot open output\n"; os.write(2, wm7.ptr, wm7.len: u64); return 1; }; let rc: i32 = emitelf(&s, fd); os.close(fd); return rc; };