hare

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

commit 721d50d0e16b9b46cb6dc1780208b38825edbb28
parent 2ebce28013663797152aa8b9238ef8cd4487d25a
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Fri, 28 May 2021 11:45:09 -0400

hare::lex: add mkloc/prevloc tests

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

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

diff --git a/hare/lex/+test.ha b/hare/lex/+test.ha @@ -276,3 +276,89 @@ fn loc(line: uint, col: uint) location = location { ]; lextest(in, expected); }; + +// Small virtual machine for testing mkloc/prevloc. +// NEXT, UNGET, LEX, and UNLEX call the obvious functions (with UNGET and UNLEX +// pulling from a buffer that NEXT/LEX feed into). +// After each instruction, the results of mkloc/prevloc are checked against the +// next element of the test vector. +type op = enum { + LEX, + NEXT, + UNGET, + UNLEX, +}; + +@test fn loc() void = { + const src = "h ello: my name is Inigo Montoya"; + let buf = bufio::fixed(strings::toutf8(src), mode::READ); + defer io::close(buf); + let lexer = init(buf, "<test>"); + const ops: [_]op = [ + op::NEXT, + op::NEXT, + op::NEXT, + op::UNGET, + op::UNGET, + op::NEXT, + op::NEXT, + op::LEX, + op::LEX, + op::UNLEX, + op::LEX, + op::LEX, + op::UNLEX, + op::LEX, + op::LEX, + op::LEX, + op::LEX, + ]; + const vector: [_](location, location) = [ + (loc(1, 2), loc(1, 1)), + (loc(1, 3), loc(1, 2)), + (loc(1, 9), loc(1, 3)), + (loc(1, 3), loc(1, 2)), + (loc(1, 2), loc(1, 1)), + (loc(1, 3), loc(1, 2)), + (loc(1, 9), loc(1, 3)), + (loc(1, 13), loc(1, 12)), + (loc(1, 14), loc(1, 13)), + (loc(1, 13), loc(1, 12)), + (loc(1, 14), loc(1, 13)), + (loc(1, 17), loc(1, 16)), + (loc(1, 14), loc(1, 13)), + (loc(1, 17), loc(1, 16)), + (loc(1, 29), loc(1, 28)), + (loc(1, 32), loc(1, 31)), + (loc(1, 38), loc(1, 37)), + ]; + + // We could statically allocate r and t, but what's the point + let r: [](rune, location) = []; + defer free(r); + let t: []token = []; + defer free(t); + for (let i = 0z; i < len(ops); i += 1) { + switch (ops[i]) { + op::LEX => append(t, lex(&lexer)!), + op::NEXT => append(r, next(&lexer) as (rune, location)), + op::UNGET => { + unget(&lexer, r[len(r) - 1]); + delete(r[len(r) - 1]); + }, + op::UNLEX => { + unlex(&lexer, t[len(t) - 1]); + delete(t[len(t) - 1]); + }, + }; + let loc = mkloc(&lexer); + let ploc = prevloc(&lexer); + // TODO: Aggregate equality + assert(loc.path == vector[i].0.path + && loc.line == vector[i].0.line + && loc.col == vector[i].0.col); + assert(ploc.path == vector[i].1.path + && ploc.line == vector[i].1.line + && ploc.col == vector[i].1.col); + }; +};