commit bec2735b7682502ef6fe593c9d9e62b7319db803
parent 0329ac741bc4f2e5cb1f8926697b4160de51f068
Author: Sebastian <sebastian@sebsite.pw>
Date: Mon, 8 May 2023 20:44:41 -0400
hare::ast: add align expression
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
5 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/hare/ast/expr.ha b/hare/ast/expr.ha
@@ -37,6 +37,11 @@ export type access_tuple = struct {
export type access_expr = (access_identifier | access_index | access_field
| access_tuple);
+// An align expression.
+//
+// align(int)
+export type align_expr = *_type;
+
// The form of an allocation expression.
//
// alloc(foo) // OBJECT
@@ -419,14 +424,14 @@ export type yield_expr = struct {
export type expr = struct {
start: lex::location,
end: lex::location,
- expr: (access_expr | alloc_expr | append_expr | assert_expr |
- assign_expr | binarithm_expr | binding_expr | break_expr |
- call_expr | cast_expr | constant_expr | continue_expr |
- defer_expr | delete_expr | for_expr | free_expr | if_expr |
- insert_expr | compound_expr | match_expr | len_expr |
- size_expr | offset_expr | propagate_expr | return_expr |
- slice_expr | switch_expr | unarithm_expr | variadic_expr |
- yield_expr),
+ expr: (access_expr | align_expr | alloc_expr | append_expr |
+ assert_expr | assign_expr | binarithm_expr | binding_expr |
+ break_expr | call_expr | cast_expr | constant_expr |
+ continue_expr | defer_expr | delete_expr | for_expr |
+ free_expr | if_expr | insert_expr | compound_expr | match_expr |
+ len_expr | size_expr | offset_expr | propagate_expr |
+ return_expr | slice_expr | switch_expr | unarithm_expr |
+ variadic_expr | yield_expr),
};
// Frees resources associated with a Hare [[expr]]ession.
@@ -454,6 +459,8 @@ case let e: expr =>
expr_finish(t.object);
expr_finish(t.value);
};
+ case let a: align_expr =>
+ type_finish(a: *_type);
case let a: alloc_expr =>
expr_finish(a.init);
expr_finish(a.capacity);
diff --git a/hare/lex/token.ha b/hare/lex/token.ha
@@ -20,6 +20,7 @@ export type ltok = enum uint {
ATTR_THREADLOCAL,
UNDERSCORE,
ABORT,
+ ALIGN,
ALLOC,
APPEND,
AS,
@@ -170,6 +171,7 @@ const bmap: [_]str = [
"@threadlocal",
"_",
"abort",
+ "align",
"alloc",
"append",
"as",
diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha
@@ -46,6 +46,7 @@
@test fn builtin() void = {
roundtrip(`export fn main() void = {
+ align(u32);
alloc(1234);
alloc(1234...);
alloc(4321, 1234);
diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha
@@ -254,11 +254,13 @@ fn append_insert_expr(
};
fn measurement(lexer: *lex::lexer) (ast::expr | error) = {
- const tok = want(lexer, ltok::LEN, ltok::SIZE, ltok::OFFSET)?;
- want(lexer, ltok::LPAREN)?;
+ const tok = want(lexer, ltok::LEN, ltok::ALIGN, ltok::SIZE, ltok::OFFSET)?;
+ want(lexer, ltok::LPAREN)?;
const expr = switch (tok.0) {
case ltok::LEN =>
yield alloc(expr(lexer)?): ast::len_expr;
+ case ltok::ALIGN =>
+ yield alloc(_type(lexer)?): ast::align_expr;
case ltok::SIZE =>
yield alloc(_type(lexer)?): ast::size_expr;
case ltok::OFFSET =>
@@ -382,9 +384,9 @@ fn binding(lexer: *lex::lexer, is_static: bool) (ast::expr | error) = {
};
fn builtin(lexer: *lex::lexer) (ast::expr | error) = {
- const tok = match (peek(lexer, ltok::ALLOC, ltok::APPEND, ltok::FREE,
- ltok::DELETE, ltok::ABORT, ltok::ASSERT, ltok::INSERT,
- ltok::STATIC, ltok::SIZE, ltok::LEN, ltok::OFFSET,
+ const tok = match (peek(lexer, ltok::ALIGN, ltok::ALLOC, ltok::APPEND,
+ ltok::FREE, ltok::DELETE, ltok::ABORT, ltok::ASSERT,
+ ltok::INSERT, ltok::STATIC, ltok::SIZE, ltok::LEN, ltok::OFFSET,
ltok::DEFER, ltok::VASTART, ltok::VAARG, ltok::VAEND)?) {
case let tok: lex::token =>
yield tok;
@@ -424,7 +426,7 @@ fn builtin(lexer: *lex::lexer) (ast::expr | error) = {
return delete_expr(lexer, true);
case => abort();
};
- case ltok::SIZE, ltok::LEN, ltok::OFFSET =>
+ case ltok::ALIGN, ltok::SIZE, ltok::LEN, ltok::OFFSET =>
return measurement(lexer);
case ltok::DEFER =>
want(lexer, ltok::DEFER)?;
diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha
@@ -38,6 +38,11 @@ export fn expr(
z += expr(out, indent, *tp.value)?;
return z;
};
+ case let e: ast::align_expr =>
+ let z = fmt::fprint(out, "align(")?;
+ z += _type(out, indent, *e)?;
+ z += fmt::fprint(out, ")")?;
+ return z;
case let e: ast::alloc_expr =>
let z = fmt::fprint(out, "alloc(")?;
z += expr(out, indent, *e.init)?;