parser: Merge the parser::end and parser::length fields

There is no need to have two fields, since it's length on input and
output. It just takes a bit of minor refactoring to cache some values
in cases where we used `p.length` after `p.end` had been written.

Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This commit is contained in:
Christophe de Dinechin 2024-06-30 23:34:47 +02:00
parent f3a3f95fbb
commit 1af3ae7f25
22 changed files with 49 additions and 51 deletions

View file

@ -115,7 +115,7 @@ PARSE_BODY(command)
return SKIP;
// Record output - Dynamically generate ID for use in programs
p.end = len;
p.length = len;
p.out = rt.make<command>(found);
return OK;

View file

@ -53,7 +53,7 @@ PARSE_BODY(comment)
size_t parsed = s - source;
size_t slen = parsed - 1;
gcutf8 txt = source + 1;
p.end = parsed;
p.length = parsed;
if (!remove)
p.out = rt.make<text>(ID_comment, txt, slen);

View file

@ -397,7 +397,7 @@ PARSE_BODY(rectangular)
algebraic_g im = algebraic_p(imobj);
p.out = rectangular::make(re, im);
p.end = offs;
p.length = offs;
return p.out ? OK : ERROR;
}
@ -430,7 +430,7 @@ PARSE_BODY(rectangular)
algebraic_g im = re ? +re : algebraic_p(integer::make(neg ? -1 : 1));
re = integer::make(0);
p.out = rectangular::make(re, im);
p.end = offs;
p.length = offs;
return p.out ? OK : ERROR;
}
algebraic_g im = imobj->as_algebraic();
@ -454,7 +454,7 @@ PARSE_BODY(rectangular)
im = neg::run(im);
p.out = rectangular::make(re, im);
p.end = offs;
p.length = offs;
return p.out ? OK : ERROR;
}
@ -640,7 +640,7 @@ PARSE_BODY(polar)
offs = utf8_next(p.source, offs, max);
p.out = polar::make(mod, im, unit);
p.end = offs;
p.length = offs;
return p.out ? OK : ERROR;
}

View file

@ -456,7 +456,7 @@ PARSE_BODY(CaseStatement)
size_t alloc = outer_scr.growth();
object_p prog = rt.make<program>(ID_block, scratch, alloc);
object_p cases = rt.make<CaseStatement>(prog, obj1);
p.end = parsed;
p.length = parsed;
p.out = cases;
return OK;

View file

@ -420,7 +420,7 @@ object::result constant::do_parsing(config_r cfg, parser &p)
size_t len = parsed - first;
constant_p cst = do_lookup(cfg, source + first, len, true);
p.end = parsed;
p.length = parsed;
p.out = cst;
return cst ? OK : ERROR;
}

View file

@ -283,8 +283,8 @@ PARSE_BODY(decimal)
// Success: build the resulting number
gcp<kint> kigits = rb;
size_t nkigs = rs;
p.end = +s - +source;
p.out = rt.make<decimal>(type, exponent, nkigs, kigits);
p.length = +s - +source;
p.out = rt.make<decimal>(type, exponent, nkigs, kigits);
return p.out ? OK : ERROR;
}

View file

@ -2245,7 +2245,7 @@ PARSE_BODY(funcall)
object_g obj = child.out;
if (!obj)
return ERROR;
parsed += child.end;
parsed += child.length;
size_t objsize = obj->size();
if (expression_p eq = obj->as<expression>())
@ -2282,7 +2282,7 @@ PARSE_BODY(funcall)
// Create the function call object
gcbytes scratch = scr.scratch();
size_t alloc = scr.growth();
p.end = parsed;
p.length = parsed;
p.out = rt.make<funcall>(ID_funcall, scratch, alloc);
return p.out ? OK : ERROR;
}

View file

@ -154,8 +154,8 @@ PARSE_BODY(grob)
if (grob)
bitflip(d0, w, h, true);
p.end = s - cstring(src);
p.out = +g;
p.length = s - cstring(src);
p.out = +g;
return OK;
}

View file

@ -150,7 +150,7 @@ PARSE_BODY(hwfp_base)
// Convert to floating point
cstring src = cstring(scr.scratch());
p.end = +s - +source;
p.length = +s - +source;
if (prec > 7)
{
double fp = std::strtod(src, nullptr);

View file

@ -527,7 +527,7 @@ PARSE_BODY(integer)
}
// Record output
p.end = (utf8) s - (utf8) p.source;
p.length = (utf8) s - (utf8) p.source;
p.out = number;
return OK;

View file

@ -166,16 +166,16 @@ object::result list::list_parse(id type,
if (obj->as_quoted<symbol>() == nullptr)
{
rt.missing_variable_error()
.source(+s+1, child.end-2);
.source(+s+1, child.length-2);
return ERROR;
}
}
}
s = s + child.end;
s = s + child.length;
record(list_parse,
"Child parsed as %t length %u",
object_p(obj), child.end);
object_p(obj), child.length);
precedence = -precedence; // Stay in postfix mode
cp = utf8_codepoint(s);
length = 0;
@ -420,8 +420,8 @@ object::result list::list_parse(id type,
}
// Create the object
p.end = parsed;
p.out = rt.make<list>(type, scratch, alloc);
p.length = parsed;
p.out = rt.make<list>(type, scratch, alloc);
record(list_parse, "Parsed as %t length %u", object_p(p.out), parsed);

View file

@ -179,7 +179,8 @@ PARSE_BODY(locals)
p.out = rt.make<locals>(ID_locals, scratch, alloc);
// Adjust size of parsed text for what we parsed before program
p.end += decls;
p.source += -decls;
p.length += decls;
return OK;
}
@ -307,9 +308,9 @@ PARSE_BODY(local)
if (nlen == len && symbol::compare(+names, source, nlen) == 0)
{
// Found a local name, return it
gcutf8 text = source;
p.end = len;
p.out = rt.make<local>(ID_local, index);
gcutf8 text = source;
p.length = len;
p.out = rt.make<local>(ID_local, index);
return OK;
}
names += nlen;

View file

@ -302,7 +302,7 @@ object::result loop::object_parser(parser &p,
}
size_t parsed = utf8(src) - utf8(p.source);
p.end = parsed;
p.length = parsed;
p.out =
name
? rt.make<ForNext>(type, obj2, name)

View file

@ -240,7 +240,7 @@ retry:
break;
if (r == COMMENTED)
{
size_t commented = p.end;
size_t commented = p.length;
if (commented >= length)
return nullptr;
length -= commented;
@ -349,15 +349,15 @@ retry:
// Compute output size
record(parse, "<Done parsing [%s], end is at %d", utf8(p.source), p.end);
size = p.end + skipped;
record(parse, "<Done parsing [%s], end is at %d", utf8(p.source), p.length);
size = p.length + skipped;
// Check if there is a second part to the object
if (r == OK && p.out && p.end < length &&
if (r == OK && p.out && p.length < length &&
cp != complex::I_MARK && cp != complex::ANGLE_MARK)
{
result r2 = SKIP;
cp = utf8_codepoint(p.source + p.end);
cp = utf8_codepoint(p.source + p.length);
bool maybe_rect =
(precedence < ADDITIVE && (cp == '+' || cp == '-')) ||
@ -370,10 +370,10 @@ retry:
{
if (p.out->is_algebraic())
{
length -= p.end;
size_t parsed = p.length;
length -= parsed;
p.length = length;
p.source += p.end;
p.end = 0;
p.source += parsed;
if (maybe_rect)
r2 = rectangular::do_parse(p);
@ -386,7 +386,7 @@ retry:
// Check if we found the second part
if (r2 == OK)
size += p.end;
size += p.length;
}
}
}

View file

@ -40,21 +40,19 @@ struct parser
typedef object::id id;
parser(utf8 source, size_t length, int precedence = 0)
: source(source), length(length),
end(), out(nullptr),
: source(source), length(length), out(nullptr),
precedence(precedence)
{}
parser(const parser &from, utf8 source, int precedence)
: source(source),
length(from.length - (+source - +from.source)),
end(), out(nullptr),
out(nullptr),
precedence(precedence) {}
public:
gcutf8 source; // Text to parse
size_t length; // Length to parse -> length parsed
size_t end; // End position after parsing
object_g out; // Output object if any
int precedence; // Precedence level in equations
};

View file

@ -1104,7 +1104,6 @@ PARSE_BODY(polynomial)
p.precedence = 0;
p.source = +p.source - parsed;
p.length += parsed;
p.end += parsed;
if (result != OK)
return result;
@ -1119,7 +1118,7 @@ PARSE_BODY(polynomial)
}
}
}
rt.invalid_polynomial_error().source(p.source, p.end);
rt.invalid_polynomial_error().source(p.source, p.length);
return ERROR;
}

View file

@ -82,7 +82,7 @@ program_p program::parse(utf8 source, size_t size)
parser p(source, size);
result r = list_parse(ID_program, p, 0, 0);
record(program, "<Command line [%s], end at %u, result %p",
utf8(p.source), p.end, object_p(p.out));
utf8(p.source), p.length, object_p(p.out));
if (r != OK)
return nullptr;
object_p obj = p.out;

View file

@ -93,8 +93,8 @@ PARSE_BODY(symbol)
// Build the resulting symbol
gcutf8 text = source;
p.end = parsed;
p.out = rt.make<symbol>(ID_symbol, text, parsed);
p.length = parsed;
p.out = rt.make<symbol>(ID_symbol, text, parsed);
return OK;
}

View file

@ -91,8 +91,8 @@ PARSE_BODY(tag)
return ERROR;
}
p.end = parsed + remaining;
p.out = rt.make<tag>(ID_tag, lbl, llen, obj);
p.length = parsed + remaining;
p.out = rt.make<tag>(ID_tag, lbl, llen, obj);
return p.out ? OK : ERROR;
}

View file

@ -88,7 +88,7 @@ PARSE_BODY(text)
size_t parsed = s - source;
size_t slen = parsed - 2;
gcutf8 txt = source + 1;
p.end = parsed;
p.length = parsed;
p.out = rt.make<text>(ID_text, txt, slen, quotes);
return p.out ? OK : ERROR;

View file

@ -78,8 +78,8 @@ PARSE_BODY(unit)
return SKIP;
offs += usz;
p.out = unit::simple(uval, uexpr);
p.end = offs;
p.out = unit::simple(uval, uexpr);
p.length = offs;
return p.out ? OK : ERROR;
}

View file

@ -102,8 +102,8 @@ PARSE_BODY(directory)
}
// If we passed all these tests, build a directory
p.out = rt.make<directory>(ID_directory, start, size);
p.end = maxlen + len;
p.out = rt.make<directory>(ID_directory, start, size);
p.length = maxlen + len;
return OK;
}
}