I’ve encountered an issue with either (join words $ into $) or (link $) {$}. Here is a minimal example:
(program entry point)
(join words [word s] into $plural)
(link [$plural]){$plural}
When run in the debugger, I would expect the output to be <[words] words>, but the actual output is <[w o r d s] words>.
$plural prints as a normal word, rather than a set of characters, in every other case, and (link){$plural} works as usual.
Furthermore, the program produces the expected output, <[words] words>, if I bind a variable to @words at any point in the program, as in this example:
(program entry point)
(join words [word s] into $plural)
(link [$plural]){$plural}
($X = @words)
I don’t see why this would matter at all. Can anyone explain what’s causing this behavior?
The reason why using @words anywhere in the program changes the output, is because that puts @words into the game’s dictionary. Words found in the dictionary are stored differently from words not found in the dictionary (so-called “extdict” or “extended dictionary” words).
But (link $ $) should be fine with extended dictionary words as well as normal ones. Do you know if this is a debugger-exclusive problem, or if it also shows up in the Å-machine web interpreter?
So it’s deliberately inserting spaces between the components of an extended dictionary word used as a link. But why would it be doing this? Is this intended behavior somehow?
It is not expected behavior, at least—here’s what the Å-machine spec says.
if(CWL == 0) {
if(nLink == 0) {
if(SPC == auto || SPC == pendingspace) output_space()
local variable input = ""
arg = deref(arg)
while(arg.tag == pair) {
local variable w = deref(heap[arg.value + 0])
if(w.tag == word
|| w.tag == char
|| w.tag == extdict
|| w.tag == number) {
* if input is non-empty, then append
space to end of input
* append text of w to end of input
}
arg = deref(heap[arg.value + 1])
}
output_enterlink(input)
SPC = nospace
}
nLink++
nSpan++
}
So there are supposed to be spaces put between the words in the list, not between the components of an extdict word. If the Å-machine web interpreter doesn’t show this behavior, then it’s a bug in the debugger (ironic!) that we can fix.
This is where it would be really nice to have some kind of specification of what an extdict actually looks like…
To the best of my understanding, an extdict is <extdict, P>, where P is a pointer to a two-word cell on the heap. Either:
The first word of that cell is <pair, Q>. In that case, <pair, Q> is a list of chars forming an unrecognized dictionary word (where Q is a pointer into the heap). The second word of the cell is…unspecified? I can’t find anywhere that its value is defined. Maybe it’s nil?
The first word of that cell is <dict, Q> and the second word of that cell is <pair, R>. In that case, <dict, Q> is the essential part of the word (where Q is an index into the dictionary) and <pair, R> is a list of chars forming the optional part of the word (where R is a pointer into the heap).
(I’m using the notation from the Å-machine spec here: <tag, value> means a 16-bit word where the top bits tag it as type “tag” and the bottom bits contain “value”.)
It seems to only be an issue with the debugger; the links behave normally on the web interpreter. Thanks for explaining about the regular and extended dictionary words. I didn’t know about that, but now it makes sense why binding a variable helped.
Oh, perfect. Then I can adjust the debugger code and call it a day!
I really should get some more thesis work done before I throw myself into this, sadly, but expect a fix sometime in the next few days, and it will be included in 1b/01. For now, it should only be a cosmetic problem, since the links in the debugger aren’t clickable anyway.