commit 0193a81d039770c7909c274d75471ac815cb8007
parent 73b846f9d8ba7eba10ae719afd1e2a68f00a7123
Author: Stacy Harper <contact@stacyharper.net>
Date: Fri, 23 Dec 2022 15:50:08 +0100
Add @packed to lexers/parsers
Signed-off-by: Stacy Harper <contact@stacyharper.net>
Diffstat:
4 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/hare/ast/type.ha b/hare/ast/type.ha
@@ -108,6 +108,7 @@ export type struct_member = struct {
// struct { ... }
export type struct_type = struct {
+ packed: bool,
members: []struct_member,
};
diff --git a/hare/lex/token.ha b/hare/lex/token.ha
@@ -14,6 +14,7 @@ export type ltok = enum uint {
ATTR_INIT,
ATTR_NORETURN,
ATTR_OFFSET,
+ ATTR_PACKED,
ATTR_SYMBOL,
ATTR_TEST,
ATTR_THREADLOCAL,
@@ -163,6 +164,7 @@ const bmap: [_]str = [
"@init",
"@noreturn",
"@offset",
+ "@packed",
"@symbol",
"@test",
"@threadlocal",
diff --git a/hare/parse/type.ha b/hare/parse/type.ha
@@ -236,6 +236,12 @@ fn fn_type(lexer: *lex::lexer) (ast::_type | error) = {
fn struct_union_type(lexer: *lex::lexer) (ast::_type | error) = {
let membs: []ast::struct_member = [];
let kind = want(lexer, ltok::STRUCT, ltok::UNION)?;
+ let packed = false;
+
+ if (kind.0 == ltok::STRUCT && try(lexer, ltok::ATTR_PACKED)? is lex::token) {
+ packed = true;
+ };
+
want(lexer, ltok::LBRACE)?;
for (true) {
@@ -291,7 +297,7 @@ fn struct_union_type(lexer: *lex::lexer) (ast::_type | error) = {
flags = ast::type_flags::NONE,
repr = switch (kind.0) {
case ltok::STRUCT =>
- yield ast::struct_type { members = membs, ...};
+ yield ast::struct_type { members = membs, packed = packed, ...};
case ltok::UNION =>
yield membs: ast::union_type;
case => abort();
diff --git a/hare/unparse/type.ha b/hare/unparse/type.ha
@@ -161,7 +161,11 @@ fn struct_union_type(
let z = 0z;
let membs = match (t.repr) {
case let st: ast::struct_type =>
- z += fmt::fprint(out, "struct {")?;
+ z += fmt::fprint(out, "struct ")?;
+ if (st.packed) {
+ z += fmt::fprint(out, "@packed ")?;
+ };
+ z += fmt::fprint(out, "{")?;
yield st.members: []ast::struct_member;
case let ut: ast::union_type =>
z += fmt::fprint(out, "union {")?;