hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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:
Mhare/ast/expr.ha | 8+++++++-
Mhare/parse/+test/expr.ha | 1+
Mhare/parse/expr.ha | 38++++++++++++++++++++++++--------------
Mhare/parse/type.ha | 4+++-
Mhare/types/store.ha | 4++++
Mhare/unparse/expr.ha | 5+++++
Mhare/unparse/type.ha | 2++
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 =>