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:
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
};