This is a new class to hold a frame of variables. This can help on making script languages, to keep variables, which means sets of Names and Values.
The interesting part, is how we can establish a reference system, so for each entity we can address to it by a long number, which have two parts, the target VarFrame and the actual position on that Varframe. Also the second part has two parts, the least 12 bits is the actual index number, and the last 4 bit used to indicate the type of the variable, and the actual array (we have for each basic type, one array).
So one type for these "basic types" is the reference one. Is an array which hold references for other VarFrames. These references are not like object references (is a kind of indirection).
For use it in a Virtual Machine for a script language, we can use the low part, as the local variable (two bytes only). The reference variable can be included in the local Varframe, which means we get also two bytes and the VarFrame handle the actual reference (and get the actual type) of the variable.
So with two bytes we may have 4096 variables of same type, 15 types and 1 type for the reference system. Also the Varframe never delete an insert (supposed the varframe can be recycled after the end of use). One type is the variant type. And there is the object type so we may have arrays. through RefArray which make arrays for any type, without using an array of variants which take a lot of space. And this is the goal for this class, to handle "local variables" for a custom virtual machine for a custom script language.
Another use is for user Objects. I didn't show that here, but I can "draw" the idea. Some arrays in VarFrame are for Modules/Functions, which supposed to be local two. So an object is a "movable" part, a "value", and a VarFrame can be done such thing. The difference is that as a Varframe, it can't be reference through a Handler (the top part), except we can use an immediate way, when a method call another method, to add the This Varframe to a one time use of handler, and pass the compound pointer (as reference) to the external method, and then at the return of execution, and the return of the object's method, we just throw the link for the handler to This Varframe (the objec'ts VarFrame). So using Custom Objects, means an expansion for the Handlers (some Handlers may used for temporary use, means can show some other VarFrame later).
So you can now forget the mention about custom objects, and focus to the program here.
The idea for VarFrame, are to NOT INCLUDE names in the varframe. So we have HASH LISTS, without saving the names as "strings". We have one HashList for all names. So a name ALFA maybe is a string in VarFrame A, but a long in varFrame B. So each Identifier NAME has a unique ID.
The Varframe has one Hash table for all types (all included arrays). Some types that not used are not exist, they have an empty "slot".
So VarFrame it's different from ordinary Hash Tables/Lists. One Hash table, addressing multiple arrays. (arrays of values for the variables, arrays per type).
For a script language, we need a way to store/retrieve values, through a "search" system (using name) and for a JIT we need a way to reference the values, without using names, just pointers (or for VarFrame, the 16bit compound indexes), and if we need references to other VarFrames, we can use handlers (16bit, as High Integer Value of a Long Value).
The HashList, and the VarFrame can used for values with same name. We can use two or more same keys, and we can "walk" easy on them.
The program in zip file has some examples:
let see the global variables:
We use Long Long also (64bit Integers)
We make a pool of VarFrames, so each time we need we see if exist in the pool and take it from there.
The basic idea is that we have Handlers which is the numbers which are the top part of a "Referenced" variable.
The VarFrame is a mix of a refArray and a Hashlist. (the last two classes I was introduced them some days ago, but here we have updated classes).
This example show how the reference work (through the WeakPtr, the compound index)
This example show the HashList with rename function.
The interesting part, is how we can establish a reference system, so for each entity we can address to it by a long number, which have two parts, the target VarFrame and the actual position on that Varframe. Also the second part has two parts, the least 12 bits is the actual index number, and the last 4 bit used to indicate the type of the variable, and the actual array (we have for each basic type, one array).
So one type for these "basic types" is the reference one. Is an array which hold references for other VarFrames. These references are not like object references (is a kind of indirection).
For use it in a Virtual Machine for a script language, we can use the low part, as the local variable (two bytes only). The reference variable can be included in the local Varframe, which means we get also two bytes and the VarFrame handle the actual reference (and get the actual type) of the variable.
So with two bytes we may have 4096 variables of same type, 15 types and 1 type for the reference system. Also the Varframe never delete an insert (supposed the varframe can be recycled after the end of use). One type is the variant type. And there is the object type so we may have arrays. through RefArray which make arrays for any type, without using an array of variants which take a lot of space. And this is the goal for this class, to handle "local variables" for a custom virtual machine for a custom script language.
Another use is for user Objects. I didn't show that here, but I can "draw" the idea. Some arrays in VarFrame are for Modules/Functions, which supposed to be local two. So an object is a "movable" part, a "value", and a VarFrame can be done such thing. The difference is that as a Varframe, it can't be reference through a Handler (the top part), except we can use an immediate way, when a method call another method, to add the This Varframe to a one time use of handler, and pass the compound pointer (as reference) to the external method, and then at the return of execution, and the return of the object's method, we just throw the link for the handler to This Varframe (the objec'ts VarFrame). So using Custom Objects, means an expansion for the Handlers (some Handlers may used for temporary use, means can show some other VarFrame later).
So you can now forget the mention about custom objects, and focus to the program here.
The idea for VarFrame, are to NOT INCLUDE names in the varframe. So we have HASH LISTS, without saving the names as "strings". We have one HashList for all names. So a name ALFA maybe is a string in VarFrame A, but a long in varFrame B. So each Identifier NAME has a unique ID.
The Varframe has one Hash table for all types (all included arrays). Some types that not used are not exist, they have an empty "slot".
So VarFrame it's different from ordinary Hash Tables/Lists. One Hash table, addressing multiple arrays. (arrays of values for the variables, arrays per type).
For a script language, we need a way to store/retrieve values, through a "search" system (using name) and for a JIT we need a way to reference the values, without using names, just pointers (or for VarFrame, the 16bit compound indexes), and if we need references to other VarFrames, we can use handlers (16bit, as High Integer Value of a Long Value).
The HashList, and the VarFrame can used for values with same name. We can use two or more same keys, and we can "walk" easy on them.
The program in zip file has some examples:
let see the global variables:
Code:
Global Const VbLongLong = 20Dim poolVarFrame() As VarFrame
Dim poolMax As Integer, NextPoolIndex As Integer
Dim poolHandlers() As Integer
Dim MaxHandler As Integer, Nexthandler As Integer, TopHandler As Integer
Public Identifiers As New HashList
Public LiteralsNum As New HashList
Public LiteralsStr As New HashList
We make a pool of VarFrames, so each time we need we see if exist in the pool and take it from there.
The basic idea is that we have Handlers which is the numbers which are the top part of a "Referenced" variable.
The VarFrame is a mix of a refArray and a Hashlist. (the last two classes I was introduced them some days ago, but here we have updated classes).
This example show how the reference work (through the WeakPtr, the compound index)
Code:
Sub main1() Identifiers.Prepare 2000
TopHandler = -1: poolMax = -1: NextPoolIndex = -1: MaxHandler = -1: Nexthandler = -1
AddHandlers 100: ExpandPool 100:
Dim a As Integer, b As Integer
a = NeoVar.NewVarFrame()
b = NeoVar.NewVarFrame()
Dim aa As VarFrame, bb As VarFrame
Set aa = poolVarFrame(a)
Set bb = poolVarFrame(b)
Debug.Print aa.VarCount(), bb.VarCount()
aa.AddVar "ALFA$", "HELLO THERE"
bb.AddVar "ALFA1$", "HELLO THERE AND THERE"
aa.AddVar "DBLBETA", 123#
bb.AddVar "DBLDELTA", 500#
Dim val
If aa.Find("ALFA$", val) Then
Debug.Print "aa.ALFA$ = "; val
End If
If bb.Find("ALFA1$", val) Then
Debug.Print "bb.ALFA1$ = "; val
End If
If aa.Find("DBLBETA", val) Then
Debug.Print "aa.DBLBETA = "; val
End If
If bb.Find("DBLDELTA", val) Then
Debug.Print "bb.DBLDELTA = "; val
End If
Dim WeakPtr, ptr1, ptr2
If aa.Find("ALFA$", , WeakPtr) Then
Debug.Print "aa.ALFA$ has weak ptr: ", aa.VarId(WeakPtr)
Debug.Print "handelr: "; aa.HandlerFromWeak(WeakPtr)
Debug.Print "Value from WeakPtr = "; aa(WeakPtr)
WeakPtr = bb.AddRefVar("HELLO$", WeakPtr)
Debug.Print "bb.HELLO$ is a reference to aa.ALFA$"
Debug.Print "local ptr="; WeakPtr
Debug.Print "Value from Local Ptr ="; bb(WeakPtr)
bb(WeakPtr) = "New Value"
Debug.Print "Value from Local Ptr ="; bb(WeakPtr)
End If
If bb.Find("HELLO$", val, WeakPtr) Then
Debug.Print "bb.HELLO$ = "; val
Debug.Print "bb.HELLO$ has weak ptr: ", bb.VarId(WeakPtr)
Debug.Print "handelr: "; bb.HandlerFromWeak(WeakPtr)
Debug.Print "Value from WeakPtr = "; bb(WeakPtr)
End If
If bb.Find("ALFA1$", , WeakPtr) Then
Debug.Print "bb.ALFA1$ has weak ptr: ", bb.VarId(WeakPtr)
Debug.Print "handelr: "; bb.HandlerFromWeak(WeakPtr)
Debug.Print "Value from WeakPtr = "; bb(WeakPtr)
End If
If aa.Find("ALFA$", val) Then
Debug.Print "aa.ALFA$ = "; val
End If
Debug.Print aa.Count(), bb.Count(), " Total fields"
Debug.Print aa.VarCount(), bb.VarCount()
Debug.Print "Identifier at id 0: "; Identifiers.Key(0)
Debug.Print "Total Identifiers: "; Identifiers.Count
Dim zero As Long
zero = LiteralsNum.Add(0#, "0", vbVariant)
Dim zerolong As Long
zerolong = LiteralsNum.Add(0&, "0&", vbVariant)
Debug.Print zero, " zero id", TypeName(LiteralsNum(zero))
Debug.Print zerolong, " zeroLong id", TypeName(LiteralsNum(zerolong))
Debug.Print "Total number literals: "; LiteralsNum.Count
Dim vars As HashList
Set vars = bb.VarNamesList()
Dim i As Long
For i = 0 To vars.Count - 1
Debug.Print vars(i), Hex$(vars.KeyNum2(i))
Next i
Debug.Print Join$(aa.VarNamesList("AA.").Values, ", ")
Debug.Print Join$(bb.VarNamesList("BB.").Values, ", ")
End Sub
Code:
Sub main()' using HashList as Variant type
Dim hash1 As New HashList
hash1.Prepare 1000
' just mark the first item as VbVariant
hash1.Add 10, "integer1", vbVariant
hash1.Add "hello", "String1"
hash1.Add hash1.cInt64("123456789012345678"), "long long 1"
hash1.Add CDec("12345678901234567800123456"), "Decimal 1"
hash1(1) = 50000
Debug.Print hash1(0), hash1(1), hash1(2), hash1(3)
hash1(0) = hash1(0) + 100
hash1(1) = 50000 ' change type
Debug.Print hash1(0), hash1(1), hash1(2), hash1(3)
hash1(2) = "ok" 'change type
Debug.Print hash1(0), hash1(1), hash1(2), hash1(3)
Debug.Print hash1.cInt64("123456789012345678")
Dim val, there, i As Long
If hash1.Find("long long 1", , there) Then
hash1.KeyNoReHash(there) = "New Key"
End If
If hash1.Find("New Key", val) Then
Debug.Print "Value at New Key = ", val
End If
If hash1.Find("Decimal 1", , there) Then
hash1.Key(there) = "New Key"
' so now we do rehash here
End If
If hash1.Find("New Key", val) Then
Debug.Print "Value at New Key = ", val
End If
Debug.Print "List"
For i = 0 To hash1.Count - 1
Debug.Print hash1(i), hash1.Key(i)
Next i
End Sub