Results 1 to 7 of 7

Thread: How to create a new thinBasic keyword in Delphi

  1. #1
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,818
    Rep Power
    10

    How to create a new thinBasic keyword in Delphi

    OK,

    you got thinBasic SDK for Delphi. You open the demo Delphi project but still you didn't figure out how interface is done. I will give you here some few points in some post.

    All starts when thinBasic parser find the USES keyword.
    When thinBasic encounter USES it start to find the specified module as described in USES help.
    So a sentence like
    [code=thinbasic]
    USES "MyDelphi"
    [/code]
    will load thinBasic_MyDelphi.dll. To know from where this dll will be loaded see USES help.

    OK, now the dll is loaded but what now?
    thinBasic search inside the dll for a function named LoadLocalSymbols or _LoadLocalSymbols or LoadLocalSymbols_Delphi.
    If none will be found, operation end but script will continue to be executed (but I can imagine a runtime error will be quite close)
    If one of those function will be found, it will be executed.
    LoadLocalSymbols (and its possible variants) have the duty to initialize any needed code by the module and link new keyword names to internal dll functions using thinBasic_LoadSymbol or thinBasic_LoadSymbol_Delphi function. Please see ThinCore.pas included in thinBasic SDK for Delphi ZIP file for thinBasic_LoadSymbol_Delphi syntax.


    OK, but how can thinBasic knows how is the syntax of my new keyword?
    Imagine you want to add a new keyword that calculates the length of the hypotenuse of a right triangle.
    Delphi has the Hypot function in Math unit. So you want to add to thinBasic keywords.

    • 1. Decide the syntax you want thinBasic will have to parse
      Native Hypot Delphi syntax is: n = Hypot(const X: Extended; const Y: Extended): Extended;
      thinBasic syntax can be something like: n = Hypot(Side1, Side2)

      So thinBasic has to parse:
      • an open (
      • a first numeric expression (Side1)
      • a comma ,
      • a second numeric expression (Side2)
      • a closed )



    • 2. Start parsing using exported thinCore.dll fucntionalities.
      Responsability to parse the syntax is moved at module level, so you as programmer has the duty to do it. Here is a possible code example of the above syntax:


    [code=delphi] //----------------------------------------------------------------------------
    // Hypot returns the length of the hypotenuse of a right triangle
    //--
    // thinBasic Syntax: n = Hypot(FirstSide, SecondSide)
    //----------------------------------------------------------------------------
    function Exec_Hypot() : extended ; stdcall;
    var FirstSide, SecondSide : extended;

    begin

    //---Init to zero to avoid compiler warning about possible undefined return
    Exec_Hypot := 0;

    //---Parse the open parenthesis
    if thinBasic_CheckOpenParens = true then
    begin
    //---Parse the X numeric expression
    thinBasic_ParseNumber(FirstSide);

    //---Parse the comma
    if thinBasic_CheckComma = true then
    begin
    //---Parse the Y numeric expression
    thinBasic_ParseNumber(SecondSide);

    //---Parse the close parenthesis
    if thinBasic_CheckCloseParens = true then
    begin
    //---Execute the function and assign as return value
    Exec_Hypot := Hypot(FirstSide, SecondSide) ;
    end;

    end;

    end;

    end;[/code]

    So, to summarize:
    1. parse the open parens with thinBasic_CheckOpenParens function
    2. parse the first number using thinBasic_ParseNumber(...) passing an extended variable byref
    3. parse a comma with thinBasic_CheckComma function
    4. parse the second number using thinBasic_ParseNumber(...) passing an extended variable byref
    5. parse the close parens with thinBasic_CheckCloseParens function

    All those functions has internal error checking so if something goes wrong a thinBasic script run time error is generated.
    If all is ok you will have now 2 numbers to be used to calculate hypotenuse.
    Assign result value to function return value and the trick is done.

    More info will follow if more interest will be expressed.

    Regards
    Eros

    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  2. #2
    thinBasic MVPs kryton9's Avatar
    Join Date
    Nov 2006
    Location
    Naples, Florida & Duluth, Georgia
    Age
    68
    Posts
    3,865
    Rep Power
    405

    Re: How to create a new thinBasic keyword in Delphi

    I started with your samples before this post even was posted Eros, been spending hours on it. Thanks for this explanation and any coming in the future!!

    May I ask why are you parsing the commands as you are with thinBasic_command to parse instead of passing the parameters directly to the dll? Or was this just to show another way to do it without passing parameters that way?

    Acer Notebook: Win 10 Home 64 Bit, Core i7-4702MQ @ 2.2Ghz, 12 GB RAM, nVidia GTX 760M and Intel HD 4600
    Raspberry Pi 3: Raspbian OS use for Home Samba Server and Test HTTP Server

  3. #3
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,818
    Rep Power
    10

    Re: How to create a new thinBasic keyword in Delphi

    Sorry, I do not understand your question.

    Remember you are in the script and parser (thinCore.dll) does not know anything about new keyword and its syntax.
    thinBasic is interpreting on the fly so it has no clue of what a command syntax is, how many parameters and which type.
    thinBasic just give you the tools (exported functions) to make what you prefer.
    All thinBasic modules are done in this way. Petr TBGL module does exactly that but using PowerBasic as development language.

    Not sure I've replied correctly to your question. If not please give me more info.

    Ciao
    Eros
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  4. #4
    thinBasic MVPs kryton9's Avatar
    Join Date
    Nov 2006
    Location
    Naples, Florida & Duluth, Georgia
    Age
    68
    Posts
    3,865
    Rep Power
    405

    Re: How to create a new thinBasic keyword in Delphi

    I will play with it Eros and see if I can give an example, will post back in a bit after I see what happens
    Acer Notebook: Win 10 Home 64 Bit, Core i7-4702MQ @ 2.2Ghz, 12 GB RAM, nVidia GTX 760M and Intel HD 4600
    Raspberry Pi 3: Raspbian OS use for Home Samba Server and Test HTTP Server

  5. #5
    thinBasic MVPs kryton9's Avatar
    Join Date
    Nov 2006
    Location
    Naples, Florida & Duluth, Georgia
    Age
    68
    Posts
    3,865
    Rep Power
    405

    Re: How to create a new thinBasic keyword in Delphi

    Ok here is what I was trying, this is just changing the function in Delphi: I tried to pass the parameter to the function and commented out all the parsing commands, but I see that this will not work as thinBasic is giving me an error about Invalid Delimiter.
    But this is what I was trying to ask earlier, nothing like an example

    //----------------------------------------------------------------------------
    FUNCTION Exec_CalculatePowerOfTwo(mvalue : extended) : extended ; stdcall;
    //var mvalue : extended;

    begin

    //IF (thinBasic_CheckOpenParens) = true THEN
    //begin
    //thinBasic_ParseNumber(mvalue);
    // IF (thinBasic_CheckCloseParens) = true THEN
    //begin
    Exec_CalculatePowerOfTwo := mvalue * mvalue ;
    //end;
    //end;

    END;

    Acer Notebook: Win 10 Home 64 Bit, Core i7-4702MQ @ 2.2Ghz, 12 GB RAM, nVidia GTX 760M and Intel HD 4600
    Raspberry Pi 3: Raspbian OS use for Home Samba Server and Test HTTP Server

  6. #6
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,818
    Rep Power
    10

    Re: How to create a new thinBasic keyword in Delphi

    kryton9,

    functions defined inside Delphi cannot have parameters passed because thinBasic cannot know the number of parameters to pass.
    Functions in modules are compiled and there is no way to know anything about them. For this reason the only way for the parser to pass one or more value is to pass control of parsing over the module.

    So your function should be something like
    [code=Delphi] //----------------------------------------------------------------------------
    FUNCTION Exec_CalculatePowerOfTwo() : extended ; stdcall;
    var mvalue : extended;

    begin

    IF (thinBasic_CheckOpenParens) = true THEN
    begin
    thinBasic_ParseNumber(mvalue);
    IF (thinBasic_CheckCloseParens) = true THEN
    begin
    Exec_CalculatePowerOfTwo := mvalue * mvalue ;
    end;
    end;

    END;[/code]

    DLL in general has no info about the functions they have inside other than the name of the exported functions. When a dll function is executed it expects that all needed parameters are already in the process stack pushed by calling process. But to do this, calling process has to know EXACTLY how many parameters called function wants and EXACTLY of what type. If something is not correct a GPF is generated by the operating system.

    Back to the problem. Imagine you have linked a new keyword "CalculatePowerOfTwo" to the function Exec_CalculatePowerOfTwo
    When thinBasic encounter "CalculatePowerOfTwo" keyword, it search into its internal dictionary, found the related module and function pointer and than it PASS THE WHOOLE CONTROL to Exec_CalculatePowerOfTwo BECAUSE thinBasic does not know anything about Exec_CalculatePowerOfTwo.

    It can seem quite complex but this is the way all functions are executed.

    Another example I can give you. When you call an OS API function like, for example, WinBeep in KERNEL32.DLL, thinBasic is able to execute it only because you have declared as:
    [code=thinbasic]DECLARE FUNCTION WinBeep LIB "KERNEL32.DLL" ALIAS "Beep" (BYVAL dwFreq AS DWORD, BYVAL dwDuration AS DWORD) AS LONG[/code]
    In this way thinBasic knows exactly what parameters and of which type WinBeep need. thinBasic start reading values from the script and before calling WinBeep parameter values (or references) are loaded into the process stack. At this point thinBasic can call WinBeep and WinBeep will start immediatelly to pop parameters from the calling stack. If something is not in the correct sequence in the stack, GPF occurs.

    Not sure if I gave you enough and clear info on why things are done in a certain way. Of course there can be other possible roads but this is how it is done now.

    Eros
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  7. #7
    thinBasic MVPs kryton9's Avatar
    Join Date
    Nov 2006
    Location
    Naples, Florida & Duluth, Georgia
    Age
    68
    Posts
    3,865
    Rep Power
    405

    Re: How to create a new thinBasic keyword in Delphi

    Eros it all makes sense the way you explained it. All of this is new to me so as you explain it, I can understand more and more. Thanks you explained it really well and when you think about it, it makes a lot of sense. Just have to think about all that is happening and you really appreciate all that happens and what you have coded!!

    I am excited to report that I will soon have a very exciting example, the example is very simple, but you will see that it could lead to great things, mainly that any thinbasic user can download the free Turbo Delphi, use the IDE to develop their forms and then call with one call the form. Hope to have an example up real soon.
    Acer Notebook: Win 10 Home 64 Bit, Core i7-4702MQ @ 2.2Ghz, 12 GB RAM, nVidia GTX 760M and Intel HD 4600
    Raspberry Pi 3: Raspbian OS use for Home Samba Server and Test HTTP Server

Similar Threads

  1. How to create a new SDK?
    By Michael Hartlef in forum Turbo Delphi language SDK development
    Replies: 2
    Last Post: 30-11-2008, 13:46

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

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