// 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 use os; use mem; use types; use lex; use parse; use asm; use 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; }; // Slurp the whole file into a fresh buffer. fn slurp(path: *u8) (*u8, u64) = { let fd: i32 = os.open(path, os.O_RDONLY, 0i32); if (fd < 0) { return nil, 0u64; }; let n: i64 = os.filesize(fd); if (n < 0i64) { os.close(fd); return nil, 0u64; }; let nz: u64 = n: u64; let buf: *u8 = os.alloc(nz + 1u64): *u8; let got: i64 = os.readfull(fd, buf, nz); os.close(fd); if (got != n) { return nil, 0u64; }; buf[nz] = 0u8; return buf, 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 asm: asm_; let nlen: u64 = cstrlen(src); let fname: str = astrndup(ar, src, nlen); a_init(&asm, ar, fname, buf, blen); if (a_parse(&asm) != 0) { return 1; }; if (a_encode(&asm) != 0) { return 1; }; // Open output for write. let fd: i32 = os.open(out, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 420i32); // 0o644 if (fd < 0) { os.write(2, "w6a: cannot open output\n".ptr, 23u64); return 1; }; let rc: i32 = a_emit_elf(&asm, fd); os.close(fd); return rc; };