Tiger-Compiler (2017)

Tiger-Compiler is a compiler that translates the functional programming language Tiger into x86 assembler. The Tiger language features functions, nested functions, record values, implicit pointers, integers and string variables, and a few simple structured control constructs. I programmed the compiler with the help of the book “Modern Compiler Implementation in C”. However, the author does just give source code snippets and never the full code.

This is a small sample program written in the Tiger language that prints the numbers from 1 to 10:

let
  function printint(i: int) =
  let function f(i:int) = if i>0
	     then (f(i/10); print(chr(i-i/10*10+ord("0"))))
   in (if i<0 then (print("-"); f(-i))
      else if i>0 then f(i)
      else print("0"))
  end

in (for i := 1 to 10
  do (printint(i); print("\n")))
end

And this is the generated assembly:

.globl tigermain

.text

# PROCEDURE tigermain

tigermain:
    pushl %ebp
    movl %esp, %ebp
    pushl %ebx
    pushl %esi
    pushl %edi
    subl $100, %esp
L19:
    movl $1, -16(%ebp)
L16:
    movl $10, %edi
    # movl %edi, %edi
    movl -16(%ebp), %esi
    # movl %esi, %esi
    # movl %edi, %edi
    cmp %edi, %esi
    jle L17
    jmp L14
L14:
    movl $0, %edi
    movl %edi, %eax
    jmp L18
L17:
    pushl %edx
    pushl %ecx
    movl -16(%ebp), %ecx
    pushl %ecx
    movl %ebp, %edi
    addl $8, %edi
    pushl %edi
    call L0
    addl $8, %esp
    popl %ecx
    popl %edx
    pushl %edx
    pushl %ecx
    movl $L15, %edi
    pushl %edi
    call print
    addl $4, %esp
    popl %ecx
    popl %edx
    movl -16(%ebp), %edi
    # movl %edi, %edi
    addl $1, %edi
    movl %edi, -16(%ebp)
    jmp L16
L18:
    nop
    addl $100, %esp
    popl %edi
    popl %esi
    popl %ebx
    leave
    ret

# END

# PROCEDURE L0

L0:
    pushl %ebp
    movl %esp, %ebp
    pushl %ebx
    pushl %esi
    pushl %edi
    subl $100, %esp
L21:
    movl 12(%ebp), %ebx
    movl $0, %edi
    # movl %ebx, %ebx
    # movl %edi, %edi
    cmp %edi, %ebx
    jl L12
    jmp L13
L13:
    movl 12(%ebp), %ebx
    movl $0, %edi
    # movl %ebx, %ebx
    # movl %edi, %edi
    cmp %edi, %ebx
    jg L9
    jmp L10
L10:
    pushl %edx
    pushl %ecx
    movl $L7, %edi
    pushl %edi
    call print
    addl $4, %esp
    popl %ecx
    popl %edx
    movl %eax, %edi
L8:
    # movl %edi, %edi
L11:
    movl %edi, %eax
    jmp L20
L12:
    pushl %edx
    pushl %ecx
    movl $L6, %edi
    pushl %edi
    call print
    addl $4, %esp
    popl %ecx
    popl %edx
    pushl %edx
    pushl %ecx
    movl $0, %edi
    movl 12(%ebp), %esi
    # movl %edi, %edi
    subl %esi, %edi
    pushl %edi
    movl %ebp, %esi
    addl $8, %esi
    pushl %esi
    call L1
    addl $8, %esp
    popl %ecx
    popl %edx
    movl %eax, %edi
    jmp L11
L9:
    pushl %edx
    pushl %ecx
    movl 12(%ebp), %ecx
    pushl %ecx
    movl %ebp, %edi
    addl $8, %edi
    pushl %edi
    call L1
    addl $8, %esp
    popl %ecx
    popl %edx
    movl %eax, %edi
    jmp L8
L20:
    nop
    addl $100, %esp
    popl %edi
    popl %esi
    popl %ebx
    leave
    ret

# END

# PROCEDURE L1

L1:
    pushl %ebp
    movl %esp, %ebp
    pushl %ebx
    pushl %esi
    pushl %edi
    subl $100, %esp
L23:
    movl 12(%ebp), %ebx
    movl $0, %edi
    # movl %ebx, %ebx
    # movl %edi, %edi
    cmp %edi, %ebx
    jg L4
    jmp L5
L5:
    movl $0, %edi
    movl %edi, %eax
    jmp L22
L4:
    pushl %edx
    pushl %ecx
    movl 12(%ebp), %edi
    movl $10, %esi
    movl %edi, %eax
    movl $0, %edx
    divl %esi
    movl %eax, %edi
    pushl %edi
    movl 8(%ebp), %ecx
    pushl %ecx
    call L1
    addl $8, %esp
    popl %ecx
    popl %edx
    movl 12(%ebp), %edi
    movl 12(%ebp), %edx
    movl $10, %ebx
    movl %edx, %eax
    movl $0, %edx
    divl %ebx
    movl %eax, %ebx
    movl $10, %esi
    # movl %ebx, %ebx
    imul %esi, %ebx
    # movl %edi, %edi
    subl %ebx, %edi
    # movl %edi, %edi
    pushl %edx
    pushl %ecx
    movl $L2, %ecx
    pushl %ecx
    call ord
    addl $4, %esp
    popl %ecx
    popl %edx
    movl %eax, %esi
    pushl %edx
    pushl %ecx
    # movl %edi, %edi
    addl %esi, %edi
    pushl %edi
    call chr
    addl $4, %esp
    popl %ecx
    popl %edx
    movl %eax, %edi
    pushl %edx
    pushl %ecx
    pushl %edi
    call print
    addl $4, %esp
    popl %ecx
    popl %edx
    jmp L5
L22:
    nop
    addl $100, %esp
    popl %edi
    popl %esi
    popl %ebx
    leave
    ret

# END

.data

L15:
    .long 0x1
    .ascii "\n\0\0\0"

L7:
    .long 0x1
    .ascii "0\0\0\0"

L6:
    .long 0x1
    .ascii "-\0\0\0"

L2:
    .long 0x1
    .ascii "0\0\0\0"

When running the program, the following gets printed to stdout:

1
2
3
4
5
6
7
8
9
10

The source code with compile instructions, can be found on Github.