Inform6 and CompareObjects

Can’t compile this piece of code from IDM:

Array sortname1 -> 128;
Array sortname2 -> 128;
[ CompareObjects obj1 obj2 i d l1 l2;
  sortname1 -> 0 = 125;
  sortname2 -> 0 = 125;
  for (i = 2: i < 128: i++) {
    sortname1->i = 0;
    sortname2->i = 0;
  }
  @output_stream 3 sortname1;
  print (name) obj1;
  @output_stream -3;
  @output_stream 3 sortname2;
  print (name) obj2;
  @output_stream -3;
  for (i = 2: : i++) {
    l1 = sortname1->i;
    l2 = sortname2->i;
    d = l1 - l2;
    if (d) return d;
    if (l1 == 0) return 0;
  }

Modern I6.42 compiler complains:

Error:  Expected an opcode name but found output_stream
>   @output_stream

(four times, for each @output_stream)

Anyone knows how to get the compiler to agree with IDM?

Are you trying to compile for Glulx, perhaps? As far as I can tell, @output_stream is still the standard Inform name for that opcode on Z-machine.

1 Like

yes, i’m using Glulx

You won’t be able to use that code as-is when compiling to Glulx, because the @output_stream opcode is not valid for that virtual machine.

The purpose of using the opcode is to copy the names of obj1 and obj2 to some variables. You might find the StdLib routines PrintAnything() and PrintAnyToArray() to be useful for the purpose when targeting Glulx.

This should be the Glulx equivalent:

Array sortname1 -> 256;
Array sortname2 -> 256;

[ CompareObjects obj1 obj2   len1 len2 i diff;
    len1 = PrintAnyToArray(sortname1, 256, obj1);
    len2 = PrintAnyToArray(sortname2, 256, obj2);

    for (i=0 : i<256 : i++) {
        if (i == len1 && i == len2) return 0;
        if (i == len1) return -(sortname2->i);
        if (i == len2) return sortname1->i;
        diff = sortname1->i - sortname2->i;
        if (diff) return diff;
    }

    return 0;
];

(Minimally tested.)

Note that the PrintAnyToArray() routine is not smart about Unicode characters, as you can tell by the fact that it uses -> arrays. Anything that doesn’t fit in a byte will get squashed to a'?' character.

2 Likes

Note that the same is generally true for anything using inline assembly instructions (that is, the @opcode syntax). Basic instructions like @add should work okay, but for basic things like that, you can just use proper I6; the main purpose for inline assembly is for fancy effects that Inform syntax doesn’t cover, like drawing status bars and clearing the screen, and those fancy effects tend to be implemented differently between platforms.

So in general, anything in the DM4 involving inline assembly won’t work on Glulx. The main exception is @push and @pull, which deliberately work the same between the two platforms, and aren’t accessible without inline assembly.

(Technically those are assembler macros, not actual instructions, which is why their syntax can be so identical. They’re just too useful to require a version check every time.)

1 Like

Thank you, that was enlightening.