Dynamic recursive type arrays
Author |
Message |
Jens Balchen J #1 / 15
|
 Dynamic recursive type arrays
Is there a way to implement dynamic recursive type arrays? What it is? This is a dynamic recursive type array: Type Jens SubJens() As Jens End Type on which you should be able to perform: Redim Jens.SubJens(x) But VB won't allow any of these. So, is there another way to do this? -- VB Info: http://www.*-*-*.com/ ~balchen/vb/visual.htm FAQ: http://www.*-*-*.com/ ~balchen/vb/faq.htm Knowledge Base: http://www.*-*-*.com/ ~balchen/vb/kb.htm
|
Thu, 28 Jan 1999 03:00:00 GMT |
|
 |
Jim Hugul #2 / 15
|
 Dynamic recursive type arrays
Quote: >Is there a way to implement dynamic recursive type arrays? What it is? This >is a dynamic recursive type array: > Type Jens > SubJens() As Jens > End Type
I don't think it is possible because you are trying to declare SubJens() as a UDT of Jens that has not yet been defined. Quote: >on which you should be able to perform: > Redim Jens.SubJens(x)
Even if you could wouldn't this be incorrect? This would have to be something like Redim JensNew as Jens Redim JensNew.SubJens(x) Don't you have to assign a name to a UDT and are not allowed to use it directly? (i.e. Type MyType abc as string End Type Dim My as MyType You can't reference MyType.abc, can you? It must be My.abc...... Quote: >But VB won't allow any of these. So, is there another way to do this?
Also I don't have a clue as to what value Jens.SubJens(x) could hold since it would not be defined as anything other than itself. How would you intend to use this? At least this is an interesting question and not "How do I keep my form on Top" <g>. Jim Huguley
* Those who sit and think * * Mostly sit *
|
Thu, 28 Jan 1999 03:00:00 GMT |
|
 |
Larry Morri #3 / 15
|
 Dynamic recursive type arrays
I probably went a little overboard, but why not use objects. Here's an example: 1. Insert a Module into your project and add the following code: Option Explicit Public Sub Main() Dim o As Parent Set o = New Parent With o .Name = "Larry" .Age = 28 End With 'Here are Larry's Children o.AddChild o, "Epson", 1 o.AddChild o, "PC", 1 o.AddChild o, "Smokey", 3 'Here are Smokey's Children, Larry's Grandchildren. Dim gc As Parent Set gc = o.cChildren("Smokey") gc.AddChild gc, "Spit-Fire", 1 gc.AddChild gc, "Tar-Baby", 47 'Note this prints 47 in the debug window. debug.print o.cChildren("Smokey").cChildren("Spit-Fire").age stop End Sub 2. Insert a new class into your project and name it Parent. Then add the following code: Option Explicit Public Name As String Public Age As Integer Public oParent As Parent Public cChildren As New Collection Public Sub AddChild(oParent As Parent, sName As String, iAge As Integer) Dim Child As Parent Set Child = New Parent With Child Set .oParent = oParent .Name = sName .Age = iAge End With cChildren.Add Item:=Child, Key:=sName Set Child = Nothing End Sub NOTES: Since collections are dynamic, you can create an class and place a collection in it. The AddChild routine places new instances of the Parent class into the collection. Using this method, I can have as many kids, grandkids, etc. as I want! Hate to see my grocery bill!
Quote: > Is there a way to implement dynamic recursive type arrays? What it is? This > is a dynamic recursive type array: > Type Jens > SubJens() As Jens > End Type > on which you should be able to perform: > Redim Jens.SubJens(x) > But VB won't allow any of these. So, is there another way to do this? > -- > VB Info: http://www.sn.no/~balchen/vb/visual.htm > FAQ: http://www.sn.no/~balchen/vb/faq.htm > Knowledge Base: http://www.sn.no/~balchen/vb/kb.htm
|
Thu, 28 Jan 1999 03:00:00 GMT |
|
 |
Jens Balchen J #4 / 15
|
 Dynamic recursive type arrays
Quote: >I don't think it is possible because you are trying to declare >SubJens() as a UDT of Jens that has not yet been defined.
Exactly. So I'm looking for a way around it. Quote: >> Redim Jens.SubJens(x) >Even if you could wouldn't this be incorrect?
Being picky, are we? Quote: >You can't reference MyType.abc, can you? It must be My.abc......
Of course, you are correct, but that is the least of my problems. Quote: >>But VB won't allow any of these. So, is there another way to do this? >Also I don't have a clue as to what value Jens.SubJens(x) could hold >since it would not be defined as anything other than itself. How would >you intend to use this?
I'm creating a command interpreter, and at one stage in the processing of code, I do a recursive check for expressions. Each expression can have several sub-expressions. As in this example: if ( gethostname ( a + b ) = c ) (pardon the C syntax) You can break this down into: expr1 ::= name ( expr2 ) ' "if ( )" expr2 ::= expr3 operator expr4 ' gethostname ( a + b ) = c expr3 ::= name ( expr5 ) ' "gethostname ( )" expr5 ::= name operator name ' a + b expr4 ::= name ' c When I do an expression parse, I would like to do this: GetExp "if ( gethostname ( a + b ) = c )", Exp Sub GetExp (ByVal CmdString, Exp As ExpType) ' blah blah parse blah blah ' Get sub expressions While SubExpressions Redim Exp.SubExp(+1) GetExp "the parsed out expression" Exp.SubExp(+1) Wend End Sub Get the point? A recursive expressions parser. As Larry Morris pointed out, this could be possible in VB 4.0, but it wouldn't be possible in VB 3.0 unless someone thinks of something clever. -- VB Info: http://www.sn.no/~balchen/vb/visual.htm FAQ: http://www.sn.no/~balchen/vb/faq.htm Knowledge Base: http://www.sn.no/~balchen/vb/kb.htm
|
Thu, 28 Jan 1999 03:00:00 GMT |
|
 |
Ed Phillip #5 / 15
|
 Dynamic recursive type arrays
Quote: >SNIP< > 'Here are Smokey's Children, Larry's Grandchildren. > Dim gc As Parent > Set gc = o.cChildren("Smokey") > gc.AddChild gc, "Spit-Fire", 1 > gc.AddChild gc, "Tar-Baby", 47 > 'Note this prints 47 in the debug window. > debug.print o.cChildren("Smokey").cChildren("Spit-Fire").age
Am I missing something here? I haven't used objects or classes and UDT's. Shouldn't the above code print 1 to the debug window? Ed ******************************************************** ** Southern Indiana Bass Fishing / Outdoor Software ** ** HTTP://www.evansville.net/~dlion/mypage.htm ** ********************************************************
|
Thu, 28 Jan 1999 03:00:00 GMT |
|
 |
Jens Balchen J #6 / 15
|
 Dynamic recursive type arrays
Quote: >I probably went a little overboard, but why not use objects.
Execpt that you should've used Tar-Baby as Key in the last line, it was a great sample. But: upon testing this code, VB 4.0 grants me with a GPF... Quote: > Set gc = o.cChildren("Smokey")
... right here. If I press Ignore four times, VB returns and gives me a "Subscript out of range" error. Duh. Forget it. Once I restarted VB, it worked like charm. I think I hate VB 4.0, even though I like classes more than ever. But, being who I am, this solution has only academic value. Thanks anyway - it was fun. -- VB Info: http://www.sn.no/~balchen/vb/visual.htm FAQ: http://www.sn.no/~balchen/vb/faq.htm Knowledge Base: http://www.sn.no/~balchen/vb/kb.htm
|
Fri, 29 Jan 1999 03:00:00 GMT |
|
 |
Richard RUD #7 / 15
|
 Dynamic recursive type arrays
Quote: >Is there a way to implement dynamic recursive type arrays? What it is? This >is a dynamic recursive type array: > Type Jens > SubJens() As Jens > End Type >on which you should be able to perform: > Redim Jens.SubJens(x) >But VB won't allow any of these. So, is there another way to do this?
This is a first for me to see you ask a question. Anyway, I don't beleive any language can do this. It is unresolvable. Normally when you want to do something like this, you are creating a reference to another object like in a linked list. That is, the SubType does not contain Type, but SubType *POINTS* to another copy of Type. In C for example, struct Jens { struct Jens * SubJens Quote: }
I would probably try to use an unbounded Array for this. But as an exercise, you could test the following in VB4. This is 1st iteration (out of my head), completely untested. (I only have VB3 which does not support objects in Types) Option Explicit Type Jens item As Integer SubJens As object ' ^^^^^^ ' VB3 Fails here End Type Sub walkJens () Dim j1 As Jens Dim j2 As Jens Dim j3 As Jens Dim jref As object j1.item = 1 Set j1.SubJens = j2 j2.item = 2 Set j2.SubJens = j2 j3.item = 3 Set j2.SubJens = j3 Set jref = j1 For a = 1 To 3 Debug.Print jref.item, Hex$(jref.SubJens) Set jref = jref.SubJens Next End Sub __ __ _______________________________ //)) //)) | Richard RUDEK. MicroDek. | Hey, Whadda ya //\\ //\\ | Chatswood, Sydney. Australia. | want for nuting... `-------------------------------'
|
Sun, 31 Jan 1999 03:00:00 GMT |
|
 |
Richard RUD #8 / 15
|
 Dynamic recursive type arrays
Quote:
>>I don't think it is possible because you are trying to declare >>SubJens() as a UDT of Jens that has not yet been defined. >Exactly. So I'm looking for a way around it. >>> Redim Jens.SubJens(x)
<snip> Quote: >I'm creating a command interpreter, and at one stage in the processing of >code, I do a recursive check for expressions. Each expression can have >several sub-expressions. As in this example: > if ( gethostname ( a + b ) = c ) >(pardon the C syntax) >You can break this down into: >expr1 ::= name ( expr2 ) ' "if ( )" >expr2 ::= expr3 operator expr4 ' gethostname ( a + b ) = c >expr3 ::= name ( expr5 ) ' "gethostname ( )" >expr5 ::= name operator name ' a + b >expr4 ::= name ' c >When I do an expression parse, I would like to do this: > GetExp "if ( gethostname ( a + b ) = c )", Exp > Sub GetExp (ByVal CmdString, Exp As ExpType) > ' blah blah parse blah blah > ' Get sub expressions > While SubExpressions > Redim Exp.SubExp(+1) > GetExp "the parsed out expression" Exp.SubExp(+1) > Wend > End Sub >Get the point? A recursive expressions parser. As Larry Morris pointed out, >this could be possible in VB 4.0, but it wouldn't be possible in VB 3.0 >unless someone thinks of something clever.
I'm confused. Looking up expression: "A combination of functions, operators, variables, and constants that yield a string or numeric result. An expression can perform a calculation, manipulate characters, or test data." As a consequence, an expression parser has to understand the language constructs. That is, interpret. I think the easiest approach would be to instead treat the data stream as a collection of tokens. Tokens can be commands, operators or data. Commands are interpreted, setting certain properties, parameter counts etc. If parameters are involved, then in reality what you have is the possiblity of an expression. Each expression, in turn has to be run by the interpreter again to break up the expression into command, data and more parameters. Anyway, I would start by looking at some of the C code out there that implement an interpreter, or compiler ? You may already have done this, But from the above, I'm not sure I understand how a "Dynamic Recursive Type Array" would operate here. This thread is interesting to me because I will be starting a new project soon that I intend to have interpreted/compiled scripts visually constructed. But my starting point will probably be a Java/postscript/BASIC Interpreter or a C compiler. I also doubt wether I'll write it in VB. __ __ _______________________________ //)) //)) | Richard RUDEK. MicroDek. | Hey, Whadda ya //\\ //\\ | Chatswood, Sydney. Australia. | want for nuting... `-------------------------------'
|
Sun, 31 Jan 1999 03:00:00 GMT |
|
 |
Jens Balchen J #9 / 15
|
 Dynamic recursive type arrays
Quote: > Normally when you want to do something like this, you are creating a > reference to another object like in a linked list. That is, the > SubType does not contain Type, but SubType *POINTS* to another copy of > Type.
So I could do this in VB using some Longs and the hmemcpy API. I already thought of that, but then I meet a problem: The Redim. Imagine SubJens is an integer array now. I've tried the following: 1: Redim Jens.SubJens(10) 2: Sub RedimArray (Array() As Integer) Redim Array(Ubound(Array) + 1) End Sub RedimArray Jens.SubJens() None of these work. So the criteria 1) subitems of the same type, and 2) redimable, aren't met. -- VB Info: http://www.sn.no/~balchen/vb/visual.htm FAQ: http://www.sn.no/~balchen/vb/faq.htm Knowledge Base: http://www.sn.no/~balchen/vb/kb.htm
|
Sun, 31 Jan 1999 03:00:00 GMT |
|
 |
Jens Balchen J #10 / 15
|
 Dynamic recursive type arrays
Quote: > I'm confused. Looking up expression:
Don't. I don't know wether I'm using the word as anyone else would. Quote: > "A combination of functions, operators, variables, and constants that > yield a string or numeric result. An expression can perform a > calculation, manipulate characters, or test data."
Well, that book isn't far off. :) Quote: > As a consequence, an expression parser has to understand the language > constructs. That is, interpret.
No, it does not. I've planned this in four steps: 1. Tokenizer (see below). Barry Wegman referred to this a lexical analyzer 2. Expression parser 3. Data storage (optional) 4. Interpreter Steps 1-3 are to be generic to all languages I plan to implement using this code. It's only step 4 that needs to be customized. Let me explain a little further. Say we have an input string like: if(gethostname(a(i+1))=gethostname(b+c(a+1)+1)){printf(c);printf(b);}else{printf(a);}; (pardon the C syntax) This is what I currently use for testing. The tokenizer generates a token stream, based on simple criteria: 1. I have made an array of statements and tokens, so that when a substring in the string matches a statement, a given token is returned (a statement will also include "(", ")", "{", "}", and so on) 2. Anything that doesn't match a statement is a (varible, function, sub) name, and the token for a name is returned 3. You have to tell the tokenizer which characters aren't allowed in a name After the tokenizer had analyzed the input string with the given criteria, it returns an array of tokens. The token array is sent to the expression parser, which also has some information on the langauge (function start = "(", function end = ")", and so on), and it generates a tree-structure of statements, like this: if gethostname a i + 1 = gethostname b + c a + 1 + 1 { printf c ; printf b ; else { printf a ; ; So every expression can have one or more sub expressions. This tree structure makes it easier for the interpreter to interpret the data (IMO). When the interpreter wants to interpret the data, it steps down the tree structure until it reaches a dead end, at which point it returns. This way, it can evaulate the expressions in an orderly manner, and recurse through the entire array. Quote: > I think the easiest approach would be to instead treat the data stream > as a collection of tokens. Tokens can be commands, operators or data.
I already do. Quote: > You may already have done this, But from the above, I'm not sure I > understand how a "Dynamic Recursive Type Array" would operate here.
Do you see now? Quote: > This thread is interesting to me because I will be starting a new > project soon that I intend to have interpreted/compiled scripts > visually constructed. But my starting point will probably be a > Java/Postscript/BASIC Interpreter or a C compiler.
With my code, you can interpret C code if you like :) Quote: > I also doubt wether I'll write it in VB.
It _is_ rather slow, but that doesn't worry me. The compiler doesn't need to be fast, as long as the interpreter is. -- VB Info: http://www.sn.no/~balchen/vb/visual.htm FAQ: http://www.sn.no/~balchen/vb/faq.htm Knowledge Base: http://www.sn.no/~balchen/vb/kb.htm
|
Sun, 31 Jan 1999 03:00:00 GMT |
|
 |
Richard RUD #11 / 15
|
 Dynamic recursive type arrays
Quote:
>> I'm confused. Looking up expression: >Don't. I don't know wether I'm using the word as anyone else would. >> "A combination of functions, operators, variables, and constants that >> yield a string or numeric result. An expression can perform a >> calculation, manipulate characters, or test data." >Well, that book isn't far off. :) >> As a consequence, an expression parser has to understand the language >> constructs. That is, interpret. >No, it does not. >I've planned this in four steps: >1. Tokenizer (see below). Barry Wegman referred to this a lexical analyzer >2. Expression parser >3. Data storage (optional) >4. Interpreter >Steps 1-3 are to be generic to all languages I plan to implement using this >code. It's only step 4 that needs to be customized. Let me explain a little >further. >Say we have an input string like: >if(gethostname(a(i+1))=gethostname(b+c(a+1)+1)){printf(c);printf(b);}else{printf(a);}; >(pardon the C syntax) >This is what I currently use for testing. The tokenizer generates a token >stream, based on simple criteria: >1. I have made an array of statements and tokens, so that when a substring >in the string matches a statement, a given token is returned (a statement >will also include "(", ")", "{", "}", and so on) >2. Anything that doesn't match a statement is a (varible, function, sub) >name, and the token for a name is returned >3. You have to tell the tokenizer which characters aren't allowed in a name >After the tokenizer had analyzed the input string with the given criteria, >it returns an array of tokens. The token array is sent to the expression >parser, which also has some information on the langauge (function start = >"(", function end = ")", and so on), and it generates a tree-structure of >statements, like this: >if > gethostname > a > i > + > 1 > = > gethostname > b > + > c > a > + > 1 > + > 1 >{ > printf > c > ; > printf > b > ; >else >{ > printf > a > ; >; >So every expression can have one or more sub expressions. This tree >structure makes it easier for the interpreter to interpret the data (IMO). >When the interpreter wants to interpret the data, it steps down the tree >structure until it reaches a dead end, at which point it returns. This way, >it can evaulate the expressions in an orderly manner, and recurse through >the entire array. >> I think the easiest approach would be to instead treat the data stream >> as a collection of tokens. Tokens can be commands, operators or data. >I already do. >> You may already have done this, But from the above, I'm not sure I >> understand how a "Dynamic Recursive Type Array" would operate here. >Do you see now? >> This thread is interesting to me because I will be starting a new >> project soon that I intend to have interpreted/compiled scripts >> visually constructed. But my starting point will probably be a >> Java/Postscript/BASIC Interpreter or a C compiler. >With my code, you can interpret C code if you like :) >> I also doubt wether I'll write it in VB. >It _is_ rather slow, but that doesn't worry me. The compiler doesn't need >to be fast, as long as the interpreter is.
OK. What I was suggesting was that instead of tokenising all of the data stream *before* it is given to the interpreter, you could try having the interpreter *request* tokens from the data stream. This way, you don't have to build and maintain a list of pointers etc. Anyway, I'll take a look at this, and your previous reply to my previous post (Sheeze, what a mouthful), and see what I can come up with using VB3. I suspect it would be easier in VB4. BTW, did you try that untested example I gave ? __ __ _______________________________ //)) //)) | Richard RUDEK. MicroDek. | Hey, Whadda ya //\\ //\\ | Chatswood, Sydney. Australia. | want for nuting... `-------------------------------'
|
Mon, 01 Feb 1999 03:00:00 GMT |
|
 |
Richard RUD #12 / 15
|
 Dynamic recursive type arrays
Quote:
>> Normally when you want to do something like this, you are creating a >> reference to another object like in a linked list. That is, the >> SubType does not contain Type, but SubType *POINTS* to another copy of >> Type.
<snip> I think this should work on VB4, but for some reason my VB3 doesn't like this. GPF's. I can't see why. Basically, you create 3 unbounded arrays. Two object arrays, and one string (or whatever). The first object array (ObjectArray), contains either String or SubObjectArrays, and is the Trunk of the Tree. SubOjectArray can also contain String or SubObjectArrays. This last part is what gives you recursion. --Module-- Option Explicit Global ObjectArray() As object Global SubObjectArray() As object Global StringArray$() --- Form -- Option Explicit Sub Command2_Click () ReDim ObjectArray(4) As Object ReDim SubObjectArray(2) As Object ReDim StrArray(3) As String Dim OB As Object Dim a% 'Fill StrArray StrArray(1) = "S1" StrArray(2) = "S2" StrArray(3) = "S3" 'Linkup SubObjectArray to either StrArray or a lower SubObject Set SubObjectArray(1) = StrArray(2) Set SubObjectArray(2) = StrArray(3) Set SubObjectArray(3) = SubObjectArray(2) 'Linkup ObjectArray to StrArray or SubObjects Set ObjectArray(1) = "Test" Set ObjectArray(2) = StrArray(1) Set ObjectArray(3) = SubObjectArray(1) Set ObjectArray(4) = SubObjectArray(3) 'Show the results List1.Clear For a = 1 To 4 Set OB = ObjectArray(a) Do Until VarType(OB) = 8 Set OB = OB DoEvents Loop List1.AddItem OB Next End Sub __ __ _______________________________ //)) //)) | Richard RUDEK. MicroDek. | Hey, Whadda ya //\\ //\\ | Chatswood, Sydney. Australia. | want for nuting... `-------------------------------'
|
Mon, 01 Feb 1999 03:00:00 GMT |
|
 |
Wayne Ming #13 / 15
|
 Dynamic recursive type arrays
Quote: >Get the point? A recursive expressions parser. As Larry Morris pointed out, >this could be possible in VB 4.0, but it wouldn't be possible in VB 3.0 >unless someone thinks of something clever.
if you just want to evaluate the expression, not save the components for later, then each time getexp finds a ( , it calls itself pointing past the ( and returning the result on a ). -------------------------------------------------------------
|
Mon, 01 Feb 1999 03:00:00 GMT |
|
 |
Jens Balchen J #14 / 15
|
 Dynamic recursive type arrays
Quote: > OK. What I was suggesting was that instead of tokenising all of the > data stream *before* it is given to the interpreter, you could try > having the interpreter *request* tokens from the data stream.
Well, things would work out like this (I guess): Send string to interpreter. Interpreter asks tokenizer to tokenize, and then ask the expression parser to parse it. Interpreter then interprets and executes commands. Quote: > Anyway, I'll take a look at this, and your previous reply to my > previous post (Sheeze, what a mouthful), and see what I can come up > with using VB3. I suspect it would be easier in VB4. > BTW, did you try that untested example I gave ?
No, I didn't. Larry Morris gave me some tips on how to do it using a class and a collection, and I have that working already. Besides, that ******* redim works in VB 4.0, but not in VB 3.0. *aaaarrrgghh* -- VB Info: http://www.sn.no/~balchen/vb/visual.htm FAQ: http://www.sn.no/~balchen/vb/faq.htm Knowledge Base: http://www.sn.no/~balchen/vb/kb.htm
|
Mon, 01 Feb 1999 03:00:00 GMT |
|
 |
Paul Sampso #15 / 15
|
 Dynamic recursive type arrays
Quote:
> Is there a way to implement dynamic recursive type arrays? What it is? This > is a dynamic recursive type array: > Type Jens > SubJens() As Jens > End Type > on which you should be able to perform: > Redim Jens.SubJens(x) > But VB won't allow any of these. So, is there another way to do this?
Without trying it, and without thinking much why you might want to do this, without much at all, really, couldn't you do it with a class? Since a class is globally registered, it should be possible to have a class Jens which can certainly dim x as object and which at run time can be assigned to an object of class Jens and which can also support methods which (at a pinch, the compiler might barf at this) might even be able to return objects of class Jens? I can see trouble with this, from recursion obviously, but this should be get-roundable (gettable round?) by implementing a class which is a collection of Jens objects. (On the grounds that recursion can always be replaced by iteration.) Do you object, Jens? [>8] -- -------------------------------------------------------------------
BB 74 A4 EF 03 F8 44 C1 F3 75 FE C6 7E F9 6E 43 --- at home -------------------------------------------------------------------
|
Tue, 02 Feb 1999 03:00:00 GMT |
|
|
|