summaryrefslogtreecommitdiff
path: root/internal/parser/parser.ha
diff options
context:
space:
mode:
authorJulian Hurst <ark@mansus.space>2026-03-29 23:45:16 +0200
committerJulian Hurst <ark@mansus.space>2026-03-29 23:45:16 +0200
commit4088afafe7599772703c8df25ad8ed55f7197fd7 (patch)
tree5d3bcc892c1a00f32c77ac4d0290fe1fced394cc /internal/parser/parser.ha
parent678a38d41ba21c260ee74e1dbc516c6f5fe7222d (diff)
downloadrabbitscript-4088afafe7599772703c8df25ad8ed55f7197fd7.tar.gz
Support string literal variables (with string interpolation)mistress
Diffstat (limited to 'internal/parser/parser.ha')
-rw-r--r--internal/parser/parser.ha47
1 files changed, 39 insertions, 8 deletions
diff --git a/internal/parser/parser.ha b/internal/parser/parser.ha
index 55b143e..0276dd6 100644
--- a/internal/parser/parser.ha
+++ b/internal/parser/parser.ha
@@ -12,13 +12,15 @@ use fmt;
// value: str,
//};
-export type token = (varname | finvoke | assign | operation | arglist);
+export type token = (varname | finvoke | assign | operation | strlit | arglist);
export type finvoke = rune;
export type assign = rune;
export type varname = str;
+export type strlit = str;
+
export type argument = (int | operator);
export type operator = enum {
ADD,
@@ -135,6 +137,7 @@ fn parsetil(
til: (rune | []rune),
cond: (void | validrunecond),
runecount: size,
+ unread: bool = true,
)
(str | io::EOF | error) = {
let m = memio::dynamic();
@@ -152,7 +155,9 @@ fn parsetil(
yield runeisin(r, ru);
};
if (ismatch) {
- unreadrune(p, r);
+ if (unread) {
+ unreadrune(p, r);
+ };
let s = strings::trim(memio::string(&m)?);
break strings::dup(s)?;
};
@@ -338,6 +343,7 @@ export fn parse(p: *parser) (ast | done | error) = {
case io::EOF =>
return done;
case let t: varname =>
+ fmt::errorln("parsed varname")!;
let node: ast = ast {
value = t,
children = [],
@@ -354,6 +360,13 @@ export fn parse(p: *parser) (ast | done | error) = {
};
append(tree, node)?;
stop = true;
+ case let t: strlit =>
+ let node: ast = ast {
+ value = t,
+ children = [],
+ };
+ append(tree, node)?;
+ stop = true;
case let t: arglist =>
let node: ast = ast {
value = t,
@@ -377,6 +390,7 @@ export fn parsetoken(p: *parser) (token | io::EOF | error) = {
case tokentype::START =>
// VARNAME
//let t = parsevarname(p, 0z)?;
+ fmt::errorln("parsevarname")!;
const cond = validrunecond {
f = &isalnum: validrunecondfn,
err = "Character is not alphanumeric",
@@ -387,7 +401,7 @@ export fn parsetoken(p: *parser) (token | io::EOF | error) = {
return io::EOF;
case let t: str =>
p.state = tokentype::VARNAME;
- yield t;
+ yield t: varname;
};
case tokentype::VARNAME =>
// look for ASSIGN
@@ -413,11 +427,28 @@ export fn parsetoken(p: *parser) (token | io::EOF | error) = {
p.state = tokentype::START;
yield t;
case tokentype::ASSIGN =>
- // look for OPERATION
- fmt::errorln("parseoperation")!;
- let t = parseoperation(p, 0z)?;
- p.state = tokentype::START;
- yield t;
+ // look for OPERATION or STRINGLIT
+ yield match (read_rune(p)?) {
+ case let r: rune =>
+ yield if (r == '"') {
+ fmt::errorln("parsestringlit")!;
+ yield match (parsetil(p, '"', void, 0z, false)?) {
+ case io::EOF =>
+ return io::EOF;
+ case let t: str =>
+ p.state = tokentype::START;
+ yield t: strlit;
+ };
+ } else {
+ unreadrune(p, r);
+ fmt::errorln("parseoperation")!;
+ let t = parseoperation(p, 0z)?;
+ p.state = tokentype::START;
+ yield t;
+ };
+ case io::EOF =>
+ yield (runecount, p.currentline, "Unexpected EOF"): error;
+ };
case =>
yield (runecount, p.currentline, "Not implemented"): error;
};