Help With Compiler Design
#1
Posted 25 November 2005 - 04:54 PM
I need some help with the compiler design. What is the fastest way to calculate an address in the bytecode that you want to jump to. I need an efficient way to do this ... and not TOO difficult
I already tried different things but they didn't work out.
Any ideas?
#2
Posted 26 November 2005 - 09:03 AM
you must do it this way: Make two tables, a lable table and an adress table, both dynamic lists.
A lable table entry stores the following data: the lable's name, the lable adress and whether the lable adress is known yet or not.
plables = ^tlables; tlables = record name: array[0..5] of char; adress: word; isknown: boolean; next: plables; end;
(you should not make the name a string because you have much lables and few memory only; I gave it 6 chars here, you can modify that). When parsing the source, set up the lable table (--> set the name field, and isknown := false. Ignore the adress field). NOTE: The lable table contains all things that have an adress, so variables and procedures are lables, too.
I don't know how you build the compiler, but if you have a kind of designator list storing all designators parsed from the source and storing whether it's a var, a procedure et.c., you can link the lable table directly to it, which would be faster and need less memory:
plables = ^tlables; tlables = record item: pdesignator; adress: word; isknown: boolean; next: plables; end;
Note that you need to have the lable table complete (you should complete it during first parsing) before going to the next step (building the bytecode), as you need the lables for it.
On building the bytecode, maybe read the source again or you have stored all neccessarry data in an internal list already (that you also did set up during parsing, but I'd advice against it because of the low memory).
Whenever you need an adress in the bytecode (e.g. "call anything"), look into the lable table what adress your needed lable has (--> "anything"). If the adress is known, insert the adress. If not, leave space in the bytecode for the adress that you can fill it in later and set up an adress table entry. An adress table entry stores where what adress has to be filled in:
padresses = ^tadresses; tadresses = record where: word; //offset in the bytecode, where you left space to recieve the adress what: plables; //pointer to the lable whose adress has to be filled in next: padresses; end;
On building the bytecode, also update the lable table permanently to determine the adresses of labels. That goes this way:
Imagine you bildet 2340 bytes of bytecode already, so your "current offset" is 2340 meaning the next thing appearing in the source will have adress 2340 (note that you need a current data offset and a current code offset if you divide the program into code and data segment). When you read in a lable declaration now (--> a lable, a variable or a procedure declaration), search the according lable table entry, set the adress field and set isnknown := true.
When ready with this step, finally work of the adress table as all lable adresses are known now. Means for all adress table entries: word(pointer(where)^) := what^.adress. Then you're ready.
Hope that'll help you
---Edit:---
>When you read in a lable declaration now, search the according lable table entry
Note that this step works very very fast! Don't search it by comparing the names through the full list, but the lable list contains it's lables already in that order they appeared in the source (if you added a new lable always to the end of the list during parsing). So when youn read through the source again and want to find the matching table entry, the matching entry is always the next one.
#3
Posted 26 November 2005 - 10:47 AM
That was excatly what I needed. I read of the address table idea already elsewhere but didn't understand how it was supposed to work. (I have the sources for fasm)
Now I know. Will try it tonight!
#4
Posted 08 December 2005 - 07:30 PM
Just to let you know ... debugging this thing is HELL!!! I can only express my depest respect for the work
of the author of fasm which is completely written in its own ASM dialect!
Anyways I got the command translation nearly working today and the interpreter still runs nicely. I will try to implement the parameter parse this night and then the expression evaluator the next weekend. Then some debugging and I hope that I have the first beta as a X-Mas / Christmas / Holiday present
Cu huhn_m
#5
Posted 08 December 2005 - 10:04 PM
Don't wanna interfere, but actual a compiler is not a thing dedicated to be written in assemblerJust to let you know ... debugging this thing is HELL!!! I can only express my depest respect for the work
of the author of fasm which is completely written in its own ASM dialect!
You might get BIG problems problems especially with the expression evaluator as it's a not that easy recursive algorithm. You should write it in Pascal or C (or some kind of pseudocode at least; not necessary that any compiler is able to compile it, but just that you have a plan of the algorithm for yourself), and only then translate it into assembler.
Does the address thing work so far?
#6
Posted 08 December 2005 - 10:24 PM
#7
Posted 09 December 2005 - 04:38 PM
And about lex: I doubt they would run on the casio and I don't think they ca buiĺd our quite specific byte code. Also I don't go over tokens but use some kind of look up table since, due to the nature of the language, it is quite easy to directly convert the source to the bytecode. But marco is right. The expression evaluation will be tricky but not SUCH a problem since, AFAIK, no brackets will be supported in MLC2 so it is just straight math and should not include to much nesting.
#8
Posted 11 December 2005 - 08:01 PM
#9
Posted 11 December 2005 - 09:04 PM
#10
Posted 19 December 2005 - 07:37 PM
1) Variables and Function Names are NOT restricted in length (except by the line length of 255 chars)! I found a method that made this possible while also decreasing table sizes at compile time. It is 100% sure that it will work this way. The method should also speed up compiling.
2) Variables MIGHT make it to the first beta! This would increase usability a lot and it seems like I did a quite big deal of it. However with christmas nearing I can not guarantee anything. But you can still expect the other BETA I announced if I failt to get this done.
However Functions and all things associated with them won't make it for now unless I find lots of time lying arround what is quite unlikely maybe till new years eve. But who knows!
Cu huhn_m
#11
Posted 23 December 2005 - 03:05 PM
#12
Posted 25 December 2005 - 12:48 PM
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users