commit 4c82f02d849e82bfa50fb188cb8d41422a5d8716
parent aba521506ff6c227f02483bcca47bca1f8646b1a
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 23 Aug 2021 16:39:29 +0200
all: move labels to compound exprs
This follows the appropriate changes to harec.
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
8 files changed, 90 insertions(+), 84 deletions(-)
diff --git a/cmd/hare/subcmds.ha b/cmd/hare/subcmds.ha
@@ -262,41 +262,43 @@ fn sched_walk(plan: *plan, ident: ast::ident, link: *[]*task) void = {
const path = module::identpath(ident);
const it = os::iter(path)?;
free(path);
- :loop for (true) match (fs::next(it)) {
- ent: fs::dirent => {
- if (ent.name == "." || ent.name == "..") {
- continue;
- };
- if (ent.ftype & fs::mode::DIR != fs::mode::DIR) {
- continue;
- };
- const d = utf8::decode(ent.name);
- match (utf8::next(&d)) {
- void => break,
- (utf8::more | utf8::invalid) => continue :loop,
- r: rune => if (!ascii::isalpha(r) && r != '_') {
- continue :loop;
- },
- };
- for (true) match (utf8::next(&d)) {
- void => break,
- (utf8::more | utf8::invalid) => continue :loop,
- r: rune => if (!ascii::isalnum(r) && r != '_') {
- continue :loop;
- },
- };
- let new = ast::ident_dup(ident);
- append(new, strings::dup(ent.name));
- sched_walk(plan, new, link);
-
- match (module::lookup(plan.context, new)) {
- ver: module::version =>
- if (len(ver.inputs) == 0) continue,
- module::error => continue,
- };
- sched_module(plan, new, link);
- },
- void => break,
+ for (true) :loop {
+ match (fs::next(it)) {
+ ent: fs::dirent => {
+ if (ent.name == "." || ent.name == "..") {
+ continue;
+ };
+ if (ent.ftype & fs::mode::DIR != fs::mode::DIR) {
+ continue;
+ };
+ const d = utf8::decode(ent.name);
+ match (utf8::next(&d)) {
+ void => break,
+ (utf8::more | utf8::invalid) => continue :loop,
+ r: rune => if (!ascii::isalpha(r) && r != '_') {
+ continue :loop;
+ },
+ };
+ for (true) match (utf8::next(&d)) {
+ void => break,
+ (utf8::more | utf8::invalid) => continue :loop,
+ r: rune => if (!ascii::isalnum(r) && r != '_') {
+ continue :loop;
+ },
+ };
+ let new = ast::ident_dup(ident);
+ append(new, strings::dup(ent.name));
+ sched_walk(plan, new, link);
+
+ match (module::lookup(plan.context, new)) {
+ ver: module::version =>
+ if (len(ver.inputs) == 0) continue,
+ module::error => continue,
+ };
+ sched_module(plan, new, link);
+ },
+ void => break,
+ };
};
};
diff --git a/getopt/getopts.ha b/getopt/getopts.ha
@@ -108,7 +108,7 @@ export type help = (cmd_help | flag_help | parameter_help);
export fn parse(args: []str, help: help...) command = {
let opts: []option = [];
let i = 1z;
- :arg for (i < len(args); i += 1) {
+ for (i < len(args); i += 1) :arg {
const arg = args[i];
if (len(arg) == 0 || arg == "-"
|| !strings::has_prefix(arg, "-")) {
@@ -122,9 +122,9 @@ export fn parse(args: []str, help: help...) command = {
let d = utf8::decode(arg);
assert(utf8::next(&d) as rune == '-');
let next = utf8::next(&d);
- :flag for (next is rune; next = utf8::next(&d)) {
+ for (next is rune; next = utf8::next(&d)) :flag {
const r = next as rune;
- :help for (let j = 0z; j < len(help); j += 1) {
+ for (let j = 0z; j < len(help); j += 1) :help {
let p: parameter_help = match (help[j]) {
cmd_help => continue :help,
f: flag_help => if (r == f.0) {
diff --git a/hare/ast/expr.ha b/hare/ast/expr.ha
@@ -156,6 +156,18 @@ export type cast_expr = struct {
_type: *_type,
};
+// A compound expression.
+//
+// {
+// foo;
+// bar;
+// // ...
+// }
+export type compound_expr = struct {
+ exprs: []*expr,
+ label: label,
+};
+
// An array constant.
//
// [foo, bar, ...]
@@ -214,7 +226,6 @@ export type delete_expr = *expr;
//
// :label for (let foo = 0; foo < bar; baz) quux
export type for_expr = struct {
- label: label,
bindings: nullable *expr,
cond: *expr,
afterthought: nullable *expr,
@@ -243,15 +254,6 @@ export type label = str;
// len(foo)
export type len_expr = *expr;
-// An expression list.
-//
-// {
-// foo;
-// bar;
-// // ...
-// }
-export type list_expr = []*expr;
-
// A match case.
//
// name: type => expr
@@ -345,7 +347,7 @@ export type expr = struct {
assign_expr | binarithm_expr | binding_expr | break_expr |
call_expr | cast_expr | constant_expr | continue_expr |
defer_expr | delete_expr | for_expr | free_expr | if_expr |
- list_expr | match_expr | len_expr | size_expr | offset_expr |
+ compound_expr | match_expr | len_expr | size_expr | offset_expr |
propagate_expr | return_expr | slice_expr | switch_expr |
unarithm_expr),
};
@@ -422,6 +424,13 @@ export fn expr_free(e: (expr | nullable *expr)) void = match (e) {
expr_free(c.value);
type_free(c._type);
},
+ c: compound_expr => {
+ for (let i = 0z; i < len(c.exprs); i += 1) {
+ expr_free(c.exprs[i]);
+ };
+ free(c.exprs);
+ free(c.label);
+ },
c: constant_expr => match(c) {
(void | lex::value) => void,
a: array_constant => {
@@ -456,7 +465,6 @@ export fn expr_free(e: (expr | nullable *expr)) void = match (e) {
d: defer_expr => expr_free(d: *expr),
d: delete_expr => expr_free(d: *expr),
f: for_expr => {
- free(f.label);
expr_free(f.bindings);
expr_free(f.cond);
expr_free(f.afterthought);
@@ -469,12 +477,6 @@ export fn expr_free(e: (expr | nullable *expr)) void = match (e) {
expr_free(i.fbranch);
},
l: len_expr => expr_free(l: *expr),
- l: list_expr => {
- for (let i = 0z; i < len(l); i += 1) {
- expr_free(l[i]);
- };
- free(l);
- },
m: match_expr => {
expr_free(m.value);
for (let i = 0z; i < len(m.cases); i += 1) {
diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha
@@ -151,7 +151,7 @@
for (true) {
x;
};
- :label for (true) {
+ for (true) :label {
x;
};
for (let x = 0; x < 10) {
diff --git a/hare/parse/+test/loc.ha b/hare/parse/+test/loc.ha
@@ -50,7 +50,7 @@ fn expr_testloc(srcs: str...) void = for (let i = 0z; i < len(srcs); i += 1) {
expr_testloc("defer foo");
expr_testloc("delete(foo[bar])", "delete(foo[bar..baz])");
expr_testloc("for (let foo = 0; bar; baz) quux",
- ":foo for (let bar = 0; baz; quux) quuux");
+ "for (let bar = 0; baz; quux) quuux");
expr_testloc("free(foo)");
expr_testloc("if (foo) bar", "if (foo) bar else baz");
expr_testloc("len(foo)");
diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha
@@ -41,11 +41,11 @@ export fn expression(lexer: *lex::lexer) (ast::expr | error) = {
ltok::CONST)?) {
void => binarithm(lexer, void, 0)?,
tok: lex::token => switch (tok.0) {
- ltok::LBRACE => expression_list(lexer)?,
+ ltok::LABEL, ltok::LBRACE => compound_expr(lexer)?,
ltok::MATCH => match_expr(lexer)?,
ltok::SWITCH => switch_expr(lexer)?,
ltok::IF => if_expr(lexer)?,
- ltok::LABEL, ltok::FOR => for_expr(lexer)?,
+ ltok::FOR => for_expr(lexer)?,
ltok::BREAK,
ltok::CONTINUE,
ltok::RETURN => control(lexer)?,
@@ -475,10 +475,18 @@ fn delete_expr(lexer: *lex::lexer) (ast::expr | error) = {
};
};
-fn expression_list(lexer: *lex::lexer) (ast::expr | error) = {
- let items: ast::list_expr = [];
+fn compound_expr(lexer: *lex::lexer) (ast::expr | error) = {
+ let items: []*ast::expr = [];
+
+ const start = want(lexer, ltok::LBRACE, ltok::LABEL)?;
+ const label = switch (start.0) {
+ ltok::LABEL => {
+ want(lexer, ltok::LBRACE)?;
+ start.1 as str;
+ },
+ * => "",
+ };
- const start = want(lexer, ltok::LBRACE)?;
for (let more = true; more) {
const item = match (peek(lexer, ltok::RBRACE)?) {
lex::token => break,
@@ -492,20 +500,15 @@ fn expression_list(lexer: *lex::lexer) (ast::expr | error) = {
return ast::expr {
start = start.2,
end = lex::prevloc(lexer),
- expr = items,
+ expr = ast::compound_expr {
+ exprs = items,
+ label = label,
+ },
};
};
fn for_expr(lexer: *lex::lexer) (ast::expr | error) = {
- const tok = want(lexer, ltok::FOR, ltok::LABEL)?;
- const label: ast::label = switch (tok.0) {
- ltok::LABEL => {
- want(lexer, ltok::FOR)?;
- tok.1 as str;
- },
- * => "",
- };
-
+ const tok = want(lexer, ltok::FOR)?;
want(lexer, ltok::LPAREN)?;
const bindings: nullable *ast::expr = match (peek(
@@ -537,7 +540,6 @@ fn for_expr(lexer: *lex::lexer) (ast::expr | error) = {
start = tok.2,
end = lex::prevloc(lexer),
expr = ast::for_expr {
- label = label,
bindings = bindings,
cond = cond,
afterthought = afterthought,
diff --git a/hare/unit/process.ha b/hare/unit/process.ha
@@ -82,6 +82,7 @@ fn process_expr(
ast::break_expr => abort(), // TODO
ast::call_expr => abort(), // TODO
ast::cast_expr => abort(), // TODO
+ ast::compound_expr => abort(), // TODO
ast::constant_expr => process_constant(ctx, expr),
ast::continue_expr => abort(), // TODO
ast::defer_expr => abort(), // TODO
@@ -89,7 +90,6 @@ fn process_expr(
ast::for_expr => abort(), // TODO
ast::free_expr => abort(), // TODO
ast::if_expr => abort(), // TODO
- ast::list_expr => abort(), // TODO
ast::match_expr => abort(), // TODO
ast::len_expr => abort(), // TODO
ast::size_expr => abort(), // TODO
diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha
@@ -236,11 +236,15 @@ export fn expr(
};
z;
},
- e: ast::list_expr => {
- let z = fmt::fprintf(out, "{{")?;
- for (let i = 0z; i < len(e); i += 1) {
+ e: ast::compound_expr => {
+ let z = 0z;
+ if (e.label != "") {
+ z += fmt::fprintf(out, ":{} ", e.label)?;
+ };
+ z += fmt::fprintf(out, "{{")?;
+ for (let i = 0z; i < len(e.exprs); i += 1) {
z += newline(out, indent + 1)?;
- z += expr(out, indent + 1, *e[i])?;
+ z += expr(out, indent + 1, *e.exprs[i])?;
z += fmt::fprintf(out, ";")?;
};
z += newline(out, indent)?;
@@ -393,11 +397,7 @@ fn for_expr(
indent: size,
e: ast::for_expr,
) (size | io::error) = {
- let z = 0z;
- if (e.label != "") {
- z += fmt::fprintf(out, ":{} ", e.label)?;
- };
- z += fmt::fprintf(out, "for (")?;
+ let z = fmt::fprintf(out, "for (")?;
z += match (e.bindings) {
null => 0z,
e: *ast::expr => expr(out, indent, *e)?