hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 5e8b42336bdb6196dcac7ba5facf4a4fb1f98c88
parent c9a7e680b20833937ad85a6dc3e020ffdbcf0067
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Fri, 28 May 2021 11:45:06 -0400

lex::prevloc: add

Signed-off-by: Eyal Sawady <ecs@d2evs.net>

Diffstat:
Mhare/lex/lex.ha | 23+++++++++++++++++++++++
1 file changed, 23 insertions(+), 0 deletions(-)

diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha @@ -15,6 +15,9 @@ export type lexer = struct { loc: (uint, uint), un: (token | void), rb: [2]((rune, location) | io::EOF | void), + // 1 more than the size of un and rb respectively + prevunlocs: [2](location, location), + prevrlocs: [3]location, flags: flags, comment: str, }; @@ -47,12 +50,15 @@ export fn init(in: *io::stream, path: str, flags: flags...) lexer = { for (let i = 0z; i < len(flags); i += 1) { f |= flags[i]; }; + const loc = location { path = path, line = 1, col = 1 }; return lexer { in = in, path = path, loc = (1, 1), un = void, rb = [void...], + prevunlocs = [(loc, loc)...], + prevrlocs = [loc...], flags = f, comment = "", }; @@ -72,6 +78,11 @@ export fn lex(lex: *lexer) (token | error) = { void => void, }; + defer { + lex.prevunlocs[1] = lex.prevunlocs[0]; + lex.prevunlocs[0] = (prevloc(lex), mkloc(lex)); + }; + let r = match (nextw(lex)?) { io::EOF => return (ltok::EOF, void, mkloc(lex)), r: (rune, location) => r, @@ -623,6 +634,9 @@ fn next(lex: *lexer) ((rune, location) | io::EOF | io::error) = { e: (io::EOF | io::error) => e, r: rune => { const loc = mkloc(lex); + let tmp = lex.prevrlocs; + lex.prevrlocs[1..] = tmp[..len(tmp) - 1]; + lex.prevrlocs[0] = loc; lexloc(lex, r); return (r, loc); }, @@ -684,4 +698,13 @@ export fn mkloc(lex: *lexer) location = match (lex.rb[0]) { }, }; +export fn prevloc(lex: *lexer) location = match (lex.un) { + t: token => lex.prevunlocs[1].0, + void => { + let i = 0z; + for (i < len(lex.rb); i += 1) if (lex.rb[i] is void) break; + return lex.prevrlocs[i]; + }, +}; + fn syntaxerr(loc: location, why: str) error = (loc, why);