Donate Now Goal amount for this month: 100 USD, Received: 0 USD (0%)
Donate to support this site and ThinBASIC project development

Results 1 to 9 of 9

Thread: Passing an array (name) as return parameter

  1. #1
    Member Johannes's Avatar
    Join Date
    Nov 2010
    Location
    Wuustwezel, Belgium
    Age
    47
    Posts
    95
    Rep Power
    15

    Passing an array (name) as return parameter

    I've defined a sub BigInt_FactPrime(a As String, ByRef pf() As String) where a is the number that is to be factorised and pf() is the array which will contain the prime factors. I've got the function working but I have to dimension the array beforehand for it to work, even though I do a ReDim (see code).
    SUB BigInt_FactPrime()
      LOCAL a,b,c,q,r AS STRING
      LOCAL i,n AS DWORD
      DIM pf() AS LOCAL STRING
      DIM p(7) AS LOCAL INTEGER
     
      ' Variables for thinBasic_ParseVariableInfo.
      LOCAL sVpt,sMtp,sStp,sFix,sElm,sEsz,sDpt,sPos AS LONG
      ' Parse parameters.
      IF thinBasic_CheckOpenParens THEN
        thinBasic_ParseString a
        IF thinBasic_CheckComma THEN
          thinBasic_ParseVariableInfo(sVpt,sMtp,sStp,sFix,sElm,sEsz,sDpt,sPos)
          IF NOT thinBasic_ErrorFlag THEN
            IF thinBasic_CheckCloseParens THEN
              ' Variabele moet een dynamische string zijn.
              IF sMtp<>%MainType_IsString OR sFix THEN RTError("Return variable for factors must be a dynamic string array") : EXIT SUB
     
              ' processing code deleted
              ' pf() is properly REDIMed here as pf(1 TO n)
     
              ' Transfer internal array to thinBasic.
              thinBasic_VariableRedim(sVpt, %TRUE, n, 0, 0)
              FOR i=1 TO n
                thinBasic_ChangeVariableStringDirect(sVpt, i, pf(i))
              NEXT i
     
            END IF
          END IF
        END IF
      END IF
    END SUB
    
    The little test script I have is the following.
    Uses "Console"
    Module "BigInt"
    Alias String As BigInt
    BigInt a,b,n,p
    DWord i,j
    Quad t
    Boolean c
    PrintL "FactPrime..."
    Dim pf(1) As BigInt
    a=BigInt_Dec(BigInt_Pow(2,64))
    Print BigInt_ToString(a)+" = "
    BigInt_SetForcePlus(FALSE)
    HiResTimer_Get
    BigInt_FactPrime(a,pf())
    t=HiResTimer_Delta
    j=UBound(pf)
    Print BigInt_ToString(pf(1))+$SPC
    If j>1 Then
    For i=2 To j
    Print "* "+BigInt_ToString(pf(i))+$SPC
    Next i
    EndIf
    BigInt_SetForcePlus(TRUE)
    PrintL " ("+TStr$(t/1000000)+")"
    PrintL
    WaitKey
    
    If I do the DIM of pf as pf() (line 9) I get a runtime error in thinBasic_ParseVariableInfo. Should I use another function from the SDK than thinBasic_ParseVariableInfo? Should I do something else so that I can supply an undimensioned array? I know it's possible because ListDir does it.

    Any help is greatly appreciated.
    Boole and Turing, help me!

    Primary programming: 200 MHz ARM StrongARM, RISC OS 4.02, BASIC V, ARM assembler.
    Secondary programming: 3.16 GHz Intel Core 2 Duo E8500, Vista Home Premium SP2, thinBasic, x86 assembler.

  2. #2
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    47
    Posts
    7,570
    Blog Entries
    2
    Rep Power
    10
    Hi Johannes,

    I'm at work at the moment so little time but try this way:

    '---Used to have a pointer to a parsed variable
    LOCAL pVariable AS LONG
    
    '---Use the following SDK thinBasic_VariableParsePtr
    '---Parse a variable and if ok pVariable will have a ptr to it (ptr is an internal thinBasic ptr so do not use directly)
    thinBasic_VariableParsePtr(pVariable)
    
    '---You can use the following to get variable pVariable info:
    DIM MainType As Long
    DIM SubType As Long
    DIM IsArray As Long
    thinBasic_VariableGetInfoPtr(pVariable, MainType, SubType , IsArray )
    if MainType = %MainType_IsString then
      if IsArray then
        ...
          '---When ready redim your parsed variable
          thinBasic_VariableRedim(pVar, %FALSE, 1, 0, 0)
        ...
      end if
    end if
    
    Let me know.
    Eros
    www.thinbasic.com | www.thinbasic.com/community/ | psch.thinbasic.com
    Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

  3. #3
    Member Johannes's Avatar
    Join Date
    Nov 2010
    Location
    Wuustwezel, Belgium
    Age
    47
    Posts
    95
    Rep Power
    15
    Eros,

    When I use thinBasic_VariableParsePtr() I get a run-time error.

    Error code: 252
    Description: Invalid delimiter
    Token found: pf
    Additional info: 1502

    The error occurs if I use pf or pf() in line 14, regardless of how I have dimensioned the variable in line 9.
    Boole and Turing, help me!

    Primary programming: 200 MHz ARM StrongARM, RISC OS 4.02, BASIC V, ARM assembler.
    Secondary programming: 3.16 GHz Intel Core 2 Duo E8500, Vista Home Premium SP2, thinBasic, x86 assembler.

  4. #4
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    47
    Posts
    7,570
    Blog Entries
    2
    Rep Power
    10
    Strange, it should work and here it is working fine.

    My example was intended to be mixed with your so do not keep my example as is but you need to parse all token like you was doing.
    Try something like the following and let me know:

    Sub BigInt_FactPrime()
    
      Local MyBigString   As String
      Local NumberOfItems As Long
      Local lCounter      As Long
      
      '---Used to have a pointer to a parsed variable
      Local pVariable As Long
      
      'Parse parameters.
      If thinBasic_CheckOpenParens Then
        thinBasic_ParseString MyBigString
        If thinBasic_CheckComma Then
          '---Use the following SDK thinBasic_VariableParsePtr
          '---Parse a variable and if ok pVariable will have a ptr to it (ptr is an internal thinBasic ptr so do not use directly)
          thinBasic_VariableParsePtr(pVariable)
          '---You can use the following to get variable pVariable info:
          Dim MainType As Long
          Dim SubType As Long
          Dim IsArray As Long
          thinBasic_VariableGetInfoPtr(pVariable, MainType, SubType, IsArray )
    
    
          If Not thinBasic_ErrorFlag Then
            If thinBasic_CheckCloseParens Then
              ' Variabele moet een dynamische string zijn.
              If MainType = %MainType_IsString Then
                If IsArray Then
                  
                    '---
                    '...do what you need to do
                    '---
                    
                    NumberOfItems = 10 '---<<<Just an example
                    '---When ready redim your parsed variable
                    thinBasic_VariableRedim(pVariable, %TRUE, NumberOfItems, 0, 0)
    
                    '---Fill with data
                    For lCounter = 1 To NumberOfItems
                      thinBasic_ChangeVariableStringDirect(pVariable, lCounter, MyBigString & Str$(lCounter))
                    Next
                End If
              Else
                '---Error
                Exit Sub
              End If  
            End If
          End If
    
        End If
      End If
    End Sub
    
    Last edited by ErosOlmi; 03-04-2011 at 22:21.
    www.thinbasic.com | www.thinbasic.com/community/ | psch.thinbasic.com
    Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

  5. #5
    Member Johannes's Avatar
    Join Date
    Nov 2010
    Location
    Wuustwezel, Belgium
    Age
    47
    Posts
    95
    Rep Power
    15
    Eros,

    I was using the thinBasic_VariableParsePtr as a function within an IF statement, not as a subroutine. That was what caused the error and it's working perfectly now, both with DIM pf(1) and with DIM pf().

    Grazie mille,
    Giovanni
    Boole and Turing, help me!

    Primary programming: 200 MHz ARM StrongARM, RISC OS 4.02, BASIC V, ARM assembler.
    Secondary programming: 3.16 GHz Intel Core 2 Duo E8500, Vista Home Premium SP2, thinBasic, x86 assembler.

  6. #6
    Member Johannes's Avatar
    Join Date
    Nov 2010
    Location
    Wuustwezel, Belgium
    Age
    47
    Posts
    95
    Rep Power
    15

    Next question...

    I want to make sure the array is one-dimensional and that the strings are not fixed-size. (BigInts are dynamic strings.) I want to use thinBasic_ArrayGetInfo but the construction below (lines 20-25) doesn't work. (Returned values sDim and sFix are always zero.)
    SUB BigInt_FactPrime()
      LOCAL a,b,c,q,r AS STRING
      LOCAL i,n AS DWORD
      DIM pf() AS LOCAL STRING
      DIM p(7) AS LOCAL INTEGER
      LOCAL sVpt,sMtp,sStp,sArr,sFix,sDim AS LONG
      ' Parse parameters.
      IF thinBasic_CheckOpenParens THEN                                         ' (
        thinBasic_ParseString a                                                 ' a AS STRING
        IF thinBasic_CheckComma THEN                                            ' ,
          thinBasic_VariableParsePtr(sVpt)                                      ' BYREF pf AS STRING
          IF NOT thinBasic_ErrorFlag THEN
            IF thinBasic_CheckCloseParens THEN                                  ' )
              ' Variable must be a one-dimensional dynamic string array.
              thinBasic_VariableGetInfoPtr(sVpt,sMtp,sStp,sArr)
              IF sMtp<>%MainType_IsString OR sArr<>%TRUE THEN RTError("Return variable for factors must be a one-dimensional dynamic string array") : EXIT SUB
    
    
    
              sFix = thinBasic_ArrayGetInfo(sVpt,%Array_ElementsAreFixed)
              sDim = thinBasic_ArrayGetInfo(sVpt,%Array_Dimensions)
    
    MSGBOX STR$(sVpt)+STR$(sFix)+STR$(sDim)
    
              if sFix or sDim<>1 THEN RTError("Return variable for factors must be a one-dimensional dynamic string array") : EXIT SUB
    
    
    
              ' (Main processing removed)
    
              ' Transfer internal array to thinBasic.
              thinBasic_VariableRedim(sVpt, %TRUE, n, 0, 0)
              FOR i=1 TO n
                thinBasic_ChangeVariableStringDirect(sVpt, i, pf(i))
              NEXT i
    
            END IF
           END IF
        END IF
      END IF
    END SUB
    
    The SDK says I need to use the pointer as returned by thinBasic_ArrayGetPtr but that function uses the name of the array. How do I get from the pointer returned by thinBasic_VariableParsePtr to the name of the variable?
    Boole and Turing, help me!

    Primary programming: 200 MHz ARM StrongARM, RISC OS 4.02, BASIC V, ARM assembler.
    Secondary programming: 3.16 GHz Intel Core 2 Duo E8500, Vista Home Premium SP2, thinBasic, x86 assembler.

  7. #7
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    47
    Posts
    7,570
    Blog Entries
    2
    Rep Power
    10
    It is a little tricky and odd but

    using your sVpt (that is a pointer to a high level variable info) you need to get another pointer using something like

    dim pArray as long
    pArray = thinBasic_VariablePtrToDirectPtr(sVpt)
    
    pArray is a variable pointer of the internal Core representation of the variable.

    With this pointer you can use thinBasic_ArrayGetInfo function in this way:
    if thinBasic_ArrayGetInfo(pArray, %Array_ElementsAreFixed) =%FALSE then ...
    if thinBasic_ArrayGetInfo(pArray, %Array_Dimensions) = 1 then ...
    
    In any case because you will REDIM your array, I do not think you need to care about how many dimensions also because if script array is not dimensioned there are no dimensions to check.
    When you redim an array with PRESERVE = %false, the full content of the array is released and a new memory storage is allocated. So even if your array has 3 dimensions, you can REDIM it with 1.

    Should work
    Let me know

    Eros
    Last edited by ErosOlmi; 06-04-2011 at 07:08.
    www.thinbasic.com | www.thinbasic.com/community/ | psch.thinbasic.com
    Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

  8. #8
    Member Johannes's Avatar
    Join Date
    Nov 2010
    Location
    Wuustwezel, Belgium
    Age
    47
    Posts
    95
    Rep Power
    15
    Eros,

    I realised the bit about REDIM, so checking for number of dimensions isn't necessary. But I absolutely need to know that the strings are not fixed because the results will be absolute garbage. (Fixed strings append CHR$20 and not CHR$0 which will give disastrous results. A string that is too short is obviously a problem. And the whole principle of Big Integers is based on dynamic strings.)

    And it works. Again, grazie mille.
    Last edited by Johannes; 04-04-2011 at 13:03.
    Boole and Turing, help me!

    Primary programming: 200 MHz ARM StrongARM, RISC OS 4.02, BASIC V, ARM assembler.
    Secondary programming: 3.16 GHz Intel Core 2 Duo E8500, Vista Home Premium SP2, thinBasic, x86 assembler.

  9. #9
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    47
    Posts
    7,570
    Blog Entries
    2
    Rep Power
    10
    Great!

    And I'm happy you are using thinBasic SDK. So thanks to you.
    www.thinbasic.com | www.thinbasic.com/community/ | psch.thinbasic.com
    Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •