summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--asm.myr97
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
diff --git a/asm.myr b/asm.myr
new file mode 100644
index 0000000..f8689d5
--- /dev/null
+++ b/asm.myr
@@ -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)
+}