commit 4efce2e290a7d42d0a4eb1c3b50460af1e3cc8e6
parent 50333fa221b728256102c0ff3ef7a93166e53841
Author: thing1 <thing1@seacrossedlovers.xyz>
Date: Wed, 13 May 2026 10:08:08 +0100
got a working parser/lexer
breaks when linked with libc???
Diffstat:
4 files changed, 81 insertions(+), 39 deletions(-)
diff --git a/zpy/lex/lexer.ha b/zpy/lex/lexer.ha
@@ -30,7 +30,6 @@ fn getItem(l: *lexer, ty: types) lexItem = {
for (let item .. l.items) {
if (item.ty == ty) return item;
};
- fmt::println(ty: int)!;
abort();
};
diff --git a/zpy/parse/+test.ha b/zpy/parse/+test.ha
@@ -1,6 +1,7 @@
use zpy::lex;
use memio;
use strings;
+use fmt;
fn equalNodes(n1: node, n2: node) bool = {
match (n1) {
@@ -11,7 +12,7 @@ fn equalNodes(n1: node, n2: node) bool = {
return false;
for (let i = 0z; i < len (n1.args); i+=1) {
- if (!equalNodes(*n1.args[i], *(n2 as sexpr).args[i]))
+ if (!equalNodes(n1.args[i], (n2 as sexpr).args[i]))
return false;
};
@@ -38,56 +39,98 @@ fn BinaryExpr() void = {
let lex = lex::new(&memio::fixed(strings::toutf8("(foo 1 2)")));
let s = try(lex, [&parseSexpr])! as sexpr;
- assert(s.func == "foo");
- assert(len(s.args) == 2);
- assert(*s.args[0] == 1);
- assert(*s.args[1] == 2);
-
- //if (!equalNodes(s, sexpr{
- // func = "foo",
- // args = [
- // &1: *node,
- // &2: *node
- // ]
- //})) abort();
+ if (!equalNodes(s, sexpr{
+ func = "foo",
+ args = [
+ 1: node,
+ 2: node
+ ]
+ })) abort();
};
@test
fn NoArgExpr() void = {
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);
+ let s = try(lex, [&parseSexpr])! as sexpr;
+
+ if (!equalNodes(s, sexpr{
+ func = "foo",
+ args = []
+ })) abort();
+
};
@test
fn ExprWithName() void = {
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);
+ let s = try(lex, [&parseSexpr])! as sexpr;
+
+ if (!equalNodes(s, sexpr{
+ func = "foo",
+ args = [
+ "bar": node
+ ]
+ })) abort();
};
@test
fn ExprWithNameAndNum() void = {
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);
+ let s = try(lex, [&parseSexpr])! as sexpr;
+
+ if (!equalNodes(s, sexpr{
+ func = "foo",
+ args = [
+ "bar": node,
+ 1: node
+ ]
+ })) abort();
+
};
@test
fn NestedExpr() void = {
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);
+ let s = try(lex, [&parseSexpr])! as sexpr;
+
+ if (!equalNodes(s, sexpr{
+ func = "foo",
+ args = [
+ sexpr{
+ func = "bar",
+ args = [
+ 1: node
+ ]
+ }
+ ]
+ })) abort();
};
@test
fn DeeplyNestedExpr() void = {
let lex = lex::new(&memio::fixed(strings::toutf8("(foo (bar (baz (boo 1))) 42)")));
- let sexpr = try(lex, [&parseSexpr])! as sexpr;
- assert(sexpr.func == "foo");
- assert(len(sexpr.args) == 2);
+ let s = try(lex, [&parseSexpr])! as sexpr;
+
+ if (!equalNodes(s, sexpr{
+ func = "foo",
+ args = [
+ sexpr{
+ func = "bar",
+ args = [
+ sexpr{
+ func = "baz",
+ args = [
+ sexpr{
+ func = "boo",
+ args = [
+ 1: node
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ 42: node
+ ]
+ })) abort();
};
diff --git a/zpy/parse/ast.ha b/zpy/parse/ast.ha
@@ -2,7 +2,7 @@ export type node = (sexpr | lit | name);
export type sexpr = struct {
func: str,
- args: []*node
+ args: []node
};
export type lit = u64;
diff --git a/zpy/parse/parse.ha b/zpy/parse/parse.ha
@@ -3,8 +3,7 @@ use io;
use strconv;
use fmt;
use bufio;
-
-// TODO put nodes on the heap, as pointers fuck this all up
+use strings;
export type parserfn = fn(_: *lex::lexer) (node | error);
@@ -30,15 +29,18 @@ export fn parseSexpr(l: *lex::lexer) (node | error) = {
let name = try(l, [&parseName])?;
- let args: []*node = [];
+ let args: []node = [];
for (true) {
match (try(l, [&parseSexpr, &parseName, &parseLit])) {
case let n: node =>
- append(args, &n)!;
+ append(args, n)!;
case let e: error =>
match (want(l, [lex::types::CBRACE])) {
- case lex::token => return sexpr{func = name: str, args = args};
+ case lex::token => return sexpr{
+ func = name: str,
+ args = args
+ }: node;
case => return e;
};
};
@@ -47,16 +49,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 let t: lex::token => return t.data: node;
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 let t: lex::token => return strconv::stou64(t.data)!: node;
case => return ("Want failed to read number", 0): error;
};
};
-
-