commit 0320abd4ee79c4139786cb01be1a09be72b93b0e
parent 2e83970d123e177196e7ea3571f7bcab399a18e8
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 22 Aug 2021 11:59:35 +0200
cmd/harec: add some meat to these bones
A brief stop is called for to implement some of these TODOs elsewhere.
Most importantly:
- Add a constant called valvoid
- Implement tagged unions (and their casts) in harec eval
- Add builtin type globals in hare::types like &types::builtin_void
Bonus points: update genutil.ha:emit's out parameter to
(...value | void) and gen breaks, should be investigated.
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
3 files changed, 217 insertions(+), 2 deletions(-)
diff --git a/cmd/harec/gen.ha b/cmd/harec/gen.ha
@@ -1,5 +1,6 @@
use bufio;
use fmt;
+use hare::ast;
use hare::module;
use hare::types;
use hare::unit;
@@ -64,7 +65,16 @@ fn gen_func(ctx: *context, decl: *unit::decl) void = {
fmt::println("}\n")!;
};
-fn gen_expr(ctx: *context, expr: *unit::expr) void = {
+fn gen_expr(ctx: *context, expr: *unit::expr) value = {
// TODO
- fmt::fprintfln(ctx.out, "\tret")!;
+ emit(ctx, void, qinstr::RET);
+
+ // TODO:
+ // - Make this a constant called valvoid
+ // - Implement tagged unions (and their casts) in eval
+ // - Add builtin type globals in hare::types like &types::builtin_void
+ return value {
+ value = qvoid,
+ _type = types::lookup_builtin(ctx.store, ast::builtin_type::VOID),
+ };
};
diff --git a/cmd/harec/genutil.ha b/cmd/harec/genutil.ha
@@ -1,5 +1,111 @@
use fmt;
+fn emit(
+ ctx: *context,
+ out: (value | void),
+ instr: qinstr,
+ args: value...
+) void = {
+ fmt::fprintf(ctx.out, "\t")!;
+ match (out) {
+ val: value => abort(), // TODO
+ void => void,
+ };
+ // TODO: The langauge should provide a means of converting enums to
+ // strings without this
+ fmt::fprint(ctx.out, switch (instr) {
+ qinstr::ADD => "add",
+ qinstr::ALLOC16 => "alloc16",
+ qinstr::ALLOC4 => "alloc4",
+ qinstr::ALLOC8 => "alloc8",
+ qinstr::AND => "and",
+ qinstr::CALL => "call",
+ qinstr::CAST => "cast",
+ qinstr::CEQD => "ceqd",
+ qinstr::CEQL => "ceql",
+ qinstr::CEQS => "ceqs",
+ qinstr::CEQW => "ceqw",
+ qinstr::CGED => "cged",
+ qinstr::CGES => "cges",
+ qinstr::CGTD => "cgtd",
+ qinstr::CGTS => "cgts",
+ qinstr::CLED => "cled",
+ qinstr::CLES => "cles",
+ qinstr::CLTD => "cltd",
+ qinstr::CLTS => "clts",
+ qinstr::CNED => "cned",
+ qinstr::CNEL => "cnel",
+ qinstr::CNES => "cnes",
+ qinstr::CNEW => "cnew",
+ qinstr::COD => "cod",
+ qinstr::COPY => "copy",
+ qinstr::COS => "cos",
+ qinstr::CSGEL => "csgel",
+ qinstr::CSGEW => "csgew",
+ qinstr::CSGTL => "csgtl",
+ qinstr::CSGTW => "csgtw",
+ qinstr::CSLEL => "cslel",
+ qinstr::CSLEW => "cslew",
+ qinstr::CSLTL => "csltl",
+ qinstr::CSLTW => "csltw",
+ qinstr::CUGEL => "cugel",
+ qinstr::CUGEW => "cugew",
+ qinstr::CUGTL => "cugtl",
+ qinstr::CUGTW => "cugtw",
+ qinstr::CULEL => "culel",
+ qinstr::CULEW => "culew",
+ qinstr::CULTL => "cultl",
+ qinstr::CULTW => "cultw",
+ qinstr::CUOD => "cuod",
+ qinstr::CUOS => "cuos",
+ qinstr::DIV => "div",
+ qinstr::DTOSI => "dtosi",
+ qinstr::EXTS => "exts",
+ qinstr::EXTSB => "extsb",
+ qinstr::EXTSH => "extsh",
+ qinstr::EXTSW => "extsw",
+ qinstr::EXTUB => "extub",
+ qinstr::EXTUH => "extuh",
+ qinstr::EXTUW => "extuw",
+ qinstr::JMP => "jmp",
+ qinstr::JNZ => "jnz",
+ qinstr::LOADD => "loadd",
+ qinstr::LOADL => "loadl",
+ qinstr::LOADS => "loads",
+ qinstr::LOADSB => "loadsb",
+ qinstr::LOADSH => "loadsh",
+ qinstr::LOADSW => "loadsw",
+ qinstr::LOADUB => "loadub",
+ qinstr::LOADUH => "loaduh",
+ qinstr::LOADUW => "loaduw",
+ qinstr::MUL => "mul",
+ qinstr::OR => "or",
+ qinstr::REM => "rem",
+ qinstr::RET => "ret",
+ qinstr::SAR => "sar",
+ qinstr::SHL => "shl",
+ qinstr::SHR => "shr",
+ qinstr::SLTOF => "sltof",
+ qinstr::STOREB => "storeb",
+ qinstr::STORED => "stored",
+ qinstr::STOREH => "storeh",
+ qinstr::STOREL => "storel",
+ qinstr::STORES => "stores",
+ qinstr::STOREW => "storew",
+ qinstr::STOSI => "stosi",
+ qinstr::SUB => "sub",
+ qinstr::SWTOF => "swtof",
+ qinstr::TRUNCD => "truncd",
+ qinstr::UDIV => "udiv",
+ qinstr::UREM => "urem",
+ qinstr::XOR => "xor",
+ })!;
+ for (let i = 0z; i < len(args); i += 1) {
+ abort(); // TODO
+ };
+ fmt::fprintln(ctx.out)!;
+};
+
fn mklabel(ctx: *context, name: str) str = {
static let buf: [1024]u8 = [0...];
let serial = ctx.serial;
diff --git a/cmd/harec/qbe.ha b/cmd/harec/qbe.ha
@@ -0,0 +1,99 @@
+use hare::types;
+
+type global = str;
+type temporary = str;
+type qvoid = void;
+type constant = (u32 | u64 | f32 | f64 | str | qvoid);
+
+type value = struct {
+ value: (global | temporary | constant),
+ _type: const *types::_type,
+};
+
+type qinstr = enum {
+ ADD,
+ ALLOC16,
+ ALLOC4,
+ ALLOC8,
+ AND,
+ CALL,
+ CAST,
+ CEQD,
+ CEQL,
+ CEQS,
+ CEQW,
+ CGED,
+ CGES,
+ CGTD,
+ CGTS,
+ CLED,
+ CLES,
+ CLTD,
+ CLTS,
+ CNED,
+ CNEL,
+ CNES,
+ CNEW,
+ COD,
+ COPY,
+ COS,
+ CSGEL,
+ CSGEW,
+ CSGTL,
+ CSGTW,
+ CSLEL,
+ CSLEW,
+ CSLTL,
+ CSLTW,
+ CUGEL,
+ CUGEW,
+ CUGTL,
+ CUGTW,
+ CULEL,
+ CULEW,
+ CULTL,
+ CULTW,
+ CUOD,
+ CUOS,
+ DIV,
+ DTOSI,
+ EXTS,
+ EXTSB,
+ EXTSH,
+ EXTSW,
+ EXTUB,
+ EXTUH,
+ EXTUW,
+ JMP,
+ JNZ,
+ LOADD,
+ LOADL,
+ LOADS,
+ LOADSB,
+ LOADSH,
+ LOADSW,
+ LOADUB,
+ LOADUH,
+ LOADUW,
+ MUL,
+ OR,
+ REM,
+ RET,
+ SAR,
+ SHL,
+ SHR,
+ SLTOF,
+ STOREB,
+ STORED,
+ STOREH,
+ STOREL,
+ STORES,
+ STOREW,
+ STOSI,
+ SUB,
+ SWTOF,
+ TRUNCD,
+ UDIV,
+ UREM,
+ XOR,
+};