hare

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

commit 80d03addce474489fb3be95293d454a667f4951f
parent 1dba69e7a4c6bfcc2ba87757fb046799d030bf6e
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 16 Apr 2021 09:20:50 -0400

hare::parse: implement struct field access

Diffstat:
Mhare/parse/+test/expr.ha | 6++++++
Mhare/parse/expr.ha | 19++++++++++++++++---
Mhare/unparse/expr.ha | 5++++-
3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha @@ -21,6 +21,12 @@ "export fn main() void = void: int as uint: u16 is u8;\n"); }; +@test fn postfix() void = { + roundtrip("export fn main() void = x.y;\n" + "export fn main() void = x.y.z.q;\n" + "export fn main() void = x().y;\n"); +}; + @test fn unarithm() void = { // TODO: object selectors/addr operator roundtrip("export fn main() void = +void;\n" diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -1,6 +1,7 @@ use hare::ast; use hare::lex::{ltok}; use hare::lex; +use fmt; // Parses an expression. export fn expression(lexer: *lex::lexer) (ast::expr | error) = { @@ -207,11 +208,11 @@ fn postfix(lexer: *lex::lexer, lvalue: (ast::expr | void)) (ast::expr | error) = ex: ast::expr => ex, }; - lvalue = match (try(lexer, ltok::LPAREN, ltok::DOT, ltok::LBRACKET, - ltok::QUESTION)) { + lvalue = match (try(lexer, ltok::LPAREN, + ltok::DOT, ltok::LBRACKET, ltok::QUESTION)) { tok: lex::token => switch (tok.0) { ltok::LPAREN => call(lexer, lvalue)?, - ltok::DOT => abort(), // TODO: Field access + ltok::DOT => postfix_dot(lexer, lvalue)?, ltok::LBRACKET => abort(), // TODO: Indexing ltok::QUESTION => abort(), // TODO: Propagation * => abort(), @@ -222,6 +223,18 @@ fn postfix(lexer: *lex::lexer, lvalue: (ast::expr | void)) (ast::expr | error) = return postfix(lexer, lvalue); }; +fn postfix_dot(lexer: *lex::lexer, lvalue: ast::expr) (ast::expr | error) = { + let tok = want(lexer, ltok::NAME, ltok::LIT_INT)?; + return switch (tok.0) { + ltok::NAME => ast::access_field { + object = alloc(lvalue), + field = tok.1 as str, + }, + ltok::LIT_INT => abort(), // TODO: Tuple access + * => abort(), + }; +}; + fn unarithm(lexer: *lex::lexer) (ast::expr | error) = { const tok = match (try(lexer, ltok::PLUS, ltok::MINUS, ltok::BNOT, diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha @@ -12,7 +12,10 @@ export fn expr( e: ast::access_expr => match (e) { id: ast::access_identifier => ident(out, id), ix: ast::access_index => abort(), - fl: ast::access_field => abort(), + fi: ast::access_field => { + let z = expr(out, indent, *fi.object)?; + z + fmt::fprintf(out, ".{}", fi.field)?; + }, tp: ast::access_tuple => abort(), }, e: ast::alloc_expr => abort(),