summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm.myr62
1 files changed, 50 insertions, 12 deletions
diff --git a/asm.myr b/asm.myr
index 800a6ef..dda4eed 100644
--- a/asm.myr
+++ b/asm.myr
@@ -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)
}