Compiler 

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_1

end

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_1

Repeat...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
Wend

While 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