Compiler 

DarkMachine Engine's Compiler parses *.dm/*.dmc source code and generates PCode instructions *.dmo 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 DarkMachine. The best way to get a feel for the internal workings of the compiler is to examine the dmcvm_Compiler.bb.

Extremely High Level Overview

The Compiler consists of 8 functions that work together recursively to generate Pcode:

1. dmcvm_CompilerLoad()
2. dmcvm_CompilerTokenGet()
2. dmcvm_CompilerParseStatement()
3. dmcvm_CompilerParseExpession()
4. dmcvm_CompilerParseTerm()
5. dmcvm_CompilerParseFact()
6. dmcvm_CompilerParseLeaf()
7. dmcvm_CompilerParseArguments()

The dmcvm_CompilerLoad() loads *.dmc file line by line. The dmcvm_TokenGet() 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 dmcvm_CompilerStatement().

The dmcvm_CompilerStatement() is reponsible for generating PCode for Keyword Constructs and Assignments to Variable/Array from the BSCVM_TOKENs returned by dmcvm_TokenGet().

dmcvm_CompilerParseExpression() is reponsible generating PCode for Conditions like Equal_to, Greater_than, etc.

dmcvm_CompilerParseTerm() and dmcvm_CompilerParseFact() are responsible for generating PCode for math operations.

dmcvm_CompilerParseLeaf()is reponsible for generating PCode for Keyword Constructs and Assignments from Variable/Array and Calls.

dmcvm_CompilerParseArguments() 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