Dear Dan,
I had some time and I developed a extremely base example of a thinBasic module developed with Free Pascal.
Module implements a single function called HalfNumber whose syntax is the following:
n = HalfNumber(AnyNumericExpression) AS Extended
In order to keep things as simple as possible, for the moment I've implemented a function that expects just a numeric expression as input.
As soon as you have got the whole picture we can see how to develop a new keyword that expects additional parameters.
Attached all the needed files:
- a Lazarus project you can open and compile or change as you need.
It produces the DLL module.
Attention: if you compile source code by manual, library MUST be compiled using -WR directive (Generate a relocatable library. This library can be moved To another location In memory If the ImageBase address it wants Is already In use) - a thinBasic example using such a module
Here the source code of the Free Pascal module just to have a look at it before downloading.
library FreePascalExample;
{$mode objfpc}{$H+}
uses
Classes, Windows
{ you can add units after this };
{$R *.res}
// ------------------------------------------------------
// thinBasic_LoadSymbol_Delphi is used to declare new keywords in thinBasic language
function thinBasic_LoadSymbol_Delphi(SymbolName: string; ReturnCode: LongInt; FunctionOrSubPointer: pointer; ForceOverWrite: LongInt = 0): LongInt; stdcall; external 'thinCore.dll';
// ------------------------------------------------------
// Tell thinCore to parse a single numeric expression
// ------------------------------------------------------
function thinBasic_Parse1Number (): Extended; stdcall; external 'thinCore.dll' ;
// ------------------------------------------------------
// ------------------------------------------------------
// Ok, here we are with our first new thinBasic new keyword function
// Syntax of the function will be: n = HalfNumber(AnyNumericExpression) AS Extended
function Exec_HalfNumber(): Extended; stdcall;
var
MyExt: Extended;
begin
//thinBasic_Parse1Number will parse any numeric expression it will encounter
//passing back the result of the operation
MyExt := thinBasic_Parse1Number;
//Now that we have a number, we can get its half and return result
Exec_HalfNumber := MyExt / 2;
end;
// ------------------------------------------------------
// LoadLocalSymbols is automatically executed by thinCore
// consider LoadLocalSymbols as entry point of the module
// when "Uses" key is encountered
// LoadLocalSymbols is the place where all internal module functions
// must be declared to thinCore using "thinBasic_LoadSymbol_Delphi" function
// LoadLocalSymbols can also be used to initialize any variable or element needed by module
// LoadLocalSymbols IS MANDATORY and MUST be present in all thinBasic module
// ------------------------------------------------------
function LoadLocalSymbols(sPath: WideString): Longint; cdecl;
begin
// messagebox(0, Pointer(sPath),'Hello World from module. Path of module is',MB_OK or MB_ICONSTOP);
// here we are telling that the module implements a new thinBasic function called "HalfNumber"
// and it is connected to Exec_HalfNumber function
thinBasic_LoadSymbol_Delphi ('HalfNumber', 10, @Exec_HalfNumber, 0);
// Just return zero
LoadLocalSymbols := 0;
end;
// ------------------------------------------------------
// UnLoadLocalSymbols is executed by thinCore when thinBasic is going
// to unload from memory
// Use UnLoadLocalSymbols to execute any needed module clean up
// UnLoadLocalSymbols is NOT mandatory to exist
// ------------------------------------------------------
function UnLoadLocalSymbols(): Longint; cdecl;
begin
UnLoadLocalSymbols := 0;
end;
exports
LoadLocalSymbols, UnLoadLocalSymbols;
end.
Hope this can help to start.
Ciao
Eros
Bookmarks