I’m at a loss. I’ve read and re-read the DM and the forum here and I can’t figure this out. It seems to me that it should be simple but I’m stumped.
First, here’s what I WANT to do:
I want to make a call like print (RuleThatCallsQuit)"Some text", someValue, "^";. The problem is that the first rule gets processed and quits before anything else is processed. Which means I get an output of Some text.
So that’s my goal. I’ll tell you how I’ve tried to solve it but maybe I’m just approaching it wrong. I’ve tried to create a function that will concatenate a set of values. I create a buffer, open it as a memory stream, set it as the current stream, and print everything to it. This returns a buffer with the correct character count (–>0) but whatever I do, I can’t get the other elements (–>1 to value of -->0) to print. I either get something like [0x73203432] or [** Programming error: tried to print (char) 0, which is not a valid Glk character code for output **].
I know a simple solution to this specific scenario would be to not call “quit” in the print rule but that won’t address the need to be able to concatenate strings.
I think that any printing rules that you create must accept only a single argument. However, that argument does not have to be meaningful to the routine’s function. Can you reorder things like this?
I believe removing the rtn rule entirely would result in the same output.
[MyFunc str; ! must have one argument
! do something with the string
];
[ Initialise someValue;
someValue = 10;
MyFunc("Some text ", someValue, "^"); ! How do I make this work?
];
Array MyString buffer 160;
Your Array is wrong. I’m looking for a simple solution with PrintToBuffer(), but I can’t find one, you have to do otherwise. And you have too many parameters in the function.
I got PrintToBuffer ( array , arraylen , arg1 , arg2 , arg3 ) prints its arguments – a string, an object’s name, the value of an object’s property, or a routine with up to two arguments – to the buffer array.
from http://inform-fiction.org/inform63/whatsnew.html, am I looking at the wrong page?
I switched -> for buffer in my code but that didn’t resolve the printing issue.
Absolutely! I’m trying to emulate just that but have the result end up in variable rather than print to the screen
That’s why I tried to leverage it in the function I made, by switching the default output stream to a memory buffer and using print to fill it with information. I’m pretty sure it worked because the resulting length of the buffer matches the length of the string as it should be. I just can’t seem to then print the resulting buffer to the screen.
Maybe I’m missing something obvious. I’m just having trouble seeing how something as fundamental as string concatenation is so difficult in a platform devoted to text-based interfaces
OK. It’s important to note that a “string array” (as it’s termed in DM4) is not the same as a “string”. The DM4 discussion on the .print_to_array() method for strings helps to illustrate the difference.
As auraes mentioned, you need to build a function to print the contents of a string array (or better yet, a buffer array, as the sample code below uses). The new function can be used in the context of a print statement, e.g.
Array my_buf buffer <size>;
[ MyBufPrint buf i ;
for (i=0:i<buf-->0:i++) ! expects first word of buffer to contain length of content
print (char) buf->(2+i); ! skips first word of buffer
];
print (MyBufPrint) my_buf, "^";
Text is handled in unusual ways within Inform because of the restrictions imposed by the Z-machine format (which compresses string text to reduce its storage space requirement).
You may find it a lot easier to just let the print statement do the concatenation for you at the point of output, instead of trying to concatenated assorted contents to a buffer or string array first. Again, if that’s not helpful, it might be helpful to post some of your actual code (or an analog), so that it’s easier to see exactly what you’re trying to do.
Pay close attention to your array access operators --> (word access) and -> (byte access). Any time that you’re printing a (char) value, it should be printing a value accessed via ->.
Likewise, in your StringOrArray() routine’s continuation condition, you want to access -->0 of your buffer to get the length value. The length requires a word’s worth of storage because, as your example demonstrates, length may exceed 255 (max for a byte).
The actual character bytes in the buffer begin at position ->2, because ->0 and ->1 are the same two bytes as -->0. Your StringOrArray() routine’s for loop initialization and print statement should reflect that.
For your print statements in Initialise(), the missing space between (char) and val-->... does not seem to be relevant, but the only one that I would expect to work correctly is:
print (char) val->(2 + 1), "^"; ! prints second character of string contents of buffer
It looks like you’re compiling to Glulx, not Z-machine, so the offset of 2 for string contents is incorrect. This can be replaced with the library constant WORDSIZE, which is set automatically for the virtual machine in use. (The release notes have additional details. See the end of the section “Word size” under “Glulx differences” for notes on this exact scenario.)
@DavidG, I looked through Standard Library 6.12.4, and I didn’t see any routine that can be used as a printing rule for the contents of a buffer array. Is there one that I missed? If not, perhaps it makes sense to include such a printing routine (i.e. a print (buffer) ... built-in like print (string) ...) in the next release to ease the way for newcomers?