hare

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

commit a05c0cd64e6d34ff64989842a9a8b79b3ad9f836
parent d457f7469580741d57e7ad843627b62c0b2a5a9a
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon,  5 Apr 2021 19:33:07 -0400

hare::parse: (mostly) implement unary arithmetic

Diffstat:
Mhare/parse/+test.ha | 17++++++++++++++++-
Mhare/parse/expr.ha | 31++++++++++++++++++++++++++++++-
Mhare/unparse/expr.ha | 13++++++++++++-
3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/hare/parse/+test.ha b/hare/parse/+test.ha @@ -173,7 +173,13 @@ fn roundtrip(src: str) void = { let lexer = lex::init(buf, "<test>"); let u = ast::subunit { imports = [], - decls = decls(&lexer) as []ast::decl, + decls: []ast::decl = match (decls(&lexer)) { + decls: []ast::decl => decls, + err: error => { + fmt::errorln(strerror(err)); + abort(); + }, + }, }; defer ast::subunit_free(u); let out = strio::dynamic(); @@ -205,3 +211,12 @@ fn roundtrip(src: str) void = { "export fn main() void = void: int: uint: u16: u8;\n" "export fn main() void = void: int as uint: u16 is u8;\n"); }; + +@test fn unarithm() void = { + // TODO: object selectors/addr operator + roundtrip("export fn main() void = +void;\n" + "export fn main() void = -void;\n" + "export fn main() void = *void;\n" + "export fn main() void = ~void;\n" + "export fn main() void = !void;\n"); +}; diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -77,11 +77,40 @@ fn cast(lexer: *lex::lexer, lvalue: (ast::expr | void)) (ast::expr | error) = { }); }; -fn unarithm(lexer: *lex::lexer) (ast::expr | error) = { +fn objsel(lexer: *lex::lexer) (ast::expr | error) = { + abort(); // TODO +}; + +fn postfix(lexer: *lex::lexer) (ast::expr | error) = { want_btoken(lexer, btoken::VOID)?; // TODO return void; }; +fn unarithm(lexer: *lex::lexer) (ast::expr | error) = { + const tok = match (try_btoken(lexer, + btoken::PLUS, btoken::MINUS, btoken::BNOT, + btoken::LNOT, btoken::TIMES, btoken::BAND)) { + void => return postfix(lexer), + tok: btoken => tok, + }; + const op = switch (tok) { + btoken::PLUS => ast::unarithm_op::PLUS, + btoken::MINUS => ast::unarithm_op::MINUS, + btoken::BNOT => ast::unarithm_op::BNOT, + btoken::LNOT => ast::unarithm_op::LNOT, + btoken::TIMES => ast::unarithm_op::DEREF, + btoken::BAND => ast::unarithm_op::ADDR, + * => abort(), + }; + let operand = + if (tok == btoken::BAND) objsel(lexer)? + else unarithm(lexer)?; + return ast::unarithm_expr { + op = op, + operand = alloc(operand), + }; +}; + fn binop_for_tok(tok: (lex::token, lex::location)) ast::binarithm_op = { let tok = match (tok.0) { b: btoken => b, diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha @@ -73,6 +73,17 @@ export fn expr( e: ast::return_expr => abort(), e: ast::slice_expr => abort(), e: ast::switch_expr => abort(), - e: ast::unarithm_expr => abort(), + e: ast::unarithm_expr => { + let z = fmt::fprintf(out, "{}", switch (e.op) { + ast::unarithm_op::ADDR => "&", + ast::unarithm_op::BNOT => "~", + ast::unarithm_op::DEREF => "*", + ast::unarithm_op::LNOT => "!", + ast::unarithm_op::MINUS => "-", + ast::unarithm_op::PLUS => "+", + })?; + z += expr(out, indent, *e.operand)?; + z; + }, }; };