BBC BASIC for Windows
Programming >> BBC BASIC language >> Variable storage in memory : Sub-Structures
http://bb4w.conforums.com/index.cgi?board=language&action=display&num=1436210740

Variable storage in memory : Sub-Structures
Post by Andy Parkes on Jul 6th, 2015, 7:25pm

Hi folks,

Structures can contain sub-structures, which can be integral to the container structure, or included from a structure prototype. E.g:

Code:
DIM Struct{Sub1{a, b}, Sub2{}=Protostruct{}}
 


Is it correct to assume that the format block for an integral sub-structure such as Sub1{}, will always follow immediately after its data block offset value? E.g:

[address of next member]Sub1{0[address of format block][offset into data block][format block for Sub1{}...]

Conversely, is it correct to assume that the format block of a sub-structure included from a prototype, will never be located immediately after its data block offset value?

If these assumptions are correct, am I right in thinking that this is sufficient for a program to be able to differentiate between an integral sub-structure and a prototype sub-structure?

Many thanks for your help

Andy
Re: Variable storage in memory : Sub-Structures
Post by rtr2 on Jul 6th, 2015, 8:27pm

on Jul 6th, 2015, 7:25pm, Andy Parkes wrote:
Is it correct to assume that the format block for an integral sub-structure such as Sub1{}, will always follow immediately after its data block offset value?

To make a guarantee of that sort I would have to study the code of BB4W and work out what can happen in all possible circumstances. That's completely impractical I'm afraid; it's several years since the code was written and I no longer understand it in anything like the detail that would be needed.

So all I can suggest, which is no doubt what you have already done, is to try as many examples as you can to see if it seems always to be the case. If it does, you will have to decide whether the statistics give you enough confidence to rely on it.

Richard.
Re: Variable storage in memory : Sub-Structures
Post by Andy Parkes on Jul 7th, 2015, 10:06am

Hi Richard,

Thanks very much for your reply.

Here is a program which randomly generates structures and tests them against the assumptions I made above. I have run it several times without encountering a problem. There might be less obvious exceptional cases that I have not thought of, otherwise the rule appears to be true.

Code:
      REM Random structure generator

      ON ERROR CLOSE#0 : PRINT REPORT$ : END

      nStruct% = 200
      tempFile$ = @tmp$ + "randomStructures.bbc"
      F% = OPENOUT(tempFile$)

      PROC_writeAsTok(F%, "DIM pFrmt%(" + STR$ nStruct% + ")")

      FOR Struct% = 1 TO nStruct%
        Name$ = "Struct" + STR$ Struct%
        Struct$ = FN_generateStruct(Name$)
        PROC_writeAsTok(F%, "DIM " + Struct$)
        PROC_writeAsTok(F%, "pFrmt%(" + STR$ Struct% + ") = !^" + Name$ + "{}")
      NEXT

      PROC_writeAsTok(F%, "nStruct% = " + STR$ nStruct%)
      RESTORE +1
      DATA "FOR I% = 1 TO nStruct%"
      DATA "IF NOT FN_structFormatAsAssumed(pFrmt%(I%)) PRINT "" GLOBAL Struct"";I%;"" not as expected!"""
      DATA "NEXT"
      DATA "PRINT ""Finished checking "";nStruct%;"" GLOBAL structures"""
      DATA "PROC_localStructs"
      DATA "END"
      DATA "DEF FN_structFormatAsAssumed(P%)"
      DATA "LOCAL L%, A%"
      DATA "P% += 4"
      DATA "REPEAT"
      DATA "L% = LEN $$(P% + 4)"
      DATA "IF ?(P% + 3 + L%) == &7B THEN"
      DATA "A% = !(P% + 5 + L%)"
      DATA "IF ?(P% + 1 + L%) == &69 THEN"
      DATA "IF A% <> P% + 13 + L% : =FALSE"
      DATA "ELSE"
      DATA "IF A% == P% + 13 + L% : =FALSE"
      DATA "ENDIF"
      DATA "IF NOT FN_structFormatAsAssumed(A%) : =FALSE"
      DATA "ENDIF"
      DATA "P% = !P%"
      DATA "UNTIL P% == 0"
      DATA "=TRUE"
      DATA ""

      REPEAT
        READ Line$
        PROC_writeAsTok(F%, Line$)
      UNTIL Line$ == ""

      PROC_writeAsTok(F%, "DEF PROC_localStructs")
      PROC_writeAsTok(F%, "LOCAL pfrmt%(), I%")
      PROC_writeAsTok(F%, "DIM pfrmt%(" + STR$ nStruct% + ")")
      FOR Struct% = 1 TO nStruct%
        Name$ = "struct" + STR$ Struct%
        PROC_writeAsTok(F%, "LOCAL " + Name$ + "{}")
        Struct$ = FN_generateStruct(Name$)
        PROC_writeAsTok(F%, "DIM " + Struct$)
        PROC_writeAsTok(F%, "pfrmt%(" + STR$ Struct% + ") = !^" + Name$ + "{}")
      NEXT

      RESTORE +1
      DATA "FOR I% = 1 TO nStruct%"
      DATA "IF NOT FN_structFormatAsAssumed(pfrmt%(I%)) PRINT "" LOCAL Struct"";I%;"" not as expected!"""
      DATA "NEXT"
      DATA "PRINT ""Finished checking "";nStruct%;"" LOCAL structures"""
      DATA "ENDPROC"
      DATA ""

      REPEAT
        READ Line$
        PROC_writeAsTok(F%, Line$)
      UNTIL Line$ == ""

      BPUT#F%,0
      BPUT#F%,&FF
      BPUT#F%,&FF
      CLOSE#F%

      SYS "ShellExecute", @hwnd%, "open", tempFile$, 0, 0, 1
      END



      DEF FN_generateStruct(name$)
      LOCAL s$, M%, N%, L%
      REPEAT
        s$ = name$ + "{"
  
        N% = RND(10) : REM number of members
        FOR M% = 1 TO N%
    
          REPEAT
            T% = RND(9) : REM member type
          UNTIL Struct% > 1 OR T% <> 2
    
          IF T% > 2 s$ += CHR$(96 + M%)
    
          CASE T% OF
            WHEN 1 : s$ += FN_generateStruct("i" + CHR$(96 + M%))
            WHEN 2 : s$ += "p" + CHR$(96 + M%) + "{}=Struct" + STR$(FN_rnd(Struct% - 1)) + "{}"
            WHEN 3 : s$ += "&"
            WHEN 4 : s$ += "%"
            WHEN 5 : s$ += "$"
            WHEN 6 : s$ += "%%"
            WHEN 7 : s$ += "#"
            WHEN 8 : s$ += "(1)"
          ENDCASE
    
          s$ += ","
    
          IF LEN s$ > 247 s$ = LEFT$(s$, L%) : EXIT FOR
          L% = LEN s$
    
        NEXT
      UNTIL L%
      =LEFT$(s$) + "}"



      DEF PROC_writeAsTok(F%, a$)
      LOCAL A%
      PRINT a$
      A% = EVAL("0:" + a$)
      a$ = $(!332 + 2)
      IF LEN a$ > 251 ERROR 100, "Line too long"
      BPUT#F%, LEN a$ + 4
      BPUT#F%, 0
      BPUT#F%, 0
      BPUT#F%, a$;
      BPUT#F%, &D
      ENDPROC



      DEF FN_rnd(N%)
      IF N% < 2 : =1
      =RND(N%)

 

Re: Variable storage in memory : Sub-Structures
Post by rtr2 on Jul 7th, 2015, 11:50am

on Jul 7th, 2015, 10:06am, Andy Parkes wrote:
Here is a program which randomly generates structures and tests them against the assumptions I made above.

It runs here, and no exceptions were reported. You can replace the ShellExecute with a CALL to run the test code in the same process context if you want to:

Code:
      CALL tempFile$ 

Richard.