Announcement

Collapse
No announcement yet.

Scripting a PB App/Dll --->Attention Eros Olmi or Florent Heyworth

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Scripting a PB App/Dll --->Attention Eros Olmi or Florent Heyworth

    I have been looking over code from Eros to include scripting capablities to PB Apps as Jose website Jose Roca Archives - BINT32
    AWESOME job by the way Eros :top:

    and a little deeper as Eros was so kind to give credit where credit is due with Florent Hayworth (Although from my understanding does not visit much if anymore)

    Trying to wrap my head around how things work, I kinda have the basics, but I am REALLY stuck on a point.

    Calling my own functions, or a windows api function from script.

    I like your way much better than my current way of doing this, so hopefully you can point me out to what I am missing. I tried the examples, but just do not get it yet but I know its there cause its all perfectly compilable (even in PB9), so maybe you guys can help

    I was looking at Exec_Run or Exec_LoadLib but like I said my limited knowledge I can only get parts to work, and parts not.

    Any help you can give, I would GREATLY appreciate it.
    Engineer's Motto: If it aint broke take it apart and fix it

    "If at 1st you don't succeed... call it version 1.0"

    "Half of Programming is coding"....."The other 90% is DEBUGGING"

    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

  • #2
    Cliff,

    what is the exact point where you need help?

    For example, if you need to create your own functions and be able to call them in the script as native function, you can check at example Test001.bas that exactly doe that.
    That example creates some compiled functions (Exec_EURO, Exec_MyDIV, Exec_MyUCASE, Exec_SUM, Exec_AVG) than it tells BINT engine about the new fucntions using BINT_LoadSymbol. BINT_LoadSymbol telle BINT engine that you want to add a new keyword to the language passing 3 parameters: the keyword name, the type of returned value (String, Number, None) and finally the code pointr to the function you want to associate with the new key.

    That is the "BINT way" to add new keywords to the engine. Every new keyword can be associated with your own compiled function.

    Let me know what exactly you do not get.

    Exec_Run is used to execute the main script. So it is the main started of script execution.

    Exec_LoadLib is used to load special libraries (I called them "modules") developed specifically for BINT. See BINT_MyLib.bas to see how to create them. BINT modules must have always an exported function called "BINT32_LoadLocalSymbols". That function is automatically invoked by BINT engine when module is loaded. It is norally used to let BINT engine know about new keywords you want to add to current execution.

    Ciao
    Eros
    thinBasic programming language
    Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

    Comment


    • #3
      Thanks Eros,
      I will have to go back and look again. My initial attempts (and where I got lost) was if I had a function (either in a dll or compiled in the same exe as the scripting) such as
      Code:
      FUNCTION DeviceOpenPort ALIAS "DeviceOpenPort"(BYVAL ComPortNumber AS LONG, BYVAL ComPortBaudRate AS LONG) EXPORT AS LONG  'Configure and open serial port
      That I would be able to use the function from script. But being it is not a known windows function, I was trying to figure out the correct way of going about it.

      My other route is to parse a string formatted to call the function. But I like your way better in a lot of cases (Once that I can get my head wrapped around how it works).

      I must say you have done and EXCELLENT job by the way. Now if I can learn how to use it, and decide which method suits best in this case.

      Thank you for any and all help
      Engineer's Motto: If it aint broke take it apart and fix it

      "If at 1st you don't succeed... call it version 1.0"

      "Half of Programming is coding"....."The other 90% is DEBUGGING"

      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

      Comment


      • #4
        Cliff,

        below an example on how you can do the job.


        Mainly the steps are:
        1. wrap whatever function you want to be able to call frem the interpreter. Wrapping means parsing any tokens needed for your keyword syntax. So if your syntax is:
          MyFunction(Expression1, Expression2)
          you have to parse:
          ( ------------------------------------> Done using BINT_CheckOpenParens
          NumericExpression 1 ------------------> Done using BINT_ParseNumber (this will solve whatever complex numerc expression)
          , ------------------------------------> Done using BINT_CheckComma
          NumericExpression 2 ------------------> Done using BINT_ParseNumber
          ) ------------------------------------> Done using BINT_CheckCloseParens

          BINT_ParseNumber is not just a tokenizer of a single value or single variable but will just parse whatever complex math expression. regardless of its complexity. BINT_ParseNumber is a full descendant math parser. The same for BINT_ParseString in case of string expressions.
          .
        2. Tell BINT you have a new keyword using BINT_LoadSymbol interface function.
          .
        3. ready to use new keyword in your script
        Let me know.
        Eros

        Code:
          '----------------------------------------------------------------------------
          #Include "BINT32.INC"
          '----------------------------------------------------------------------------
          '----------------------------------------------------------------------------
          ' This is your compiled function
          '----------------------------------------------------------------------------
          Function DeviceOpenPort (ByVal ComPortNumber As Long, ByVal ComPortBaudRate As Long) As Long
          '----------------------------------------------------------------------------
            '---Do something with the params and return something
            Local lTemp As Long
         
            lTemp = ComPortNumber * 1000000 + ComPortBaudRate
         
            Function = lTemp 
          End Function
         
          '----------------------------------------------------------------------------
          ' This is your script wrapper for your compiled function
          '----------------------------------------------------------------------------
          Function Exec_DeviceOpenPort() As Ext
          'Syntax: Number = DeviceOpenPort(Number, Number)
          '----------------------------------------------------------------------------
            Local lFirstNumber As Ext
            Local lSecondNumber As Ext
            If BINT_CheckOpenParens Then                 '---Parse (
              BINT_ParseNumber lFirstNumber              '---Parse first value
              If BINT_CheckComma Then                    '---Parse ,
                BINT_ParseNumber lSecondNumber           '---Parse second value
                If BINT_CheckCloseParens Then            '---Parse )
                                                         '---Now do whatever needed
                  Function = DeviceOpenPort(lFirstNumber, lSecondNumber)
                End If
              End If
            End If
          End Function
         
          '------------------------------------------------------------------------------
          '------------------------------------------------------------------------------
          Function WinMain(ByVal hCurInstance  As Long, _
                             ByVal hPrevInstance As Long, _
                             ByVal lpszCmdLine   As Asciiz Ptr, _
                             ByVal nCmdShow      As Long) _
                             Export As Long
            Local MyProgram As String
            Local rtError   As Long
         
            '---
            ' Load into the Interpreter your defined Subs/Functions
            ' As you can see you can give them the name you prefer
            '---
            Call BINT_LoadSymbol("DeviceOpenPort",    %BINT_ReturnNumber, CodePtr(Exec_DeviceOpenPort))
            '---
            ' Now make a simple script in order to test some of your user defines language
            ' extension. In order to be simple to
            '---
            MyProgram = _
                        "'---------------------------------------  " + $CrLf + _
                        "'Declare a numeric var, use user defined  " + $CrLf + _
                        "'function EURO to pass a value (in this   " + $CrLf + _
                        "'case EURO value) than make some test.    " + $CrLf + _
                        "'---------------------------------------  " + $CrLf + _
                        "DIM ComPort  AS Number                       'declare a variable   " + $CrLf + _
                        "DIM BaudRate AS Number                       'declare a variable   " + $CrLf + _
                        "DIM Result   AS Number                       'declare a variable   " + $CrLf + _
                        "ComPort  = 1                                 'Assign a value       " + $CrLf + _
                        "BaudRate = 9600                              'Assign a value       " + $CrLf + _
                        "Result = DeviceOpenPort(ComPort, BaudRate)   'Call your new keyword" + $CrLf + _
                        "MSGBOX(''Result is: '' & Result)                                   " + $CrLf + _
                        ""
            '---
            ' Show the script
            '---
            Call BINT_Message("Code that will be executed", MyProgram)
            '---
            ' Run the script
            '---
            Call BINT_Run(MyProgram, %BINT_ExecString)
            rtError = BINT_ErrorClear
            If rtError <> 0 Then
              MsgBox  "An error occurred."                              + $CrLf + _
                      "Error code:" + Str$(rtError)                     + $CrLf + _
                      "Description: " + BINT_ErrorDescription(rtError)  + $CrLf + _
                      "Token found: " + BINT_ErrorGetToken              + $CrLf + _
                      "Occurred at line:" + Str$(BINT_ErrorGetLine), _
                      &H00000010& , _
                      "RunTimer Error"
            End If
         
            '---
            ' Here show some results and see how you can get back some of the internal
            ' script variables
            '---
            MsgBox "Outside source program, internal script vars value are:"  + $CrLf + _
                   " - ComPort   is: " + Str$(BINT_GetNumber("ComPort"))      + $CrLf + _
                   " - BaudRate  is: " + Str$(BINT_GetNumber("BaudRate"))     + $CrLf + _
                   " - Result    is: " + Str$(BINT_GetNumber("Result"))       + $CrLf + _
                   ""
          End Function
        Attached Files
        Last edited by Eros Olmi; 3 Nov 2008, 08:14 AM.
        thinBasic programming language
        Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

        Comment


        • #5
          Thank you Eros,
          I got the basics down in my head when I stripped back your Test01.bas and got this to work
          Code:
                          "     Dim Results AS Long                                                " + $CRLF + _
                          "     Dim i AS Long                                                " + $CRLF + _
                          "     Dim nLoops AS Long                                                " + $CRLF + _
                          "     nLoops = 2                                                " + $CRLF + _
                          "     For i = 1 to nLoops                                                " + $CRLF + _
                          "          Results = DeviceOpenPort(1, 9600)" + $CRLF + _
                          "MSGBOX(''Function Called Results: '' & str$(Results))                                    " + $CRLF + _
                          "     next                                                " + $CRLF + _
                          ""
          The 2 minor things things I did run into (and should be able to account for or correct myself) are that no matter the return value from a function has to be declared EXT, and doing a For loop, causes an error if using "Next i" instead of just "Next"

          But like I said these are minor in my mind, the ability to script and which was is best in this case take priority.

          Thank you Eros :top:
          Engineer's Motto: If it aint broke take it apart and fix it

          "If at 1st you don't succeed... call it version 1.0"

          "Half of Programming is coding"....."The other 90% is DEBUGGING"

          "Document my code????" .... "WHYYY??? do you think they call it CODE? "

          Comment


          • #6
            Numbers work, and I am getting used to some of the other concepts, but what I have been butting my head up against the wall all day is strings

            Code:
              #INCLUDE "Win32Api.inc"
              #INCLUDE "BINT32.INC"
              #INCLUDE "ErrorHandling.Inc"
            
              FUNCTION Exec_MyUcase() AS STRING
              'Syntax: String = MyUcase(String, Number)
                LOCAL lString AS STRING
                LOCAL lOption AS EXT
                IF BINT_CheckOpenParens THEN
                  BINT_ParseString lString
                  IF BINT_CheckComma THEN
                    BINT_ParseNumber lOption
                    IF BINT_CheckCloseParens THEN
                      SELECT CASE lOption
                        CASE 0,1
                          FUNCTION = UCASE$(lString)
                        CASE 2
                          FUNCTION = LCASE$(lString)
                        CASE 3
                          FUNCTION = MCASE$(lString)
                      END SELECT
                    END IF
                  END IF
                END IF
              END FUNCTION
            
            FUNCTION DeviceOpenPort ALIAS "DeviceOpenPort"(BYVAL ComPortNumber AS LONG, BYVAL ComPortBaudRate AS LONG) EXPORT AS EXT  'Configure and open serial port
                 FUNCTION = %TRUE
                 MSGBOX FUNCNAME$
            END FUNCTION
            
            FUNCTION DeviceSendToPort ALIAS "DeviceSendToPort" (BYVAL CommandOut AS STRING) EXPORT AS EXT 'Send Command BYVAL for Matlab and other ASCIIZ strings
                 FUNCTION = %TRUE
                 MSGBOX CommandOut + $CR + STR$(LEN(CommandOut))
            END FUNCTION
            
              '------------------------------------------------------------------------------
              '------------------------------------------------------------------------------
              FUNCTION WINMAIN(BYVAL hCurInstance  AS LONG, _
                                 BYVAL hPrevInstance AS LONG, _
                                 BYVAL lpszCmdLine   AS ASCIIZ PTR, _
                                 BYVAL nCmdShow      AS LONG) _
                                 EXPORT AS LONG
                LOCAL MyProgram AS STRING
                LOCAL rtError   AS LONG
                
                '---
                ' Load into the Interpreter your defined Subs/Functions
                ' As you can see you can give them the name you prefere
                '---
                CALL BINT_LoadSymbol("MyUCASE", %BINT_ReturnString, CODEPTR(Exec_MyUcase))
                CALL BINT_LoadSymbol("DeviceOpenPort",     %BINT_ReturnNumber, CODEPTR(DeviceOpenPort))
                CALL BINT_LoadSymbol("DeviceSendToPort",     %BINT_ReturnNumber, CODEPTR(DeviceSendToPort))
            
                '---
                ' Now make a simple script in order to test some of your user defines language
                ' extension. In order to be simple to
                '---
                MyProgram = _
                            "     Dim Results AS Long                                                " + $CRLF + _
                            "     Dim i AS Long                                                " + $CRLF + _
                            "     Dim nLoops AS Long                                                " + $CRLF + _
                            "     Dim Command AS string                                                " + $CRLF + _
                            "     nLoops = 2                                                " + $CRLF + _
                            "          Results = DeviceOpenPort(1, 9600)" + $CRLF + _
                            "     For i = 1 to nLoops                                                " + $CRLF + _
                            "          Command = ''F,C,I1M1000,R''" + $CRLF + _
                            "          MSGBOX(MyUCASE(''f,C,i1M1000,r'', 3))" + $CRLF + _
                            "          Results = DeviceSendToPort Command" + $CRLF + _
                            "MSGBOX(''Function Called Results: '' & str$(Results))                                    " + $CRLF + _
                            "     next                                                " + $CRLF + _
                            ""
                '---
                ' Show the script
                '---
                CALL BINT_Message("Code that will be executed", MyProgram)
            
                '---
                ' Run the script
                '---
                CALL BINT_Run(MyProgram, %BINT_ExecString)
                rtError = BINT_ErrorClear
                IF rtError <> 0 THEN
                  MSGBOX  "An error occurred."                              + $CRLF + _
                          "Error code:" + STR$(rtError)                     + $CRLF + _
                          "Description: " + BINT_ErrorDescription(rtError)  + $CRLF + _
                          "Token found: " + BINT_ErrorGetToken              + $CRLF + _
                          "Occurred at line:" + STR$(BINT_ErrorGetLine), _
                          &H00000010&     , _
                          "RunTimer Error"
                END IF
              END FUNCTION
            With this sample, I can see that I have the string before passing into the function, but once passed the function itself says I passed nothing to it????
            I am lost again
            Engineer's Motto: If it aint broke take it apart and fix it

            "If at 1st you don't succeed... call it version 1.0"

            "Half of Programming is coding"....."The other 90% is DEBUGGING"

            "Document my code????" .... "WHYYY??? do you think they call it CODE? "

            Comment


            • #7
              Cliff,

              you need to wrap your own function with a parsing function.
              When BINT call functions connected with your new keywords, it does nothjing about them and their parameters, it just have a pointer to them.

              You need to associate a wrapping Exec_... function that does parsing and return something (if needed). All wrapping functions MUST not have any paramaters but those params are parsed by BINT_PArseString or BINT_ParseNumber.

              Remember, you are inside the script when it is executed, not in your compiled code.

              Here a revised version of your script with your commuinication functions wrapped. Wrapped function can be passed to BINT_LoadSymbol.

              Code:
                #Include "Win32Api.inc"
                #Include "BINT32.INC"
                '#Include "ErrorHandling.Inc"
                Function Exec_MyUcase() As String
                'Syntax: String = MyUcase(String, Number)
                  Local lString As String
                  Local lOption As Ext
                  If BINT_CheckOpenParens Then
                    BINT_ParseString lString
                    If BINT_CheckComma Then
                      BINT_ParseNumber lOption
                      If BINT_CheckCloseParens Then
                        Select Case lOption
                          Case 0,1
                            Function = UCase$(lString)
                          Case 2
                            Function = LCase$(lString)
                          Case 3
                            Function = MCase$(lString)
                        End Select
                      End If
                    End If
                  End If
                End Function
              Function DeviceOpenPort Alias "DeviceOpenPort"(ByVal ComPortNumber As Long, ByVal ComPortBaudRate As Long) Export As Ext  'Configure and open serial port
                   Function = %TRUE
                   MsgBox FuncName$
              End Function
                Function Exec_DeviceOpenPort() As Long
                'Syntax: Number = DeviceOpenPort(ComPortNumber, ComPortBaudRate)
                  Local ComPort As Ext
                  Local BaudRate As Ext
                  If BINT_CheckOpenParens Then
                    BINT_ParseNumber ComPort
                    If BINT_CheckComma Then
                      BINT_ParseNumber BaudRate
                      If BINT_CheckCloseParens Then
                        DeviceOpenPort(ComPort, BaudRate)
                      End If
                    End If
                  End If
                End Function
              Function DeviceSendToPort Alias "DeviceSendToPort" (ByVal CommandOut As String) Export As Ext 'Send Command BYVAL for Matlab and other ASCIIZ strings
                   Function = %TRUE
                   MsgBox CommandOut + $Cr + Str$(Len(CommandOut))
              End Function
                Function Exec_DeviceSendToPort() As Long
                'Syntax: Number = DeviceSendToPort(CommandOut)
                  Local CommandOut As String
                  If BINT_CheckOpenParens Then
                    BINT_ParseString CommandOut
                    If BINT_CheckCloseParens Then
                      DeviceSendToPort(CommandOut)
                    End If
                  End If
                End Function
                '------------------------------------------------------------------------------
                '------------------------------------------------------------------------------
                Function WinMain(ByVal hCurInstance  As Long, _
                                   ByVal hPrevInstance As Long, _
                                   ByVal lpszCmdLine   As Asciiz Ptr, _
                                   ByVal nCmdShow      As Long) _
                                   Export As Long
                  Local MyProgram As String
                  Local rtError   As Long
                  
                  '---
                  ' Load into the Interpreter your defined Subs/Functions
                  ' As you can see you can give them the name you prefere
                  '---
                  Call BINT_LoadSymbol("MyUCASE"            , %BINT_ReturnString, CodePtr(Exec_MyUcase))
                  Call BINT_LoadSymbol("DeviceOpenPort"     , %BINT_ReturnNumber, CodePtr(Exec_DeviceOpenPort))
                  Call BINT_LoadSymbol("DeviceSendToPort"   , %BINT_ReturnNumber, CodePtr(Exec_DeviceSendToPort))
                  '---
                  ' Now make a simple script in order to test some of your user defines language
                  ' extension. In order to be simple to
                  '---
                  MyProgram = _
                              "     Dim Results AS Long                                                " + $CrLf + _
                              "     Dim i AS Long                                                " + $CrLf + _
                              "     Dim nLoops AS Long                                                " + $CrLf + _
                              "     Dim Command AS string                                                " + $CrLf + _
                              "     nLoops = 2                                                " + $CrLf + _
                              "          Results = DeviceOpenPort(1, 9600)" + $CrLf + _
                              "     For i = 1 to nLoops                                                " + $CrLf + _
                              "          Command = ''F,C,I1M1000,R''" + $CrLf + _
                              "          MSGBOX(MyUCASE(''f,C,i1M1000,r'', 3))" + $CrLf + _
                              "          Results = DeviceSendToPort(Command)" + $CrLf + _
                              "MSGBOX(''Function Called Results: '' & str$(Results))                                    " + $CrLf + _
                              "     next                                                " + $CrLf + _
                              ""
                  '---
                  ' Show the script
                  '---
                  Call BINT_Message("Code that will be executed", MyProgram)
                  '---
                  ' Run the script
                  '---
                  Call BINT_Run(MyProgram, %BINT_ExecString)
                  rtError = BINT_ErrorClear
                  If rtError <> 0 Then
                    MsgBox  "An error occurred."                              + $CrLf + _
                            "Error code:" + Str$(rtError)                     + $CrLf + _
                            "Description: " + BINT_ErrorDescription(rtError)  + $CrLf + _
                            "Token found: " + BINT_ErrorGetToken              + $CrLf + _
                            "Occurred at line:" + Str$(BINT_ErrorGetLine), _
                            &H00000010&     , _
                            "RunTimer Error"
                  End If
                End FUNCTION
              thinBasic programming language
              Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

              Comment


              • #8
                Cliff,

                just to let you know, I think BINT32 is quite good starting point for writing a nice interpreter (I started from BINT32 to write thinBasic programming language) but it is not perfect and can be improved a lot.

                For example your indication about NEXT followed by the controlling variable: it is quite easy to add cheking for NEXT and see if after it there is an EOL sequence or a token. You can do like in PowerBasic that whatever token is present it will be just ignored.

                A little more complex is to be able to handle different numeric data type. I did it in thinBasic but I can assure it is a lot of work.

                Ciao
                Eros
                thinBasic programming language
                Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

                Comment


                • #9
                  Thank you Eros, and I hate to keep bugging you, but one more I think I can figure out some major concepts (although I am still just learning, and just starting, but trying not to bug you too tooooooo much on this idea)

                  I have another function that normally stays stuck (until a timeout, or the reply appears, and I have no idea when the reply will appear) that works good as real code, but I am trying to determine if I can hold off scripting till a reply.

                  Initial attempts have not worked so far (mostly from trying to remember to keep "TEXT" and "ACTUAL CODE" separate in my mind)

                  Hopefully I explain the next correctly, but hard to do, but lets say for over-exaggeration that the time to read from one line of text to the next (and parse it) took 1 second, and My wait for a reply took 10 seconds, then a "FOR....NEXT" loop could do the loop 10x in 10 seconds, when in reality (if it were code) should take 100 seconds.

                  I realize in this situation, I may have to use a wrapper to Sleep or Pause a certain time based on the value passed to slow things down, but would like to make the original code work "As Advertised" kind of thing without the trick, but also caught in the realm of not really understanding what I am doing just yet.

                  So my question is, when parsing a string, or a file (and my guess so far is line by line) is "Where is this happening?" because I keep losing myself while parsing, so I can build in a handler for "What IF??"

                  Any help you can give, I would appreciate it, and again sorry if I am asking too much, but I am just trying to figure out "Fundamentals, of something I did not write, so best to ask the writer"
                  Engineer's Motto: If it aint broke take it apart and fix it

                  "If at 1st you don't succeed... call it version 1.0"

                  "Half of Programming is coding"....."The other 90% is DEBUGGING"

                  "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                  Comment


                  • #10
                    Originally posted by Cliff Nichols View Post
                    So my question is, when parsing a string, or a file (and my guess so far is line by line) is "Where is this happening?" because I keep losing myself while parsing, so I can build in a handler for "What IF??"
                    Cliff,

                    I'm sorry but I cannot understand what you are asking. Can you be so kind to explain a little bit (my English has big limits sometimes).

                    If I got correctly you need to remain in wait situation while nothing is happening (I suppose you are waiting for data to be received) and than react.
                    I suppose the best way is to write your own compiled function to do this job and wrap it into a new keyword.
                    Doing this directly in script code can be done with WHILE/WEND, adding a DOEVENT or a SLEEP inside it in order to slower down CPU usage. When data is received, do an EXIT WHILE.

                    Regarding parsing, BINT is a not a line by line parser but a tokenizer, so every single piece of source code is separated, organized and than executed.

                    Ciao
                    Eros
                    thinBasic programming language
                    Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

                    Comment


                    • #11
                      My mistake Eros, my codeptr was pointed at the actual function and not the wrapper for the function.

                      Now if I can figure out how to release the variables I declare, so I can run the same script twice without crashing (or I think thats where the problem occurs)
                      Engineer's Motto: If it aint broke take it apart and fix it

                      "If at 1st you don't succeed... call it version 1.0"

                      "Half of Programming is coding"....."The other 90% is DEBUGGING"

                      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                      Comment


                      • #12
                        You can call BINT_Reset function after execution of BINT_Run (or after further checking of your internal application).
                        This will reset all internal BINT stuff and you can call your script again and again.

                        Hope it works fine.
                        Ciao
                        Eros
                        thinBasic programming language
                        Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

                        Comment


                        • #13
                          Thank you Eros.

                          I added "BINT_Reset" after each "BINT_Run" which works GREAT!!!!
                          Then I tried to take it a step farther with adding the line
                          Code:
                              CALL BINT_LoadSymbol("ResetVariables",     %BINT_ReturnNone, CODEPTR(BINT_RESET), %BINT_ForceOverWrite)
                          Which fails, so I played around with things a bit, I think the difference is calling from code, the variables are no longer in use, and calling from text, they are still in use, so you can not reset.

                          One thing I did try was
                          Code:
                              CALL BINT_LoadSymbol("ResetVariables",     %BINT_ReturnNone, CODEPTR(Parser_SemiReset), %BINT_ForceOverWrite)
                          which seems to work better (or at least 1 line farther, in test code but fails when I DIM the same variable again.

                          I am working on a sample of the minor changes I made but maybe seeing the text file will help till I can
                          Code:
                          '----------------------------------------------------------------------------------------------------------
                          Function MyFunction() AS LONG
                               Dim Results2 AS Long
                                  Dim i2 AS Long
                                  Dim nLoops2 AS Long
                               Dim CommandOut as string
                                  Results2 = DeviceOpenPort(1, 9600)
                               nLoops2 = INPUTBOX$("How many parts?", "COSMOS", 3)
                                  For i2 = 1 to nLoops2
                                    DeviceClearPort()
                                    CommandOut = "F,C,I1M1000,R"
                                    DeviceSendToPort(CommandOUt)
                                    DeviceWaitForChar("^", 0)
                                  next
                          END FUNCTION
                          '----------------------------------------------------------------------------------------------------------
                          
                          '----------------------------------------------------------------------------------------------------------
                          Function MyFunction() AS LONG
                          MsgBox("I made it this far")
                               Dim Results2 AS Long
                          msgbox("But not this far?")
                                  Dim i2 AS Long
                                  Dim nLoops2 AS Long
                               Dim CommandOut as string
                                  Results2 = DeviceOpenPort(1, 9600)
                               nLoops2 = INPUTBOX$("How many parts?", "COSMOS", 3)
                                  For i2 = 1 to nLoops2
                                    DeviceClearPort()
                                    CommandOut = "F,C,I1M1000,R"
                                    DeviceSendToPort(CommandOUt)
                                    DeviceWaitForChar("^", 0)
                                  next
                          END FUNCTION
                          '----------------------------------------------------------------------------------------------------------
                          I appreciate all the help Eros, and sorry to keep asking. (maybe I should go back to "Understanding Tokens 101" and learn what I do not understand yet.) But I appreciate you taking to time to answer my questions, and point me the right directions so that I can learn on my own. (some points I get, some I miss completely, but the more turned around I get, when I see the path, I see the :doh: and realize the light-bulb is getting brighter )
                          Engineer's Motto: If it aint broke take it apart and fix it

                          "If at 1st you don't succeed... call it version 1.0"

                          "Half of Programming is coding"....."The other 90% is DEBUGGING"

                          "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                          Comment


                          • #14
                            No wrapper needed with uCalc

                            With uCalc it is extremely easy to define a function that is directly attached to an API function or a function defined in your PB code. No "wrapper" code is necessary. The lines below with ucDefineFunction in it are all you need along with the addresses of the functions, obtainable with CodePtr() if the function is in your source code, or GetProcAddress() if it's in a DLL.

                            Code:
                            #Include "uCalcPB.bas"
                            
                            Function DeviceOpenPort(ByVal ComPortNumber As Long, ByVal ComPortBaudRate As Long) As Extended
                               ? ComPortNumber : ? ComPortBaudRate
                            End Function
                            
                            Function DeviceSendToPort(ByVal CommandOut As String) As Extended
                               ? CommandOut
                            End Function
                            
                            Function PBMain () As Long
                               ucDefineFunction "DeviceOpenPort(ByVal ComPortNumber As Long, ByVal ComPortBaudRate As Long) As Extended", CodePtr(DeviceOpenPort)
                               ucDefineFunction "DeviceSendToPort(ByVal CommandOut As String) As Extended", CodePtr(DeviceSendToPort)
                               ucEval "DeviceOpenPort(1, 9600)"
                               ucEval "DeviceSendToPort('f,C,i1M1000,r')"
                            End Function
                            That's all there is to it. You can do the above with uCalc Fast Math Parser. However, the BASIC-like scripting language is in the uCalc Language Builder zip file, which is a separate download and not yet integrated in a way that you can call it from your host program (unless you add some code for it). This is a project I can work in if there's enough interest.

                            uCalc FMP has a For loop routine that works with any numeric type. And you can release any item you defined, using ucReleaseItem().
                            Daniel Corbier
                            uCalc Fast Math Parser
                            uCalc Language Builder
                            sigpic

                            Comment

                            Working...
                            X