DavidGriffith / inform6lib

The Inform6 interactive fiction standard library (moved to https://gitlab.com/DavidGriffith/inform6lib)
Other
22 stars 9 forks source link

"take all" results in [Programming Error] (again!) #14

Closed jmcb closed 9 years ago

jmcb commented 9 years ago

(I found the password to my original account again, hooray).

To the contrary of my previous report, it now seems that /any/ game I compile results in the following:

take all [\ Programming error: tried to test "in" or "notin" of <illegal object number 1> **] There is nothing to take.

This is happening on all interpreters and platforms for me, including the website where I'm hosting daily builds (kind of a challenge a friend set): http://wxwhatever.com/mat/15/play/day05.html That's using an extremely outdated version of Quixe, though, but I wasn't able to work out how to update it and get it to run properly before the start of the month's challenge.

The compiled game can be found at http://wxwhatever.com/mat/15/downloads/mars_05.ulx

In addition, to ensure it wasn't the complexity of the game was that causing problems, I created a "simple" game of a single room with a single object, which results in the same error. Interpreters I've tried: Wingit, Glulxe, and Quixe (of various versions, which can be discovered if you need).

Of note, I compiled test.inf into a z5 and ran it through your latest WindowsFrotz (presumably your, I didn't quadruple-check the archive) with no issues with "take all": clearly it's something to do with glulx compilation.

Zarf suggested somewhere (in another thread) that compiling the debug versions of gluxle and cheapglk would allow you to set a breakpoint for that error and then do a stack trace, but I've not been able to get them to compile on my windows platform, and I don't have access to a unix platform currently.


Test.inf: http://pastebin.com/tJsj9yGe Test.ulx: http://wxwhatever.com/test.ulx Mars5.ulx: http://wxwhatever.com/mat/15/downloads/mars_05.ulx Mars5 in quixe: http://wxwhatever.com/mat/15/play/day05.html Mars5 source: http://wxwhatever.com/mat/15/downloads/mars_05.inf (not complete, as the included libraries have been modified)


Current variables:

Compiler: Inform 6.33N (20th August 2014) (compiled from DavidKindler's repository, checked out ~1 week ago, compiled 1 week ago, for Windows 64bit) Library: From your repository, last commit Jun 6th (~47251182b) (with a local commit to modify behaviour of KeyboardPrimitive to be similar to KeyCharPrimitive, in that you can provide a window argument)


In summary, I'm not really sure what this issue is: library? compiler? interpreter? glulx-specific code? a ghost in my own system?

As I recall last year, you were unable to duplicate the error, but it no longer appears to be related to the found_in function as I suspected.

Look forward to finding a solution!

DavidGriffith commented 9 years ago

Confirmed. Problem manifests for me. Putting test code directly into the bug report is always welcome.

Constant Story "ifmo15";
Constant Headline "^By A Trizbort User^^^";

Include "Parser";
Include "VerbLib";

Object  Jetty "Jetty"
  with  description
            "",
   has  light;

Object -> item "item",
    with
        name 'item',
        description "An item.",
    has
        concealed;

[ Initialise;
    location = Jetty;
    ! "^^Your opening paragraph here...^^";
];

Include "Grammar";
DavidGriffith commented 9 years ago

I posted a bug report at http://inform7.com/mantis/view.php?id=1747. Where's this thread that Zarf made these suggestions? I don't see offhand how to build debug versions of CheapGlk, GlkTerm, or Glulxe.

jmcb commented 9 years ago

Sorry, took me a minute to remember something unique that I could actually Google, the thread in question was: http://www.intfiction.org/forum/viewtopic.php?f=7&t=16744&start=10

I didn't actually read the entirety of the thread once I found the post re: debug build, so I'm not sure if there's other relevant information; the error reported itself there seemed to be unrelated.

jmcb commented 9 years ago

Quick note: the debug branch of glulxe also requires you uncomment the definition of a VM_DEBUGGER (or something similar named) in glulxe.h before it will actually compile the debug mode. This is probably obvious to everyone else, but it took me about half an hour before I realised what I was doing wrong -- which is when I ran into (more) platform-related issues and was unable to compile.

DavidGriffith commented 9 years ago

Well, I figured out how to build the debug versions. Now I don't know how to use the debugger.

jmcb commented 9 years ago

According to glulxe's debugger.c, "/" is cheapglk's debug command. So "/help" should give you a list of available commands. I haven't tested it myself, obviously.

DavidGriffith commented 9 years ago

I figured out that much. I just don't know how to use the commands.

jmcb commented 9 years ago

Zarf suggested backtrace on RT__Err but I wasn't sure how to work out what the address of a specific function was once it was compiled...

DavidGriffith commented 9 years ago

I just emailed Zarf about the problem. Let's wait to see what he has to say.

erkyrath commented 9 years ago
glulxedebugc -D --gameinfo gameinfo.dbg game.ulx

...where gameinfo.dbg is produced by the inform -k flag. (Make sure you use gameinfo.dbg and game.ulx produced by the same compile run.)

Then, in the game, type

/break RT__Err

When you hit the breakpoint, type

bt

to see the backtrace.

DavidGriffith commented 9 years ago
$ glulxe-debug -D --gameinfo gameinfo.dbg takeall2.ulx 
Welcome to the Cheap Glk Implementation, library version 1.0.4. Debug support is on.

ifmo15
By A Trizbort User

Release 1 / Serial number 150906 / Inform v6.33 Library 6/12-beta1 SD

Jetty

>/break RT__Err
Debug: Breakpoint set for function: 108190 ($1A69E), RT__Err()
>take all
Debug: Breakpoint:
Debug: RT__Err()  (pc=$1A6A3)
Debug:   crime=2; obj=1; id=0; size=0; p=0; q=0
>>bt
Debug: RT__Err()  (pc=$1A6A3)
Debug:   crime=2; obj=1; id=0; size=0; p=0; q=0
Debug: ParseToken__()  (pc=$8506)
Debug:   given_ttype=1; given_tdata=2; token_n=0; token=2; l=1; o=142773 ($22DB5); i=0; j=0; k=0; and_parity=1; single_object=0; desc_wn=2; many_flag=0; token_allows_multiple=1; prev_indef_wanted=0
Debug: Parser__parse()  (pc=$6E63)
Debug:   results=129636 ($1FA64), inputobjs[16]; syntax=141635 ($22943); line=0; num_lines=3; line_address=141645 ($2294D); i=1; j=1; k=0; token=141639 ($22947); l=0; m=1; line_etype=100 ($64); vw=0
Debug: InformParser.parse_input()  (pc=$543D)
Debug:   results=129636 ($1FA64), inputobjs[16]
Debug: CA__Pr()  (pc=$1A32D)
Debug:   _vararg_count=1; obj=134269 ($20C7D), InformParser; id=270 ($10E); zr=1; s=0; s2=0; z=0; addr=136616 ($215A8); len=4; m=0; val=21551 ($542F), InformParser.parse_input()
Debug: InformLibrary.play()  (pc=$CF16)
Debug:   i=0; j=0; k=0; l=0
Debug: CA__Pr()  (pc=$1A32D)
Debug:   _vararg_count=0; obj=134301 ($20C9D), InformLibrary; id=271 ($10F); zr=1; s=0; s2=0; z=0; addr=136664 ($215D8); len=4; m=0; val=52864 ($CE80), InformLibrary.play()
Debug: Main()  (pc=$5B)
Debug:   (no locals)
Debug: Main__()  (pc=$46)
Debug:   (no locals)
>>
DavidGriffith commented 9 years ago

Looks like the bug is in the Library. This commit caused the trouble: 5675c836b074633d697c52e24ac98bba1d9b86e0

See also http://inform7.com/mantis/view.php?id=977

I suspect that NounDomain() sometimes returns 1 which is then used to test "notin actor".

jmcb commented 9 years ago

My copy of the library has:

    if (l ~= nothing && l notin actor && token == MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN) {

Implying that the code has changed to test whether or not l is nothing, perhaps to identify this issue. Adding a print (name) l for debugging purposes implies that it is itself an "illegal object" (not sure where that's defined), as opposed to being "nothing".

Interesting, l == nothing returns 0, but metaclass(l) == metaclass(nothing) returns 1.

The issue seems to be that l is an illegal object, but it's not nothing, hence why the l ~= nothing test fails, and it continues to the notin test, which is what results in the error. What is l at that point if it isn't nothing but it isn't something?

(Don't mind my musings on the topic, I'd like to get to know the code base of the compiler and the library a bit better for the future.)


EDIT: Making new comment instead.

DavidGriffith commented 9 years ago

Changing that line to this allows TAKE ALL to work correctly:

if (l ~= nothing && l ~= 1 && l notin actor && token == MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN) {

But I'm unsure of the side effects.

jmcb commented 9 years ago

Ignoring my above, l is the result of NounDomain, which can return 0 for no match, 1 for multi-object match, and k if a specific object was decided upon. The issue seems to be a lack of test that l is actually k (an object), rather than no match/multi-match/reparse, and treating any non-nothing object as an object.

I'm not sure what the accepted method of testing for objects is, outside of:

 if (metaclass(l) == object && l ~= nothing && l notin actor && token == MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN) {

seems to fix it for me.

jmcb commented 9 years ago

The only potential side-effect of either of the above changes that I can imagine is a situation where multiple items are in scope which could be ImplicitlyTaken to conform with a multiheld or multiexcept token. Even then, the current code assumes that there is only /1/ item that can be implicitly taken, rather than multiples. So, inserting a test for objectness/not 1/not 0 does nothing except fix the error.

Resolving the other issue would require determining if NounDomain has found multiple objects, and then, if multiheld token, attempting to implicitly take all of them. No idea how that would work -- or even if I'm correct. I just quite enjoy trying to work through things like this.