{"id":14566371,"url":"https://github.com/mignon-p/json65","last_synced_at":"2025-08-20T12:31:35.217Z","repository":{"id":141895726,"uuid":"145919981","full_name":"mignon-p/json65","owner":"mignon-p","description":"A JSON parser written in 6502 assembly language.","archived":false,"fork":false,"pushed_at":"2021-03-04T07:08:53.000Z","size":169,"stargazers_count":242,"open_issues_count":0,"forks_count":6,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-12-09T02:38:50.545Z","etag":null,"topics":["6502","6502-assembly","json","retrocomputing"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"zlib","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mignon-p.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-08-24T00:01:15.000Z","updated_at":"2024-11-24T12:54:30.000Z","dependencies_parsed_at":"2023-03-13T10:27:54.426Z","dependency_job_id":null,"html_url":"https://github.com/mignon-p/json65","commit_stats":null,"previous_names":["mignon-p/json65","ppelleti/json65"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mignon-p%2Fjson65","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mignon-p%2Fjson65/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mignon-p%2Fjson65/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mignon-p%2Fjson65/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mignon-p","download_url":"https://codeload.github.com/mignon-p/json65/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230423563,"owners_count":18223435,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["6502","6502-assembly","json","retrocomputing"],"created_at":"2024-09-07T05:00:35.201Z","updated_at":"2024-12-19T11:12:14.863Z","avatar_url":"https://github.com/mignon-p.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"I was watching TV, and there was a commercial which proclaimed, \"It's\ntime to do what *you* want!\"  I replied to the TV, \"It's time to write\na JSON parser in 6502 assembly language?\"  Somehow I don't think\nthat's what they had in mind, but the TV is right, I *should* do what\nI want.\n\nSo, here is my JSON parser.  The core parser is written entirely in\n6502 assembly language, and is meant to be assembled with [ca65][1].\nHowever, it is meant to be called from C, and uses the\n[cc65 calling convention][2] (specifically, the `fastcall` convention).\n\nJSON65 should work on any processor in the 6502 family.  (It does not\nuse any 65C02 instructions.)\n\nThe assembly language parts of JSON65 use the zero page locations used\nby `cc65`, in a way which is compatible with the C calling convention.\n\nJSON65 should work on any target supported by the `cc65` toolchain.  I\nhave tested it on `sim65` and on an unenhanced Apple //e.\n\n## Parser (json65.h)\n\nJSON65 is an event-driven (SAX-style) parser, so the parser is given a\ncallback function, which it calls for each event.\n\nJSON65 supports incremental parsing, so you can freely feed it any\nsized chunks of input, and you don't need to have the whole file in\nmemory at once.\n\nJSON65 is fully reentrant, so you can incrementally parse several\nfiles at once if you so desire.\n\nJSON65 does have a couple of limits: strings are limited to 255 bytes,\nand the nesting depth (of nested arrays or objects) is limited to 224.\nHowever, there is no limit on the length of a line, or the length of a\nfile.\n\nJSON65 uses 512 bytes of memory for each parser, which must be\nallocated by the caller.  JSON65 does not use dynamic memory\nallocation.\n\nIn accordance with the [JSON specification][3], JSON65 assumes its\ninput is UTF-8 encoded.  However JSON65 does not validate the UTF-8,\nso any encoding can be used, as long as all bytes with the high bit\nclear represent ASCII characters.  Bytes with the high bit set are\nonly allowed inside strings.  The only place where JSON65 assumes\nUTF-8 is in the processing of `\\u` escape sequences.  In accordance\nwith the JSON specification, a single `\\u` escape can be used to\nspecify code points in the Basic Multilingual Plane, and two\nconsecutive `\\u` escapes (a UTF-16 surrogate pair) can be used to\nspecify a code point outside the Basic Multilingual Plane.  These\nescapes will be translated into the proper UTF-8.\n\nBecause JSON only allows newlines in places where arbitrary whitespace\nis allowed, JSON65 is agnostic to the type of line ending.  (CR, LF,\nor CRLF.)  For the purposes of counting line numbers for error\nreporting, JSON65 handles CR, LF, or CRLF line endings.\n\nJSON65 will parse numbers which fit into a 32-bit signed long, and\nwill provide the long to the callback.  All other numbers\n(i. e. floating point numbers, or integers which overflow a 32-bit\nlong) are provided to the callback as a string.  (Like strings,\nnumbers cannot be more than 255 digits long.)\n\nThe callback function may return an error if it wishes.  This will\ncause parsing to stop immediately, and the error code returned by the\ncallback will be returned by `j65_parse()`.  Error codes are negative\nnumbers, and the user may use the codes from `J65_USER_ERROR` to\n`-1`, inclusive, for their own error codes.\n\n## Tree interface (json65-tree.h)\n\nIf you use the event-driver parser, you'll need to build your own data\nstructure (or otherwise handle the data somehow) as the events come\nin.  If you don't want to do that, you can use the tree interface\n(`json65-tree.h`) instead, which builds up a data structure for you.\nThis only works for small files, because the entire tree has to fit in\nmemory at once.\n\nUnlike the event-based parser, the tree interface uses dynamic memory\nallocation.\n\n## Printing JSON (json65-print.h)\n\nMostly, JSON65 is a parser.  However, it does have some support for\nprinting JSON back to a file, in `json65-print.h`.  The function\n`j65_print_tree()` will print a JSON tree (from the tree interface in\n`json65-tree.h`) to a given filehandle.  It prints the entire JSON\ntree on a single line with no whitespace.  This is the most compact\nformat for a machine-readable JSON file, but it is not particularly\nhuman-readable.\n\nIf you write your own code to print JSON, either because you want to\npretty-print it, or because you are using a data structure other than\n`j65_node`, you may still want to use the function\n`j65_print_escaped()` from `json65-quote.h`.  It handles escaping a\nstring using the JSON escape sequences.\n\n## API documentation\n\nI don't have any fancy Doxygen documentation, but the API is\ndocumented by comments in the header files.  If you wish to use the\nevent-driven parser, read [json65.h](src/json65.h).  If you wish to\nuse the tree interface, read [json65-tree.h](src/json65-tree.h).\n\n## Library organization\n\nIf you simply wish to use the event-driven (SAX-style) parser, you\nonly need one header file (`json65.h`) and one assembly file\n(`json65.s`).  However, there are some helper functions in other\nfiles, which you can optionally use with JSON65 if you like.  Most\nnotable is the tree interface to JSON65, which you may use instead of\nthe event-driven interface for small files.\n\nEach header file corresponds directly to one implementation file.\nSome of the implementation files are written in assembly language, and\nsome are written in C.  Here is a description of each, along with the\nsize of the machine code of the implementation (`CODE` section plus\n`RODATA` section; none of the implementation files have any `DATA` or\n`BSS`).\n\n* [json65.h](src/json65.h) (2240 bytes) - The core, event-driven\n  parser.  This is the only file that is required if you wish to build\n  your own data structure.\n* [json65-string.h](src/json65-string.h) (291 bytes) - This implements\n  a [string intern pool][4] which is used by the tree interface.\n* [json65-tree.h](src/json65-tree.h) (1300 bytes) - The tree\n  interface, which builds up a tree data structure as the file is\n  parsed.  You may then traverse the tree to your heart's content.\n* [json65-quote.h](src/json65-quote.h) (226 bytes) - This has a\n  function which prints strings, replacing special characters with the\n  escape sequences from the JSON specification.  It is used by the\n  tree printer, but can also be used standalone if you are printing\n  JSON files yourself without using the tree interface.\n* [json65-print.h](src/json65-print.h) (710 bytes) - Prints a tree to\n  a file as JSON.  Use this if you are using the tree interface, and\n  wish to write JSON files as well as read them.\n* [json65-file.h](src/json65-file.h) (1378 bytes) - Provides a helper\n  function to feed data to the parser from a file, in chunks, and to\n  display error messages to the user (including printing the offending\n  line, and printing a caret to indicate the offending position of the\n  line).\n\nI hate build systems (or at least, build systems for C code), so I\nhave not provided one.  (Other than a lame little Perl script to build\nand run the tests using [sim65][5].)  Instead, I encourage you to copy\nthe source files and header files you need into your own project, and\nuse whatever build system you are already using for your project.\n(Such as the GNU Make based [cc65 build system][6].)\n\nYou can use the following dependency graph to determine which source\nfiles you will need to copy into your project.  (For each source file,\nyou will also need to copy the corresponding header file.)  Source\nfiles with no dependencies (such as `json65.s`) are at the top of the\ngraph, while the source file with the most dependencies\n(`json65-print.c`) is at the bottom of the graph.\n\n```\n                json65.s    json65-string.s\n                  /  \\         /\n                 /    \\       /\n                /      \\     /\n     json65-file.c    json65-tree.c     json65-quote.s\n                           \\             /\n                            \\           /\n                             \\         /\n                            json65-print.c\n```\n\nIf you wish to build and run the tests, simply run the `run-test.pl`\nPerl script at the top level of the repository.  (It takes no\narguments.)  You'll need to have the [cc65][7] toolchain installed.\n\nNote: version 2.17 and earlier of [sim65][5] have a\n[bug in the implementation of the BIT instruction][8], so the tests\nwill fail.  You'll need a more recent version to get the tests to\npass.  (This only affects the simulation of the tests.  If you plan on\nrunning JSON65 on real hardware, or on an emulator *other* than sim65,\nthen you'll be fine with an older version of cc65.)\n\n## License\n\nJSON65 is licensed under the [zlib/libpng license](LICENSE.txt), which\nis approved by the [OSI][9] and the [FSF][10].\n\n## Background\n\nFor more information about how and why I wrote JSON65, see [my blog post][11].\n\n[1]: https://cc65.github.io/doc/ca65.html\n[2]: https://cc65.github.io/doc/cc65-intern.html\n[3]: https://tools.ietf.org/html/rfc8259#section-8.1\n[4]: https://en.wikipedia.org/wiki/String_interning\n[5]: https://cc65.github.io/doc/sim65.html\n[6]: https://github.com/cc65/wiki/wiki/Bigger-Projects\n[7]: https://cc65.github.io/cc65/\n[8]: https://github.com/cc65/cc65/pull/712\n[9]: https://opensource.org/licenses/Zlib\n[10]: https://www.gnu.org/licenses/license-list.en.html#ZLib\n[11]: https://funwithsoftware.org/posts/2021-03-03-json-on-the-apple-ii.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmignon-p%2Fjson65","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmignon-p%2Fjson65","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmignon-p%2Fjson65/lists"}