commit b00e7b8c3656c23cc616f8c9c33fc2a11bb68f07
parent eb72c729f534b1247d130af4d4bc3770c3ae581e
Author: thing1 <thing1@seacrossedlovers.xyz>
Date: Wed, 6 May 2026 13:24:11 +0100
fixed minor bugs from yersterday
Diffstat:
6 files changed, 45 insertions(+), 49 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,7 +1,7 @@
.POSIX:
.SUFFIXES:
HARE=hare
-HAREFLAGS= -lc
+HAREFLAGS=
DESTDIR=
PREFIX=/usr/local
diff --git a/zpy/lex/+test.ha b/zpy/lex/+test.ha
@@ -18,35 +18,35 @@ fn check(lex: *lexer, expect: [](types | invalid)) void = {
@test
fn NoArgExpr() void = {
- let lex = &new(&memio::fixed(strings::toutf8("(foo)")));
+ let lex = new(&memio::fixed(strings::toutf8("(foo)")));
check(lex, [types::OBRACE, types::NAME, types::CBRACE, types::EOF]);
};
@test
fn HasArgsExpr() void = {
- let lex = &new(&memio::fixed(strings::toutf8("(foo 1 2 3)")));
+ let lex = new(&memio::fixed(strings::toutf8("(foo 1 2 3)")));
check(lex, [types::OBRACE, types::NAME, types::NUM, types::NUM, types::NUM, types::CBRACE, types::EOF]);
};
@test
fn NestedArgsExpr() void = {
- let lex = &new(&memio::fixed(strings::toutf8("(foo (bar 1 2) 3)")));
+ let lex = new(&memio::fixed(strings::toutf8("(foo (bar 1 2) 3)")));
check(lex, [types::OBRACE, types::NAME, types::OBRACE, types::NAME, types::NUM, types::NUM, types::CBRACE, types::NUM, types::CBRACE, types::EOF]);
};
@test
fn NameNumExpr() void = {
- let lex = &new(&memio::fixed(strings::toutf8("(foo bar 1)")));
+ let lex = new(&memio::fixed(strings::toutf8("(foo bar 1)")));
check(lex, [types::OBRACE, types::NAME, types::NAME, types::NUM, types::CBRACE, types::EOF]);
};
@test
fn NumNameExpr() void = {
- let lex = &new(&memio::fixed(strings::toutf8("(foo 1 bar)")));
+ let lex = new(&memio::fixed(strings::toutf8("(foo 1 bar)")));
check(lex, [types::OBRACE, types::NAME, types::NUM, types::NAME, types::CBRACE, types::EOF]);
};
@@ -56,28 +56,28 @@ fn NumNameExpr() void = {
@test
fn EmptyExpr() void = {
- let lex = &new(&memio::fixed(strings::toutf8("")));
+ let lex = new(&memio::fixed(strings::toutf8("")));
check(lex, [invalid]);
};
@test
fn SingleOBraceExpr() void = {
- let lex = &new(&memio::fixed(strings::toutf8("(")));
+ let lex = new(&memio::fixed(strings::toutf8("(")));
check(lex, [types::OBRACE, invalid]);
};
@test
fn SingleCBraceExpr() void = {
- let lex = &new(&memio::fixed(strings::toutf8(")")));
+ let lex = new(&memio::fixed(strings::toutf8(")")));
check(lex, [invalid]);
};
@test
fn SingleNameExpr() void = {
- let lex = &new(&memio::fixed(strings::toutf8("foo")));
+ let lex = new(&memio::fixed(strings::toutf8("foo")));
check(lex, [invalid]);
};
diff --git a/zpy/parse/+test.ha b/zpy/parse/+test.ha
@@ -4,48 +4,40 @@ use strings;
@test
fn BinaryExpr() void = {
- let lex = &lex::new(&memio::fixed(strings::toutf8("(foo 1 2)")));
-
- assert(((try(lex, [&parseSexpr]) as node) as sexpr).func == "foo");
- assert(len(((try(lex, [&parseSexpr]) as node) as sexpr).args) == 2);
- assert((*(((try(lex, [&parseSexpr]) as node) as sexpr).args[0]) as lit) == 1);
- assert((*(((try(lex, [&parseSexpr]) as node) as sexpr).args[1]) as lit) == 2);
+ let lex = lex::new(&memio::fixed(strings::toutf8("(foo 1 2)")));
+ let sexpr = try(lex, [&parseSexpr])! as sexpr;
+ assert(sexpr.func == "foo");
+ assert(len(sexpr.args) == 2);
};
@test
fn NoArgExpr() void = {
- let lex = &lex::new(&memio::fixed(strings::toutf8("(foo)")));
-
- assert(((try(lex, [&parseSexpr]) as node) as sexpr).func == "foo");
- assert(len(((try(lex, [&parseSexpr]) as node) as sexpr).args) == 0);
+ let lex = lex::new(&memio::fixed(strings::toutf8("(foo)")));
+ let sexpr = try(lex, [&parseSexpr])! as sexpr;
+ assert(sexpr.func == "foo");
+ assert(len(sexpr.args) == 0);
};
@test
fn ExprWithName() void = {
- let lex = &lex::new(&memio::fixed(strings::toutf8("(foo bar)")));
-
- assert(((try(lex, [&parseSexpr]) as node) as sexpr).func == "foo");
- assert(len(((try(lex, [&parseSexpr]) as node) as sexpr).args) == 1);
- assert((*(((try(lex, [&parseSexpr]) as node) as sexpr).args[0]) as name) == "bar");
+ let lex = lex::new(&memio::fixed(strings::toutf8("(foo bar)")));
+ let sexpr = try(lex, [&parseSexpr])! as sexpr;
+ assert(sexpr.func == "foo");
+ assert(len(sexpr.args) == 1);
};
@test
fn ExprWithNameAndNum() void = {
- let lex = &lex::new(&memio::fixed(strings::toutf8("(foo bar 1)")));
-
- assert(((try(lex, [&parseSexpr]) as node) as sexpr).func == "foo");
- assert(len(((try(lex, [&parseSexpr]) as node) as sexpr).args) == 2);
- assert((*(((try(lex, [&parseSexpr]) as node) as sexpr).args[0]) as name) == "bar");
- assert((*(((try(lex, [&parseSexpr]) as node) as sexpr).args[1]) as lit) == 1);
+ let lex = lex::new(&memio::fixed(strings::toutf8("(foo bar 1)")));
+ let sexpr = try(lex, [&parseSexpr])! as sexpr;
+ assert(sexpr.func == "foo");
+ assert(len(sexpr.args) == 2);
};
@test
fn NestedExpr() void = {
- let lex = &lex::new(&memio::fixed(strings::toutf8("(foo (bar 1))")));
-
- assert(((try(lex, [&parseSexpr]) as node) as sexpr).func == "foo");
- assert(len(((try(lex, [&parseSexpr]) as node) as sexpr).args) == 1);
- assert((*(((try(lex, [&parseSexpr]) as node) as sexpr).args[0]) as sexpr).func == "bar");
- assert(len((*(((try(lex, [&parseSexpr]) as node) as sexpr).args[0]) as sexpr).args) == 1);
- assert((*((*(((try(lex, [&parseSexpr]) as node) as sexpr).args[0]) as sexpr).args[0]) as lit) == 1);
+ let lex = lex::new(&memio::fixed(strings::toutf8("(foo (bar 1))")));
+ let sexpr = try(lex, [&parseSexpr])! as sexpr;
+ assert(sexpr.func == "foo");
+ assert(len(sexpr.args) == 1);
};
diff --git a/zpy/parse/error.ha b/zpy/parse/error.ha
@@ -0,0 +1,3 @@
+use zpy::lex;
+
+export type error = !(str, lex::pos);
diff --git a/zpy/parse/help.ha b/zpy/parse/help.ha
@@ -1,9 +1,14 @@
use zpy::lex;
+use fmt;
fn want(l: *lex::lexer, want: []lex::types) (lex::token | lex::error | error) = {
let n = lex::next(l)?;
+ fmt::print("\n", lex::strtypes(n.ty))!;
+
for (let ty .. want) {
- if (n.ty == ty) return n;
+ fmt::print(lex::strtypes(ty))!;
+ if (n.ty == ty)
+ return n;
};
- abort();
+ return ("Want failed", 0): error;
};
diff --git a/zpy/parse/parse.ha b/zpy/parse/parse.ha
@@ -3,16 +3,13 @@ use io;
use strconv;
use fmt;
-export type error = !int;
-
export type parserfn = fn(_: *lex::lexer) (node | error);
export fn try(l: *lex::lexer, fs: []*parserfn) (node | error) = {
let errors: []error = [];
+ let save = io::tell(l.in)!;
for (let f .. fs) {
- let save = io::tell(l.in)!;
-
return match (f(l)) {
case let n: node => return n;
case let e: error =>
@@ -22,15 +19,14 @@ export fn try(l: *lex::lexer, fs: []*parserfn) (node | error) = {
};
};
- abort();
+ return errors[0]; //("reached end of try block", 0);
};
export fn parseSexpr(l: *lex::lexer) (node | error) = {
match (want(l, [lex::types::OBRACE])) {
case lex::token => yield;
- case => abort();
+ case => return ("Want failed to read OBRACE", 0): error;
};
- fmt::println("got brace")!;
let name = try(l, [&parseName])?;
@@ -51,14 +47,14 @@ export fn parseSexpr(l: *lex::lexer) (node | error) = {
export fn parseName(l: *lex::lexer) (node | error) = {
match (want(l, [lex::types::NAME])) {
case let t: lex::token => return t.data;
- case => abort();
+ case => return ("Want failed to read name", 0): error;
};
};
export fn parseLit(l: *lex::lexer) (node | error) = {
match (want(l, [lex::types::NUM])) {
case let t: lex::token => return strconv::stou64(t.data)!;
- case => abort();
+ case => return ("Want failed to read number", 0): error;
};
};