Hey guys,
Today's blog is more of an interest than a progress report. Sorry, I didn't get much time to work today, personal stuff, boring. Oh, I got to see my dad dance, drunk off his ass, with a belly dancer. Long story. Oh, right, programming! So, as I mentioned in a previous post, programming is creating a set of instructions to be executed. Well, when you actually send a program to a compiler, the code is translated into something that the system hardware can read. Now, lets say we are designing a compiler with 3 things: preprocessors, functions and variables. Keep in mind that the code I am showing is somewhat psuedo and obviously not instructed for use.
Take this program in our custom language:
#include "io.lang"
function test()
{
var x=5;
end_program();
}
Please ignore the obvious pointless-ness of this program. The compiler would do something along these lines:
1) Find any preprocessors and append the defined information in.
2) Look for any variables at a global scope and store their values in memory.
3) Search for all functions and repeat step 2-3, but since its recursive it is at a block scope.
4) Take the gathered information and convert it into working machine code.
While it seems easy, talk is cheap. Compilers often involve WEEKS of headache as well as gaining a ton of weight. The steps above don't necessarily apply for all languages, but it should give you an idea of how it works. Now, that stuff mostly applies if someone were to design a low-level machine code compiled language. I am interested in something a bit different.
JIT is a term that people usually just go, "... oh yeah, JIT, indeed!" The fact is that its a fairly simple acronym. It stands for "just-in-time." A lot of great languages use a JIT compiler, but instead of compiling to machine code, it is compiled into ALMOST machine code. Look at this for instance:
enum OPCodes
{
OPCode_Function = 0,
OPCode_Variable
};
Then what happens is the compiler actually writes a file like this:
OPCode_Byte Identifier_String Code
So a variable named test with a value of 5 would look like this:
0x01 "test" 0x00000005
The string "test" would actually be in hex or something but it doesn't matter. The point is, the code isn't system based, but rather something that EASILY can translate JUST in time.
What is the different about JIT and low-level system compiled languages? Well, you usually get a trade off. JIT languages are easy to design around, and very much so more compatible across platforms. The interpreter gets built for different platforms, but code that goes in will always be the same. This gives coders using your language peace of mind that they won't have to do a bunch of crap to make their stuff Linux/Windows/Mac compatible. Take this code for example in a psuedo JIT:
#include "core.h"
print("blah\n");
Now what it would look like in a system code language:
#ifdef WINDOWS
#include "win32core.h"
#elseif LINUX
#include "linuxcore.h"
#else
#include "maccore.h"
#endif
// lol MAC decides to use a different function name for print
#ifdef MAC
print_to_console("test\n");
#else
printf("test\n");
#endif
Oh, did I mention the fact that you need to build for each and every platform with machine code based languages? While this all seems to make JIT out to be a hero, its not ALL better. The fact is that machine code will always be faster than going through an interpreter first. But yeah, hope you learned something from my rant.
Your coder,
Anthony Iacono