Structure of how this language should work

Started by
15 comments, last by Zotoaster 16 years, 11 months ago
It seems to me that your problem is that you have no separation between parsing and execution, when in fact these are two distinct actions.

IMO, scripts should be transformed into a form more easily executed either at load time (once when the script is loaded) or Just-In-Time (once, the first time a function is encountered) rather than run-time interpretted. Expression trees or an assembly-like stack-based language are usually pretty good options. Even globals could be JIT'ed, so long as they are completely initialized before their first use.


The basic approach I would use is this:

Scan the file at load time for symbols (class/function names, class definitions). Place them in a symbol table with an offset to the beginning of the definition in the file, but don't translate them yet.

Begin execution at your entry point, when a symbol is encountered check the symbol table to see if it has been translated, if not, use the offset to find it again and translate it. In the case of a function/method Push a return location and any parameters and jump to it's exectutable form. In the case of a class definition, check the symbol table to see if the class itself has been translated, if not, translate it. Minimally, the data layout and appropriate constructor must be translated (other methods can be translated now, or JIT'ed as encountered if you wish.) then push a return value and any parameters and jump to the appropriate constructor.

For simple built-in types which are global, I'd just instantiate them once at load time as they're encountered.

Also, if you were to impliment the JIT approach, you must watch out for dependancies. If a class takes another class or another class's member as a parameter, that class must be translated/instantiated first; so-on and so-forth all the way down until no dependancies exist. If you instantiate all globals at load time, you'll have a much easier time since you can instantiate the data as encountered, without trying to walk back up the dependancy chain.

throw table_exception("(? ???)? ? ???");

Advertisement
Quote: It seems to me that your problem is that you have no separation between parsing and execution

Actually, I am working in a strange order just now. I am starting off with the virtual machine, so I can know that the bytecode can work well. I have a descent parser in another file, but I'm not using that just now. :)
Quote:Original post by Zotoaster
Oh also, as for the local variables bit, I have never understood them (obviously I know what they are etc), I understand turning parameters into variables, but having an array for local variables seems kinda of pointless, seeing as the braces {} will clear all the variables by the time the function has finished anyway.


That makes no sense. That's like saying "allocating memory with 'new' is pointless, as it'll just get deleted." Local variables have to exist somewhere while you use them. How you handle them is up to you. And I never used the word 'array'.
Quote: "And I never used the word 'array'."

Heh, sorry, I just figured that's what you meant.

But really what I meant was that, atleast in my scripting (not sure about anything else), when a variable is created, a pointer to it is added to the stack, and obviously when it reaches a } it clears the stack till it finds a {, so to me atleast, there is no difference between local and global variables, so actually treating what turns out to be "local variables" as a different type of variable seemed pretty pointless, heheh.

But anyway, I have figured out functions, and just working on my virtual machine. I think once I get a clear understanding of them, I will try to implement classes.

Thanks everyone :)
*Bump*

I have encountered another problem. It's about parameters. I figured, if I made a variable in a function, and set it as a parameter, it would just pop the top stack item into it. There's a problem though, when the program moves the the start of the function, it adds the { to the stack for scoping purposes.

Should I just work around this by only popping any actual values into the variable? I don't like "work arounds", they annoy me. There must be something better I can do.
Google and read up on "Stack Frames"

throw table_exception("(? ???)? ? ???");

Thanks, everything seems to be working out good. I can succesfully compile code like this:

void foo(){    int bar[3+2];}void main(){    foo();    int hi;}


But that's about as complex as the compiler can handle. Obviously the virtual machine is capable of alot more, but soon enough it'll work fine :)

This topic is closed to new replies.

Advertisement