Hi, some people asked on this forums about creating an scripting language, and this is an example to manage variables, and execute internal instuctions, but this internal executions can be called itself, or can be call also other instructions, that can be difficult to implement for some newbies users.
This is the byte code script interpreter:
Code: Select all
; Recurrence execution of virtual code
; By Pedro Gil, Balrog Soft
Global *memAddress,IR,MakeJump,Quit,DontExecute
Global VariableNumber,VariableNumberByte,VariableNumberWord
Global VariableNumberLong,VariableNumberFloat,VariableNumberString
VariableNb=10000
Global Dim ValueReturn($FF)
Global Dim ValueParam($FF,20)
Global Dim VariableType.b(VariableNb)
Global Dim VariableTypeNumber.b(VariableNb)
Global Dim VariableStByte.b(VariableNb) ; Type = 1
Global Dim VariableStWord.w(VariableNb) ; Type = 2
Global Dim VariableStLong(VariableNb) ; Type = 3
Global Dim VariableStFloat.f(VariableNb) ; Type = 4
Global Dim VariableStString.s(VariableNb) ; Type = 5
Declare GetParams(Nb,IRAd,SPtr)
Procedure ExecuteVMInstruction(IRAdd,SP)
PCAdd=0
OpCode.b=PeekB(*memAddress+IRAdd)
;Define variable function
If OpCode=$0
If DontExecute=#False
TotalVariableNumber+1
VariableType.b=PeekB(*memAddress+IRAdd+1)
VariableType(TotalVariableNumber)=VariableType
If VariableType=1
VarNb=VariableNumberByte
VariableStByte(VarNb)=0
VariableNumberByte+1
ElseIf VariableType=2
VarNb=VariableNumberWord
VariableStWord(VarNb)=0
VariableNumberWord+1
ElseIf VariableType=3
VarNb=VariableNumberLong
VariableStLong(VarNb)=0
VariableNumberLong+1
ElseIf VariableType=4
VarNb=VariableNumberFloat
VariableStFloat(VarNb)=0
VariableNumberFloat+1
ElseIf VariableType=5
VarNb=VariableNumberString
VariableStString(VarNb)=""
VariableNumberString+1
EndIf
VariableTypeNumber(TotalVariableNumber)=VarNb
EndIf
PCAdd=2
EndIf
;Add function
If OpCode=$1
ParamBytes=GetParams(1,3+IRAdd,SP)
If DontExecute=#False
VariableNumberReturn=PeekW(*memAddress+IRAdd+1)
VariableTypeReturn=VariableType(VariableNumberReturn)
VariableInternalNumberReturn=VariableTypeNumber(VariableNumberReturn)
returnvalue=ValueParam(SP,0)+ValueParam(SP,1)
If SP=0
If VariableNumberReturn<>0 And VariableTypeReturn=3
VariableStLong(VariableInternalNumberReturn)=returnvalue
EndIf
Else
ValueReturn(SP)=returnvalue
EndIf
EndIf
PCAdd=3+ParamBytes
EndIf
;Debug function
If OpCode=$D
If DontExecute=#False
VariableNumber1=PeekW(*memAddress+IRAdd+1)
VariableType1=VariableType(VariableNumber1)
VariableInternalNumber1=VariableTypeNumber(VariableNumber1)
If VariableType1=1
Output.s=Str(VariableStByte(VariableInternalNumber1))
ElseIf VariableType1=2
Output.s=Str(VariableStWord(VariableInternalNumber1))
ElseIf VariableType1=3
Output.s=Str(VariableStLong(VariableInternalNumber1))
ElseIf VariableType1=4
Output.s=StrF(VariableStFloat(VariableInternalNumber1))
ElseIf VariableType1=5
Output.s=VariableStString(VariableInternalNumber1)
EndIf
MessageRequester("ScriptVM","V["+Str(VariableNumber1)+"] = "+Output.s,0)
EndIf
PCAdd=3
EndIf
;End function
If OpCode=$F
If DontExecute=#False
Quit=#True
EndIf
PCAdd=1
EndIf
ProcedureReturn PCAdd
EndProcedure
Procedure GetParams(Nb,IRAd,SPtr)
ParamB=0
For Param=0 To Nb
ValueType1=PeekB(*memAddress+(ParamB)+IRAd)
If ValueType1=1
VariableNumber1=PeekW(*memAddress+(ParamB)+IRAd+1)
VariableType1=VariableType(VariableNumber1)
VariableInternalNumber1=VariableTypeNumber(VariableNumber1)
If VariableType1=1
ValueParam(SPtr,Param)=VariableStByte(VariableInternalNumber1)
ElseIf VariableType1=2
ValueParam(SPtr,Param)=VariableStWord(VariableInternalNumber1)
ElseIf VariableType1=3
ValueParam(SPtr,Param)=VariableStLong(VariableInternalNumber1)
ElseIf VariableType1=4
ValueParam(SPtr,Param)=VariableStFloat(VariableInternalNumber1)
ElseIf VariableType1=5
ValueParam(SPtr,Param)=@VariableStString(VariableInternalNumber1)
EndIf
ParamB+3
ElseIf ValueType1=2
ValueParam(SPtr,Param)=PeekL(*memAddress+(ParamB)+IRAd+1)
ParamB+5
ElseIf ValueType1=3
ParamBAdd=ExecuteVMInstruction((ParamB)+IRAd+1,SPtr+1)
Rtn=ValueReturn(SPtr+1)
ValueParam(SPtr,Param)=Rtn
ParamB+ParamBAdd+1
EndIf
Next Param
ProcedureReturn ParamB
EndProcedure
PC=0
Filename.s= "test.svm"
Size=FileSize(Filename.s)
*memAddress = AllocateMemory(Size)
If OpenFile(0,Filename.s)
ReadData(0,*memAddress,Size)
CloseFile(0)
EndIf
Repeat
If MakeJump=#False
IR+PC
ElseIf MakeJump=#True
IR=PC
MakeJump=#False
EndIf
PC=ExecuteVMInstruction(IR,0)
Until Quit=#True Or Error=#True
FreeMemory(*memAddress)ExecuteVMInstruction execute a instruction on a speficic IR(Instruction register, contains direction of actual execution opcode).
SP its stack pointer to difference the level of recurrence
How to use GetParams?
Nb is number of params, 0 counts for this, it means that if it have 2 parameters, Nb must be 1.
IRAd, its the internal address to where parameters can be founded.
SPtr, is stack pointer
An this is the program to make an example:
Code: Select all
If CreateFile(0,"test.svm")
;Define var01 as long
WriteByte(0,$0)
WriteByte(0,$3)
;add function: Add(var01,Add(3,5))
WriteByte(0,$1)
;Return variable 01
WriteWord(0,$1)
;Param1 is a variable
WriteByte(0,$1)
;VarNb
WriteWord(0,$1)
;Param2 is a function
WriteByte(0,$3)
;Add function
WriteByte(0,$1)
;return variable
WriteWord(0,$0)
;Param1 is a direct value
WriteByte(0,$2)
; Value
WriteLong(0,$3)
;Param2 is a direct value
WriteByte(0,$2)
; Value
WriteLong(0,$5)
;Debug var01
WriteByte(0,$D)
WriteWord(0,$1)
;End
WriteByte(0,$F)
CloseFile(0)
EndIfDefine Var01 as long
Var01=Add(Var01,Add(3,5))
Debug Var01
EndProgram
I know that can be a little complicated to understand, but if you have any question only send me an email.
