Hey all,
I haven't used DBP for a while, but today I just kinda felt like it, so I decided to revisit my old scripting systems and see if I could make anything better in DBP this time.
Update: slightly fixed version
` Setup
sync on
sync rate 60
set window on
` Text and screen
ink rgb( 200, 200, 200 ), 0
cls rgb( 20, 20, 20 )
set text font "Lucida Console"
set text to bold
` Execute or show compiled form?
bExecShow as boolean
bExecShow = 0 ` 1 = Execute, 0 = Show compiled form
` Setup scripting system
scSetupScriptHandler()
scSetupLexer()
scSetupCompiler()
scSetupVirtualMachine()
` Read basic script
scLoadScript( "test script.txt" )
` Tokenize
scTokenize()
` Compile
scCompile()
` Executing or showing opcodes?
if ( bExecShow )
` Execute
scExecuteScript()
else
`remstart
` Loop through opcodes
for iCur = 0 to array count( g_Opcode() )
` Print opcode
text 10, 12 * iCur, g_Opcode( iCur ).sOp
` Print parameters
if ( g_Opcode( iCur ).iParamType = 1 ) then text 80, 20 * iCur, str$( g_Opcode( iCur ).iParam )
if ( g_Opcode( iCur ).iParamType = 2 ) then text 80, 20 * iCur, str$( g_Opcode( iCur ).fParam )
if ( g_Opcode( iCur ).iParamType = 3 ) then text 80, 20 * iCur, g_Opcode( iCur ).sParam
next iCur
`remend
`for iCur = 0 to scGetTokenCount()
`text 10, 13 * iCur, scGetToken( iCur )
`next iCur
endif
` Loop
do
sync
loop
` ------------------------------------------------
` Script Functions
` ------------------------------------------------
` *** Begin script handler ***
` ****************************
` Setup script handler
function scSetupScriptHandler()
` Script string
global g_sScriptString as string
endfunction
` Add script line
function scAddScriptLine( sLine as string )
` Append string
g_sScriptString = g_sScriptString + scRemoveSingleComment( sLine ) + "\n"
endfunction
` Get script line
function scGetScriptLine()
` Get return data
local sRet as string
sRet = g_sScriptString
endfunction sRet
` Load script
function scLoadScript( sFile as string )
` Current line
local sCurLine as string
` Open file
open to read 1, sFile
` While there are lines to be read
while ( not file end( 1 ) )
` Read string
read string 1, sCurLine
` Do not add blanks
if ( scRemoveWhite( sCurLine ) <> "" )
` Add to script
scAddScriptLine( sCurLine )
endif
endwhile
` Close file
close file 1
endfunction
` *** End script handler ***
` **************************
` *** Begin Lexer ***
` *******************
` Lexer
function scSetupLexer()
` Token data
global dim g_sToken( -1 ) as string
endfunction
` Clear tokens
function scClearTokens()
` Remove all tokens from list
empty array g_sToken()
endfunction
` Add token to list
function scAddToken( sToken as string )
` Remove spaces from token
sToken = scRemoveWhite( sToken )
sToken = lower$( sToken )
` Add to list
array insert at bottom g_sToken()
g_sToken( array count( g_sToken() ) ) = sToken
` If duplicate new line token
if ( array count( g_sToken() ) > 0 )
` Pop from stream
if ( ( g_sToken( array count( g_sToken() ) - 1 ) = "\n" ) && ( sToken = "\n" ) ) then remove from stack g_sToken()
endif
endfunction
` Get token count
function scGetTokenCount()
` Token data
local iCount as integer
` Get count
iCount = array count( g_sToken() )
endfunction iCount
` Get token
function scGetToken( iToken as integer )
` Token data
local sToken as string
` Get token
sToken = g_sToken( iToken )
endfunction sToken
` Find token
function scFindToken( iStart as integer, sToken as string )
` Token position
local iPos as integer
` Loop from start
for iPos = iStart to scGetTokenCount()
` Exit on finding token
if ( scGetToken( iPos ) = sToken ) then exit
next iPos
endfunction iPos
` Tokenize
function scTokenize()
` Set script
local sScript as string
sScript = scGetScriptLine()
` Clear token list
scClearTokens()
` (cheat) Add blank token to start and end
sScript = sScript + " "
` Data
local sPrev as string
local sCur as string
local sNext as string
local bInStr as boolean
local iTokStart as integer
local sCurToken as string
` Set token starting point
iTokStart = 1
` Loop through characters
for iCur = 1 to len( sScript )
` Grab current characters
if ( iCur > 1 ) then sPrev = mid$( sScript, iCur - 1 )
sCur = mid$( sScript, iCur )
if ( iCur < len( sScript ) - 1 ) then sNext = mid$( sScript, iCur + 1 )
` Escapce character functions
if ( sCur = "\" )
` Skip
inc iCur, 2
` New line
if ( sNext = "n" ) then iTokStart = iCur
` Add colon
scAddToken( "\n" )
endif
` Check if in "string"
if ( sCur = "'" ) then bInStr = not bInStr
` If not in string
if ( not bInStr )
` If current character is letter and next is not and not number, add token
if ( ( scIsLetter( sCur ) || scIsNumber( sCur ) ) && ( scIsOther( sNext ) && ( sNext <> "." ) ) )
` Create token
sCurToken = scCreateToken( sScript, iTokStart, iCur )
scAddToken( sCurToken )
` Set token start
iTokStart = iCur + 1
endif
` If single character symbol (exculsively):
if ( ( sCur = "(" ) || ( sCur = ")" ) || ( sCur = "+" ) || ( sCur = "-" ) || ( sCur = "*" ) || ( sCur = "/" ) || ( sCur = "," ) )
` Add token
scAddToken( sCur )
` Set token start
iTokStart = iCur + 1
endif
` If character that could be followed by an = but isn't:
if ( ( ( sCur = "=" ) || ( sCur = ">" ) || ( sCur = "<" ) ) && ( sNext <> "=" ) )
` Add token
scAddToken( sCur )
` Set token start
iTokStart = iCur + 1
endif
` If character that could be followed by an = and is:
if ( ( ( sCur = "=" ) || ( sCur = ">" ) || ( sCur = "<" ) || ( sCur = "!" ) ) && ( sNext = "=" ) )
` Add token
scAddToken( sCur + sNext )
` Set token start
inc iCur
iTokStart = iCur + 1
endif
` If &&
if ( ( sCur = "&" ) && ( sNext = "&" ) )
` Add token
scAddToken( sCur + sNext )
` Set token start
inc iCur
iTokStart = iCur + 1
endif
` If ||
if ( ( sCur = "|" ) && ( sNext = "|" ) )
` Add token
scAddToken( sCur + sNext )
` Set token start
inc iCur
iTokStart = iCur + 1
endif
else
` If closing string
if ( sNext = "'" )
` Create token
sCurToken = scCreateToken( sScript, iTokStart + 1, iCur + 1 )
scAddToken( sCurToken )
` Set token start
iTokStart = iCur + 1
endif
endif
next iCur
endfunction
` *** End Lexer ***
` *****************
` *** Begin Compiler ***
` **********************
` Setup compiler
function scSetupCompiler()
` Create blank list of opcodes
global dim g_Opcode( -1 ) as s_scOpcode
` Current compile token
global g_iCurCToken as integer
endfunction
` Add opcode
function scAddOpcode( sOp as string )
` Add opcode (no parameters)
array insert at bottom g_Opcode()
g_Opcode( array count( g_Opcode() ) ).sOp = sOp
endfunction
` Set parameter integer
function scSetOpParamInt( iParam as integer )
` Set parameter
g_Opcode( array count( g_Opcode() ) ).iParam = iParam
g_Opcode( array count( g_Opcode() ) ).iParamType = 1
endfunction
` Set parameter float
function scSetOpParamFloat( fParam as float )
` Set parameter
g_Opcode( array count( g_Opcode() ) ).fParam = fParam
g_Opcode( array count( g_Opcode() ) ).iParamType = 2
endfunction
` Set parameter string
function scSetOpParamString( sParam as string )
` Set parameter
g_Opcode( array count( g_Opcode() ) ).sParam = sParam
g_Opcode( array count( g_Opcode() ) ).iParamType = 3
endfunction
` Set previous parameter integer
function scSetPOpParamInt( iOp as integer, iParam as integer )
` Set parameter
g_Opcode( iOp ).iParam = iParam
g_Opcode( iOp ).iParamType = 1
endfunction
` Set previous parameter float
function scSetPOpParamFloat( iOp as integer, fParam as float )
` Set parameter
g_Opcode( iOp ).fParam = fParam
g_Opcode( iOp ).iParamType = 2
endfunction
` Set previous parameter string
function scSetPOpParamString( iOp as integer, sParam as string )
` Set parameter
g_Opcode( iOp ).sParam = sParam
g_Opcode( iOp ).iParamType = 3
endfunction
` Get opcode count
function scGetOpCodeCount()
` Count
local iCount as integer
` Get number of opcodes
iCount = array count( g_Opcode() )
endfunction iCount
` Get opcode
function scGetOpCode( iOp as integer )
` Opcode
local sOp as string
` Get opcode
sOp = g_Opcode( iOp ).sOp
endfunction sOp
` Get opcode param int
function scGetOpParamInt( iOp as integer )
` Opcode param
local iData as integer
` Get parameter
iData = g_Opcode( iOp ).iParam
endfunction iData
` Get opcode param float
function scGetOpParamFloat( iOp as integer )
` Opcode param
local fData as float
` Get parameter
fData = g_Opcode( iOp ).fParam
endfunction fData
` Get opcode param int
function scGetOpParamString( iOp as integer )
` Opcode param
local sData as string
` Get parameter
sData = g_Opcode( iOp ).sParam
endfunction sData
` Get opcode param type
function scGetOpParamType( iOp as integer )
` Opcode param type
local iType as integer
` Get parameter
iType = g_Opcode( iOp ).iParamType
endfunction iType
` Compile script
function scCompile()
` Reset current token
g_iCurCToken = 0
` Empty opcode list
empty array g_Opcode()
` Compile as block
scCompileBlock( scGetTokenCount() + 1 )
endfunction
` Compile if statement
function scCompileIfStmt()
` If statement data
local iCurIfOp as integer
` Skip "if"
inc g_iCurCToken
` Compile expression
scCompileExpr( scFindToken( g_iCurCToken, "\n" ) )
` Add if opcode
scAddOpcode( "if" )
` Get opcode count
iCurIfOp = scGetOpCodeCount()
` Compile block
scCompileBlock( scFindToken( g_iCurCToken, "endif" ) - 1 )
` Add endif opcode
scAddOpcode( "endif" )
` Set jump point for if statement
scSetPOpParamInt( iCurIfOp, scGetOpCodeCount() )
endfunction
` Compile block
function scCompileBlock( iTerminate as integer )
` Token data
local sCurTok as string
` Loop data
local iLastDoLoc as integer
` Loop through tokens
while ( g_iCurCToken < iTerminate )
` Get current token
sCurTok = scGetToken( g_iCurCToken )
` If variable
if ( sCurTok = "dim" )
scCompileVarDecl( scFindToken( g_iCurCToken, "\n" ) )
endif
` Assignment
if ( ( g_iCurCToken < iTerminate - 1 ) && ( scGetToken( g_iCurCToken + 1 ) = "=" ) )
` Go back
`dec g_iCurCToken, 2
` Compile
scCompileVarAssign( scFindToken( g_iCurCToken, "\n" ) )
endif
` Command or statement
if ( scIsLetter( sCurTok ) && ( scGetToken( g_iCurCToken + 1 ) = "(" ) )
` If not block statement
if ( sCurTok <> "if" )
` Compile
scCompileCommand( scFindToken( g_iCurCToken, "\n" ) )
endif
endif
` If statement
if ( sCurTok = "if" ) then scCompileIfStmt()
` Do/Loop
if ( sCurTok = "do" )
` Skip tokens
inc g_iCurCToken, 2
` Add opcode
scAddOpcode( "do" )
` Record location
iLastDoLoc = scGetOpCodeCount()
endif
if ( sCurTok = "loop" )
` Skip tokens
inc g_iCurCToken, 2
` Add opcode
scAddOpcode( "loop" )
` Jump to last 'do'
scSetOpParamInt( iLastDoLoc )
endif
` Other
if ( sCurTok = "endif" ) then inc g_iCurCToken, 2
endwhile
` Move to end
`g_iCurCToken = iTerminate + 1
endfunction
` Compile variable assignment
function scCompileVarAssign( iTerminate as integer )
` Get variable
local sVar as string
sVar = scGetToken( g_iCurCToken )
` Skip equal sign
inc g_iCurCToken, 2
` Compile expression
scCompileExpr( iTerminate )
` Assign
scAddOpcode( "setv" )
scSetOpParamString( sVar )
` Move to end
g_iCurCToken = iTerminate + 1
endfunction
` Compile variable declaration
function scCompileVarDecl( iTerminate as integer )
` Create variable
scAddOpcode( "var" )
scSetOpParamString( scGetToken( iTerminate - 1 ) )
` Move to end
g_iCurCToken = iTerminate + 1
endfunction
` Compile command
function scCompileCommand( iTerminate as integer )
` Get command name
local sCommand as string
sCommand = scGetToken( g_iCurCToken )
` Compile expression
inc g_iCurCToken, 2
scCompileExpr( iTerminate - 1 )
` Call command
scAddOpcode( "callc" )
scSetOpParamString( sCommand )
` Move to end
g_iCurCToken = iTerminate + 1
endfunction
` Compile expression
function scCompileExpr( iTerminate as integer )
` Operator stack
local dim sOpStack( -1 ) as string
` Current token
local sCurTok as string
` Loop till terminating token
while ( g_iCurCToken < iTerminate )
` Read current token
sCurTok = scGetToken( g_iCurCToken )
` Inc current token
inc g_iCurCToken
` If number
if ( scIsNumber( sCurTok ) )
` Add to output
scAddOpcode( "push" )
scSetOpParamFloat( val( sCurTok ) )
endif
` If string
if ( ( right$( sCurTok, 1 ) = "'" ) && ( left$( sCurTok, 1 ) = "'" ) )
` Add to output
scAddOpcode( "push" )
scSetOpParamString( right$( left$( sCurTok, len( sCurTok ) - 1 ), len( left$( sCurTok, len( sCurTok ) - 1 ) ) - 1 ) )
endif
` If identifier
if ( scIsLetter( sCurTok ) )
` If function
if ( scGetToken( g_iCurCToken ) = "(" )
` Push onto stack
array insert at bottom sOpStack()
sOpStack( array count( sOpStack() ) ) = sCurTok
else
` Load data onto stack
scAddOpcode( "load" )
scSetOpParamString( sCurTok )
endif
endif
` If comma
if ( sCurTok = "," )
` Until left parenthesis is found on stack
while ( sOpStack( array count( sOpStack() ) ) <> "(" )
` Pop into output
scAddOpcode( sOpStack( array count( sOpStack() ) ) )
remove from stack sOpStack()
endwhile
endif
` If operator
if ( scIsOperator( sCurTok ) )
` While there is an operator on the top of stack
if ( array count( sOpStack() ) > 0 )
while ( scIsOperator( sOpStack( array count( sOpStack() ) ) ) )
` Pop into output
scAddOpcode( sOpStack( array count( sOpStack() ) ) )
remove from stack sOpStack()
endwhile
endif
` Push current op onto stack
array insert at bottom sOpStack()
sOpStack( array count( sOpStack() ) ) = sCurTok
endif
` If left parenthesis
if ( sCurTok = "(" )
` Push onto stack
array insert at bottom sOpStack()
sOpStack( array count( sOpStack() ) ) = "("
endif
` If right parenthesis
if ( sCurTok = ")" )
` Loop until top stack item is left parenthesis
while ( sOpStack( array count( sOpStack() ) ) <> "(" )
` Pop into output
scAddOpcode( sOpStack( array count( sOpStack() ) ) )
remove from stack sOpStack()
endwhile
` Pop parenthesis
remove from stack sOpStack()
` If top of stack is function, pop to output
if ( array count( sOpStack() ) > -1 )
if ( scIsLetter( sOpStack( array count( sOpStack() ) ) ) )
` Pop into output
scAddOpcode( "callf" )
scSetOpParamString( sOpStack( array count( sOpStack() ) ) )
remove from stack sOpStack()
endif
endif
endif
endwhile
` If stack still has operators
if ( array count( sOpStack() ) > -1 )
` Pop into output
scAddOpcode( sOpStack( array count( sOpStack() ) ) )
remove from stack sOpStack()
endif
` Move to end
g_iCurCToken = iTerminate + 1
endfunction
` *** End Compiler ***
` ********************
` *** Begin Virtual Machine ***
` *****************************
` Setup VM
function scSetupVirtualMachine()
` Create blank list of variables
global dim g_Variable( -1 ) as s_scVariable
` Create blank stack
global dim g_Stack( -1 ) as s_scStackItem
endfunction
` Push int data onto stack
function scPushBackInt( iData as integer )
` Add to stack
array insert at bottom g_Stack()
g_Stack( array count( g_Stack() ) ).iVal = iData
g_Stack( array count( g_Stack() ) ).iValType = 1
endfunction
` Push float data onto stack
function scPushBackFloat( fData as float )
` Add to stack
array insert at bottom g_Stack()
g_Stack( array count( g_Stack() ) ).fVal = fData
g_Stack( array count( g_Stack() ) ).iValType = 2
endfunction
` Push string data onto stack
function scPushBackString( sData as string )
` Add to stack
array insert at bottom g_Stack()
g_Stack( array count( g_Stack() ) ).sVal = sData
g_Stack( array count( g_Stack() ) ).iValType = 3
endfunction
` Pop off stack
function scPopBack()
` Pop off stack
remove from stack g_Stack()
endfunction
` Get stack int
function scGetStackInt()
` Stack data
local iData as integer
` Get data
iData = g_Stack( array count( g_Stack() ) ).iVal
endfunction iData
` Get stack float
function scGetStackFloat()
` Stack data
local fData as float
` Get data
fData = g_Stack( array count( g_Stack() ) ).fVal
endfunction fData
` Get stack string
function scGetStackString()
` Stack data
local sData as string
` Get data
sData = g_Stack( array count( g_Stack() ) ).sVal
endfunction sData
` Get stack type
function scGetStackType()
` Stack datatype
local iDataType as integer
` Get data
iDataType = g_Stack( array count( g_Stack() ) ).iValType
endfunction iDataType
` Create variable
function scCreateVar( sIdent as string )
` Add new variable
array insert at bottom g_Variable()
g_Variable( array count( g_Variable() ) ).sName = sIdent
endfunction
` Set variable int
function scSetVarInt( iVar as integer, iData as integer )
` Set data
g_Variable( iVar ).iVal = iData
g_Variable( iVar ).iValType = 1
endfunction
` Set variable float
function scSetVarFloat( iVar as integer, fData as float )
` Set data
g_Variable( iVar ).fVal = fData
g_Variable( iVar ).iValType = 2
endfunction
` Set variable string
function scSetVarString( iVar as integer, sData as string )
` Set data
g_Variable( iVar ).sVal = sData
g_Variable( iVar ).iValType = 3
endfunction
` Get variable data int
function scGetVarValInt( iVar as integer )
` Variable data
local iData as integer
` Get data
iData = g_Variable( iVar ).iVal
endfunction iData
` Get variable data float
function scGetVarValFloat( iVar as integer )
` Variable data
local fData as float
` Get data
fData = g_Variable( iVar ).fVal
endfunction fData
` Get variable data string
function scGetVarValString( iVar as integer )
` Variable data
local sData as string
` Get data
sData = g_Variable( iVar ).sVal
endfunction sData
` Get variable data type
function scGetVarValType( iVar as integer )
` Variable data
local iDataType as integer
` Get data
iDataType = g_Variable( iVar ).iValType
endfunction iDataType
` Get variable index
function scGetVarIndex( sVar as string )
` Index
local iIndex as integer
` Loop through variables
for iVar = 0 to array count( g_Variable() )
` Match name
if ( g_Variable( iVar ).sName = sVar )
` Record index and break
iIndex = iVar
exit
endif
next iVar
endfunction iIndex
` Execute script
function scExecuteScript()
` Loop through opcodes
for iCurOp = 0 to scGetOpCodeCount()
` Push onto stack
if ( scGetOpCode( iCurOp ) = "push" )
` Different actions for different datatypes
if ( scGetOpParamType( iCurOp ) = 1 ) then scPushBackInt( scGetOpParamInt( iCurOp ) )
if ( scGetOpParamType( iCurOp ) = 2 ) then scPushBackFloat( scGetOpParamFloat( iCurOp ) )
if ( scGetOpParamType( iCurOp ) = 3 ) then scPushBackString( scGetOpParamString( iCurOp ) )
endif
` Create variable
if ( scGetOpCode( iCurOp ) = "var" )
scCreateVar( scGetOpParamString( iCurOp ) )
endif
` Set variable to top stack item
if ( scGetOpCode( iCurOp ) = "setv" )
` Different actions for different datatypes
if ( scGetStackType() = 1 ) then scSetVarInt( scGetVarIndex( scGetOpParamString( iCurOp ) ), scGetStackInt() )
if ( scGetStackType() = 2 ) then scSetVarFloat( scGetVarIndex( scGetOpParamString( iCurOp ) ), scGetStackFloat() )
if ( scGetStackType() = 3 ) then scSetVarString( scGetVarIndex( scGetOpParamString( iCurOp ) ), scGetStackString() )
endif
` Load variable data into stack
if ( scGetOpCode( iCurOp ) = "load" )
` Different actions for different datatypes
if ( scGetVarValType( scGetVarIndex( scGetOpParamString( iCurOp ) ) ) = 1 ) then scPushBackInt( scGetVarValInt( scGetVarIndex( scGetOpParamString( iCurOp ) ) ) )
if ( scGetVarValType( scGetVarIndex( scGetOpParamString( iCurOp ) ) ) = 2 ) then scPushBackFloat( scGetVarValFloat( scGetVarIndex( scGetOpParamString( iCurOp ) ) ) )
if ( scGetVarValType( scGetVarIndex( scGetOpParamString( iCurOp ) ) ) = 3 ) then scPushBackString( scGetVarValString( scGetVarIndex( scGetOpParamString( iCurOp ) ) ) )
endif
` If
if ( scGetOpCode( iCurOp ) = "if" )
` If top of stack is false
if ( ( scGetStackType() = 1 ) && ( scGetStackInt() = 0 ) )
` Jump to endif
iCurOp = scGetOpParamInt( iCurOp )
endif
endif
` Loop
if ( scGetOpCode( iCurOp ) = "loop" )
` Jump to do
iCurOp = scGetOpParamInt( iCurOp )
endif
` Functions
if ( scGetOpCode( iCurOp ) = "callf" )
` *** Add functions here ***
endif
` Commands
if ( scGetOpCode( iCurOp ) = "callc" )
` *** Add commands here ***
` Print
if ( scGetOpParamString( iCurOp ) = "print" )
` Print top stack item
if ( scGetStackType() = 1 ) then print scGetStackInt()
if ( scGetStackType() = 2 ) then print scGetStackFloat()
if ( scGetStackType() = 3 ) then print scGetStackString()
` Pop stack
scPopBack()
endif
endif
` Plus
if ( scGetOpCode( iCurOp ) = "+" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).iVal + g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Int Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total# = g_Stack( array count( g_Stack() ) ).iVal + g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
` Float Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total# = g_Stack( array count( g_Stack() ) ).fVal + g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
` Float Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total# = g_Stack( array count( g_Stack() ) ).fVal + g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
endif
` Minus
if ( scGetOpCode( iCurOp ) = "-" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) - 1 ).iVal - g_Stack( array count( g_Stack() ) ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Int Float
if ( ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) )
total# = g_Stack( array count( g_Stack() ) - 1 ).iVal - g_Stack( array count( g_Stack() ) ).fVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
` Float Int
if ( ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) )
total# = g_Stack( array count( g_Stack() ) - 1 ).fVal - g_Stack( array count( g_Stack() ) ).iVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
` Float Float
if ( ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) )
total# = g_Stack( array count( g_Stack() ) - 1 ).fVal - g_Stack( array count( g_Stack() ) ).fVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
endif
` Mult
if ( scGetOpCode( iCurOp ) = "*" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).iVal * g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Int Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total# = g_Stack( array count( g_Stack() ) ).iVal * g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
` Float Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total# = g_Stack( array count( g_Stack() ) ).fVal * g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
` Float Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total# = g_Stack( array count( g_Stack() ) ).fVal * g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
endif
` Divide
if ( scGetOpCode( iCurOp ) = "/" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) - 1 ).iVal / g_Stack( array count( g_Stack() ) ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Int Float
if ( ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) )
total# = g_Stack( array count( g_Stack() ) - 1 ).iVal / g_Stack( array count( g_Stack() ) ).fVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
` Float Int
if ( ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) )
total# = g_Stack( array count( g_Stack() ) - 1 ).fVal / g_Stack( array count( g_Stack() ) ).iVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
` Float Float
if ( ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) )
total# = g_Stack( array count( g_Stack() ) - 1 ).fVal / g_Stack( array count( g_Stack() ) ).fVal
scPopBack()
scPopBack()
scPushBackFloat( total# )
endif
endif
` More
if ( scGetOpCode( iCurOp ) = ">" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).iVal < g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Int Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).iVal < g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).fVal < g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).fVal < g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
endif
` Less
if ( scGetOpCode( iCurOp ) = "<" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).iVal > g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Int Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).iVal > g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).fVal > g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).fVal > g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
endif
` More Equal
if ( scGetOpCode( iCurOp ) = ">=" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).iVal <= g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Int Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).iVal <= g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).fVal <= g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).fVal <= g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
endif
` Less Equal
if ( scGetOpCode( iCurOp ) = "<=" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).iVal >= g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Int Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).iVal >= g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).fVal >= g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).fVal >= g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
endif
` And
if ( scGetOpCode( iCurOp ) = "&&" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).iVal && g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
endif
` Or
if ( scGetOpCode( iCurOp ) = "||" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).iVal || g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
endif
` Equal
if ( scGetOpCode( iCurOp ) = "==" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).iVal = g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Int Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).iVal = g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).fVal = g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).fVal = g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
endif
` Not Equal
if ( scGetOpCode( iCurOp ) = "!=" )
` Int Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).iVal <> g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Int Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 1 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).iVal <> g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Int
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 1 ) )
total = g_Stack( array count( g_Stack() ) ).fVal <> g_Stack( array count( g_Stack() ) - 1 ).iVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
` Float Float
if ( ( g_Stack( array count( g_Stack() ) ).iValType = 2 ) && ( g_Stack( array count( g_Stack() ) - 1 ).iValType = 2 ) )
total = g_Stack( array count( g_Stack() ) ).fVal <> g_Stack( array count( g_Stack() ) - 1 ).fVal
scPopBack()
scPopBack()
scPushBackInt( total )
endif
endif
next i
endfunction
` *** End Virtual Machine ***
` ***************************
` ------------------------------------------------
` General functions
` ------------------------------------------------
` Check if charater is a letter
function scIsLetter( sText as string )
` Character data
local bAlpha as boolean
` Only get first character
sText = mid$( sText, 1 )
` Check is letter
if asc( sText ) >= asc("a") and asc( sText ) <= asc( "z" ) then bAlpha = 1
if asc( sText ) >= asc("A") and asc( sText ) <= asc( "Z" ) then bAlpha = 1
endfunction bAlpha
` Check if character is a number
function scIsNumber( sText as string )
` Character data
local bNum as boolean
` Only get first character
sText = mid$( sText, 1 )
` Check if number
if asc( sText ) >= asc( "0" ) and asc( sText ) <= asc( "9" ) then bNum = 1
endfunction bNum
` Check if character is not letter or number
function scIsOther( sText as string )
` Character data
local bOther as boolean
` Check if other
if ( scIsLetter( sText ) = 0 ) && ( scIsNumber( sText ) = 0 ) then bOther = 1
endfunction bOther
` Remove spaces from text
function scRemoveWhite( sText as string )
` Data
local sRet as string
local bInStr as boolean
` Loop through string
for iCur = 1 to len( sText )
` Check if in string
if ( mid$( sText, iCur ) = "'" ) then bInStr = not bInStr
` If not in string
if ( not bInStr )
` If not space, append
if ( ( mid$( sText, iCur ) <> " " ) && ( mid$( sText, iCur ) <> " " ) ) then sRet = sRet + mid$( sText, iCur )
endif
next iCur
endfunction sRet
` Remove single comment
function scRemoveSingleComment( sText as string )
` Return string
local sRet as string
` Loop through string and append till a ` is reached
for iCur = 1 to len( sText )
` Exit on comment
if ( mid$( sText, iCur ) = "`" ) then exit
` Append
sRet = sRet + mid$( sText, iCur )
next iCur
endfunction sRet
` Create token from text
function scCreateToken( sString as string, iStart as integer, iEnd as integer )
` Token data
local sRet as string
` Loop through string
for iCur = iStart to iEnd
` Append return string
sRet = sRet + mid$( sString, iCur )
next iCur
endfunction sRet
` Check if operator
function scIsOperator( sText as string )
` Return data
local bIsOp as boolean
` Check if operator
if ( ( sText = "+" ) || ( sText = "-" ) || ( sText = "*" ) || ( sText = "/" ) || ( sText = ">" ) || ( sText = "<" ) || ( sText = ">=" ) || ( sText = "<=" ) || ( sText = "&&" ) || ( sText = "||" ) || ( sText = "==" ) || ( sText = "!=" ) ) then bIsOp = 1
endfunction bIsOp
` ------------------------------------------------
` Script structs
` ------------------------------------------------
` Opcode struct
type s_scOpcode
sOp as string ` Opcode (bad habit to use strings, but nevermind)
iParam as integer ` Parameter integer
fParam as float ` Parameter float
sParam as string ` Parameter string
iParamType as integer ` Parameter type ( 1 = int, 2 = float, 3 = string )
endtype
` Variable struct
type s_scVariable
sName as string ` Variable identifier
iVal as integer ` Value integer
fVal as float ` Value float
sVal as string ` Value string
iValType as integer ` Value type ( 1 = int, 2 = float, 3 = string )
endtype
` Stack item
type s_scStackItem
iVal as integer ` Value integer
fVal as float ` Value float
sVal as string ` Value string
iValType as integer ` Value type ( 1 = int, 2 = float, 3 = string )
endtype
Just make a file called "test script.txt" and put in this code:
dim lol
lol = 3
if lol > 2
print( lol * ( 5 - 3 ) )
endif
Tell me if you find any problems,
Thanks.