! End of the parser proper: the remaining routines are its front end. ! ---------------------------------------------------------------------------- Object InformLibrary "(Inform Library)" with play [ i j k l; standard_interpreter = $32-->0; transcript_mode = ((0-->8) & 1); ChangeDefault(cant_go, CANTGO__TX); buffer->0 = 120; buffer2->0 = 120; buffer3->0 = 120; parse->0 = 64; parse2->0 = 64; real_location = thedark; player = selfobj; actor = player; top_object = #largest_object-255; selfobj.capacity = MAX_CARRIED; #ifdef LanguageInitialise; LanguageInitialise(); #endif; new_line; j=Initialise(); last_score = score; move player to location; while (parent(location)~=0) location=parent(location); real_location = location; objectloop (i in player) give i moved ~concealed; if (j~=2) Banner(); MoveFloatingObjects(); lightflag=OffersLight(parent(player)); if (lightflag==0) { real_location=location; location=thedark; } ; for (i=1:i<=100:i++) j=random(i); #ifdef EnglishNaturalLanguage; old_itobj = itobj; old_himobj = himobj; old_herobj = herobj; #endif; while (~~deadflag) { #ifdef EnglishNaturalLanguage; PronounOldEnglish(); old_itobj = PronounValue('it'); old_himobj = PronounValue('him'); old_herobj = PronounValue('her'); #endif; .very__late__error; if (score ~= last_score) { if (notify_mode==1) NotifyTheScore(); last_score=score; } .late__error; inputobjs-->0 = 0; inputobjs-->1 = 0; inputobjs-->2 = 0; inputobjs-->3 = 0; meta=false; ! The Parser writes its results into inputobjs and meta, ! a flag indicating a "meta-verb". This can only be set for ! commands by the player, not for orders to others. InformParser.parse_input(inputobjs); action=inputobjs-->0; ! -------------------------------------------------------------- ! Reverse "give fred biscuit" into "give biscuit to fred" if (action==##GiveR or ##ShowR) { i=inputobjs-->2; inputobjs-->2=inputobjs-->3; inputobjs-->3=i; if (action==##GiveR) action=##Give; else action=##Show; } ! Convert "P, tell me about X" to "ask P about X" if (action==##Tell && inputobjs-->2==player && actor~=player) { inputobjs-->2=actor; actor=player; action=##Ask; } ! Convert "ask P for X" to "P, give X to me" if (action==##AskFor && inputobjs-->2~=player && actor==player) { actor=inputobjs-->2; inputobjs-->2=inputobjs-->3; inputobjs-->3=player; action=##Give; } ! For old, obsolete code: special_word contains the topic word ! in conversation if (action==##Ask or ##Tell or ##Answer) special_word = special_number1; ! -------------------------------------------------------------- multiflag=false; onotheld_mode=notheld_mode; notheld_mode=false; ! For implicit taking and multiple object detection .begin__action; inp1 = 0; inp2 = 0; i=inputobjs-->1; if (i>=1) inp1=inputobjs-->2; if (i>=2) inp2=inputobjs-->3; ! inp1 and inp2 hold: object numbers, or 0 for "multiple object", ! or 1 for "a number or dictionary address" if (inp1 == 1) noun = special_number1; else noun = inp1; if (inp2 == 1) { if (inp1 == 1) second = special_number2; else second = special_number1; } else second = inp2; ! -------------------------------------------------------------- if (actor~=player) { ! The player's "orders" property can refuse to allow conversation ! here, by returning true. If not, the order is sent to the ! other person's "orders" property. If that also returns false, ! then: if it was a misunderstood command anyway, it is converted ! to an Answer action (thus "floyd, grrr" ends up as ! "say grrr to floyd"). If it was a good command, it is finally ! offered to the Order: part of the other person's "life" ! property, the old-fashioned way of dealing with conversation. j=RunRoutines(player,orders); if (j==0) { j=RunRoutines(actor,orders); if (j==0) { if (action==##NotUnderstood) { inputobjs-->3=actor; actor=player; action=##Answer; jump begin__action; } if (RunLife(actor,##Order)==0) L__M(##Order,1,actor); } } jump turn__end; } ! -------------------------------------------------------------- ! Generate the action... if ((i==0) || (i==1 && inp1 ~= 0) || (i==2 && inp1 ~= 0 && inp2 ~= 0)) { self.begin_action(action, noun, second, 0); jump turn__end; } ! ...unless a multiple object must be substituted. First: ! (a) check the multiple list isn't empty; ! (b) warn the player if it has been cut short because too long; ! (c) generate a sequence of actions from the list ! (stopping in the event of death or movement away). multiflag = true; j=multiple_object-->0; if (j==0) { L__M(##Miscellany,2); jump late__error; } if (toomany_flag) { toomany_flag = false; L__M(##Miscellany,1); } i=location; for (k=1:k<=j:k++) { if (deadflag) break; if (location ~= i) { L__M(##Miscellany, 51); break; } l = multiple_object-->k; PronounNotice(l); print (name) l, ": "; if (inp1 == 0) { inp1 = l; self.begin_action(action, l, second, 0); inp1 = 0; } else { inp2 = l; self.begin_action(action, noun, l, 0); inp2 = 0; } } ! -------------------------------------------------------------- .turn__end; ! No time passes if either (i) the verb was meta, or ! (ii) we've only had the implicit take before the "real" ! action to follow. if (notheld_mode==1) { NoteObjectAcquisitions(); continue; } if (meta) continue; if (~~deadflag) self.end_turn_sequence(); } if (deadflag~=2) AfterLife(); if (deadflag==0) jump very__late__error; print "^^ "; #IFV5; style bold; #ENDIF; print "***"; if (deadflag==1) L__M(##Miscellany,3); if (deadflag==2) L__M(##Miscellany,4); if (deadflag>2) { print " "; DeathMessage(); print " "; } print "***"; #IFV5; style roman; #ENDIF; print "^^^"; ScoreSub(); DisplayStatus(); AfterGameOver(); ], end_turn_sequence [ i j; turns++; if (the_time~=NULL) { if (time_rate>=0) the_time=the_time+time_rate; else { time_step--; if (time_step==0) { the_time++; time_step = -time_rate; } } the_time=the_time % 1440; } #IFDEF DEBUG; if (debug_flag & 4 ~= 0) { for (i=0: ii; if (j~=0) { print (name) (j&$7fff), ": "; if (j & $8000) print "daemon"; else { print "timer with ", j.time_left, " turns to go"; } new_line; } } } #ENDIF; for (i=0: ii; if (j~=0) { if (j & $8000) RunRoutines(j&$7fff,daemon); else { if (j.time_left==0) { StopTimer(j); RunRoutines(j,time_out); } else j.time_left=j.time_left-1; } } } if (deadflag) return; scope_reason=EACH_TURN_REASON; verb_word=0; DoScopeAction(location); SearchScope(ScopeCeiling(player), player, 0); scope_reason=PARSING_REASON; if (deadflag) return; TimePasses(); if (deadflag) return; AdjustLight(); if (deadflag) return; NoteObjectAcquisitions(); ], begin_action [ a n s source sa sn ss; sa = action; sn = noun; ss = second; action = a; noun = n; second = s; #IFDEF DEBUG; if (debug_flag & 2 ~= 0) TraceAction(source); #IFNOT; source = 0; #ENDIF; #IFTRUE Grammar__Version == 1; if ((meta || BeforeRoutines()==false) && action<256) ActionPrimitive(); #IFNOT; if ((meta || BeforeRoutines()==false) && action<4096) ActionPrimitive(); #ENDIF; action = sa; noun = sn; second = ss; ], has proper; [ ActionPrimitive; indirect(#actions_table-->action); ];