Re: Yet Another JSON Parser
Hi Lindsay, > I still confuse instances of when CARs and arguments in > general are, or not, evaluated. True, this is often not obvious. You surely know that the references show it by marking evaluated arguments with a quote, e.g. : (help 'case) (case 'any (any1 . prg1) (any2 . prg2) ..) -> any ... as opposed to : (help 'cond) (cond ('any1 . prg1) ('any2 . prg2) ..) -> any ... "'any1" means that this datum is evaluated and can be anything (number, symbol or list). > 'sp?' I didn't use here because I wasn't sure what it considers white space > and I just wanted to match the set defined in the json spec. OK, then an explicit check is more correct. 'sp?' takes all ASCII characters 1 .. 32 as white space. BTW, in the 'seek' example (seek '(((C)) (not (sp? C))) Lst) it may not be obvious that it uses destructuring bind. 'seek' always gets the full (rest)list as argument, so the example could also be written as (seek '((L) (not (sp? (car L Lst) ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Yet Another JSON Parser
Thanks Alex! I appreciate the insight! On Sat, Feb 1, 2025 at 1:45 AM Alexander Burger wrote: >('(" " "^I" "^J" "^M") .. > > Strictly speaking this is not correct or at least not needed, as 'case' > does not evaluate the CARs. > Thanks! I'll fix. I still confuse instances of when CARs and arguments in general are, or not, evaluated. > so the symbol 'quote' is simply also checked for. > In other use cases this might cause me no end of frustration. :) >(de jsonSkipWhiteSpace (Lst) > (while (member (car Lst) '(" " "^I" "^J" "^M")) > (++ Lst) ) > Lst ) > I will try this. Much easier to follow! > But anyway, it could be just >(seek '(((C)) (not (sp? C))) Lst) > 'seek' I did not know about. Very useful! 'sp?' I didn't use here because I wasn't sure what it considers white space and I just wanted to match the set defined in the json spec. /Lindsay
Re: Yet Another JSON Parser
Hi Geri, > Good thing you're having fun writing useful projects! > I am indeed. Especially now, I am getting past more academic exercises and appreciating how easy it is to wire things together with picolisp. https://en.wikipedia.org/wiki/Unix_philosophy I do want to get a better handle on native interfacing and the db mechanism. - Data on json.org is not a full spec, I recommend using ECMA404 or > RFC8259, as they specify behaviours way more accurately. For example, I'm > not sure if i saw if it can parse UTF-16 surrogate pairs (this lets you > parse encoded emojis), which is specified in the RFC. > - Look into `loop`, it can make your code quite a bit neater. For example > most of the NotDone flags could be removed by using loop conditionals. > 👍 - You can probably use make and link in more cases, but I'm not sure if > it's better than current approach, @abu probably knows. > I will try this. If it is possible to nest make environments recursing into nested structures it would neaten things up quite a bit. > - Check out https://picolisp.com/wiki/?simplerfc8259json if you want some > inspiration (maybe into direction of "oh god this is horrible", I don't > mind :D) > Nice example! and very neat code I am aspiring to. Is this page linked from one of the main pages? I missed it earlier when I was looking for examples to start from. I went with a very consistent data structure where the parser represents all values as strings and makes an effort to infer the json type and include it in the output. It doesn't try to map to a picolisp type and leaves the interpretation context to whatever is consuming the output. I used nested (assoc) lists and am adding a function, something like 'nth', to easily extract elements from the structure. For very large datasets that need random access it is straightforward to convert the 'assoc' lists to 'idx' or 'enum'. So far, the assoc lookup is more than performant enough for my purpose. Sets: ((NIL . "object") ... ) ((NIL . "array") ...) Values: ("true" . "bool") ("false" . "bool") ("null" . "null") ("abcd" . "string") ("1234" . "number") ( NIL . "undefined") etc > Have fun! > Ditto! /Lindsay
Re: Yet Another JSON Parser
Hi Lindsay, > https://picolisp.com/wiki/?Documentation#yajson Thanks! One minor point: In the 'case' calls, the CARs of clauses with multiple keys are quoted, like ('(" " "^I" "^J" "^M") .. Strictly speaking this is not correct or at least not needed, as 'case' does not evaluate the CARs. It works correctly though, because it expands to ((quote " " "^I" "^J" "^M") .. so the symbol 'quote' is simply also checked for. If OK, I'd also propose a simplification of (de jsonSkipWhiteSpace (Lst) (let (C NIL NotDone T) (while (and NotDone Lst (setq C (car Lst))) (if (sect (list C) '(" " "^I" "^J" "^M")) (++ Lst) (setq NotDone NIL) ) ) Lst ) ) Couldn't it be just the following? (de jsonSkipWhiteSpace (Lst) (while (member (car Lst) '(" " "^I" "^J" "^M")) (++ Lst) ) Lst ) But anyway, it could be just (seek '(((C)) (not (sp? C))) Lst) or, if we remove also white spac at the end (clip Lst) ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe