hare

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

commit a41a1d8a4dd5e9381cee7f1aa81df61b930164cd
parent 7a2db287a1eed527edc155668844a99f030d3aac
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 26 Mar 2021 19:52:18 -0400

hare::parse: flesh out expressions a bit

Diffstat:
Mcmd/hare/schedule.ha | 2+-
Mhare/parse/decl.ha | 4++--
Mhare/parse/expr.ha | 70+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/cmd/hare/schedule.ha b/cmd/hare/schedule.ha @@ -40,6 +40,7 @@ fn sched_module(plan: *plan, ident: ast::ident, link: *[]*task) *task = { }; let depends: []*task = []; + defer free(depends); for (let i = 0z; i < len(ver.depends); i += 1) { const dep = ver.depends[i]; let obj = sched_module(plan, dep, link); @@ -54,7 +55,6 @@ fn sched_module(plan: *plan, ident: ast::ident, link: *[]*task) *task = { version = ver, }); append(*link, obj); - free(depends); return obj; }; diff --git a/hare/parse/decl.ha b/hare/parse/decl.ha @@ -58,7 +58,7 @@ fn decl_global( _type.flags |= ast::type_flags::CONST; }; want_btoken(lexer, btoken::EQUAL)?; - let init = expr(lexer)?; + let init = simple_expression(lexer)?; let btok = try_btoken(lexer, btoken::COMMA)?; append(decl, ast::decl_global { is_const = tok == btoken::DEF, @@ -132,7 +132,7 @@ fn decl_func(lexer: *lex::lexer) (ast::decl_func | error) = { len(params[i].name) > 0, "Expected parameter name in function declaration")?; }; - expr(lexer)?; + compound_expression(lexer)?; }, // We don't care about the location btoken::SEMICOLON => lex::unlex(lexer, (tok, proto_loc)), diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -2,9 +2,69 @@ use hare::ast; use hare::lex; use hare::lex::{btoken}; -// Parses an expression -// TODO: Actually implement this -export fn expr(lexer: *lex::lexer) (ast::expr | error) = { - want_btoken(lexer, btoken::VOID)?; - return void; +// Parses a compound-expression +export fn compound_expression(lexer: *lex::lexer) (ast::expr | error) = { + let tok = match (lex::lex(lexer)?) { + io::EOF => return syntaxerr(mkloc(lexer), + "Expected EOF, expected compound expression"), + t: (lex::token, lex::location) => t, + }; + + lex::unlex(lexer, tok); + let tok = match (tok.0) { + tok: btoken => tok, + * => return complex_expression(lexer), + }; + + return switch (tok) { + btoken::LBRACE => expression_list(lexer), + btoken::BREAK, btoken::CONTINUE, btoken::RETURN => + control_statement(lexer), + * => abort(), + }; +}; + +// Parses a simple-expression +export fn simple_expression(lexer: *lex::lexer) (ast::expr | error) = { + abort(); // TODO +}; + +// Parses a complex-expression +export fn complex_expression(lexer: *lex::lexer) (ast::expr | error) = { + abort(); // TODO +}; + +fn expression_list(lexer: *lex::lexer) (ast::expr | error) = { + let items: ast::list_expr = []; + + for (true) { + let tok = match (lex::lex(lexer)?) { + io::EOF => return syntaxerr(mkloc(lexer), + "Unexpected EOF, expected scope or control expression"), + t: (lex::token, lex::location) => t, + }; + lex::unlex(lexer, tok); + let item = match (tok.0) { + tok: btoken => switch (tok) { + btoken::RBRACE => break, + btoken::BREAK, + btoken::CONTINUE, + btoken::RETURN => control_statement(lexer)?, + * => scope_expression(lexer)?, + }, + * => scope_expression(lexer)?, + }; + append(items, alloc(item)); + want_btoken(lexer, btoken::SEMICOLON)?; + }; + + return items; +}; + +fn scope_expression(lexer: *lex::lexer) (ast::expr | error) = { + abort(); // TODO +}; + +fn control_statement(lexer: *lex::lexer) (ast::expr | error) = { + abort(); // TODO };