Translating #define
This code shows how to translate #define into % equates. It collects the equates as it parses the entire source code, and prefixes the constants with '%', for PowerBasic syntax.
This was tested on $.bas (FreeBasic source code)
$ script
function main()
replace_hash_define("$.bas","t.bas")
end function
function replace_hash_define(nfi,nfo)
new fi=input(nfi)
new fo=output(nfo)
new t-"", crlf=chr(13)+chr(10)
new eqls=" "
new w="",w1="",p1,p2,p3
{
if eof(fi) then exit
t=in(fi)
read(lower(t),1,"#:")
{
w=word(); if not w then exit
p1=@1 // start position
{ // cases
p3=pos(eqls," "+w+" ")
if p3
p2=p1+len(w)
t=midl(t,1,p1)+"%"+upper(w)+mid(t,p2)
t? // monitor progress
p2++
read(lower(t),p2,"#:")
exit
end if
if w EQ "#"
w=word()
if w EQ "define"
w=word()
eqls+=w+" "
w1="%"+upper(w)+"="
p2=@2 //next word pos
t=midl(t,1,p1)+w1+mid(t,p2)
read(lower(t),p2,"#:")
end if
exit
end if
} // cases
repeat
}
out(fo,t+crlf)
repeat
}
close(fi)
close(fo)
'"REPLACED: "+eqls?
"done"?
end function
Splitting DIMs
Translating from this:
FreeBasic
#define constA 123
#define constB 456
dim ba as long
dim ab as string
dim shared as string abz ' comment
dim shared as long a,b(constA,constB),c=31,d="intial string"
dim ub as ubyte pointer : #define aaa 32
#define aab 33
Into this:
PowerBasic
%CONSTA=123
%CONSTB=456
DIM ba AS LONG
DIM ab AS STRING
DIM abz AS GLOBAL STRING ' comment
DIM a AS GLOBAL LONG
DIM b(%CONSTA,%CONSTB) AS GLOBAL LONG
DIM c AS GLOBAL LONG
DIM d AS GLOBAL LONG
c=31
d="intial string"
DIM ub AS BYTE PTR
%AAA=32
%AAB=33
$ script
function main()
fb_to_pb("s.bas","t.bas") ' for #define and dims
end function
'
' System variables:
' These values are set as a result of using the word() function
' @1 position of word
' @2 position of next word
' @3 length of word
' @4 ascii of start of word
' @5 ascii of start of next word
function fb_to_pb(nfi,nfo)
' translates #define and dim
new fi=input(nfi)
new fo=output(nfo)
new t-"", crlf=chr(13)+chr(10)
new eqls=" " // equates list
new w1="",p1,p2,p3,p4,dop
{
if eof(fi) then exit
t=in(fi)
read(lower(t),1,"#:")
dop=1
{
w1=word(); if not w1 then exit
p1=@1 // start position
{ // cases
if w1 EQ "dim"
do dims
exit
end if
do const_check
if p4 then exit
if w1 EQ "#"
w1=word()
if w1 EQ "define"
w1=word()
eqls+=w1+" "
w1="%"+upper(w1)+"="
p2=@2 //next word pos
t=midl(t,1,p1)+w1+mid(t,p2)
read(lower(t),p2,"#:")
end if
exit
end if
} // cases
repeat
}
if dop then out(fo,t ? +crlf)
repeat
}
close(fi)
close(fo)
"CONSTANTS: "+eqls?
"done"?
end
def dims
{ // block scope
new wd[16]="", c=0, s="", nt=0,ta="",ct="",b=0
new asf="",scopef="",typef=""
{ // loop
w1=word()
if not w1
exit
end if
if @4 EQ 58
read(t,@2,"#:"); nt=1
exit
end if
if w1 EQ "shared"
scopef="GLOBAL "
repeat
end if
if w1 EQ "common" // ignore
repeat
end if
if w1 EQ "as"
asf=" AS "
w1=word()
typef=upper(w1) // AS [type]
if typef EQ "UBYTE" then typef="BYTE"
p3=@2
w1=word()
if (w1 EQ "ptr")or(w1 EQ "pointer")
typef+=" PTR"
p3=@2
end if
set @2=p3 // set lex position
repeat
end if
if w1 EQ ","
repeat
end if
c++
wd[c]=w1
'do var_expr
'@5?
if @5 EQ 40 // look ahead
b=0
p3=@2
{ // skip brackets
w1=word()
if not w1 then exit
if w1 EQ "(" then b++
if w1 EQ ")" then b--
if b EQ 0 then exit
do const_check
'" decl const check: "+w1? // monitor progress
repeat
} // skip brackets
wd[c]=wd[c]+midl(t,p3,@2)
end if
if @5 EQ 61
p3=@2
{ // skip till comma (skip barackets)
w1=word()
if not w1 then exit
if w1 EQ "(" then b++
if w1 EQ ")" then b--
if w1 EQ "," then if b EQ 0 then exit
do const_check
'" expr const check: "+w1? // monitor progress
repeat
} // skip expr
ta+=wd[c]+midl(t,p3,@1)+crlf
end if
if @5 EQ 39 // comment
ct=" "+mid(t,@2)
t=""
exit
end if
repeat // main dim loop
} // main DIM loop
new i=0
{ // iterate
if ++i GT c then exit
s="DIM "+wd[i]+asf+scopef+typef+ct
ct=""
out(fo,s+crlf)
s?
repeat
} // iterate for each var
if len(ta) // assigned vars
ta?
out(fo,ta); ta=""
end if
dop=nt // can suppress further output if nt was 0
t=mid(t,@2)
read(lower(t),1,"#:")
} // scope
end // DIM
def const_check
p4=pos(eqls," "+w1+" ")
'w1?
if p4
p2=@1+len(w1)
t=midl(t,1,@1)+"%"+upper(w1)+mid(t,p2)
p2++
read(lower(t),p2,"#:")
end if
end
end function
Hi,
thanks for your samples, "$" looks interesting!
Do you have some IDE for it ?
Thanks,
Petr
Nothing specific Petr. I use Notepad in MS Windows and Kwrite in Linux, which looks very nice with context-sensitive highlighting, even though its not a perfect match.
When you run $ it always starts execution with the main.pro source file and the default output is to log.txt as well as the console. It's a minimalist idea but I find it works well straight from the desktop where you may be using multiple input and output files.
Because $ is such a small file, I just drop a copy into each project folder that uses it.
I am also working on the logistics of making it work as an embeddable script language. I think deploying it in a DLL will be the best way to do this.