Post Reply 
EMU48: anomaly in local-variable structure
10-22-2022, 09:48 PM (This post was last modified: 10-24-2022 04:47 PM by rickster.)
Post: #1
EMU48: anomaly in local-variable structure
I am writing a program to generate characters for a role-playing game (Avalon-Hill/Chaosium RuneQuest 3e from the 1980's. Real old school.). The main routine and all subroutines written so far worked to spec, so I moved them all into a project subdirectory, { HOME XGEN }.
Now suddenly there is a problem: in the $$ATTRS routine, which sets up the values for an INFORM dialog box in ATTRS, the system reports an error 'Undefined local name' on encountering GHP. The thing is, GHP is already defined with a dummy value in the global scope, and the name is not lower-case, nor does it have a back-arrow prefix.
It is referenced inside a local-variable structure, and the calculation of GHP involves two of those compiled local variables, but I doubt that is the problem.
Any ideas on what I'm doing wrong would be really appreciated.

Complete listing follows.

Code:

HPHP48-W,*°Â


@ RcDarwin (c) 2022
@ XGEN2 - main routine
@
«   
    INI$LOG
    LOAD$$
    "->X XGEN" LOGGIT
    CLFX
    DO
        SP$PICK
    UNTIL 1 ==
    END
    @ spcode on stack is DW$$ | EL$$ | HU$$ | etc, unquoted hence evaluated
    BUMPX
    ADJX    
    EDITX  @ returns a list of ten items 
    DUP 'CHRXCX' STO
    OBJ→ DROP
    → 
        ←str ←con ←siz ←int ←pow ←dex ←app ←mov ←age ←gnr
        «
           ATTRS
           'CHRXAT' STO
            SCMS
            'CHRXSC' STO
            PR$EXP
           'CHRXPE' STO
        »
    "X-> XGEN" LOGGIT
    LOG$S @ show the log
»
'XGEN2' STO


@ ENUM - basic enum(), doesn't re-base like 'enum(a, b, c=10)' in C
«
  → lsx      @ make sure that lsx is a list!
  « 1 lsx SIZE FOR i
      i 
      lsx i GET
      STO
    NEXT   
  »
»
'ENUM' STO


@ INI$LOG - really basic logger routine
@ \   ---   
« 
  {} 
  DATE + TIME +  
   LOGGIT
»
'INI$LOG' STO


@ LOGGIT -- append string to log 
@ \ str ---- 
«
   LOG$S SWAP +
   'LOG$S' STO
»
'LOGGIT' STO


@ LOAD$$ - load the main data structures.
@ \   ---   
« 
  "  ->X LOAD$$"  LOGGIT
  { 'STR' 'C0N' 'SIZ' 'INT' 'POW' 'DEX' 'APP' 'MOV' 'age' 'gnr' }
  'XN' STO
  XN ENUM

  { 'DW' 'EL' 'HU' 'TR' 'AR' 'AN' 'BR' 'CE' 'DU' 'EF' 'GO' 'HA' 'NA' 'OG' 'RC' 'PA' } 
  'SP' STO
  SP ENUM

  { 'DW$$' 'EL$$' 'HU$$' 'TR$$' 'ms$$' 'AR$$' 'AN$$' 'BR$$' 'CE$$' 'DU$$' 'EF$$' 'GO$$' 'HA$$' 'NA$$' 'OG$$' 'RC$$' 'PA$$' } 
  'SP$$' STO
  
  { 'Dwarf' 'Elf' 'Human' 'Troll' '$ms$' 'Aardvark' 'Anemid' 'Broo' 'Centaur' 'Duck' 'Eftling' 'Goblin' 'Halfling' 'Nachaak' 'Ogre' 'Orc' 'Pandry' } 
  'SP$NOM' STO

SP$NOM SP$$  « 2 →LIST » DOLIST 'ZIP$2SP' STO
  
{ {'n'} {'h'} {'m' 'f'} {'m' 'f' 'a'} {'j' 'b' 'e'} { m a } }
  'GNRA' STO

  {}
  'CHRXCX' STO
  {}
  'CHRXAT' STO
  {}
  'CHRXSC' STO.
  {}
  'CHRXPE' STO

  0 'GHP' STO
  0 'MP' STO
  0 'FTG' STO
  "" 'D$A' STO
  (0,0) 'D$S' STO
  0 'A$G' STO

  "  X-> LOAD$$" LOGGIT
»
'LOAD$$' STO


@ CLFX - clear user flags 1-7 for use by XX$$ routines and BUMPX
«
    "  ->X CLFX" LOGGIT
    1 7 FOR i
        i CF
    NEXT
    "  X-> CLFX" LOGGIT
»
'CLFX' STO


@ SP$PICK - choose "Species" from box, return 'SP$$' from sublist
« 
    "    ->X SP$PICK" LOGGIT
    "PICK SPECIES"
    @ {{"Dwarf" 'DW$$'}{"Elf" 'EL$$'}{"Human" 'HU$$'}{"Troll" 'TR$$'}
     {    }{"Aardvark" 'AR$$'}{"Anemid" 'AN$$'}{"Centaur" 'CE$$'}
     {"Duck" 'DU$$'}{"Eftling" 'EF$$'}{"Goblin" 'GO$$'}{"Halfling" 'HA$$'}
     {"Nachaak" 'NA$$'}{"Ogre" 'OG$$'}{"Orc " 'RC$$'}{"Pandry" 'PA$$'}} @
    ZIP$2SP    @ list of fields 
    3    @ Human by default
    CHOOSE
    "    X-> SP$PICK" LOGGIT
»
'SP$PICK' STO


@ GNR$GET - determine gender of this chrx
« 
    "      ->X GNR$GET" LOGGIT
    'GNRA' SWAP @ using stack-top as index,     
    GET         @ get one sublist, eg., {'m' 'f'}
   "Pick "
   SPNAME
   " Gender"  
   + +     @ title 
   SWAP        @ set up the available genders
   1 
   CHOOSE      @ pick one  
   DROP        @ just the char value, not the OK flag
   "      X-> GNR$GET"  LOGGIT
»
'GNR$GET' STO


@ BUMPX - average values in CHRXCX are 'low-side' integers, eg 10
@ if flag i is set, add 1 half the time, simulating eg 10.5 as average on 3D6
«
    "  ->X BUMPX"  LOGGIT
    1 7 FOR i
        IF i FS? RAND 0.5 >= AND 
        THEN CHRXCX  i  GET
          1 +
            CHRXCX i ROT
            PUT
        END    
    NEXT
    "  X-> BUMPX"  LOGGIT
»
'BUMPX' STO


@ ADJX - adjust each charax by 2D4-4
«
  "  ->X ADJX"  LOGGIT
    1 7 FOR i
        CHRXCX i GET
         4 DIE
         4 DIE +
         4 -
        +
        CHRXCX i ROT
        PUT
    NEXT
    "  X-> ADJX" c LOGGIT
»
'ADJX' STO


@ $$EDITX - parameters for EDITX INFORM

  "EDIT CHARAX"    
@ fields: 0 -> real , 1 -> complex, 2 -> string, 13 -> unit_type
  {{"STR:" "" 0}{"CON:" "" 0}{"SIZ:" "" 0}
   {"INT:" "" 0}{"POW:" "" 0}{"DEX:" "" 0}
   {"APP:" "" 0}{"MOV:" "ms"  13}{}
   {"age:" "yr"  0}{} {"gnr:" "m,f,..." }}
@ 3 columns, 4 tab stops between fields
  {3 4}
@ no reset values
  {}
@ the changeable recipient
  'CHRXCX' EVAL

'$$EDITX' STO


@ EDITX - edit and show charax values
«
  "  ->X EDITX" LOGGIT
  DO
        @ set up the input form's levels:
      $$EDITX
      OBJ→ DROP
      EVAL
      INFORM    @ show the input form, get value list on L2, 1|0 on L1
        IF 1 ==
        THEN
            1
        ELSE]
            0
        END
    UNTIL 1 ==
    END
    "  X-> EDITX"  LOGGIT
»
'EDITX' STO


@
@ Second big section
@


@ AGE$GET - get current age of chrx, calc prev.exp. years, return  as 2-tuple
« 
    "      ->X AGE$GET"  LOGGIT
   CLLCD
  "Current Age (xx): "
    PROMPT DUP
    'CURR$AGE' STO
    CHRXCX 9 GET  2DUP -
    'PREV$EXP' STO
    SWAP DROP
    PREV$EXP
    R→C         @ -- (C,P)
    "     X-> AGE$GET" LOGGIT
»
'AGE$GET' STO


@ $$ATTRS - parameters for ATTRS 
«
  { } 'CHRXAT' STO
  @ gHP
    ←con ←siz + 2 / CEIL
  'GHP' STO
    @ mp
  ←pow
  'MP' STO                                 
    @ Ftg
    ←str ←con +
  'FTG' STO
  @ Dmg Adj
    DMG$ADJ
    'D$A' STO
    @ SR
    DO$SR
    'D$S' STO
  @ age 
    AGE$GET
    'A$G' STO
    { GHP MP FTG D$A D$S A$G }
  'CHRXAT' STO
    @ here is the five-level parameterset for INFORM
  {
  @ title    
    "ATTRIBUTES"
    @ field specs
    {{" gHP:" "" 0}{"  mp:" "" 0}{" Ftg:" "" 0}
     {"DmgA:" "" 0}{"  SR:" "Fdex ,Tot" 1}{ }{" age:" "22" 0}{ }}
    @ format
    { 2 4}
    @ defaults
    { }
  }
    @ add in the initial values ←→
    'CHRXAT' EVAL EVAL 6 →LIST 1 →LIST
  +
»
'$$ATTRS' STO


@ ATTRS - show the values for Attributes: gHP, mp, Fatigue,...
«
  "    ->X ATTRS"  LOGGIT
  @ we want this to just show not edit
  $$ATTRS
  OBJ→ DROP 
  INFORM DROP
  "    X-> ATTRS"  LOGGIT
»
'ATTRS' STO


@ DMG$ADJ - calculate Damage Adjustment 
«
  "    ->X DMG$ADJ"  LOGGIT
    '←str+←siz-1' EVAL
    DUP 
    32 SWAP
    IF  <
    THEN
        12 / IP
        $D4 EVAL
    ELSE
        24 -
        16 / IP
        1 +
        $D6    EVAL
    END
    "    X-> DMG$ADJ"  LOGGIT
»
'DMG$ADJ' STO


@ $D4 - calculate D4-sized value of Damage Adjustment
«
    "      ->X $D4"  LOGGIT
     ←x
    «  CASE
        '←x == 0' THEN "-" END
        '←x == 1' THEN "0]" END
        '←x == 2' THEN "+" END
        " "
        END
        "D4"
        +
    »
    "      X-> $D4"  LOGGIT
»
'$D4' STO


@ $D6 - calculate D6-sized value of Damage Adjustment
«
    "      ->X $D6"  LOGGIT
    48 +
    CHR
    "D6"
    +
    "      X-> $D6" LOGGIT
»
'$D6' STO


@ DO$SR - calculate sr
«
    "    ->X DO$SR" + LOGGIT
    5 ←dex $SR
       4 ←siz $SR
    0 MAX  @ -- DX SZ|0
    OVER   @ -- DX SZ|0 DX
    +
    R→C    @ DX,Tot -> (DX,Tot)
    "    X-> DO$SR"  LOGGIT
»
'DO$SR' STO


@ $SR - calculate one term of SR
«
  "      ->X $SR"   LOGGIT
    →
         ←spx
    «            
    CASE
        ←spx 10 < THEN  1 - END    
        ←spx 16 < THEN  2 - END
         ←spx 20 < THEN  3 - END
        ←spx 23 < THEN  4 - END
        0
    END
  »
  "      X-> $SR"  LOGGIT
»
'$SR' STO


@ $$SCMS - parameters for INFORM in SCMS
«
  ←dex PRIM ←str SECN +  ←siz PRIM -
   'AGL' STO
   ←int PRIM ←pow SECN +  ←app SECN +
   'C0M' STO
   ←int PRIM
   'KNO' STO
   ←int PRIM ←dex PRIM +  ←pow SECN +
   'MAN' STO
   ←int PRIM ←pow SECN +  ←con SECN +
   'PER' STO
   ←dex PRIM ←siz PRIM -  ←pow PRIM -
   'STL' STO
   ←int PRIM ←pow PRIM +  ←dex SECN +
   'MGK' STO
   ←int PRIM ←dex SECN +
   'TEK' STO
  { 
  @ title
  "SCMs"
  @ field specs
  {{"Agl" "" 0}{"Com" "" 0}{"Kno" "" 0}
  {"Man" "" 0}{"Per" "" 0}{"Stl" "" 0}{"Mgk" "" 0}{"Tek" "" 0}{}}
   @ format
   { 2 4 }
   @ initial
   {} 
   @defaults
   { AGL C0M KNO MAN PER STL MGK TEK } EVAL  EVAL 8 →LIST 1 →LIST         
    
  }
»
'$$SCMS' STO


@ SCMS - show values for SCMS: Agl, Com, etc.
«
  @ again, we just want to show, not edit
  "      ->X SCMS"  LOGGIT
  '$$SCMS'
  OBJ→ DROP
  INFORM DROP @ get rid of Boolean in Level 1
  "    X-> SCMS" LOGGIT
»
'SCMS' STO


@
@ Third big section
@


@ PR$EXP - calculate previous experience: a big task!!!
«
  "      ->X PR$EXP"  LOGGIT
  CLLCD
  "Under construction"
  MSGBOX
  { 
  SPNAME ←gnr Vrty "OCC_BACK" CURR$AGE 
  "Skills" 
    "Agl" [ B C D J Rb S Th ] 
    "Com" [ FA O S ] 
    "Kno" { "Lor" [ A S M P W ] 
                "Dsc" [ E FA MA Sh TD TW ] 
                "Cra"[ A B C ] }
    "Man" [ C D Pi S ] 
    "Per" [ L VC VE S T Tr ] 
    "Stl" [ H S T ] 
    "Mgk" { "Rit" [ C E S ] 
                "Sor" [ I D R M ] }
    "Tek" [ A B C D E F ] 
  "Languages" { "own" [spk lit] 
                            "other1" [spk lit] } 
  "Magic" {
    "primitive" {} 
    "Divine" {} 
    "Sorcery" {} }
  "Gear" {armour {}
                weapons {}
                other {} } 
  } EVAL
  "      X-> PR$EXP"  LOGGIT
»
'PR$EXP' STO


@
@ Low-level routines
@


@ PRIM - return primary value (x - 10)
«
  10 -
»
'PRIM' STO


@ SECN - return secondary value, fn(prim(x))
«
    PRIM DUP
    2 / 
    ABS 0.5 +     IP
    SWAP
    SIGN *
    10 MIN
»
'SECN' STO


@DIE - given n, return i | i in 1{..n}
«
  RAND * 
  1 + IP
»
'DIE' STO


@
@ Fourth
 big section
@


@ 2019-08-21 15:24 
@ DW$$ - parameters for Dwarf
«
   "DWARF" 'SPNAME' STO  
     { 14 15  7 13 10 10 10 '2_ms' 12 }
   3 GNR$GET
   +
   'CHRXCX' STO 
 {  2  5  6  7 }  « SF » DOLIST
»
'DW$$' STO


@ EL$$ - parameters for Elf
«
   "ELF" 'SPNAME' STO
    { 9 10  9 16 13 13 10  '4_ms' 20}
   3 GNR$GET
   +
   'CHRXCX' STO
 
 {  2  4  6  7 }  « SF » DOLIST 
»
'EL$$' STO


@ HU$$ - parameters for Human    
«
   "HUMAN" 'SPNAME' STO
   { 10 10 13 13 10 10 10  '3_ms' '15' m } 
   4 GNR$GET
   +
   'CHRXCX' STO 
 
 {  1 2  5  6  7 }  « SF » DOLIST
»
'HU$$' STO


@ TR$$ - parameters for Troll
«
   "TROLL" 'SPNAME' STO
   { 16 10 18 13 10 10 10  '3_ms' '15'  }
   3 GNR$GET
   +
   'CHRXCX' STO  
     { 1  2  3  5  6  7 }  « SF » DOLIST
»
'TR$$' STO


@ --------- minor species --------- 


@ AR$$ - parameters for Aardvark (why not?)
«
     "AARDVARK" 'SPNAME' STO
    {14 12  5 13 10 10  7   '2_ms' 15  }
   3 GNR$GET
   +
 'CHRXCX' STO
 { 1 2  5  6  }  « SF » DOLIST
»
'AR$$' STO


@ AN$$ - parameters for Anemid (winged humanoids)
«
    "ANEMID" 'SPNAME' STO
    {7 10. 7 13 13 17 10.  '2.9_ms' 15 } 
   3 GNR$GET
   +
 'CHRXCX' STO
 {  2  7 }  « SF » DOLIST
»
'AN$$' STO


@ BR$$ - parameters for Broo (nasty chaotic brutes)
«
    "BROO" 'SPNAME' STO
    {13 15 15 13 10 10  7  '4_ms' 15 }
   3 GNR$GET
   +
 'CHRXCX' STO
 {   2  3  5  6  }  « SF » DOLIST
»
'BR$$' STO


@ CE$$ - parameters for Centaur
«
    "CENTAUR" 'SPNAME' STO
    {16 10 15 13 10 13  10 '10_ms' 15  } 
3 GNR$GET
   +
 'CHRXCX' STO
 {  1 2  4  5  6  7}  « SF » DOLIST
»
'CE$$' STO


@ DU$$ - parameters for Duck
«
    "DUCK" 'SPNAME' STO
    {8 13 5 13 10 13 7  '2_ms' 15  } 
3 GNR$GET
   +
 'CHRXCX' STO
 { 3  5 }  « SF » DOLIST
»
'DU$$' STO


@ EF$$ - parameters for Eftling (amphibian folk)
«
    "EFTLING" 'SPNAME' STO
    {10 10 7 13 10 13 10  '2_ms' 3  } 
3 GNR$GET
   +
 'CHRXCX' STO
 {  1  2  5  7 }  « SF » DOLIST
»
'EF$$' STO


@ GO$$ - parameters for Goblin
«
    "GOBLIN" 'SPNAME' STO
    {14 10  7  9  8 13 10  '2_ms' 15 }
    3 GNR$GET
   +
 'CHRXCX' STO
 {  2  7 }  « SF » DOLIST
»
'GO$$' STO


@ HA$$ - parameters for Halfling
«
    "HALFLING" 'SPNAME' STO
    {7 19 4 13 10 17 10  '2_ms' 15  } 
     3 GNR$GET
   +
 'CHRXCX' STO
 {   7 }  « SF » DOLIST
»
'HA$$' STO


@ NA$$ - parameters for Nachaak (badger folk)
«
    "NACHAAK" 'SPNAME' STO
    {7 10 5 13 13 14 7  '3_ms' 13 }
3 GNR$GET
   +
 'CHRXCX' STO
 {  2  }  « SF » DOLIST
»
'NA$$' STO


@ OG$$ - parameters for Ogre
«
    "OGRE" 'SPNAME' STO
    {19 13 13 13 13 10 13  '3_ms' 15 } 
3 GNR$GET
   +
 'CHRXCX' STO
 {   6  7 }  « SF » DOLIST
»
'OG$$' STO


@ RC$$ - parameters for Orc
«
    "ORC" 'SPNAME' STO
    {14 10  9 13 10 14  7  '3_ms' 15 }
3 GNR$GET
   +
 'CHRXCX' STO
 {  2  4 }  « SF » DOLIST
»
'RC$$' STO


@ PA$$ - parameters for Pandry (hermaphroditic cyborgs)
«
    "PANDRY" 'SPNAME' STO
    {12 13 11 15 10 13 13  '4_ms' 13 }
     2 GNR$GET
   +
 'CHRXCX' STO
 {  3  6  7 }  « SF » DOLIST
»
'PA$$' STO

Charles? He was my grandfather. --Oh, *that* Charles. We share a common ancestor.
Find all posts by this user
Quote this message in a reply
10-23-2022, 03:52 PM
Post: #2
RE: EMU48: anomaly in local-variable structure
What platform are you targeting? It appears to be an emulated 48gx, but I wanted to make sure before assuming too much.

The code as provided won't compile on a 48gx due to some syntax errors, so it's difficult to say exactly what problems you may be running into. Generally speaking, though, the error you are seeing is likely to be happening for a different reason than you might expect. That specific error is usually a result of referencing a compiled local variable (ie. one that has the <- character at the beginning) that has not yet been instantiated. In that case, though, the error message that is shown onscreen will likely be referencing the previous UserRPL command. This is obviously a misleading error message (the reason for the error is correct, but the attribution is not).

Here's a simple example that shows what I'm talking about:
Code:
CLV
\<<
  999 \-> \<-X
  \<<
    \<-X 1 +
    \<-Y 2 *
  \>>
\>>

If you run the above code, the 48gx will present you with
+ Error:
Undefined Local Name


In the above program, the error message incorrectly attributes the problem to the "+" step, but in reality it happened at the "<-Y" step. To add insult to injury, it even leaves 999 and 1 on the stack, which seem to support the error happening with "+".

To prove where the actual problem is, though, simply change the "<-Y" variable name to a constant (eg. 50). Now run the program again. You will find that it now completes successfully with the expected results.

Hopefully this will at least provide some clarity for the specific error you've mentioned, though of course there may be others as well that need to be addressed.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)