commit dc75fea624fffe0a27bb67c982565bc3fd840f8a
parent 437c7d0464620a00e28c4e825468ff3f34ee5a6c
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 3 Oct 2021 11:49:53 +0200
hare::*: implement type builtin
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
7 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/hare/ast/expr.ha b/hare/ast/expr.ha
@@ -336,6 +336,9 @@ export type switch_expr = struct {
cases: []switch_case,
};
+// A type expression
+export type type_expr = *_type;
+
// A unary operator
export type unarithm_op = enum {
// TODO: Should this be rehomed with the checked AST?
@@ -373,7 +376,8 @@ export type expr = struct {
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 | yield_expr),
+ slice_expr | switch_expr | type_expr | unarithm_expr |
+ yield_expr),
};
// Frees resources associated with a Hare [[expr]]ession.
@@ -538,6 +542,8 @@ case e: expr =>
free(exprs);
};
free(s.cases);
+ case t: type_expr =>
+ type_free(t);
case u: unarithm_expr =>
expr_free(u.operand);
case y: yield_expr =>
diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha
@@ -64,6 +64,7 @@
static insert(x[0], foo);
len([1, 2, 3, 4]);
size(u32);
+ type(u32);
};
");
};
diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha
@@ -344,23 +344,23 @@ 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,
- ltok::DEFER)?) {
+ ltok::DEFER, ltok::TYPE)?) {
case tok: lex::token =>
yield tok;
case void =>
return postfix(lexer, void);
};
- return switch (tok.0) {
+ switch (tok.0) {
case ltok::ALLOC =>
- yield alloc_expr(lexer);
+ return alloc_expr(lexer);
case ltok::APPEND, ltok::INSERT =>
- yield append_insert_expr(lexer, false);
+ return append_insert_expr(lexer, false);
case ltok::DELETE =>
- yield delete_expr(lexer, false);
+ return delete_expr(lexer, false);
case ltok::FREE =>
- yield free_expr(lexer);
+ return free_expr(lexer);
case ltok::ABORT, ltok::ASSERT =>
- yield assert_expr(lexer, false);
+ return assert_expr(lexer, false);
case ltok::STATIC =>
want(lexer, ltok::STATIC)?;
let tok = match (peek(lexer, ltok::LET, ltok::CONST,
@@ -372,23 +372,33 @@ fn builtin(lexer: *lex::lexer) (ast::expr | error) = {
// TODO: The following is lame:
return syntaxerr(tok.2, "Expected let, const, or assert");
};
- yield switch (tok.0) {
+ switch (tok.0) {
case ltok::LET, ltok::CONST =>
- yield binding(lexer, true);
+ return binding(lexer, true);
case ltok::ABORT, ltok::ASSERT =>
- yield assert_expr(lexer, true);
+ return assert_expr(lexer, true);
case ltok::APPEND, ltok::INSERT =>
- yield append_insert_expr(lexer, true);
+ return append_insert_expr(lexer, true);
case ltok::DELETE =>
- yield delete_expr(lexer, true);
+ return delete_expr(lexer, true);
case => abort();
};
case ltok::SIZE, ltok::LEN, ltok::OFFSET =>
- yield measurement(lexer);
+ return measurement(lexer);
+ case ltok::TYPE =>
+ want(lexer, ltok::TYPE)?;
+ want(lexer, ltok::LPAREN)?;
+ let expr = ast::expr {
+ start = tok.2,
+ end = lex::prevloc(lexer),
+ expr = alloc(_type(lexer)?): ast::type_expr,
+ };
+ want(lexer, ltok::RPAREN)?;
+ return expr;
case ltok::DEFER =>
want(lexer, ltok::DEFER)?;
let expr = alloc(expression(lexer)?);
- yield ast::expr {
+ return ast::expr {
start = tok.2,
end = lex::prevloc(lexer),
expr = expr: ast::defer_expr,
diff --git a/hare/parse/type.ha b/hare/parse/type.ha
@@ -116,6 +116,8 @@ fn primitive_type(lexer: *lex::lexer) (ast::_type | error) = {
yield builtin_type::F64;
case ltok::BOOL =>
yield builtin_type::BOOL;
+ case ltok::TYPE =>
+ yield builtin_type::TYPE;
case ltok::VOID =>
yield builtin_type::VOID;
case =>
@@ -433,7 +435,7 @@ export fn _type(lexer: *lex::lexer) (ast::_type | error) = {
ltok::INT, ltok::SIZE, ltok::U16, ltok::U32, ltok::U64,
ltok::U8, ltok::UINT, ltok::UINTPTR, ltok::RUNE,
ltok::STR, ltok::F32, ltok::F64, ltok::BOOL,
- ltok::VOID =>
+ ltok::VOID, ltok::TYPE =>
yield primitive_type(lexer)?;
case ltok::ENUM =>
yield enum_type(lexer)?;
diff --git a/hare/types/store.ha b/hare/types/store.ha
@@ -173,6 +173,10 @@ fn fromast(store: *typestore, atype: *ast::_type) (_type | deferred | error) = {
else
store.arch._pointer;
yield builtin::STR;
+ case ast::builtin_type::TYPE =>
+ sz = store.arch._pointer;
+ align = store.arch._pointer;
+ yield builtin::TYPE;
case ast::builtin_type::U16 =>
sz = 2; align = 2;
yield builtin::U16;
diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha
@@ -351,6 +351,11 @@ export fn expr(
return z;
case e: ast::switch_expr =>
return switch_expr(out, indent, e)?;
+ case t: ast::type_expr =>
+ let z = fmt::fprint(out, "type(")?;
+ z += _type(out, indent, *t)?;
+ z += fmt::fprint(out, ")")?;
+ return z;
case e: ast::unarithm_expr =>
let z = fmt::fprintf(out, "{}", switch (e.op) {
case ast::unarithm_op::ADDR =>
diff --git a/hare/unparse/type.ha b/hare/unparse/type.ha
@@ -33,6 +33,8 @@ case ast::builtin_type::SIZE =>
yield "size";
case ast::builtin_type::STR =>
yield "str";
+case ast::builtin_type::TYPE =>
+ yield "type";
case ast::builtin_type::U16 =>
yield "u16";
case ast::builtin_type::U32 =>