s" unexpected input" exception constant unexpected : match? { c-addr1 u1 c-addr2 u2 -- c-addr3 u3 f } c-addr1 u1 2dup c-addr2 u2 string-prefix? dup if ( c-addr1 u1 true ) >r u2 /string r> then ; : match { c-addr1 u1 c-addr2 u2 -- c-addr3 u3 } c-addr1 u1 c-addr2 u2 match? ?exit cr ." error: " c-addr2 u2 type ." expected, found: " cr c-addr1 u1 70 min type unexpected throw ; : 'field ( c-addr1 u1 -- c-addr2 u2 ) case s\" \\'" match? ?of ." '" contof s" '" match? ?of endof s\" \nENTRY:" match? ?of ." (" contof over c@ emit 1 /string next-case ; : number-field ( c-addr1 u1 -- c-addr2 u2 ) #0. 2over >number s" ." match? if >number then 2nip dup >r 2swap r> - type ; : field ( c-addr1 u1 -- c-addr2 u2 ) s" NULL" match? ?exit s" '" match? if 'field exit then number-field ; : record ( c-addr u -- c-addr u ) s" ENTRY:" match #0. 2swap >number 2nip begin over c@ ',' = while s" ," match field ." ^" repeat s\" ),\n" match ; : process ( c-addr u -- ) begin dup while record cr repeat 2drop ; \ s\" ENTRY:3,'Handbook of Programming Languages','Salus, P.H.','1998','Programmiersprachen',NULL,'I,II,III','MacMillan','Indianapolis','1578700094/0108','2373',NULL,'1999-10-29',NULL,NULL,2011.50,NULL,NULL,'Buch','Verfügbar',NULL,'0000-00-00 00:00:00',NULL,'0000-00-00 00:00:00'),\n" process bye s" books" slurp-file process bye