diff options
| -rw-r--r-- | asm.myr | 50 |
1 files changed, 38 insertions, 12 deletions
@@ -40,6 +40,8 @@ type literal = union `Number int `Register int `Label byte[:] + `DerefAddr int + `DerefLabel byte[:] `Invalid ;; @@ -48,16 +50,23 @@ const getnum = {s } const parselit = {s - if s[0] == ('#' : byte) + if s.len < 1 + -> `Invalid + elif s[0] == ('#' : byte) match getnum(s) |`std.Some(n): -> `Number(n) |`std.None: -> `Invalid ;; - elif s[0] == ('v' : byte) + elif s[0] == ('v' : byte) || s[0] == ('V' : byte) match getnum(s) |`std.Some(n): -> `Register(n) |`std.None: -> `Invalid ;; + elif s[0] == ('[' : byte) + match getnum(s[:s.len-1]) + |`std.Some(n): -> `DerefAddr(n) + |`std.None: -> `DerefLabel(s[:s.len-1]) + ;; else -> `Label(s) ;; @@ -82,25 +91,42 @@ const emitinstr = {p ;; match parselit(p[1]) | `Number(n): b = `std.Some([0x00 | (n & 0x0f00), (n & 0xff)]) - | `Label(l): b = `std.Some([0x20, 0x00]) + | `Label(l): b = `std.Some([0x00, 0x00]) mark = `std.Some(strdup(l)) - | `Register(_): - -> `std.Err("SYS called with register instruction") - | `Invalid: - -> `std.Err(std.fmt("invalid literal {}", p[1])) + | _: + -> `std.Err(std.fmt("invalid argument to SYS: {}", p[1])) ;; | "CALL": if p.len < 2 -> `std.Err("CALL missing subroutine address") ;; match parselit(p[1]) - | `Number(n): b = `std.Some([0x00 | (n & 0x0f00), (n & 0xff)]) + | `Number(n): b = `std.Some([0x20 | (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(std.fmt("invalid argument to CALL: {}", p[1])) + ;; + | "JP": + if p.len < 2 + -> `std.Err("JP missing address") + elif p.len == 2 + match parselit(p[1]) + | `Number(n): b = `std.Some([0x10 | (n & 0x0f00), (n & 0xff)]) + | `Label(l): b = `std.Some([0x10, 0x00]) + mark = `std.Some(strdup(l)) + | _: + -> `std.Err(std.fmt("invalid argument to JP: {}", p[1])) + ;; + else + match (parselit(p[1]), parselit(p[2])) + | (`Register(0), `Number(n)): + b = `std.Some([0xb0 | (n & 0x0f00), (n & 0xff)]) + | (`Register(0), `Label(l)): b = `std.Some([0xb0, 0x00]) + mark = `std.Some(strdup(l)) + | _: + -> `std.Err(std.fmt("invalid arguments to JP: {}, {}", p[1], p[2])) + ;; ;; | _: -> `std.Err("unrecognized instruction") |