• Welcome to Jose's Read Only Forum 2023.
 

Using $ to Translate Source Code

Started by Charles Pegge, August 10, 2007, 09:04:05 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Charles Pegge

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



Charles Pegge

#1
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



Petr Schreiber

Hi,

thanks for your samples, "$" looks interesting!
Do you have some IDE for it ?


Thanks,
Petr
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Charles Pegge

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.