diff options
| author | Julian Hurst <ark@mansus.space> | 2026-03-29 23:45:16 +0200 |
|---|---|---|
| committer | Julian Hurst <ark@mansus.space> | 2026-03-29 23:45:16 +0200 |
| commit | 4088afafe7599772703c8df25ad8ed55f7197fd7 (patch) | |
| tree | 5d3bcc892c1a00f32c77ac4d0290fe1fced394cc | |
| parent | 678a38d41ba21c260ee74e1dbc516c6f5fe7222d (diff) | |
| download | rabbitscript-mistress.tar.gz | |
Support string literal variables (with string interpolation)mistress
| -rw-r--r-- | cmd/hs/hs.ha | 1 | ||||
| -rw-r--r-- | internal/interpreter/interpreter.ha | 16 | ||||
| -rw-r--r-- | internal/parser/parser.ha | 47 | ||||
| -rw-r--r-- | test.ra | 2 |
4 files changed, 53 insertions, 13 deletions
diff --git a/cmd/hs/hs.ha b/cmd/hs/hs.ha index 233c54f..4efae44 100644 --- a/cmd/hs/hs.ha +++ b/cmd/hs/hs.ha @@ -25,7 +25,6 @@ export fn main() void = { case let a: parser::ast => yield a; case let e: parser::error => - fmt::println("poopies")!; fmt::fatal(parser::strerror(e)); }; interpreter::interpret(&it, ast); diff --git a/internal/interpreter/interpreter.ha b/internal/interpreter/interpreter.ha index 947dc8f..24f6f01 100644 --- a/internal/interpreter/interpreter.ha +++ b/internal/interpreter/interpreter.ha @@ -77,10 +77,7 @@ fn replacevars(it: *interpreter, s: str) str = { return sa; }; -fn assign(it: *interpreter, nodes: []parser::ast) (void | error) = { - const varname = nodes[0].value as parser::varname; - const operation = nodes[1].value as parser::operation; - +fn assignop(it: *interpreter, nodes: []parser::ast, varname: parser::varname, operation: parser::operation) (void | error) = { let value = 0; let stack: []int = []; @@ -114,3 +111,14 @@ fn assign(it: *interpreter, nodes: []parser::ast) (void | error) = { let last = len(stack) - 1; append(it.vars, (varname, strings::dup(strconv::itos(stack[last]))?))?; }; + +fn assign(it: *interpreter, nodes: []parser::ast) (void | error) = { + const varname = nodes[0].value as parser::varname; + const operation = match (nodes[1].value) { + case let op: parser::operation => + return assignop(it, nodes, varname, op); + case let s: parser::strlit => + let sa = replacevars(it, s); + append(it.vars, (varname, sa))?; + }; +}; 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; }; @@ -1,8 +1,10 @@ a=2 1 + 6 * b=3 5 * +c="string literal ${a}" ls() print("hello world!") print("(2 + 1) * 6 = ${a}") print("3 * 5 = ${b}") +print("strlit in var c is: ${c}") mpv("--shuffle", "/home/juju/vids/Simpsons") |
