diff options
Diffstat (limited to 'asm.myr')
| -rw-r--r-- | asm.myr | 62 |
1 files changed, 50 insertions, 12 deletions
@@ -36,11 +36,30 @@ const readline = {line ;; } -const parsehex = {s +type literal = union + `Number int + `Register int + `Label byte[:] + `Invalid +;; + +const getnum = {s + -> std.intparsebase((s[1:] : byte[:]), 16) +} + +const parselit = {s if s[0] == ('#' : byte) - -> std.intparsebase((s[1:] : byte[:]), 16) + match getnum(s) + |`std.Some(n): -> `Number(n) + |`std.None: -> `Invalid + ;; + elif s[0] == ('v' : byte) + match getnum(s) + |`std.Some(n): -> `Register(n) + |`std.None: -> `Invalid + ;; else - -> `std.None + -> `Label(s) ;; } @@ -61,19 +80,27 @@ const emitinstr = {p if p.len < 2 -> `std.Err("SYS missing subroutine address") ;; - match parsehex(p[1]) - | `std.Some(n): b = `std.Some([0x00 | (n & 0x0f00), (n & 0xff)]) - | `std.None: b = `std.Some([0x20, 0x00]) - mark = `std.Some(strdup(p[1])) + match parselit(p[1]) + | `Number(n): b = `std.Some([0x00 | (n & 0x0f00), (n & 0xff)]) + | `Label(l): b = `std.Some([0x20, 0x00]) + mark = `std.Some(strdup(l)) + | `Register(_): + -> `std.Err("SYS called with register instruction") + | `Invalid: + -> `std.Err(std.fmt("invalid literal {}", p[1])) ;; | "CALL": if p.len < 2 -> `std.Err("CALL missing subroutine address") ;; - match parsehex(p[1]) - | `std.Some(n): b = `std.Some([0x20 | (n & 0x0f00), (n & 0xff)]) - | `std.None: b = `std.Some([0x20, 0x00]) - mark = `std.Some(strdup(p[1])) + match parselit(p[1]) + | `Number(n): b = `std.Some([0x00 | (n & 0x0f00), (n & 0xff)]) + | `Label(l): b = `std.Some([0x20, 0x00]) + mark = `std.Some(strdup(l)) + | `Register(_): + -> `std.Err("CALL called with register instruction") + | `Invalid: + -> `std.Err(std.fmt("invalid literal {}", p[1])) ;; | _: -> `std.Err("unrecognized instruction") @@ -91,6 +118,17 @@ const die_rewrite = {l, lc std.die(std.fmt(s, l, lc)) } + +/* convert `arr` to a byte[:] slice */ +const itob = {arr + var i + var ret = std.slalloc(arr.len) + for i = 0; i < arr.len; i++; + ret[i] = ((arr[i] & 0xff) : byte) + ;; + -> ret +} + const main = { var fd = bio.mkfile(std.In, bio.Rd) var src = bio.byline(fd) @@ -140,7 +178,7 @@ const main = { ;; ;; - std.write(std.Out, buf) + std.write(std.Out, itob(buf)) bio.free(fd) } |