BlitzScript3D Engine's Compiler parses *.bs/*.bsc source code and generates PCode instructions *.bso that are executed by the Virtual Machine. I selected this method over interpreting for speed and security.
I started with Mark Sibly's Compiler Code because it had a excellent way of parsing expressions and tokenizing BASIC statements, keywords, etc and output instructions. With some research and reading on Assembler, I was armed with enough info to pursue development of BlitzScript3D. The best way to get a feel for the internal workings of the compiler is to examine the bscvmCompiler.bb.
Extremely High Level Overview
The Compiler consists of 8 functions that work together recursively to generate Pcode:
1. bscvmCompilerLoad()
2. bscvmCompilerTokenGet()
2. bscvmCompilerParseStatement()
3. bscvmCompilerParseExpession()
4. bscvmCompilerParseTerm()
5. bscvmCompilerParseFact()
6. bscvmCompilerParseLeaf()
7. bscvmCompilerParseArguments()The bscvmCompilerLoad() loads *.bsc file line by line. The bscvmTokenGet() parses the line by one character at a time returning a BSCVM_TOKEN that represents a Keyword, Value, Array, Variable, or CALL to the function that called it, usually the bscvmCompilerStatement().
The bscvmCompilerStatement() is reponsible for generating PCode for Keyword Constructs and Assignments to Variable/Array from the BSCVM_TOKENs returned by bscvmTokenGet().
bscvmCompilerParseExpression() is reponsible generating PCode for Conditions like Equal_to, Greater_than, etc.
bscvmCompilerParseTerm() and bscvmCompilerParseFact() are responsible for generating PCode for math operations.
bscvmCompilerParseLeaf()is reponsible for generating PCode for Keyword Constructs and Assignments from Variable/Array and Calls.
bscvmCompilerParseArguments() generates PCode for generating PCode for Call Parameters.
BlitzBasic3D --> OpCode Conversion
Select...Case
Select a
Case 1
a=2
Case 2, 0
a=1
Default
a=0
EndSelect;Select a
mov eax,[a]
mov ebx, eax;Case 1
label_2
mov eax,1
cEQ eax, ebx
jz label_3;a=2
mov eax,2
mov [a], eax
jmp label_1;Case 2
label_3
mov eax,2
push eax
mov eax,0
pop ecx
or eax, ecx
cEQ eax, ebx
jz label_4;a=1
mov eax,1
mov [a], eax
jmp label_1;Default
label_4;a=0
mov eax,0
mov [a], eax
jmp label_1;EndSelect
label_5
label_1end
For...Next
For a = 1 To 10 Step 2
b=1
Next;For a = 1 To 10 Step 2
mov eax,1
mov [a], eax
label_2
mov eax, [a]
push eax
mov eax,10
pop ecx
cLT eax, ecx
jz label_1;b=1
mov eax,1
mov [b], eax;Next
mov eax, [a]
add eax, 2.0
mov [a], eax
jmp label_2
label_1Repeat...Until
Repeat
a=a-1
Until a=0;Repeat
label_2;a=a-1
mov eax,[a]
push eax
mov eax,1
pop ecx
sub eax,ecx
mov [a], eax;Until a=0
mov eax,[a]
push eax
mov eax,0
pop ecx
cEQ ecx,eax
jz label_2
label_1
While...Wend
While a<10
a=a+1
WendWhile a<10
label_2
mov eax,[a]
push eax
mov eax,10
pop ecx
cLT ecx,eax
jz label_1;a=a+1
mov eax,[a]
push eax
mov eax,1
pop ecx
add eax,ecx
mov [a], eax;Wend
jmp label_2
label_1