~mrms/jsonum

13f001dd08cf21ee3f5ace2f248584e11bbd20a9 — Marek Maškarinec 9 months ago 94d8aa4
Improve error handling
2 files changed, 25 insertions(+), 9 deletions(-)

M box.json
M json.um
M box.json => box.json +4 -4
@@ 1,13 1,13 @@
{
    "name": "json",
    "version": "v0.1.0",
    "version": "v1.0.0",
    "author": "Marek Maškarinec <marek@mrms.cz>",
    "license": "Unlicense/MIT",
    "description": "JSON decoder library",
    "readme": "README.md",
    "link": "",
    "link": "https://git.sr.ht/~mrms/jsonum",
    "dependencies": [],
    "include": ["json.um"],
    "run_posix": "./pak/umka/linux/umka json.um",
    "run_windows": ".\\pak\\umka\\windows\\umka.exe json.um"
    "run_posix": "./umbox/umka/linux/umka json.um",
    "run_windows": ".\\umbox\\umka\\windows\\umka.exe json.um"
}

M json.um => json.um +21 -5
@@ 17,11 17,17 @@ const (
	tok_lcloser
)

type Error* = struct {
	message: str
	lno: int
}

type lexer = struct {
	inp: str
	len: int
	pos: int
	lineno: int
	errors: []Error
}

type token = struct {


@@ 132,7 138,7 @@ fn (l: ^lexer) lex_next(): (token, bool) {
}

fn (l: ^lexer) parser_error(msg: str) {
	printf("error %d:%d: %s\n", l.lineno, msg)
	l.errors = append(l.errors, Error{msg, l.lineno})
}

fn (l: ^lexer) parse_object(): map[str]any


@@ 158,7 164,7 @@ fn (l: ^lexer) parse_val(t: token): any {
		} else if t.value == "null" {
			return null
		} else {
			l.parser_error("unknonw constant")
			l.parser_error("unknown constant")
		}
	default:
		l.parser_error("unsupported json feature")


@@ 188,7 194,7 @@ fn (l: ^lexer) parse_object(): map[str]any {
			next, stay = l.lex_next()

			if stay && next.t != tok_separator && next.t != tok_closer {
				l.parser_error("missing comma.")
				l.parser_error("missing comma")
			}

			out[key] = val


@@ 226,10 232,11 @@ fn (l: ^lexer) parse_array(): []any {
}

//~~fn parse
// parses json provided as an input and returns either map[str]any or []any
// Parses the JSON from the `inp` string. On success, returns either a
// `[]any` or `map[str]any`. On error, returns `[]Error`.
fn parse*(inp: str): any {
//~~
	l := lexer{inp, len(inp), 0, 1}
	l := lexer{inp, len(inp), 0, 1, {}}

	t, end := l.lex_next()
	var out: any


@@ 243,5 250,14 @@ fn parse*(inp: str): any {
		l.parser_error("top level type can only be an object or an array")
	}

	if len(l.errors) > 0 {
		return l.errors
	}

	return out
}

fn main() {
	printf("%v\n", parse("{ \"a\": 1.2, \"b\": 34 }"))
	printf("%v\n", parse("{ \"a\": 1.2 \"b\": 34 }"))
}