commit dc4f509f414ae5c0d621ee56f3785b92fa630e0f
parent 3360dd77e0dcc6484b29dde9ab0942f57b37212b
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 2 Sep 2021 11:06:45 +0200
cmd/harec: basic qtypes
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
4 files changed, 187 insertions(+), 107 deletions(-)
diff --git a/cmd/harec/gen.ha b/cmd/harec/gen.ha
@@ -49,7 +49,8 @@ fn gen_func(ctx: *context, decl: *unit::decl) void = {
* => true,
};
if (has_rval) {
- abort(); // TODO: Return type
+ const qrtype = qtype_lookup(ctx, rtype, false);
+ fmt::printf(" {}", qtype_repr(qrtype))!;
};
fmt::printf(" ${}(", ident)!;
assert(len(fntype.params) == 0); // TODO
diff --git a/cmd/harec/genutil.ha b/cmd/harec/genutil.ha
@@ -1,111 +1,5 @@
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
@@ -1,3 +1,4 @@
+use fmt;
use hare::types;
type global = str;
@@ -16,6 +17,112 @@ const vvoid: value = value {
_type = &types::builtin_void,
};
+fn emit(
+ ctx: *context,
+ out: (value | void),
+ instr: qinstr,
+ args: (value | qval | qtype)...
+) 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)!;
+};
+
type qinstr = enum {
ADD,
ALLOC16,
diff --git a/cmd/harec/qtype.ha b/cmd/harec/qtype.ha
@@ -0,0 +1,78 @@
+use fmt;
+use hare::types;
+use hare::types::{builtin};
+
+type stype = enum {
+ BYTE = 'b',
+ HALF = 'h',
+ WORD = 'w',
+ LONG = 'l',
+ SINGLE = 's',
+ DOUBLE = 'd',
+};
+
+type qcompound = struct {
+ name: str,
+ fields: []qtype_field,
+ base: const *types::_type,
+};
+
+type qtype = (stype | qcompound | void);
+
+type qtype_field = struct {
+ qtype: const *qtype,
+ count: size,
+};
+
+// Singletons
+const qbyte: qtype = stype::BYTE;
+const qhalf: qtype = stype::HALF;
+const qword: qtype = stype::WORD;
+const qlong: qtype = stype::LONG;
+const qsingle: qtype = stype::SINGLE;
+const qdouble: qtype = stype::DOUBLE;
+
+fn qtype_lookup(
+ ctx: *context,
+ _type: const *types::_type,
+ extype: bool,
+) const *qtype = match (_type.repr) {
+ bi: builtin => switch (bi) {
+ builtin::CHAR =>
+ if (extype) &qbyte else &qword,
+ builtin::I8, builtin::U8 =>
+ if (extype) &qbyte else &qword,
+ builtin::I16, builtin::U16 =>
+ if (extype) &qhalf else &qword,
+ builtin::BOOL => &qword,
+ builtin::F32 => &qsingle,
+ builtin::F64 => &qdouble,
+ builtin::I32, builtin::U32, builtin::RUNE => &qword,
+ builtin::I64, builtin::U64 => &qlong,
+ builtin::INT, builtin::UINT,
+ builtin::NULL, builtin::UINTPTR,
+ builtin::SIZE => switch (_type.sz) {
+ 4 => &qword,
+ 8 => &qlong,
+ * => abort(),
+ },
+ builtin::STR => qtype_aggregate(ctx, _type),
+ builtin::VOID => abort(),
+ },
+ * => abort(),
+};
+
+fn qtype_aggregate(ctx: *context, _type: const *types::_type) const *qtype = {
+ abort(); // TODO
+};
+
+// XXX: This dereference should not be necessary after the match
+// overhaul
+fn qtype_repr(qtype: const *qtype) const str = match (*qtype) {
+ st: stype => {
+ static let buf: [1]u8 = [0...];
+ yield fmt::bsprintf(buf, "{}", st: rune);
+ },
+ qc: qcompound => abort(), // TODO
+ void => "",
+};