Oxygenbasic comes in the form of a single-32 bit DLL. It can be used for both immediate compile/execute and for producing conventional PE binary files.
This is the current API for PowerBasic use.
'OxygenBasic API for PowerBasic
'10:07 28/02/2013
'Charles Pegge
MACRO oxy="..\..\oxygen.dll"
DECLARE FUNCTION o2_asmo LIB oxy ALIAS "o2_asmo" (BYVAL STRING) AS STRING ' compile
DECLARE FUNCTION o2_basic LIB oxy ALIAS "o2_basic" (BYVAL STRING) AS STRING ' compile
DECLARE FUNCTION o2_exec LIB oxy ALIAS "o2_exec" (OPTIONAL BYVAL LONG) AS LONG ' run compile program
DECLARE FUNCTION o2_link LIB oxy ALIAS "o2_link" (BYVAL STRING) AS STRING ' o2 link **
DECLARE FUNCTION o2_view LIB oxy ALIAS "o2_view" (BYVAL STRING) AS STRING ' o2 coding
DECLARE FUNCTION o2_prep LIB oxy ALIAS "o2_prep" (BYVAL STRING) AS STRING ' assembly code (x86)
DECLARE FUNCTION o2_abst LIB oxy ALIAS "o2_abst" (BYVAL STRING) AS STRING ' abstract assembly code
DECLARE FUNCTION o2_error LIB oxy ALIAS "o2_error" () AS STRING ' error message if any
DECLARE FUNCTION o2_errno LIB oxy ALIAS "o2_errno" () AS LONG ' error number or zero
DECLARE FUNCTION o2_len LIB oxy ALIAS "o2_len" () AS LONG ' length of returned string
DECLARE FUNCTION o2_buf LIB oxy ALIAS "o2_buf" (BYVAL LONG)AS LONG ' buffer selector 0..511 (returns pointer)
DECLARE SUB o2_mode LIB oxy ALIAS "o2_mode" (BYVAL LONG) ' set string i/o mode: 1 asciiz 9 bstring (pb)
DECLARE SUB o2_put LIB oxy ALIAS "o2_put" (BYVAL STRING) ' load code into an exec buffer
DECLARE FUNCTION o2_get LIB oxy ALIAS "o2_get" ()AS LONG ' get pointer to code in exec buffer
And here is a minimal example of using OxygenBasic:
#COMPILE EXE
#DIM ALL
#INCLUDE "OxygenPb.inc"
FUNCTION PBMAIN () AS LONG
DIM s AS STRING
'
s="print 100+20+3"
'
o2_basic s
IF o2_errno THEN
MSGBOX o2_error(),%MB_OK,"Oxygen"
ELSE
o2_exec
END IF
END FUNCTION
Charles
Really nice work Charles.
Thanks Charles - Just what I've been looking for, for a while. Much appreciated
To produce independent EXE/DLL files, one of the runtime libraries is included at the top of the source:
'COMPILING 32BIT OR 64BIT PE FILES
#COMPILE EXE
#DIM ALL
#INCLUDE "OxygenPb.inc"
FUNCTION PBMAIN () AS LONG
DIM exe32 AS STRING
DIM exe64 AS STRING
DIM t AS STRING
'
exe32="%filename `t32.exe`"+$CRLF+"include `..\..\inc\RTL32.inc`"+$CRLF
exe64="%filename `t64.exe`"+$CRLF+"include `..\..\inc\RTL64.inc`"+$CRLF
t="print 100+20+3"
'
o2_basic exe64+t
IF o2_errno THEN
MSGBOX o2_error(),%MB_OK,"Oxygen"
END IF
END FUNCTION
Charles
The run time libraries contain all the core functions that OxygenBasic knows about. It only includes the bare essentials, so it is quite a small set. But the compiler can be deployed to add its own library extensions.
Also, by adding alternative syntax translation and error-trapping, it is possible to build a new language shell around this kernel.
KB - Kernel Basic 8)
Just wondering - being lazy really but then there is no point re inventing the wheel. Is there any code to pass PowerBasic variables to the OxygenBasic in existence, this would be extremely useful.
Jon
Yes,sharing variables directly between a PB host program and OxygenBasic at run time, in memory, not using a DLL.
This is a little complex but very efficient once set up.
On o2_exec, Oxygen returns a table of functions back to PB.
PB can then pass a VARPTR to Oxygen..
Then both sides have mutual access to the PB host variables.
The Oxygen program is finally terminated to release its memory allocations.
PB side
#COMPILE EXE
#DIM ALL
#INCLUDE "OxygenPb.inc"
DECLARE SUB ShareWithOxygen(BYVAL pv AS LONG PTR, BYVAL n AS LONG)
DECLARE SUB ShowHostVars()
DECLARE SUB EndOxygen()
FUNCTION PBMAIN () AS LONG
DIM SharedVars(1024) AS STATIC LONG
DIM s AS STRING
DIM a AS LONG PTR
DIM pv AS LONG PTR
DIM i AS LONG
'
'SOME DATA
'
FOR i=0 TO 9
SharedVars(i)=i*2
NEXT
'
'COMPILE
'
s="Include `ShareVarsWithHost.o2bas`"
o2_basic s
IF o2_errno THEN
MSGBOX o2_error(),%MB_OK,"Oxygen"
ELSE
a=o2_exec
'msgbox(hex$(a)+" "+hex$(@a[0])+" "+hex$(@a[1]))
CALL DWORD @a[0] USING ShareWithOxygen (VARPTR(SharedVars(0)),10)
CALL DWORD @a[1] USING ShowHostVars
'...
CALL DWORD @a[2] USING EndOxygen
END IF
END FUNCTION
Oxygen side: ShareVarsWithHost.o2bas
sys *HostVars 'accepts vartptr to host variable block
sys nHostVars 'number of variables in block
sub ShareWithOxygen(sys a,n) external
=====================================
@hostvars=a
nhostvars=n
end sub
sub ShowHostVars() external
===========================
sys i
string pr="Host variables:"+chr(13,10)
for i=1 to nHostVars
pr+=HostVars[i]+chr(13,10)
next
print pr
end sub
sub EndOxygen() external
========================
terminate
end sub
sys ProcTable[3]={&ShareWithOxygen,&ShowHostVars,&EndOxygen}
= &ProcTable
end
You can of course, also use the subs and functions for passing data in the conventional way
Charles
Thanks Charles - you have saved me hours of work and probably a lot of others if they have the sense to use your very useful OxygenBasic
Thanks again - Much appreciated
Jon
You are welcome John. I am collecting these examples together in the Oxygen in-progress version. The folder is currently ProjectsB/PowerBasic