View previous topic - View next topic |
Author |
Message |
Ninkazu Demon Hunter
Joined: 08 Aug 2002 Posts: 945 Location: Location:
|
Posted: Thu Aug 12, 2004 4:59 am Post subject: Super tricky code problem |
[quote] |
|
Ok, as you may already know, I've been programming a scripting language....
Well, the problem lies in the fact that I've been learning from Game Scripting Mastery, and have everything working EXCEPT the variable amount operand functionality.
The big thing is, instead of Game Scripting Mastery's technique of allocating space for all operands to begin with, since they're all a fixed amount, I use a linked list to keep track of them.
In my system, operands are stored as WORDs, and are split into hi and lo bytes. The lo byte defines how many definite operands there are, and the hi byte defines how many variable operands there are (say if it's 3, you can have extra operands, but the amount has to be divisible by three - and you have to have at least one set). If the hi byte is 255, that means the operator doesn't know how many variable operands there are, because one of its operands has the capability for variable operands.
In my test source file, I use the following line to test:
CALLHOST AddWatch testFunc, ON_SCROLL, 1, 2
CALLHOST is defined with one definite operand - the API function name (in this case - AddWatch).
AddWatch is defined with two definite operands - the function to call when the watch state has been triggered, and the watch state
ON_SCROLL is the only operand with a definite amount of operands with no variable operands - and those are X and Y
This is the big problem (line 208+ in Assembler.cpp)
Code: | int op_ind = 0;
int def = nop->parameters & LOBYTE_MASK;
int var = (nop->parameters & HIBYTE_MASK)>>8;
int ntok;
for(;;)
{
nop = AddOperand(&operandList,nop,op_ind++,curFuncIndex);
if (nop)
{
op_ind = 0;
def = nop->parameters & LOBYTE_MASK;
var = (nop->parameters & HIBYTE_MASK)>>8;
}
ntok = GetNextToken();
if((op_ind < def-1 && var == 0) || (var > 0 && var < 255 && (op_ind - def >= 0) && ((op_ind-def)%var != 0)))
if (ntok != TOKEN_COMMA)
ExitOnCharExpectedError(',');
if ((op_ind == def && var == 0) || (var > 0 && var < 255 && (op_ind - def >= 0) && ((op_ind-def)%var ==0)))
if (ntok != TOKEN_COMMA)
break;
} |
The problem is, I have not a blazing clue if that's right. I know I have to somehow change my OPERATOR object and update the definite and variable operand values when an API function, watch state or another operator has been used as an operand.
The full source (VC++6) and test script is here: http://www.venosoft.com/venosoft/VSMC.zip
|
|
Back to top |
|
|
Ninkazu Demon Hunter
Joined: 08 Aug 2002 Posts: 945 Location: Location:
|
Posted: Thu Aug 12, 2004 6:31 pm Post subject: |
[quote] |
|
Ok. All solved.
http://www.venosoft.com/venosoft/VSMC.rar
Ya, it's a full compiler. If you manage to understand the program and how to run its compiled files you can go on ahead and use it (but give me credit of course).
::EDIT::
Nope. I found something that will be a problem.
CALLHOST AddTrigger, ID, ON_SCROLL, x, y, x1, y1, x2, y2, line_of_code
Looking at this you'll see that it has two operands that have undefined variable operands. This poses a problem, since I don't know how I can go from:
CALLHOST -> AddTrigger (ID, x1, y1, x2, y2) -> state (state operands) <- AddTrigger -> line_of_code (operator with operands, quite possibly written in a way that needs to go forwards and backwards as well)
So.... I have almost no clue how to fix this, other than maybe have a linked list built as a stack to:
push callhost
add callhost's definite operands (just AddTrigger)
push AddTrigger
add AddTrigger's definite operands (ID, x1, y1, x2, y2)
add AddTrigger's variable operands (state, line_of_code)
push state
add state's definite operands (x, y)
pop state
push operator
see push callhost up to this point
pop operator
pop AddTrigger
pop callhost
then on to the next line of code Think it will work?
....
God damn it, I have to go to the animal shelter today. Fucking nag of a mom... Ok, I'll be back later to work on this some more and tell you about it, but I have to go to a play with my foreign exchange student from 6:30 to about 12:00 so no more work after I leave for that :(
|
|
Back to top |
|
|
BigManJones Scholar
Joined: 22 Mar 2003 Posts: 196
|
Posted: Fri Aug 13, 2004 2:30 am Post subject: |
[quote] |
|
Variable operands sounds like a huge pita. Why bother?
|
|
Back to top |
|
|
Ninkazu Demon Hunter
Joined: 08 Aug 2002 Posts: 945 Location: Location:
|
|
Back to top |
|
|
tcaudilllg Dragonmaster
Joined: 20 Jun 2002 Posts: 1731 Location: Cedar Bluff, VA
|
Posted: Fri Aug 13, 2004 7:08 am Post subject: Great Idea |
[quote] |
|
I think I'll enjoy using your language. Keep us posted. :)
|
|
Back to top |
|
|
Aptyp Egg-Sucking Troll Humper
Joined: 09 Jun 2004 Posts: 36
|
Posted: Fri Aug 13, 2004 3:18 pm Post subject: |
[quote] |
|
Any particular reason why you wrote your own parser instead of using Lex/Yacc?
|
|
Back to top |
|
|
Ninkazu Demon Hunter
Joined: 08 Aug 2002 Posts: 945 Location: Location:
|
Posted: Fri Aug 13, 2004 3:56 pm Post subject: |
[quote] |
|
This is a learning experience. I like to use things only when I really know how they work (household appliances excluded).
|
|
Back to top |
|
|
LeoDraco Demon Hunter
Joined: 24 Jun 2003 Posts: 584 Location: Riverside, South Cali
|
Posted: Fri Aug 13, 2004 4:00 pm Post subject: |
[quote] |
|
Aptyp wrote: | Any particular reason why you wrote your own parser instead of using Lex/Yacc? |
I'm curious on this point, too. Parser/Lexer generators are great tools. While I can understand penis enlargement desires, Ockham's Razor suggests that the simplest approach is by far the better. _________________ "...LeoDraco is a pompus git..." -- Mandrake
Last edited by LeoDraco on Fri Aug 13, 2004 9:12 pm; edited 1 time in total
|
|
Back to top |
|
|
Aptyp Egg-Sucking Troll Humper
Joined: 09 Jun 2004 Posts: 36
|
Posted: Fri Aug 13, 2004 4:55 pm Post subject: |
[quote] |
|
Hell you don't even know how your own code works, but you use it anyway!
Besides, what exactly are you hoping to learn? How to make a tokenizer and a parser? Why, so that if one day you will have to write it, you will? Well, nobody does that anymore, everyone uses tools that were around for 30 years (yes, Lex is that old). Besides you can write a much more powerful language much more quickly using Lex/Yacc than writing your own.
|
|
Back to top |
|
|
Nodtveidt Demon Hunter
Joined: 11 Nov 2002 Posts: 786 Location: Camuy, PR
|
Posted: Fri Aug 13, 2004 5:22 pm Post subject: |
[quote] |
|
Identify the uneducated lazy n00b in this thread, folks! :D _________________ If you play a Microsoft CD backwards you can hear demonic voices. The scary part is that if you play it forwards it installs Windows. - wallace
|
|
Back to top |
|
|
Ninkazu Demon Hunter
Joined: 08 Aug 2002 Posts: 945 Location: Location:
|
Posted: Fri Aug 13, 2004 9:11 pm Post subject: |
[quote] |
|
I have it all fixed and I'm going to write the VM now. If there are problems with the VM, then I'll know my compiler is wrong, but for now I'm almost certain the compiler is right now.
Oh, and I will continue to write my own code because:
1) I am a programmer
2) I want to be a better programmer
3) If you don't learn things the hard way, you'll become a lazy, crappy programmer that both André LaMothe and I hate.
So you must all:
1) Fuck off
2) Fuck off
3) Go fuck yourselves
Good. Now see 1 & 2.
|
|
Back to top |
|
|
LeoDraco Demon Hunter
Joined: 24 Jun 2003 Posts: 584 Location: Riverside, South Cali
|
Posted: Fri Aug 13, 2004 9:19 pm Post subject: |
[quote] |
|
Ninkazu wrote: | Oh, and I will continue to write my own code because:
1) I am a programmer
2) I want to be a better programmer
3) If you don't learn things the hard way, you'll become a lazy, crappy programmer that both André LaMothe and I hate. |
Well, there is learning how to do things the hard way, and then there is learning how to dig a six-foot deep hole with a spoon.
Out of pure curiosity, is your compiler based either on a state machine, or upon the Interpreter pattern? Because if it isn't, you are hardly doing yourself a favor with respects to either points 2 or 3. Hell, even Gamma, et al, in Design Patterns suggests that lexer/parser generators are by far ideal over hand-coded alternatives. _________________ "...LeoDraco is a pompus git..." -- Mandrake
|
|
Back to top |
|
|
Ninkazu Demon Hunter
Joined: 08 Aug 2002 Posts: 945 Location: Location:
|
Posted: Fri Aug 13, 2004 10:16 pm Post subject: |
[quote] |
|
LeoDraco wrote: | Out of pure curiosity, is your compiler based either on a state machine, or upon the Interpreter pattern? |
Heh, what do you mean by these?
|
|
Back to top |
|
|
tcaudilllg Dragonmaster
Joined: 20 Jun 2002 Posts: 1731 Location: Cedar Bluff, VA
|
Posted: Sat Aug 14, 2004 12:57 am Post subject: |
[quote] |
|
It's a matter of mindset, really, and of thinking procedure. Personalities with investigative thinking procedure like to know the innards of something before they use it. If I use a library or generator of some kind to write a program, and then witness it crash in a way that I've never before seen, the first thing I suspect is the library. When you depend on others for your program accessories, without fully understanding how their systems function, you're in all practicality rolling a die.
I've heard that standardization is an important part of quick design process. But I've also heard of building a better mousetrap, however slow and painstaking a process that may be. Am I writing my own programming language? Yeah. Am I using standardized parser generator tools. Not at all. Their technology is a bit old and antiquidated, maybe a bit too specialized for my experimental purposes. Besides, the standardized lexical generation procedures were designed by INTP "mathematician" types, and their "explicit is better than implicit" mentality confuses me to no end! @_@
Maybe they confuse Ninkazu, too.
|
|
Back to top |
|
|
LeoDraco Demon Hunter
Joined: 24 Jun 2003 Posts: 584 Location: Riverside, South Cali
|
Posted: Sat Aug 14, 2004 1:51 am Post subject: |
[quote] |
|
Ninkazu wrote: | LeoDraco wrote: | Out of pure curiosity, is your compiler based either on a state machine, or upon the Interpreter pattern? |
Heh, what do you mean by these? |
Most parsers generated by generators are some form of state machine: that is to say that a set of states of the parser are generated; from a given state, on a given token, the parser is pushed into another state. This process, however, is usually required to be deterministic. Parse trees are usefully built from the traversal of the state machine. More information can be found in here (taken from the Bison manual).
The Interpreter pattern is one of the various patterns discussed in Gamma's Design Patterns; it's a way of representing grammars via a object hierarchy. You can find some more information here. Also, more information on the Gang of Four's book can be found here. _________________ "...LeoDraco is a pompus git..." -- Mandrake
|
|
Back to top |
|
|
|
Page 1 of 2 |
All times are GMT Goto page 1, 2 Next
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|