Last active
September 29, 2020 19:29
-
-
Save Pebaz/8cb385411fc788d61af36051d7484f7f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Followed tutorial from: | |
https://keleshev.com/one-pass-compiler-primer | |
python .\calc_compiler.py 1 + 2; bat calc.s; zig cc -Wno-everything calc.s -o calc.exe; ./calc.exe; Write-Host $LASTEXITCODE | |
The Program: | |
1 + 2 + 3 * 4 | |
Will Be Compiled To: | |
.global main | |
main: | |
push $1 | |
push $2 | |
pop %rax | |
pop %rbx | |
add %rbx, %rax | |
push %rax | |
push $3 | |
pop %rax | |
pop %rbx | |
add %rbx, %rax | |
push %rax | |
push $4 | |
pop %rax | |
pop %rbx | |
mul %rbx | |
push %rax | |
pop %rax | |
ret | |
""" | |
import sys | |
def gen(tokens, out=sys.stdout): | |
emit = out.write | |
emit('.global main\n') | |
emit('main:\n') | |
for token in tokens: | |
if isinstance(token, int): | |
emit(f'\tpush ${token}\n') | |
elif 'ADD' in token: | |
emit('\tpop %rax\n') | |
emit('\tpop %rbx\n') | |
emit('\tadd %rbx, %rax\n') | |
emit('\tpush %rax\n') | |
elif 'MUL' in token: | |
emit('\tpop %rax\n') | |
emit('\tpop %rbx\n') | |
emit('\tmul %rbx\n') | |
emit('\tpush %rax\n') | |
emit('\tpop %rax\n') | |
emit('\tret\n') | |
def lex(text): | |
for t in text.split(): | |
if t.isnumeric(): | |
yield int(t) | |
else: | |
yield 'OP_' + {'+' : 'ADD', '*' : 'MUL'}[t] | |
def parse(tokens): | |
yield next(tokens) | |
for b in tokens: | |
op = next(tokens) | |
yield op | |
yield b | |
def compile(text, out=sys.stdout): | |
gen(parse(lex(text)), out) | |
if __name__ == '__main__': | |
with open('calc.s', 'w') as outfile: | |
compile(' '.join(sys.argv[1:]), outfile) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment