summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm.myr50
1 files changed, 38 insertions, 12 deletions
diff --git a/asm.myr b/asm.myr
index dda4eed..250f242 100644
--- a/asm.myr
+++ b/asm.myr
@@ -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")