Thank you so much, Daniel! That was incredibly helpful… after a whole bunch of banging around with it I realized that I also had an off-by-one error, starting the copy look at entry 1 rather than entry 0 of the text; I guess StorageForShortName is one of those arrays (“string”?) that doesn’t have its length in the first entry, while I6 Buffer is one of those arrays (“table”) that does. (Although I defined it as “buffer,” which doesn’t seem to be documented in DM4; is that defined somewhere in the I6 template?) And of course looking back at your post you have that correction.
I had thought that I wouldn’t need to worry about the junk at the end, because all I care about in general is going to be the beginning of the string–but it turns out that the junk was affecting the individual words, which wouldn’t do. (Overwriting “dishonest yak” with “yttrium” yielded “yttriumst yak,” and my rules don’t recognize “yttriumst” as a word that starts with a vowel sound.) But your tip about Glulx_PrintAnyToArray solved that.
It’s even working with characters like ü and Ø and Æ if I put the relevant word on the list of words that start with vowel sounds. Which is surprising in light of what you said about Unicode. Or are those not Unicode?
Now all I have to do is find the part that is making everything print on a different line, but in my adventures looking through the I6 template I remember running across something about the flag that produces line breaks, so I should be able to work that out.
On further reflection, urgh. The thing I ran across is informing me that there is no such thing as the flag that produces line breaks. The problem seems to be that my initial sound rulebook wants to produce line breaks. I bonked all but one of them by adding this to the initial sound rulebook, but I’m still getting a spurious break before the first article. Maybe I have to add that to the you can also see rule as well.
Thank you so much! As I said, this has been bugging me for a while.
Current code:
[spoiler][code]The Lab is a room.
An animal can be honest or dishonest. Understand the honest property as describing an animal.
Before printing the name of an animal (called beast): say "[if beast is dishonest]dis[end if]honest ".
The unicorn is an animal. It is honest.
The yak is an animal. It is dishonest.
A block is a kind of thing. It has a number called weight. The description of a block is “It looks to be about [weight of the item described in words] pound[s].”
After examining a block (called B):
now the printed name of B is “[weight of B in words]-pound block of [B]”.
The yttrium is a block. The weight is one.
The uniform is wearable. The description is “It’s a United States Army uniform.”
After examining the uniform for the first time:
now the printed name of the uniform is “United States Army uniform”.
A unicorn, a uniform, an hourglass, a yak and yttrium are in the lab. An Æsop anthology is in the lab.
[Matt’s code - additions noted]
[create a global variable to be called later in i6:]
[Current vowel sound is a number that varies. Current vowel sound variable translates into i6 as “vowel_sound”.
Before printing the name of a thing (called x):
let T be a text;
now T is the printed name of x;
now Current vowel sound is T evaluated.
[say Current vowel sound.]
To decide what number is (s - a text) evaluated:
if s starts with a vowel sound:
decide on 1;
decide on 0. ]
To decide whether (string - a text) starts with a vowel sound (this is vowel sound checking):
let the first word be punctuated word number 1 in string;
if the first word is a word listed in the Table of Words That Start With Vowel Sounds, yes;
if the first word is a word listed in the Table of Words That Don’t Start With Vowel Sounds, no;
if character number 1 in the first word is a vowel, yes;
no.
To decide whether (letter - a text) is a vowel:
if letter exactly matches the regular expression “a|e|i|o|u|A|E|I|O|U”, yes;
no.
The initial sound rules are a rulebook. The initial sound rules have outcomes vowel and consonant.
To skip upcoming rulebook break: (- say__pc = say__pc | PARA_NORULEBOOKBREAKS; -).
First initial sound rule: skip upcoming rulebook break.
An initial sound rule (this is the basic initial sound test rule):
let temp be the substituted form of “[I6 buffer]”;
[say “(DBG: [temp])”;]
if “[temp]” starts with a vowel sound:
vowel;
otherwise:
consonant.
To say the/-- I6 buffer:
(- PrintI6Buffer(); -).
Include (-
Array I6Buffer buffer 250;
[ PrintI6Buffer len i;
len = I6Buffer->0;
for ( i = 0 : i < len : i++ )
{
glk_put_char(I6Buffer->(i + 1));
}
];
-)
.
Table of Words That Start With Vowel Sounds
word
“hour”
“hourglass”
“honest”
“yttrium”
“Æsop”
Table of Words That Don’t Start With Vowel Sounds
word
“uniform”
“unicorn”
“united”
“United”
“one”
[end]
[Include (-
Global vowel_sound = 0;
-) after “Definitions.i6t”.]
Include (-
Global short_name_case;
[ PrefaceByArticle obj acode pluralise capitalise i artform findout artval buflen;
if (obj provides articles) {
artval=(obj.&articles)–>(acode+short_name_case*LanguageCases);
if (capitalise)
print (Cap) artval, " ";
else
print (string) artval, " ";
if (pluralise) return;
print (PSN__) obj; return;
}
i = GetGNAOfObject(obj);
if (pluralise) {
if (i < 3 || (i >= 6 && i < 9)) i = i + 3;
}
i = LanguageGNAsToArticles-->i;
artform = LanguageArticles
+ 3*WORDSIZE*LanguageContractionForms*(short_name_case + i*LanguageCases);
#Iftrue (LanguageContractionForms == 2);
if (artform-->acode ~= artform-->(acode+3)) findout = true;
#Endif; ! LanguageContractionForms
#Iftrue (LanguageContractionForms == 3);
if (artform-->acode ~= artform-->(acode+3)) findout = true;
if (artform-->(acode+3) ~= artform-->(acode+6)) findout = true;
#Endif; ! LanguageContractionForms
#Iftrue (LanguageContractionForms == 4);
if (artform-->acode ~= artform-->(acode+3)) findout = true;
if (artform-->(acode+3) ~= artform-->(acode+6)) findout = true;
if (artform-->(acode+6) ~= artform-->(acode+9)) findout = true;
#Endif; ! LanguageContractionForms
#Iftrue (LanguageContractionForms > 4);
findout = true;
#Endif; ! LanguageContractionForms
#Ifdef TARGET_ZCODE;
if (standard_interpreter ~= 0 && findout) {
StorageForShortName-->0 = 160;
@output_stream 3 StorageForShortName;
if (pluralise) print (number) pluralise; else print (PSN__) obj;
@output_stream -3;
acode = acode + 3*LanguageContraction(StorageForShortName + 2);
}
#Ifnot; ! TARGET_GLULX
if (findout) {
if (pluralise)
buflen = Glulx_PrintAnyToArray(StorageForShortName, 160, EnglishNumber, pluralise);
else
buflen = Glulx_PrintAnyToArray(StorageForShortName, 160, PSN__, obj);
acode = acode + 3*LanguageContraction(StorageForShortName, buflen);
}
#Endif; ! TARGET_
Cap (artform-->acode, ~~capitalise); ! print article
if (pluralise) return;
print (PSN__) obj;
];
-) instead of “Object Names II” in “Printing.i6t”.
Include (-
Constant LanguageAnimateGender = male;
Constant LanguageInanimateGender = neuter;
Constant LanguageContractionForms = 2; ! English has two:
! 0 = starting with a consonant
! 1 = starting with a vowel
[ LanguageContraction text len result rv i;
!!! This is the old routine:
!if (text->0 == ’a’ or ’e’ or ’i’ or ’o’ or ’u’
!or ’A’ or ’E’ or ’I’ or ’O’ or ’U’) return 1;
!return 0;
!!! Out w/ old – in w/ new:
I6Buffer->0 = len;
for (i=0:i<len+1:i++) I6Buffer->(i+1) = text->i;
rv = FollowRulebook( (+ initial sound rules +) );
if ((rv) && RulebookSucceeded()) {
result = ResultOfRule();
if (result == (+ vowel outcome +)) return 1;
return 0;}
return 0;
];
Array LanguageArticles -->
! Contraction form 0: Contraction form 1:
! Cdef Def Indef Cdef Def Indef
"The " "the " "a " "The " "the " "an " ! Articles 0
"The " "the " "some " "The " "the " "some "; ! Articles 1
! a i
! s p s p
! m f n m f n m f n m f n
Array LanguageGNAsToArticles --> 0 0 0 1 1 1 0 0 0 1 1 1;
-) instead of “Articles” in “Language.i6t”.[/code][/spoiler]