Files
Noja/examples/json.noja
T
2022-04-02 23:07:37 +02:00

95 lines
1.7 KiB
Plaintext

fun is_space(c)
return c == ' '
or c == '\t'
or c == '\n';
fun is_digit(c)
return unicode(c) <= unicode('9')
and unicode(c) >= unicode('0');
fun skip(ctx, test)
while not ended(ctx): {
if not test(current(ctx)):
break;
next(ctx);
}
fun ended(ctx)
return ctx.i == count(ctx.str);
fun next(ctx) {
assert(ctx.i < count(ctx.str));
ctx.i = ctx.i + 1;
}
fun current(ctx) {
assert(ctx.i < count(ctx.str));
return ctx.str[ctx.i];
}
fun parse(str) {
if str == none:
str = '';
ctx = {str: str, i: 0};
skip(ctx, is_space);
if ended(ctx): {
print('Source only contains whitespace');
return none;
}
return parse_any_value(ctx);
}
fun parse_any_value(ctx) {
if is_digit(current(ctx)): {
# Number (int or float)
parsed = 0;
while not ended(ctx) and is_digit(current(ctx)): {
parsed = parsed * 10 + unicode(current(ctx)) - unicode('0');
next(ctx);
}
if current(ctx) == '.': {
next(ctx);
if ended(ctx):
# Source string ended unexpectedly after dot.
return none;
if not is_digit(current(ctx)):
# Got something other than a digit after dot.
return none;
fact = 1;
while not ended(ctx) and is_digit(current(ctx)): {
fact = fact / 10.0;
parsed = parsed + fact * (unicode(current(ctx)) - unicode('0'));
next(ctx);
}
}
return parsed;
}
assert(false);
}
tests = [
'',
'1'
];
i = 0;
while i < count(tests): {
parse(tests[i]);
i = i + 1;
}