// selfhost/cmd/w6a/main.ww — port of cmd/w6a/main.c. // // w6a = amd64 assembler. Read .s, parse, encode, emit ELF .o. // // w6a_ww -o file.o file.s package main; import os; import rt; import mem; import types; import lex; import parse; import asm; import obj; 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; }; // pathstr — view a NUL-terminated *u8 as a str. Bridges argv/arena // 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; }; // Slurp the whole file into a fresh buffer. 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) { os.write(2, "w6a: -o requires arg\n".ptr, 20u64); return 2; }; out = argv[i]; } else { if (a[0u64] == 45u8) { os.write(2, "w6a: unknown flag\n".ptr, 17u64); return 2; } else { if (src != nil) { os.write(2, "w6a: only one input\n".ptr, 19u64); return 2; }; src = a; }; }; i += 1; }; if (src == nil) { os.write(2, "usage: w6a_ww -o file.o file.s\n".ptr, 30u64); return 2; }; if (out == nil) { os.write(2, "w6a: missing -o\n".ptr, 15u64); return 2; }; let buf: *u8; let blen: u64; buf, blen = slurp(src); if (buf == nil) { os.write(2, "w6a: cannot read input\n".ptr, 22u64); return 1; }; let ar: *arena = newarena(); let s: asm_; let nlen: u64 = cstrlen(src); let fname: str = astrndup(ar, src, nlen); init(&s, ar, fname, buf, blen); if (parse(&s) != 0) { return 1; }; if (encode(&s) != 0) { return 1; }; // Open output for write. let fd: i32 = os.open(pathstr(out), os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC, 420i32); // 0o644 if (fd < 0) { os.write(2, "w6a: cannot open output\n".ptr, 23u64); return 1; }; let rc: i32 = emitelf(&s, fd); os.close(fd); return rc; };