Old 23rd March 2008, 10:57   #1
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
OO Design Question

Let's say I have a base class A. Logically, all of the subclasses of A fall into two groups B and C. All of the B classes share some additional functionality that can go into the B base class and we'll have something like so.

code:

A
/ \
B C
/ \ / \
D E F G



There's more than the two classes for each, I'm just giving an example.

Here's the issue I'm grappling with. F and G in this example don't have any additional functionality from A. From this standpoint, they should directly subclass A. But, at runtime, I'll have a whole bunch of A objects that I need to determine whether they are B or C types.

So, is the solution to have a pretty much empty C subclass, or is the solution to have F and G directly subclass A and then come up with some other way to figure out whether they are B or C.


Sorry for the alphabet soup. I thought it might simplify things a bit.

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.
k_rock923 is offline   Reply With Quote
Old 23rd March 2008, 11:24   #2
zootm
Forum King
 
zootm's Avatar
 
Join Date: Jan 2002
Location: the nether reaches of bonnie scotland
Posts: 13,375
Generally you don't have this sort of nominal intermediate type for this sort of thing. The fact that B and C add no new functionality imply that they are qualitatively the same as A; having some form of "getCategory" call on the A class, abstract if necessary, which returns which of B or C the item falls. If there is no typing difference between B or C, then the "type safety" you earn by forcing the object into one of those types is effectively meaningless.

If you replace B and C with an external enumeration which can exist as a field on A you'll avoid tying yourself into the more-restrictive world of a type hierarchy and avoid the inflexibility and lack of convenience associated with it. Although it might be desirable to have this sort of thing type-checked on function calls you really have to ask yourself why you're doing this; pretty much any time I've considered this in the past there's been some better design.

If this is unclear I can provide more concrete examples.

zootm is offline   Reply With Quote
Old 23rd March 2008, 11:26   #3
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
Would it help if I gave the real objects I'm working with rather than this A,B,C business?

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.
k_rock923 is offline   Reply With Quote
Old 23rd March 2008, 11:30   #4
zootm
Forum King
 
zootm's Avatar
 
Join Date: Jan 2002
Location: the nether reaches of bonnie scotland
Posts: 13,375
It might. I've just updated the last post a little, incidentally.

zootm is offline   Reply With Quote
Old 23rd March 2008, 11:39   #5
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
It's an interpreter for a tiny language (the point of the whole thing is to understand operator precedence parsing)

So, we basically have symbols that are either Operands or Operators.

Here's the line of thinking I was taking

code:

public abstract class Symbol
{
protected String text;

public Symbol( String text )
{
this.text = text;
}

public String getText()
{
return text;
}
}

public interface Operand
{
public Symbol add( Symbol sym );

public Symbol div( Symbol sym );

public Symbol exp( Symbol sym );

public Symbol mod( Symbol sym );

public Symbol mult( Symbol sym );

public Symbol sub( Symbol sym );
}

public class StringToken extends Symbol implements Operand
{
public Symbol mult( Symbol sym )
{
if( sym instanceof IntegerToken )
{
//calculate it
}

throw new TypeMismatchException();
}
}



So, you think the right thing to do is replace the instanceof with an isInteger method? I had something like that before and what bothered me about it was adding a type would force me to change all of the other types.

Or would it. . . I guess not, huh?

The only real issue now is how to do the calculations cleanly.

Something like this maybe?

code:

public Symbol mult( Symbol sym )
{
if( sym.isInt() )
{
return multInt( sym );
}

throw new TypeMismatchException();
}

private Symbol multInt( Symbol sym )
{
int1 = Integer.parseInt( this.text );
int2 = Integer.parseInt( sym.text );

return new Symbol( (String) int1 * int2 );
}



That's where I'm stuck. I don't like that at all and I'm not sure how I indicate that the new Symbol is an Operand without making it ugly as hell.

//Being stuck in this kind of whole might mean there's a far bigger design problem

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.
k_rock923 is offline   Reply With Quote
Old 23rd March 2008, 11:57   #6
zootm
Forum King
 
zootm's Avatar
 
Join Date: Jan 2002
Location: the nether reaches of bonnie scotland
Posts: 13,375
Well the interesting thing here is that if you create an IntegerSymbol/IntegerToken class, you can put an "intValue()" method on it, which means that you have a good reason for your extra class. Why is Operand an interface, and why does StringToken implement it? What do these things represent?

I've not really the time to go into the subtleties of these things but this is highly dependent on the semantics of the language you're parsing, and usually people use grammars for this sort of thing, but I guess that'd be kinda missing the point here . I'm not sure I understand what the control flow in your approach is though; I suspect you want independent classes for each token type and work from there. Consider using a factory to create your token stream.

zootm is offline   Reply With Quote
Old 23rd March 2008, 12:00   #7
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
I'll play with it a bit more when I get back tonight. Originally, I had just what you're describing, exactly. The intValue method was why IntegerToken and StringToken were separate classes, but doing the calculations became ugly.

I had a bunch of instanceof if statements trying to figure out if I had a valid combination of operand/operand/operator.

That's really the stumbling block here. I'll have three and know only that they're symbols. Assuming that they're operand/operand/operator, I need to combine those to form a new symbol, discarding the old ones.

The actual parsing part works find, it's just that it's not clean.

It's low on the priority list because I have a completely working version, but the design is ugly and it bothers me enough that I want to fix it.

Thanks for the suggestions

//hehe I know, a grammar is the right way to go. Although I did use the FIRST sets and such to write the Tokenizer. At this point, it's more of an exercise in designing a class hierarchy, which is fine by me.

Stop reading my mind At some point the other day I said to myself "creating the tokens screams factory"

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.
k_rock923 is offline   Reply With Quote
Old 23rd March 2008, 12:16   #8
zootm
Forum King
 
zootm's Avatar
 
Join Date: Jan 2002
Location: the nether reaches of bonnie scotland
Posts: 13,375
Quote:
Originally posted by k_rock923
That's really the stumbling block here. I'll have three and know only that they're symbols. Assuming that they're operand/operand/operator, I need to combine those to form a new symbol, discarding the old ones.
For the record, in a language with pattern matching this would be really easy . I still think that's the right way to go, though; what was making the calculations "ugly"?

Quote:
Originally posted by k_rock923
I had a bunch of instanceof if statements trying to figure out if I had a valid combination of operand/operand/operator.
If you don't mind duplicating information an enum could make this sort of stuff neater. A method like:

code:
TokenType getTokenTypeForSymbol( Symbol symbol );


Would abstract away the actual implementation of that if needs-be, too.

Quote:
Originally posted by k_rock923
Stop reading my mind At some point the other day I said to myself "creating the tokens screams factory"
Design patterns are basically just names for the stock answers to these questions

zootm is offline   Reply With Quote
Old 23rd March 2008, 16:03   #9
jheriko
Forum King
 
jheriko's Avatar
 
Join Date: Aug 2002
Location: a twist in the fabric of space
Posts: 2,150
Send a message via ICQ to jheriko
Quote:
Originally posted by k_rock923

code:

public Symbol mult( Symbol sym )
{
if( sym.isInt() )
{
return multInt( sym );
}

throw new TypeMismatchException();
}

private Symbol multInt( Symbol sym )
{
int1 = Integer.parseInt( this.text );
int2 = Integer.parseInt( sym.text );

return new Symbol( (String) int1 * int2 );
}



That's where I'm stuck. I don't like that at all and I'm not sure how I indicate that the new Symbol is an Operand without making it ugly as hell.

//Being stuck in this kind of whole might mean there's a far bigger design problem
Correct me if I am wrong by I guess that what you don't like here is using the if to check the type here...

The way I would implement this sort of thing, would be to give "Symbol" virtual member functions for every thing that both operators and operands can do with some generic exception throwing as the default. For the operators, assuming they are all binary (for simplicity), you then have some method like Symbol Symbol::Execute(Symbol p1, Symbol p2) which is overriden in Operand to throw an exception or error message about syntax ("expected operator, found operand" or something). For each type of operator you have to derive a new class and override Execute to do the calculation.

For Operand typing you would implement GetInt, GetString, GetFloat etc... as virtuals in Symbol and overriding in Operator to return appropriate errors ("operand expected, found operator"). You would then need to derive a class for each Operand type, overriding GetInt/String... to return the actual value, rather than triggering the default "throw an exception or error message" behaviour inherited from Operand. This also lets you implement types like the Variant in VB or the php variables where, for an int for example, you can overload GetInt to return the int, GetString to return the string etc... allowing for automatic type conversion.

I've implemented this before a couple of times in C++ but not in C# or anything else... using function pointers to implement this manually rather than using classes... it saves making a class for each operator/operand type but its certainly possible within OO designs to accomplish the same thing with inheritance. You can also create a similar effect to the function pointer using delegates in .net, so that rather than full inheritance you just implement a load of static functions for the different operators/operands and set the function pointers/delegates in the constructor as appropriate. This is what most implementations of inheritance do internally with the virutal function table anyway...

Hope that makes sense...

-- Jheriko

'Everything around us can be represented and understood through numbers'
jheriko is offline   Reply With Quote
Old 23rd March 2008, 22:37   #10
zootm
Forum King
 
zootm's Avatar
 
Join Date: Jan 2002
Location: the nether reaches of bonnie scotland
Posts: 13,375
If I'm reading that right, jheriko, you're essentially flattening what I suggested in my third post in this thread into a single class; I'm not sure what benefit is gotten with that approach, though, could you explain? I'm concerned that by putting all the functions into one place you're essentially turning compile-time errors into runtime errors, which is something that I try to avoid as much as possible.

For what it's worth, delegated functions in .NET don't have to be static, either; they can be associated with an object and it all just works as it should.

zootm is offline   Reply With Quote
Old 24th March 2008, 18:47   #11
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
Here's the thing. . . + and a few others are overloaded.

So, if 'abc' + 'e' = abce

I think that I won't have any other choice but to figure out the type in the calc method and then call a private method to calculate it. Here's what I have at the moment. I think it's better:

So, I figure I'll just need to see what types I have and calculate a valid expression if there is one.

Thoughts?

//I really do think zootm is in my head. I just looked back at the first version that started getting ugly and what did I find? A TokenType enum. . .

//edit2: I still think that, especially with the design as it is now, Operator might be better off as an interface.
Attached Images
File Type: png classdiagram1.png (6.2 KB, 104 views)

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.

Last edited by k_rock923; 24th March 2008 at 21:14.
k_rock923 is offline   Reply With Quote
Old 25th March 2008, 02:52   #12
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
Yea, here's what I end up with. . .

code:

public Symbol calc( Symbol sym1, Symbol sym2 )
{

if( ( sym1.getType() == SymbolType.INTEGER ) &&
( sym2.getType() == SymbolType.INTEGER ) )

{
return calcInt( sym1, sym2 );
}

if( ( sym1.getType() == SymbolType.STRING ) &&
( sym2.getType() == SymbolType.STRING ) )

{
return calcString( sym1, sym2 );
}

throw new TypeMismatchException();
}



I think that's about as clean as it can get. Adding a new symbol means only adding a single class and adding a definition to the enum.

Adding a new Operand type will be more work, but I guess it's a compromise. I can't make it easy to add both.

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.
k_rock923 is offline   Reply With Quote
Old 25th March 2008, 09:09   #13
jheriko
Forum King
 
jheriko's Avatar
 
Join Date: Aug 2002
Location: a twist in the fabric of space
Posts: 2,150
Send a message via ICQ to jheriko
Quote:
Originally posted by zootm
If I'm reading that right, jheriko, you're essentially flattening what I suggested in my third post in this thread into a single class
I assume you are talking about the point i made re function pointers... there is no functional benefit other than a minor potential speed increase, mainly I just do it that way for ease of implementation. I find its nicer to have a pile of static functions than it is to have inherited classes for each and every operator, generally there is much less repitition of code and less room for error etc...

I get what you mean about putting off compile time errors till run time... I assumed that this is for an interpreter. You would normally pick up errors when the parse tree is constructed, but here I assume that one line is being parsed at a time using a stack or something, and is being compiled and executed on the fly. If there was a parse tree then the typing issue would never be an issue... you could pick it up at compile time as you suggest.

Quote:
Originally posted by zootm
Here's the thing. . . + and a few others are overloaded.

So, if 'abc' + 'e' = abce

I think that I won't have any other choice but to figure out the type in the calc method and then call a private method to calculate it. Here's what I have at the moment. I think it's better:
Thats a good point, but its not fatal. You just have to enforce types rather than allow the flexible typing I suggested. Then if "getInt()" returns 0 you do a string concatenation rather than an integer addition. You could still keep the other functions behaving differently though... and another solution would be to drop "+" and use ".", for example. (PHP does this.... I wonder why? )

The better solution would be to pick that up at compile time though...

I'm assuming that this is for an interpreter still... otherwise stuff like:

code:

private Symbol multInt( Symbol sym )
{
int1 = Integer.parseInt( this.text );
int2 = Integer.parseInt( sym.text );

return new Symbol( (String) int1 * int2 );
}



Would be quite out of place... or wasteful (passing around "Symbol" objects and doing string conversions), one or other.

I see you have already implemented the "repeated if statement" method though... there is nothing wrong with that if speed is not an issue. The only advantage of using inheritance of function pointers as suggested is that the if doesn't have to be done at runtime. Ifs are fast though, so unless you want to factorise integers in your new language I wouldn't bother changing it if it works.

-- Jheriko

'Everything around us can be represented and understood through numbers'
jheriko is offline   Reply With Quote
Old 25th March 2008, 10:10   #14
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
I'd use function pointers if Java had them.

If it wasn't clear, this is an assignment for a course. So, I'm stuck with Java and using '+'.

I just cant think of a good way to avoid using the if statements for type (and and integer could very well be 0).

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.
k_rock923 is offline   Reply With Quote
Old 25th March 2008, 10:54   #15
jheriko
Forum King
 
jheriko's Avatar
 
Join Date: Aug 2002
Location: a twist in the fabric of space
Posts: 2,150
Send a message via ICQ to jheriko
Quote:
Originally posted by k_rock923
I just cant think of a good way to avoid using the if statements for type (and and integer could very well be 0).
Well then you just have to check the string length too then :P

I kid though... that idea is too tailored to a specific case (variable types) to employ here... all the workarounds are a pain. I should have realised the error to begin with.

A much better solution would be a proper compiler... but if its an assignment for writing interpreter then you are just stuffed...

You can still use the inheritance idea though, you would just need a work around for the overloaded +, either that or to implement the types by using function pointers/delegates that are set when the type is decided during some first pass. You can distinguish a string and non-string at this stage and when creating the "operand" or relevant object you would set the function pointer there. No "if" needed at runtime then, just dereference and call the function pointer.

Does Java have a void pointer equivalent? In that case there are more tricks that can be done here to avoid code repitition...

In short you still need the ifs, but you can get away with doing them, at most, once per sub-expression requiring one. This isn't really worth it though unless you need the speed... better to leave as it is, even if its an ugly solution, at least it works.

EDIT: Note that you can use function pointers in general to remove any multiple if to check some static requirement. I often use this for renderer options since speed is often required and doing an multiple ifs per triangle/vertex is often a colossal overhead. Its a pretty useful general technique for speeding things up...

-- Jheriko

'Everything around us can be represented and understood through numbers'
jheriko is offline   Reply With Quote
Old 25th March 2008, 11:01   #16
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
I often wish Java had function pointer. I think you can sort of fake them with some constructs.


The thing is that this solution isn't terribly ugly. It just doesn't scale too well. I only need to convert string to int once - at the object creation and then the IntegerSymbol object has a field for the primitive int value.

You're absolutely right - a proper scanner/parser/generator etc would be nice, but that's a lot more work and I need to write an interpreter for this assignment.

As I said, I already have a fully working version of it, but it's ugly and I didn't like it.

Thanks for the help

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.
k_rock923 is offline   Reply With Quote
Old 25th March 2008, 17:43   #17
zootm
Forum King
 
zootm's Avatar
 
Join Date: Jan 2002
Location: the nether reaches of bonnie scotland
Posts: 13,375
Quote:
Originally posted by k_rock923
I often wish Java had function pointer. I think you can sort of fake them with some constructs.
They call the construct a "functor". They're used for callbacks and the like. C-style function pointers are not "safe" in any way, shape, or form and are quite frightening things to use.

If it's working and you don't wanna change it, go right ahead. If you want to change it I would suggest trying the most elegant design you can find, though, since you'll probably get the most out of it.

zootm is offline   Reply With Quote
Old 25th March 2008, 17:49   #18
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
Well, without telling me exactly how (because I wouldn't learn anything that way) do you think it's possible to design it in way that avoids the if statements for type checking overloaded operators? This solution is nice, but it doesn't scale very well.

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.
k_rock923 is offline   Reply With Quote
Old 25th March 2008, 21:12   #19
zootm
Forum King
 
zootm's Avatar
 
Join Date: Jan 2002
Location: the nether reaches of bonnie scotland
Posts: 13,375
If you maintain a context as you consume your tokens you should always know what you're building, I think?

zootm is offline   Reply With Quote
Old 25th March 2008, 22:36   #20
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
hmmm. Maybe. I probably should have mentioned this before, but parentheses are allowed.

So, if I have something like ( 1 + 2 ) + ( 1 + ( 3 * 4 ) )

etc, it's hard to maintain context. I'm pretty sure for now that I'm going to go with the type checking within the operator classes.

I sort of like how it makes the parsing part of the program be able to just pop some tokens off the stack and do the operation without knowing or caring what they are.

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.
k_rock923 is offline   Reply With Quote
Old 25th March 2008, 23:07   #21
zootm
Forum King
 
zootm's Avatar
 
Join Date: Jan 2002
Location: the nether reaches of bonnie scotland
Posts: 13,375
How complex is your typesystem? Don't you just have one class of number with no implicit conversions?

zootm is offline   Reply With Quote
Old 25th March 2008, 23:12   #22
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
It's just numbers and strings, with some overloaded operators.

"x" * 3 = xxx

stuff like that.

There's also operators that aren't overloaded:

"x" * "x" = type mismatch.


//This has led me to the State pattern, but it seems very similar to what I already have, just with a zillion objects. . .

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.

Last edited by k_rock923; 25th March 2008 at 23:33.
k_rock923 is offline   Reply With Quote
Old 26th March 2008, 02:17   #23
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
I'm a fucking moron. It's not the state pattern that I wanted, but the visitor pattern. That seems to be a whole lot better.

//really anything that allows me to emulate multiple dispatching is what I was looking for and avoids exactly what I thought was messy.

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.

Last edited by k_rock923; 26th March 2008 at 03:09.
k_rock923 is offline   Reply With Quote
Old 27th March 2008, 12:03   #24
jheriko
Forum King
 
jheriko's Avatar
 
Join Date: Aug 2002
Location: a twist in the fabric of space
Posts: 2,150
Send a message via ICQ to jheriko
Design patterns are bad!!!

Well not really... I just think maybe you are overkilling the problem with theory somewhat. I guess its the context of the homework problem though...

There are certainly much better ways to approach the problem imo. Personally I usually refer to my knowledge of how C++ or the Intel CPU works to decide how to do something... I find it a much more effective way of thinking than looking at design patterns. For instance I always implemented function calls by passing parameters on a stack like "cdecl" or "stdcall", I usually use a list of function pointers or actual code for the code that is generated... this is a direct parallel to the execution model of the x86 too, you can have an "instruction" pointer etc... and it automatically gives you a way to implement branching and looping and function calls. :P

using a stack to parse the infix expressions (like known C++ compilers do afaik - possibly converting to postfix first) its easy to keep track of the types refered to by function calls and operators as long as you have well defined return types for all of the operators and functions...

I haven't implemented this as an "execute on the fly" though, I almost always build a "half-compiled program" first... it makes so much stuff easier imo

-- Jheriko

'Everything around us can be represented and understood through numbers'
jheriko is offline   Reply With Quote
Old 27th March 2008, 12:56   #25
k_rock923
\m/
(Forum King)
 
k_rock923's Avatar
 
Join Date: Jul 2003
Location: /bin/bash
Posts: 7,850
Send a message via AIM to k_rock923
I'm absolutely overkilling the problem with theory. Don't worry, I'm aware that this isn't at all necessary and not even practical. It's just interesting

I ended up using reflection, if anyone is at all interested. Someone can just drop in a new class file that sublasses Symbol and tell the SymbolFactory class about it. The Symbol abstract class specifies a boolean 'matcher' function, er method. That takes a String as a parameter.

Then, if we do SymbolFactory.create( "^" ) or whatever the symbol was, it knows about it. If it happened to also be an operator (a subclass of Operator that is), the code will start using the operator in calculations automatically.

Was this necessary? Nope. Was it interesting? Yup. Most importantly, did I learn something? Absolutely.

Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.
k_rock923 is offline   Reply With Quote
Old 27th March 2008, 17:57   #26
zootm
Forum King
 
zootm's Avatar
 
Join Date: Jan 2002
Location: the nether reaches of bonnie scotland
Posts: 13,375
Quote:
Originally posted by jheriko
There are certainly much better ways to approach the problem imo. Personally I usually refer to my knowledge of how C++ or the Intel CPU works to decide how to do something... I find it a much more effective way of thinking than looking at design patterns. For instance I always implemented function calls by passing parameters on a stack like "cdecl" or "stdcall", I usually use a list of function pointers or actual code for the code that is generated... this is a direct parallel to the execution model of the x86 too, you can have an "instruction" pointer etc... and it automatically gives you a way to implement branching and looping and function calls. :P
I don't think this is a problem being solved by "looking at design patterns". This is a problem which is being solved by looking at how it's done in normal languages. The Intel CPU does not solve this problem at all and C++ has such complex syntax that I would not recommend either as good examples of what to do, though.

Patterns are not being put forward as the solution to the problem here, though. They just give an easy way to talk about the correct solution. A C++ solution would do the same thing.

Quote:
Originally posted by jheriko
using a stack to parse the infix expressions (like known C++ compilers do afaik - possibly converting to postfix first) its easy to keep track of the types refered to by function calls and operators as long as you have well defined return types for all of the operators and functions...
This is effectively the state approach being put forward, although you're using a stack rather than a tree, which also works.

Quote:
Originally posted by jheriko
I haven't implemented this as an "execute on the fly" though, I almost always build a "half-compiled program" first... it makes so much stuff easier imo
An abstract syntax tree is probably what you're thinking here, or some other intermediate representation, yes.

zootm is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Community Center > General Discussions

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump