diff options
| author | Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> | 2019-12-21 19:54:35 -0500 |
|---|---|---|
| committer | Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> | 2019-12-21 19:54:58 -0500 |
| commit | d58a71909e3d9cf586dc156a5285488343334dd2 (patch) | |
| tree | 860f747221b2276980110776676d33112e1ce613 | |
Initial commit.
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | asm.myr | 97 |
2 files changed, 99 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b980033 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.o +*.use @@ -0,0 +1,97 @@ +use bio +use std + +const readline = {line + var cmt = std.strfind(line, ";") + + match cmt + | `std.Some (pos): line = line[:pos] + | `std.None: + ;; + + var parts = std.strtok(line) + if std.isspace((line[0] : char)) + -> (`std.None, parts) + else + -> (`std.Some(parts[0]), parts[1:]) + ;; +} + +const upcase = {s + var i + var buf = std.mksb() + for i = 0; i < s.len; i++ + std.sbputc(buf, std.toupper((s[i] : char))) + ;; + -> std.sbfin(buf) +} + +const parsehex = {s + if s[0] == ('#' : byte) + -> std.intparsebase((s[1:] : byte[:]), 16) + else + -> `std.None + ;; +} + +const emitinstr = {p + var b + var mark = `std.None + + if p.len < 1 + -> `std.Ok([][:], mark) + ;; + + match upcase(p[0]) + | "CLS": + b = [0x00, 0xe0][:] + | "SYS": + if p.len < 2 + -> `std.Err("SYS missing subroutine address") + ;; + match parsehex(p[1]) + | `std.Some(n): b = [0x20 | (n & 0x0f00), (n & 0xff)][:] + | `std.None: b = [0x2f, 0xff][:] + mark = `std.Some(p[1]) + ;; + | _: + -> `std.Err("unrecognized instruction") + ;; + + -> `std.Ok((b, mark)) +} + +const main = { + var fd = bio.mkfile(std.In, bio.Rd) + var src = bio.byline(fd) + var lc = 0 + + var offset = 0 + var queue = [][:] + var buf = [][:] + var labels = std.mkht() + var res + + for line : src ; + match readline(line) + | (`std.None, i): res = emitinstr(i) + | (`std.Some (label), i): res = emitinstr(i) + std.htput(labels, label, offset) + ;; + + match res + | `std.Err(msg): std.die(std.fmt("{} at {}", msg, lc)) + | `std.Ok((bytes, marker)): buf = std.sljoin(&buf, bytes) + offset += bytes.len + match marker + | `std.Some(label): queue = std.slpush(&queue, label) + | `std.None: + ;; + ;; + + lc++ + ;; + std.put("{}", buf) + + bio.free(fd) +} |