Skip to content

Instantly share code, notes, and snippets.

@nicklockwood
Last active August 29, 2019 19:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicklockwood/550792a453b1fcd77548572440e838ad to your computer and use it in GitHub Desktop.
Save nicklockwood/550792a453b1fcd77548572440e838ad to your computer and use it in GitHub Desktop.

A very basic JSON parser, written in [new language]. Only supports String, Int and Array so far.

json := "[42, \"hello\", [\"good\", \"bye\"]]"

JSON = String|Int|[JSON] // TODO: true, false, null, object

skipSpace(json: String) String {
    input := json
    while input.first == " " {
        input = input.removingFirst
    }
    return input
}

readChar(json: String, char: String) String|Void {
    if c := json.first, c == char {
        return json.removingFirst
    }
    return null
}

readChars(json: String, chars: [String]) (String, String) {
    input := json
    output := ""
    while c := input.first, chars.contains(c) {
        output = output + c
        input = input.removingFirst
    }
    return (input, output)
}

readUpTo(json: String, char: String) (String, String) {
    input := json
    output := ""
    while c := input.first, c != char {
        output = output + c
        input = input.removingFirst
    }
    return (input, output)
}

readValue(json: String) (String, JSON)|Void {
    input := json
    input = skipSpace(input)
    match c in input.first {
    "0" ... "9":
        result := input.readChars("0" ... "9")
        return (result.0, result.1.toInt)
    "\"":
        input = input.removingFirst
        result := input.readUpTo("\"")
        input = result.0
        if input := input.readChar("\"") {
            return (input, result.1)
        }
    "[":
        input = input.removingFirst
        values: [JSON] = []
        while result := input.readValue {
            input = result.0
            values = values.append(result.1)
            if i := input.readChar(",") {
                input = i
            } else {
                break
            }
        }
        if input := input.readChar("]") {
            return (input, values)
        }
    }
    return null
}

parseJSON(json: String) JSON {
    if json := readValue(json) {
        return json.1
    }
    return []
}

return parseJSON(json)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment