Change symbol internally to support opaque octet strings - #17
Conversation
|
I am still thinking about minimal changes to minilisp to support modifying octet-strings which may simply be to add some methods to index bytes within symbols without adding any new types. I want to port a pure implementation of SHA-256 to minilisp as an exercise and possibly add it to a minimal escape sequence so that we can round trip an octet-string as a symbol, and an indexed set and get might be the bare minimum change for a compact in-memory representation of a byte array for a pure lisp hash algorithm. sure, we can simulate a byte array using a list but that is going to be very inefficient. even if we can index bytes in a symbol we would need shift, and, or to compose uint as SHA-256 actually needs uint typed arrays. if we took the approach of reusing symbol we would just need to add an escape like curious about your thoughts. I'm just letting you know what I'm thinking of in case there is a preferred type of change that you might accept as a minimal change. perhaps it is a just to use a list of integers... curious how you would do it? |
|
|
I don't expect you to merge this, as it's mostly a hint at a possible direction as it would be useful for hashing graphs of symbols containing binary data so as a step, the symbol should be an opaque octet string i.e. change from zero terminated string to length prefix octet-string using the length from the object. To do this we need to 1). defer the size padding and alignment calculations and 2). as a discrete step, hoist
strlenfrominternandmake_symbol.obj_sizefunction that derives the padded and aligned size to be used insidealloc,forwardandgc.intern_opaqueandmake_symbol_opaquewith wrappers that callstrlen. before this change, the symbol is still zero-terminated, but after this change they are binary data and we usememcmpinintern. this also changedprintto use "%.*s" which I verified will truncate the string and I tested it on Linux and Windows.There should be no functionally visible change if this works. It passes all tests in
test.sh. btw it's great that the code is so simple because a core change like this is rather easy to do without the noise in a larger codebase likeminischeme.addendum
I might consider adding some backslash escapes to
read_symbolandprintin my tree. that makes sense if we were to add a double quoted octet string type like the scheme string type. but there is also the question about isomorphic forward and reverse of opaque symbols in lisp code using some escape sequence like\{#x0}inread_symbolandprintso that binary data can 100% forward and reverse when parsing and emitting quoted or unquoted symbols. the curly escape is used in LaTeX and termcap (it's percent escaped as%{num}in termcap) and the #x0 us a hex literal. from scheme. I like the curly escape and I like the scheme method for hex literal i.e.\{0}==\{#x0}and it also could support constants like character names from the Unicode database such as "U+220E ∎ END OF PROOF" which we would escape as\{end-of-proof}if we had the Unicode symbol table. also minischeme uses#\Afor its char type, so\{#\A}would basically be embedding a char code for 'A' inside a symbol using the numeric integer or char code escape which would be UTF-8 encoded, so while it is an integer code it in fact inserts a one-byte string. C has an N in front with it's new\N{symbol}escape but I personally think the N is redundant. also I am not sure if you want to complicate minilisp with any of this?in any case this is a preparatory change so that folks who derive from minilisp can support '\0' in their symbols in out-of-tree code. I think it makes sense to have something like this in-tree even if more complicated things are kept out-of-tree because its a rather simple core infrastructure change. My motivation is that I want to use minilisp for testing some termcap entries for a terminal emulator project that I am working on and they have some zeroes in them thus I need to support zeroes in my tests and I don't like that they store zeros as
\{#x80}then later clear the top bit making them only 7-bit clean and thus making it not possible to cleanly support UTF-8 in termcap entries.