summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob L. Kreuze <zerodaysfordays@sdf.lonestar.org>2019-12-25 16:36:12 -0500
committerJakob L. Kreuze <zerodaysfordays@sdf.lonestar.org>2019-12-25 16:36:12 -0500
commitfab0dae5a3f048a5085bc6329833dbd8d977c5ba (patch)
tree9c3d226c96bb4b98337afc2dd2fe15d20cbe1e1b
parentd58a71909e3d9cf586dc156a5285488343334dd2 (diff)
Reindent according to myddin-mode.
-rw-r--r--asm.myr166
1 files changed, 96 insertions, 70 deletions
diff --git a/asm.myr b/asm.myr
index f8689d5..5206f86 100644
--- a/asm.myr
+++ b/asm.myr
@@ -1,97 +1,123 @@
use bio
use std
+const strdup = {s
+ var buf = std.slalloc(s.len)
+ std.slcp(buf, s)
+ -> buf
+}
+
+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 readline = {line
- var cmt = std.strfind(line, ";")
+ var cmt = std.strfind(line, ";")
- match cmt
- | `std.Some (pos): line = line[:pos]
- | `std.None:
- ;;
+ 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:])
- ;;
-}
+ if line.len == 0
+ -> (`std.None, [][:])
+ ;;
-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)
+ var parts = std.strtok(line)
+ if std.isspace((line[0] : char))
+ -> (`std.None, parts)
+ else
+ -> (`std.Some(parts[0]), parts[1:])
+ ;;
}
const parsehex = {s
- if s[0] == ('#' : byte)
- -> std.intparsebase((s[1:] : byte[:]), 16)
- else
- -> `std.None
- ;;
+ if s[0] == ('#' : byte)
+ -> std.intparsebase((s[1:] : byte[:]), 16)
+ else
+ -> `std.None
+ ;;
}
const emitinstr = {p
- var b
- var mark = `std.None
+ var b = `std.None
+ var mark = `std.None
- if p.len < 1
- -> `std.Ok([][:], mark)
- ;;
+ if p.len < 1
+ -> `std.Ok(b, 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")
+ match upcase(p[0])
+ | "CLS":
+ b = `std.Some([0x00, 0xe0])
+ | "SYS":
+ if p.len < 2
+ -> `std.Err("SYS 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]))
;;
+ | _:
+ -> `std.Err("unrecognized instruction")
+ ;;
- -> `std.Ok((b, mark))
+ -> `std.Ok((b, mark))
}
const main = {
- var fd = bio.mkfile(std.In, bio.Rd)
- var src = bio.byline(fd)
- var lc = 0
+ 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
+ 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)
- ;;
+ for line : src ;
+ match readline(line)
+ | (`std.None, i): res = emitinstr(i)
+ | (`std.Some (label), i): res = emitinstr(i)
+ std.htput(labels, strdup(label), offset)
+ ;;
+
+ match res
+ | `std.Err(msg): std.die(std.fmt("{} on line {}\n", msg, lc))
+ | `std.Ok((bytes, marker)):
+ match marker
+ | `std.Some(label): queue = std.slpush(&queue, (label, offset, lc))
+ | `std.None:
+ ;;
+ match bytes
+ | `std.Some(arr): buf = std.sljoin(&buf, arr[:])
+ offset += 2
+ | `std.None:
+ ;;
+ ;;
- 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++
+ ;;
- lc++
+ for replacement : queue ;
+ match replacement
+ | (l, buf_pos, src_pos):
+ match std.htget(labels, l)
+ | `std.None: std.die(std.fmt("reference to undefined label '{}' on line {}\n", l, src_pos))
+ | `std.Some(addr): buf[buf_pos] |= addr & 0x0f00
+ buf[buf_pos + 1] |= addr & 0xff
+ ;;
;;
- std.put("{}", buf)
+ ;;
+
+ std.write(std.Out, buf)
- bio.free(fd)
+ bio.free(fd)
}