[ New messages · Members · Forum rules · Search · RSS ]
  • Page 1 of 1
  • 1
Forum » General category » ALL HOBBY programming » micro(A) Interpreter
micro(A) Interpreter
ZlatkoDate: Thursday, 2019-10-24, 9:02 PM | Message # 1
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
Token based simple experimental interpreter (o2):
https://aurelsoft.ucoz.com/microAInterpreter.zip
 
ZlatkoDate: Monday, 2020-03-30, 7:00 PM | Message # 2
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
Here is a source code of tokenizer 30.3.2020

'micro(A) tokenizer by Aurel 29.3.2020
Include "microBh.inc"
INT startTime ,endTime: float procTime  ' GetTickCount -timer init
declare sub tokenizer( src as string) as INT
declare sub run_tokenizer(inputCode as string) as INT
int tkNULL=0, tkPLUS=1, tkMINUS=2, tkMULTI=3, tkDIVIDE=4
int tkCOLON=5, tkCOMMA=6, tkLPAREN=7, tkRPAREN=8, tkLBRACKET=9, tkRBRACKET=10
int tkIDENT = 11 , tkNUMBER = 12 , tkSTRING = 13, tkCOMMAND =14 ,tkEOL = 15
int tkEQUAL = 16, tkMORE = 17, tkLESS =18,tkAND=19, tkOR=20, tkNOT = 21
int tkHASH=22 , tkSSTR=23, tkMOD=24

string tokList[1024] : int typList[1024]                     'token/type arrays
int start , p = 1 ,start = p ,tp , tn, n ,ltp=1 ,nTokens     ' nTokens -> number of tokens
int lineCount, Lpar, Rpar, Lbrk, Rbrk, tokerr ,codeLen=0
string code,ch,tch,tk ,crlf=chr(13)+chr(10),bf,ntk
'--------------------------------------------------------------------
'code = "2*(3+4)"     + crlf  +  ' line 1
       '"': b =6 "   + crlf  +  ' line 2
      ' ":if a>b"    + crlf     ' line 3
' ~~~~~~~~~~~~~~~~     MAIN TOKENIZER SUBROUTINE  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SUB tokenizer(src as string) as int 
'print "tokenizer run;" + src
lineCount=0:ltp=start : nTokens = 0
while p <= len(src)
 '................................................................................................          
    ch = mid(src,p,1)                                                  ' get char
 If asc(ch)=32 : p=p+1 : end if                                        ' skip blank space[ ]
 If asc(ch)=9  : p=p+1 : end if                                        ' skip TAB [    ]
 if asc(ch)=13 : p=p+1 : end if                                        ' skip CR
 if asc(ch)=39                                                         ' skip comment line[ ' ]                                                       
    while asc(ch) <> 10 
      p++ : ch = mid(src,p,1) : if asc(ch)= 10 then exit while
    wend
   p++: goto endLoop                                                   ' jump to end of loop
 end if 

 If asc(ch)=10                                                         ' EOL
if Lpar > Rpar  : tokerr=3 : goto tokExit : end if   ' if Rparen ((...)
if Lpar < Rpar  : tokerr=4 : goto tokExit : end if   ' if Lparen (...))
if Lbrk > Rbrk  : tokerr=5 : goto tokExit : end if   ' if Lbracket [..
if Lbrk < Rbrk  : tokerr=6 : goto tokExit : end if   ' if Rbracket ...]
 lineCount++ : tp++ : tokList[tp]="EOL" :typList[tp]= tkEOL: tk="": ch="" : p++ 
 End if 
'--------------------------------------------------------
 If asc(ch)=34                                                         ' if char is QUOTE "
 p++ :  ch = mid(src,p,1) : tk=ch : p++                                ' skip quote :add ch TO tk buffer: p+1
while asc(ch) <> 34        
   ch = mid(src,p,1) : if asc(ch)= 34 then exit while
        tk=tk+ch : p++ 
        IF ch = chr(10): tokerr = 2: goto tokExit : end if
wend
    tp++ : tokList[tp]= tk :typList[tp]= tkSTRING: tk="":ch="": p++    ' add quoted string to token list
 End if
'-------------------------------------------------------            
 If (asc(ch)>96 and asc(ch)<123) or (asc(ch)>64 and asc(ch)<91)                                         ' [a-z,A-Z]
   while (asc(ch)>96 and asc(ch)<123) or  (asc(ch)>64 and asc(ch)<91) or (asc(ch)>47 and asc(ch)<58)    ' [a-z,A-Z,0-9]*
         tk=tk+ch : p++ : ch = mid(src,p,1) 
   wend
      ' ' add token ,add token type/IDENT:{VAR/COMMAND}
       tp++ : tokList [tp]= tk :typList[tp]= tkIDENT: tk="":ch=""       
 End If
'--------------------------------------------------------------
 If (asc(ch)>47 and asc(ch)<58)                                       ' [0-9.]
    while (asc(ch)>47 AND asc(ch)<58) OR asc(ch)=46                   ' [0-9[0.0]]*
        tk=tk+ch :p++ : ch = mid(src,p,1)
    wend
       ' add token ,add token type/NUMBER
       tp++ : tokList [tp]= tk : typList[tp]= tkNUMBER: tk="":ch=""
 End if
'--------------------------------------------------------------------
 If asc(ch)=43 : tp++ : tokList [tp]= ch :typList[tp]= tkPLUS:    ch="" : p++ : End if  ' + plus 
 If asc(ch)=45 : tp++ : tokList [tp]= ch :typList[tp]= tkMINUS:   ch="" : p++ : End if  ' - minus
 If asc(ch)=42 : tp++ : tokList [tp]= ch :typList[tp]= tkMULTI:   ch="" : p++ : End if  ' * multiply
 If asc(ch)=47 : tp++ : tokList [tp]= ch :typList[tp]= tkDIVIDE:  ch="" : p++ : End if ' / divide
 If asc(ch)=40 : tp++ : tokList [tp]= ch :typList[tp]= tkLPAREN:  ch="" : p++ : Lpar++ : End if ' ( Lparen
 If asc(ch)=41 : tp++ : tokList [tp]= ch :typList[tp]= tkRPAREN:  ch="" : p++ : Rpar++ : End if ' ) Rparen
 If asc(ch)=44 : tp++ : tokList [tp]= ch :typList[tp]= tkCOMMA:   ch="" : p++ : End if  ' , comma
 If asc(ch)=58 : tp++ : tokList [tp]= ch :typList[tp]= tkCOLON:   ch="" : p++ : End if  ' : colon
 If asc(ch)=60 : tp++ : tokList [tp]= ch :typList[tp]= tkLESS:    ch="" : p++ : End if  ' < less
 If asc(ch)=61 : tp++ : tokList [tp]= ch :typList[tp]= tkEQUAL:   ch="" : p++ : End if  ' = equal
 If asc(ch)=62 : tp++ : tokList [tp]= ch :typList[tp]= tkMORE:    ch="" : p++ : End if  ' > more(greater)
 If asc(ch)=91 : tp++ : tokList [tp]= ch :typList[tp]= tkLBRACKET:ch="" : p++ : Lbrk++ :End if  ' [ Lbracket
 If asc(ch)=93 : tp++ : tokList [tp]= ch :typList[tp]= tkRBRACKET:ch="" : p++ : Rbrk++ :End if  ' ] Rbracket
 If asc(ch)=38 : tp++ : tokList [tp]= ch :typList[tp]= tkAND:     ch="" : p++ : End if  ' & AND
 If asc(ch)=124 :tp++ : tokList [tp]= ch :typList[tp]= tkOR:      ch="" : p++ : End if       ' | OR
 If asc(ch)=33 : tp++ : tokList [tp]= ch :typList[tp]= tkNOT:     ch="" : p++ : End if  ' ! NOT
 If asc(ch)=35 : tp++ : tokList [tp]= ch :typList[tp]= tkHASH:    ch="" : p++ : End if  ' # hash
 If asc(ch)=36 : tp++ : tokList [tp]= ch :typList[tp]= tkSSTR:    ch="" : p++ : End if  ' $ $TRING
 If asc(ch)=37 : tp++ : tokList [tp]= ch :typList[tp]= tkMOD :    ch="" : p++ : End if  ' % percent/MOD 
 
IF ASC(ch)>125 : tokerr = 1 : goto tokExit : END IF
'.............................................................................................
endLoop:
wend
Return tp
tokExit:
  IF tokerr > 0 
if tokerr = 1: MsgBox "Unknown token!-[ " + ch +" ] at LINE: " + str(lineCount),"T:Error"  : end if
if tokerr = 2: MsgBox "Unclosed Quote!- at LINE: " + str(lineCount),"T:Error"              : end if
if tokerr = 3: MsgBox "Missing right paren! ((...)- at LINE: " + str(lineCount),"T:Error"  : end if
if tokerr = 4: MsgBox "Missing left paren!- at LINE: " + str(lineCount),"T:Error"          : end if
if tokerr = 5: MsgBox "Missing right bracket!- at LINE: " + str(lineCount),"T:Error"       : end if
if tokerr = 6: MsgBox "Missing left bracket!- at LINE: " + str(lineCount),"T:Error"        : end if
Return 0 
  END IF

END SUB

/*'call tokenizer..tested(ident,numbers) /////////////////////////////////
int tn: tn = tokenizer(code) 
*/
 'if tn=0 then goto ExitProgram  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
SUB run_tokenizer(s as string ) as INT
  
     tn = tokenizer(s)
     If tokerr > 0 
     if tn = 0 then goto ExitTokenizer
     End if
  
print "Number of tokens: " + str(tn) + crlf + "Number of lines: " + str(lineCount): nTokens = tn
For n = 1 to tn : bf = bf + tokList [n]+ crlf : Next n
MsgBox bf,"Token List:"  ' show token list
return 1  ' if OK return 1
ExitTokenizer:
MsgBox "EXIT from TOKENIZER" ,"Process Terminated!"
return 0
END SUB

IF codeLen>0
ExitProgram:
MsgBox "EXIT..." ,"Program Terminated!" : tn = 0
END IF
 
ZlatkoDate: Monday, 2020-03-30, 7:03 PM | Message # 3
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
And here is src of Interpreter:

'micro(A) Interpreter - with recursive descent token evaluator
' by Aurel - 26.3.2019 - last test 30.1.2020
include "awinh037.inc"                              ' awinh GUI api function
include "microAT.inc"                               ' tokenizer include
#lookahead
int tc=0                                            ' token count
string token                                        ' define   token as string
'*********************************************************************
'globals
INT win,x=0,y=0,w=400,h=300,wstyle = WS_MINMAXSIZE
INT button0,b0ID=100
NumberFormat 6,1,0,0,0,0
'Interpreter Globals .........................................................................
string kwList[8]   'keyword list 
kwList[1] = "VARNUM" : kwList[2] = "VARSTR" : kwList[3] = "VARPTR"

'..............................................................................................
int tkSTRING = 32, tkFLOAT = 33 , tkPOINTER = 34 , tkIF = 35 , tkELSE = 36, tkENDIF = 37
int tkWHILE = 38, tkWEND = 39 , tkPRINT = 40 
'Global Variable,ID etc array ................................................................
int varID = 0
int varList[1024] : string varStr[1024] : float varNum[1024] : int varPtr[1024]
 
' Open Window with message loop...
win = SetWindow("micro(A):",x,y,w,h,0,wstyle)
'button0 = SetButton(win,180,4,80,26,"Close (X)",0x50001000,0x200,b0ID)
'*********************************************************************

'test 1 - load source code into (microAT.inc) Tokenizer
string code = "varNum a,b" + crlf             'enter your expression / crlf=EOL
codeLen=len(code)
tn = run_tokenizer(code) 
MsgBox  str(tn) ,"Tokenizer Out"                     ' 1 means OK!
'---------------------------------------------------------------
' prescan for variables,commands....
'---------------------------------------------------------------
'if tokenization error=0 then OK!..preScan()
int ps
If tokerr = 0 and tn = 1
   ps = preScan()   
Else
   MsgBox "END" ,"Program Exit!"
End if

'if ps = 1 then OK...........................
if ps = 1 
   MsgBox "PreScan:OK!" ,"Continue..."
   exec_expr()
Else
   MsgBox "END" ,"Program Exit!"
End if

'================================================================
Wait()  '/// message loop ///
'===========================================================================================
Function WndProc (sys hwnd,wmsg,wparam,lparam) as sys callback
SELECT hwnd
CASE win
Select wmsg
CASE WM_CLOSE
CloseWindow(win) 
EndProgram
End Select
END SELECT
RETURN Default
END FUNCTION

'===========================================================================================

Sub preScan() as int
'MsgBox "OK..." ,"Pre:SCAN"
int i , numOfTokens = nTokens : nTokens=0 :varID=0    ' numofTokens as local/reset global nTokens
For i = 1 to numOfTokens
IF typList = tkIDENT

             if ucase(tokList) = kwList[1]     ' if token -> varNum
               typList = tkFLOAT

    elseif ucase(tokList) = kwList[2] ' if token -> varStr
               typList = tkSTRING

    elseif ucase(tokList) = kwList[3] ' if token -> varPtr
typList = tkPOINTER

else
               'is variable name
               varID = varID + 1 : varList = varID
   end if
         
END IF

Next i
return 1

End sub

'while typList <> tkEOL OR typList <> tkCOMMA
'i=i+1 
'if typlist = tkCOMMA then i=i+1
'wend                 
'-----------------------------------------------------
sub gettok()
tc++
token = tokList 
[tc]
'test
if tokList[tc+1] <> "" then return
end sub
'----------------------------------------------------
sub expr() as float
float v
If token = "-" 
 v = -(term())
else
 v = term()
end if 
 
while token = "+" or token = "-"
if token = "+": gettok() : v = v + term(): end if
if token = "-": gettok() : v = v - term(): end if
wend

return v
end sub
'---------------------------------------------------
sub term() as float
float v 
v = factor()

while token = "*" or token = "/"
if token = "*": gettok() : v = v * factor(): end if
if token = "/": gettok() : v = v / factor(): end if
wend

return v
end sub 
'-------------------------------------------------------

sub factor() as float
float v
if asc(token)>47  and asc(token)<58 'nums
v = val(token) 
'print str(v)+ " factor"
gettok()
end if

if asc(token)=40 and asc(token)<>41 'match (...)
gettok() : v = expr() : gettok()
end if

return v
end sub

'execute-----------------------------------------------------
sub exec_expr
gettok()'start
float res = expr()
MsgBox "RESULT=" + str(res) , "EXEC_EXPR:"
end sub
 
ZlatkoDate: Tuesday, 2020-03-31, 5:40 PM | Message # 4
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
31.3.2020

'micro(A) Interpreter - with recursive descent token evaluator
' by Aurel - 26.3.2019 - last test 30.1.2020
include "awinh037.inc"                              ' awinh GUI api function
include "microAT.inc"                               ' tokenizer include
#lookahead
int tc=0                                            ' token count
string token                                        ' define   token as string
'*********************************************************************
'globals
INT win,x=0,y=0,w=400,h=300,wstyle = WS_MINMAXSIZE
INT button0,b0ID=100
NumberFormat 6,1,0,0,0,0
'Interpreter Globals .........................................................................
string kwList[8]   'keyword list 
kwList[1] = "VARNUM" : kwList[2] = "VARSTR" : kwList[3] = "VARPTR"

'..............................................................................................
int tkSTRING = 32, tkFLOAT = 33 , tkPOINTER = 34 , tkIF = 35 , tkELSE = 36, tkENDIF = 37
int tkWHILE = 38, tkWEND = 39 , tkPRINT = 40 
'Global Variable,ID etc array ................................................................
int varID = 0
int varList[1024] : string varName[1024] :   string varStr[1024] : float varNum[1024] : int varPtr[1024]
 
' Open Window with message loop...
win = SetWindow("micro(A):",x,y,w,h,0,wstyle)'
'button0 = SetButton(win,180,4,80,26,"Close (X)",0x50001000,0x200,b0ID)
'*********************************************************************

'test 1 - load source code into (microAT.inc) Tokenizer
string code = "vaRnum a,b,c,d:" + crlf            'enter your expression / crlf=EOL
codeLen=len(code)
tn = run_tokenizer(code) 
MsgBox  str(tn) ,"Tokenizer Out"                     ' 1 means OK!
'---------------------------------------------------------------
' prescan for variables,commands....
'---------------------------------------------------------------
'if tokenization error=0 then OK!..preScan()
int ps
If tokerr = 0 and tn = 1
   ps = preScan()   
Else
   MsgBox "END" ,"Program Exit!"
End if

'if ps = 1 then OK...........................
if ps = 1 
   MsgBox "PreScan:OK!" ,"Continue..."
   exec_expr()
Else
   MsgBox "END" ,"Program Exit!"
End if

'================================================================
Wait()  '/// message loop ///
'===========================================================================================
Function WndProc (sys hwnd,wmsg,wparam,lparam) as sys callback
SELECT hwnd
CASE win
Select wmsg
CASE WM_CLOSE
CloseWindow(win) 
EndProgram
End Select
END SELECT
RETURN Default
END FUNCTION

'===========================================================================================

Sub preScan() as int
'MsgBox "OK..." ,"Pre:SCAN"
int i , numOfTokens = nTokens ,lineNum=0 : nTokens=0 :varID=0     ' numofTokens as local/reset global nTokens
For i = 1 to numOfTokens

IF typList=tkEOL:tokList="EOL":lineNum++ :END IF  'check EndOfLine

IF typList = tkIDENT
           If ucase(tokList) = kwList[1]: typList = tkFLOAT  'if varNUM ...........................
              if typList[i+1] <> tkIDENT 'check err
                 MsgBox "Missing variable after VARNUM! line: " + str(lineNum),"ERROR": return 0
else
              i=i+1 ' next token
               While typList <> tkCOLON And typList <> tkEOL  'store num variable
                  If typList = tkIDENT : varID = varID + 1 : varList = varID : varNum [varID]= 0 
                     MsgBox "Variable name: " + tokList ,"variable->Numeric"
                  End if
                i++
               Wend 
     end if
          End if  ' endOf varNUM..........................................................................
         
END IF

Next i
return 1

End sub

'while typList <> tkEOL OR typList <> tkCOMMA
'i=i+1 
'if typlist = tkCOMMA then i=i+1
'wend    
'elseif ucase(tokList) = kwList[2] ' if token -> varStr
               'typList = tkSTRING

   ' elseif ucase(tokList) = kwList[3] ' if token -> varPtr
' typList = tkPOINTER
             
'-----------------------------------------------------
sub gettok()
tc++
token = tokList 
[tc]
'test
if tokList[tc+1] <> "" then return
end sub
'----------------------------------------------------
sub expr() as float
float v
If token = "-" 
 v = -(term())
else
 v = term()
end if 
 
while token = "+" or token = "-"
if token = "+": gettok() : v = v + term(): end if
if token = "-": gettok() : v = v - term(): end if
wend

return v
end sub
'---------------------------------------------------
sub term() as float
float v 
v = factor()

while token = "*" or token = "/"
if token = "*": gettok() : v = v * factor(): end if
if token = "/": gettok() : v = v / factor(): end if
wend

return v
end sub 
'-------------------------------------------------------

sub factor() as float
float v
if asc(token)>47  and asc(token)<58 'nums
v = val(token) 
'print str(v)+ " factor"
gettok()
end if

if asc(token)=40 and asc(token)<>41 'match (...)
gettok() : v = expr() : gettok()
end if

return v
end sub

'execute-----------------------------------------------------
sub exec_expr
gettok()'start
float res = expr()
MsgBox "RESULT=" + str(res) , "EXEC_EXPR:"
end sub
 
ZlatkoDate: Tuesday, 2020-03-31, 11:12 PM | Message # 5
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
function prescan..so far: 
'micro(A) Interpreter - with recursive descent token evaluator
' by Aurel - 26.3.2019 - last test 30.1.2020
include "awinh037.inc"                              ' awinh GUI api function
include "microAT.inc"                               ' tokenizer include
#lookahead
int tc=0                                            ' token count
string token                                        ' define   token as string
'*********************************************************************
'globals
INT win,x=0,y=0,w=400,h=300,wstyle = WS_MINMAXSIZE
INT button0,b0ID=100
NumberFormat 6,1,0,0,0,0
'Interpreter Globals .........................................................................
string kwList[8]   'keyword list 
kwList[1] = "VARNUM" : kwList[2] = "VARSTR" : kwList[3] = "VARPTR"

'..............................................................................................
int tkSTRING = 32, tkFLOAT = 33 , tkPOINTER = 34 , tkIF = 35 , tkELSE = 36, tkENDIF = 37
int tkWHILE = 38, tkWEND = 39 , tkPRINT = 40 
'Global Variable,ID etc array ................................................................
int varID = 0
int varList[1024] : string varName[1024] :   string varStr[1024] : float varNum[1024] : int varPtr[1024]
 
' Open Window with message loop...
win = SetWindow("micro(A):",x,y,w,h,0,wstyle)'
'button0 = SetButton(win,180,4,80,26,"Close (X)",0x50001000,0x200,b0ID)
'*********************************************************************

'test 1 - load source code into (microAT.inc) Tokenizer
string code = "vaRnum a,b: varSTR c,d:varPtr p,pp" + crlf            'enter your expression / crlf=EOL
codeLen=len(code)
tn = run_tokenizer(code) 
MsgBox  str(tn) ,"Tokenizer Out"                     ' 1 means OK!
'---------------------------------------------------------------
' prescan for variables,commands....
'---------------------------------------------------------------
'if tokenization error=0 then OK!..preScan()
int ps
If tokerr = 0 and tn = 1
   ps = preScan()   
Else
   MsgBox "END" ,"Program Exit!"
End if

'if ps = 1 then OK...........................
if ps = 1 
   MsgBox "PreScan:OK!" ,"Continue..."
   exec_expr()
Else
   MsgBox "END" ,"Program Exit!"
End if

'================================================================
Wait()  '/// message loop ///
'===========================================================================================
Function WndProc (sys hwnd,wmsg,wparam,lparam) as sys callback
SELECT hwnd
CASE win
Select wmsg
CASE WM_CLOSE
CloseWindow(win) 
EndProgram
End Select
END SELECT
RETURN Default
END FUNCTION

'===========================================================================================

Sub preScan() as int
'MsgBox "OK..." ,"Pre:SCAN"
int i , numOfTokens = nTokens ,lineNum=0 : nTokens=0 :varID=0     ' numofTokens as local/reset global nTokens
For i = 1 to numOfTokens

IF typList=tkEOL:tokList="EOL":lineNum++  : END IF  'check EndOfLine

IF typList = tkIDENT
           If ucase(tokList) = kwList[1]: typList = tkFLOAT  'if varNUM ...........................
              if typList[i+1] <> tkIDENT 'check err
                 MsgBox "Missing variable after VARNUM! line: " + str(lineNum),"ERROR": return 0
else
              i=i+1 ' next token
               While typList <> tkCOLON And typList <> tkEOL  'store num variable
                  If typList = tkIDENT : varID = varID + 1 : varList = varID : varNum [varID]= 0 
                     MsgBox "Variable name: " + tokList ,"variable->NUM"
                  End if
                i++
               Wend 
     end if
          End if  ' endOf varNUM..........................................................................
          If ucase(tokList) = kwList[2]: typList = tkSTRING  'if varSTR ...........................
              if typList[i+1] <> tkIDENT 'check err
                 MsgBox "Missing variable after VARSTR! line: " + str(lineNum),"ERROR": return 0
else
              i=i+1 ' next token
               While typList <> tkCOLON And typList <> tkEOL  'store str variable
                  If typList = tkIDENT : varID = varID + 1 : varList = varID : varStr [varID]= "" 
                     MsgBox "Variable name: " + tokList ,"variable->STR"
                  End if
                i++
               Wend 
     end if
          End if  ' endOf varSTR.......................................
          If ucase(tokList) = kwList[3]: typList = tkPOINTER  'if varPTR ...........................
              if typList[i+1] <> tkIDENT 'check err
                 MsgBox "Missing variable after VARPTR! line: " + str(lineNum),"ERROR": return 0
else
              i=i+1 ' next token
               While typList <> tkCOLON And typList <> tkEOL  'store ptr variable
                  If typList = tkIDENT : varID = varID + 1 : varList = varID : varPtr [varID]= 0 
                     MsgBox "Variable name: " + tokList ,"variable->PTR"
                  End if
                i++
               Wend 
     end if
          End if  ' endOf varPTR.......................................

END IF

Next i
return 1

End sub

'while typList <> tkEOL OR typList <> tkCOMMA
'i=i+1 
'if typlist = tkCOMMA then i=i+1
'wend    
'elseif ucase(tokList) = kwList[2] ' if token -> varStr
               'typList = tkSTRING

   ' elseif ucase(tokList) = kwList[3] ' if token -> varPtr
' typList = tkPOINTER
             
'-----------------------------------------------------
sub gettok()
tc++
token = tokList 
[tc]
'test
if tokList[tc+1] <> "" then return
end sub
'----------------------------------------------------
sub expr() as float
float v
If token = "-" 
 v = -(term())
else
 v = term()
end if 
 
while token = "+" or token = "-"
if token = "+": gettok() : v = v + term(): end if
if token = "-": gettok() : v = v - term(): end if
wend

return v
end sub
'---------------------------------------------------
sub term() as float
float v 
v = factor()

while token = "*" or token = "/"
if token = "*": gettok() : v = v * factor(): end if
if token = "/": gettok() : v = v / factor(): end if
wend

return v
end sub 
'-------------------------------------------------------

sub factor() as float
float v
if asc(token)>47  and asc(token)<58 'nums
v = val(token) 
'print str(v)+ " factor"
gettok()
end if

if asc(token)=40 and asc(token)<>41 'match (...)
gettok() : v = expr() : gettok()
end if

return v
end sub

'execute-----------------------------------------------------
sub exec_expr
gettok()'start
float res = expr()
MsgBox "RESULT=" + str(res) , "EXEC_EXPR:"
end sub
 
ZlatkoDate: Saturday, 2020-04-04, 10:37 PM | Message # 6
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
changes in preScan(pass1), add varName array to leave token list untouched varList[ID]
code:

'micro(A) Interpreter - with recursive descent token evaluator
' by Aurel - 26.3.2019 - last test 30.1.2020
include "awinh037.inc"                              ' awinh GUI api function
include "microAT.inc"                               ' tokenizer include
#lookahead
int tc=0 , ierror=0                                 ' token count, interpreting  error
string token : int tkTyp                            ' define  token as STRING : tkType as INT
'*********************************************************************
'globals
INT win,x=0,y=0,w=400,h=300,wstyle = WS_MINMAXSIZE
INT button0,b0ID=100
NumberFormat 6,1,0,0,0,0
'Interpreter Globals .........................................................................
string kwList[32]   'keyword list
kwList[1] = "VARNUM" : kwList[2] = "VARSTR" : kwList[3] = "VARPTR" : kwList[4] = "IF" : kwList[5] = "ELSE" : kwList[6] = "ENDIF"
kwList[7] = "WHILE" : kwList[8] = "WEND" : kwList[9] = "FOR" : kwList[10] = "TO" : kwList[11] = "STEP" : kwList[12] = "NEXT"
kwList[13]="PRINT" : kwList[14]="STR" : kwList[15]="VAL"
'..............................................................................................
int tkSTRING = 32, tkFLOAT = 33 , tkPOINTER = 34 , tkIF = 35 , tkELSE = 36, tkENDIF = 37
int tkWHILE = 38, tkWEND = 39 , tkFOR = 40 , tkTO = 41 , tkSTEP = 42 , tkNEXT = 43
int tkPRINT = 44 , tkSTR = 45, tkVAL = 46
'Global Variable,ID etc array ................................................................
int varID = 0
int varList[1024] : int varType[1024] :string varName[1024]: string varStr[1024] : float varNum[1024] : int varPtr[1024]
int ifCounter=0, elseCounter=0, endifCounter=0, whileCounter=0,wendCounter=0 ,forCounter=0,nextCounter=0

' Open Window with message loop...
win = SetWindow("micro(A):",x,y,w,h,0,wstyle)'
'button0 = SetButton(win,180,4,80,26,"Close (X)",0x50001000,0x200,b0ID)
'*********************************************************************

'test 1 - load source code into (microAT.inc) Tokenizer
string code = "varNum a: a=3 " + crlf            'enter your expression / crlf=EOL
codeLen=len(code)
tn = run_tokenizer(code)
MsgBox  str(tn) ,"Tokenizer Out"                     ' 1 means OK!
'---------------------------------------------------------------
' prescan for variables,commands....
'---------------------------------------------------------------
'if tokenization error=0 then OK!..preScan()
int ps
If tokerr = 0 and tn = 1
   ps = preScan()  
Else
   MsgBox "END" ,"Program Exit!"
End if

'if ps = 1 then OK...........................
if ps = 1
   MsgBox "PreScan:OK!" ,"Continue..."
   tokInterpreter()                  ' run token-interpreter
Else
   MsgBox "END" ,"Program Exit!"
End if

'================================================================
Wait()  '/// message loop ///
'===========================================================================================
Function WndProc (sys hwnd,wmsg,wparam,lparam) as sys callback
SELECT hwnd
CASE win
Select wmsg
    CASE WM_CLOSE
    CloseWindow(win)
    EndProgram
End Select
END SELECT
RETURN Default
END FUNCTION

'===========================================================================================

Sub preScan() as int
'MsgBox "OK..." ,"Pre:SCAN"
int i , numOfTokens = nTokens ,lineNum=0 :varID=0     ' numofTokens as local/reset global nTokens
    For i = 1 to numOfTokens

        IF typList=tkEOL: tokList="EOL": lineNum++ : END IF  'check EndOfLine

        IF typList = tkIDENT
           If ucase(tokList) = kwList[1]: typList = tkFLOAT  'if varNUM ...........................
              if typList[i+1] <> tkIDENT 'check err
                 MsgBox "Missing variable after VARNUM! line: " + str(lineNum),"ERROR": return 0
            else
              i=i+1 ' next token
               While typList <> tkCOLON And typList <> tkEOL  'store num variable              -low case var name-
                  If typList = tkIDENT : varID = varID + 1 : varList = varID : varName [varID]= lcase(tokList) : varType [varID]= tkFLOAT :varNum [varID]= 0
                     MsgBox "Variable name: " + tokList + "VAR.TYPE:" + str(varType) , "TYPE"
                  End if
                i++
               Wend
             end if

          End if  ' endOf varNUM..........................................................................
          If ucase(tokList) = kwList[2]: typList = tkSTRING  'if varSTR ...........................
              if typList[i+1] <> tkIDENT 'check err
                 MsgBox "Missing variable after VARSTR! line: " + str(lineNum),"ERROR": return 0
            else
              i=i+1 ' next token
               While typList <> tkCOLON And typList <> tkEOL  'store str variable
                  If typList = tkIDENT : varID = varID + 1 : varList = varID :: varName [varID]= lcase(tokList): varType [varID]= tkSTRING: varStr [varID]= ""
                     MsgBox "Variable name: " + tokList ,"variable->STR"
                  End if
                i++
               Wend
             end if
                End if  ' endOf varSTR.......................................
          If ucase(tokList) = kwList[3]: typList = tkPOINTER  'if varPTR ...........................
              if typList[i+1] <> tkIDENT 'check err
                 MsgBox "Missing variable after VARPTR! line: " + str(lineNum),"ERROR": return 0
            else
              i=i+1 ' next token
               While typList <> tkCOLON And typList <> tkEOL  'store ptr variable
                  If typList = tkIDENT : varID = varID + 1 : varList = varID :: varName [varID]= lcase(tokList): varType [varID]= tkPOINTER: varPtr [varID]= 0
                     MsgBox "Variable name: " + tokList ,"variable->PTR"
                  End if
                i++
               Wend
             end if
          End if  ' endOf varPTR.......................................
         
          If ucase(tokList) = kwList[4]  : typList = tkIF : ifCounter++ : End If        'if token 'IF
          If ucase(tokList) = kwList[5]  : typList = tkELSE : elseCounter++ : End If    'if token 'ELSE
          If ucase(tokList) = kwList[6]  : typList = tkENDIF : endifCounter++ : End If  'if token 'ENDIF'
          If ucase(tokList) = kwList[7]  : typList = tkWHILE : whileCounter++ : End If  'if token 'WHILE
          If ucase(tokList) = kwList[8]  : typList = tkWEND : wendCounter++ : End If    'if token 'WEND
          If ucase(tokList) = kwList[9]  : typList = tkFOR : forCounter++ : End If      'if token 'FOR
          If ucase(tokList) = kwList[10] : typList = tkTO : End If                      'if token 'TO
          If ucase(tokList) = kwList[11] : typList = tkSTEP : End If                    'if token 'STEP
          If ucase(tokList) = kwList[12] : typList = tkNEXT : nextCounter++ : End If    'if token 'NEXT
          If ucase(tokList) = kwList[13] : typList = tkPRINT : End If                   'if token 'PRINT

        ELSE ' if is variable outside declaration

       END IF

    Next i
return 1

End sub
'=================================================================================================================
Sub tokInterpreter()
    int tok=0,ntok=0,vID=0 ,vTyp=0
    tc=0

    While tc < nTokens
         start:
        gettok() : print "TOKEN:" + tokList
         [tc]tok = tkTyp : ntok = typList[tc+1]

         IF tok = tkFLOAT ' token is varNUM
            tc++
            While typList [tc]<> tkCOLON And typList [tc]<> tkEOL 'skip tokens to colon/eol
            tc++
            Wend
            print "TC-test" + str(tc)
            'goto start
         END IF
        
        IF tok = tkIDENT
           print "IDENT-TOKEN:" + tokList
           [tc]print "tok:" + str(tok)
           print "varType:" + str(varType[tc])
           vTyp = varType

           [tc]' vID = varList [tc]: vTyp = varType [vID]: print "varID: " + str(vID) + ":VarType:: " + str(vTyp)
             If vTyp = tkFLOAT  ' numeric var
                 if ntok = tkEQUAL
                    tc++  : print "TC:" + str(tc) ' skip "=" is assign
                    exec_expr()
                  end if
              End if
         END IF

    Wend

End Sub
'=================================================================================================================
'-----------------------------------------------------
sub gettok()
tc++
token = tokList [tc]: tkTyp = typList
[tc]
'test
if tokList[tc+1] <> "" then return
end sub
'----------------------------------------------------
sub expr() as float
float v
If token = "-"
 v = -(term())
else
 v = term()
end if
 
while token = "+" or token = "-"
if token = "+": gettok() : v = v + term(): end if
if token = "-": gettok() : v = v - term(): end if
wend

return v
end sub
'---------------------------------------------------
sub term() as float
float v
v = factor()

while token = "*" or token = "/"
if token = "*": gettok() : v = v * factor(): end if
if token = "/": gettok() : v = v / factor(): end if
wend

return v
end sub
'-------------------------------------------------------

sub factor() as float
float v
if asc(token)>47  and asc(token)<58 'nums
v = val(token)
gettok()
end if

if asc(token)=40 and asc(token)<>41 'match (...)
gettok() : v = expr() : gettok()
end if

return v
end sub

'execute-----------------------------------------------------
sub exec_expr
gettok()'start
float res = expr()
MsgBox "RESULT=" + str(res) , "EXEC_EXPR:"
end sub
 
ZlatkoDate: Thursday, 2020-04-16, 9:52 PM | Message # 7
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
added variable lookup with varID,work in expression eval
Attachments: MicroA_Interpre.o2bas(11.6 Kb)
 
ZlatkoDate: Saturday, 2020-05-09, 6:59 PM | Message # 8
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
Latest code : 9.5.2020

Attachments: 2403668.o2bas(12.3 Kb)
 
ZlatkoDate: Saturday, 2020-05-16, 5:06 PM | Message # 9
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
Latest code : 16.5.2020
add print x,y,var
error checking with print statement
Attachments: 4878307.o2bas(14.5 Kb)
 
ZlatkoDate: Sunday, 2020-05-17, 1:34 PM | Message # 10
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
After error checking I am close to REPL execution .
Well this error checking use too much time but is important part.
When i say REPL..in fact it would be REP ..Read..Eval...Print 
Loop will be next step..so for now,,it is ;

varStr a,b,c : varNum d,e,f
 d=625 : e=25.1 : f = d/e : print 10,10,f
 print 10,30,"numeric expr OK!"
 a= "aurel"
 b= " micro(A)"           
 c=a+b
print 10,50,"string expr OK!"
 
ZlatkoDate: Sunday, 2020-05-31, 10:25 PM | Message # 11
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
statement IF error checking added...currently supported
IF var {<>=!} var/val  {log Operator & ,| } var {<>=!} var/val
some small changes in tokenizer adding EOL after commented line.

'check IF x(1) <(2) y(3) &(4) a=v | c="X"   if var = varName|number|quoted string cop(<,>,=,!) LESS,GREAT,EQUAL,NOT------
       IF typList = tkIF
              'check next token as var(arg1)
          If typList[i+1] <> tkIDENT 
MsgBox "Wrong Argument(1)! -{ " + tokList[i+1] +" }-Line: " + str(lineNum+1),"ERROR~IF": return 0
          End if
              'check operator <,>,=,!
          If instr("<>=!",tokList[i+2]) = 0
             MsgBox "Wrong operator(2)! -{ " + tokList[i+2] +" }-Line: " + str(lineNum+1),"ERROR~IF": return 0
          End if
              'check next arg(3) 
          If typList[i+3] <> tkIDENT and  typList[i+3] <> tkNUMBER and  typList[i+3] <> tkQSTRING
MsgBox "Wrong Argument(3)! -{ " + tokList[i+3] +" }-Line: " + str(lineNum+1),"ERROR~IF": return 0
          End if
              'check logic operator AND or OR -> & or | (used in micro(A)) ..........................................
          IF typList[i+4] = tkAND OR typList[i+4] = tkOR
              'MsgBox "token AND or OR","AND~OR"-> if a>b & c=d
               If typList[i+5] <> tkIDENT 
    MsgBox "Wrong Argument(5)! -{ " + tokList[i+5] +" }-Line: " + str(lineNum+1),"ERROR~IF": return 0
               End if
     'check operator <,>,=,!
               If instr("<>=!",tokList[i+6]) = 0
                  MsgBox "Wrong operator(2)! -{ " + tokList[i+6] +" }-Line: " + str(lineNum+1),"ERROR~IF": return 0
               End if
                   'check next arg(7) 
               If typList[i+7] <> tkIDENT and  typList[i+7] <> tkNUMBER and  typList[i+7] <> tkQSTRING
    MsgBox "Wrong Argument(7)! -{ " + tokList[i+7] +" }-Line: " + str(lineNum+1),"ERROR~IF": return 0
               End if
          END IF
Attachments: 9458296.o2bas(18.5 Kb)
 
ZlatkoDate: Tuesday, 2020-06-16, 11:00 PM | Message # 12
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
release 16.6.2020
testing wcolor
Attachments: 4977855.o2bas(31.3 Kb)
 
ZlatkoDate: Friday, 2020-06-19, 0:39 AM | Message # 13
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
added sin,cos,tan,rnd,fcolor,bcolor..
Attachments: 8772724.o2bas(40.0 Kb)
 
ZlatkoDate: Saturday, 2020-06-27, 1:08 PM | Message # 14
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
latest update while/wend loop
Attachments: 2350054.o2bas(47.6 Kb)
 
ZlatkoDate: Tuesday, 2020-07-07, 1:17 AM | Message # 15
Lieutenant
Group: Administrators
Messages: 62
Reputation: 0
Status: Offline
fixed nested while loop
Attachments: 6889284.o2bas(48.8 Kb)
 
Forum » General category » ALL HOBBY programming » micro(A) Interpreter
  • Page 1 of 1
  • 1
Search: