Skip to content

calint/compiler-2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

compiler-2: baz

Experimental compiler for a minimalistic, specialized language that targets NASM x86_64 assembly on Linux.

Intention

  • minimalistic language
  • gain experience writing compilers
  • generate handwritten-like assembler compiled by NASM for x86_64
  • super loop program with non-reentrant inlined functions

Supports

  • built-in integer types (64, 32, 16, 8 bit)
  • built-in boolean type
  • user defined types
  • inlined functions
  • keywords: func, field, var, loop, if, else, continue, break, return

Howto

  • to compile the compiler that compiles prog.baz and assembles the generated code run ./make.sh
  • after that use ./run-baz.sh myprogram.baz or ./run-baz.sh to compile and run prog.baz
  • to run the tests qa/coverage/run-tests.sh and see coverage report in qa/coverage/report/

Source

Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C/C++ Header                    35            791            533           4262
C++                              1             51             64            385
-------------------------------------------------------------------------------
SUM:                            36            842            597           4647
-------------------------------------------------------------------------------

Sample

field   hello = "hello world from baz\n"
field   input = "............................................................"
field prompt1 = "enter name:\n"
field prompt2 = "that is not a name.\n"
field prompt3 = "hello "
field     dot = "."
field      nl = "\n"

# all functions are inlined

# arguments can be placed in specified register using `reg_...` syntax
func exit(v : reg_rdi) {
    mov(rax, 60)  # exit system call
    mov(rdi, v)   # return code
    syscall()
}

func print(len : reg_rdx, ptr : reg_rsi) {
    mov(rax, 1)   # write system call
    mov(rdi, 1)   # file descriptor for standard out
    mov(rsi, ptr) # buffer address 
    mov(rdx, len) # buffer size
    syscall()
}

func read(len : reg_rdx, ptr : reg_rsi) : i64 nbytes {
    mov(rax, 0)   # read system call
    mov(rdi, 0)   # file descriptor for standard input
    mov(rsi, ptr) # buffer address
    mov(rdx, len) # buffer size
    syscall()
    mov(nbytes, rax) # return value
}

func assert(expr : bool) {
    if not expr exit(1)
}

# user types are defined using keyword `type`

# default type is `i64` and does not need to be specified
type point {x, y}

type object {pos : point, color : i32}

# function arguments are equivalent to mutable references
func foo(pt : point) {
    pt.x = 0b10    # binary value 2
    pt.y = 0xb     # hex value 11
}

# default argument type is `i64`
func bar(arg) {
    if arg == 0 return
    arg = 0xff
}

# return target is specified as a variable, in this case `res`
func baz(arg) : i64 res {
    res = arg * 2
}

func main() {
    var p : point = {0, 0}
    foo(p)
    assert(p.x == 2)
    assert(p.y == 0xb)

    var i = 0
    bar(i)
    assert(i == 0)

    i = 1
    bar(i)
    assert(i == 0xff)

    var j = 1
    var k = baz(j)
    assert(k == 2)

    k = baz(1)
    assert(k == 2)

    var p0 : point = {baz(2), 0}
    assert(p0.x == 4)

    var x = 1
    var y = 2

    var o1 : object = {{x * 10, y}, 0xff0000}
    assert(o1.pos.x == 10)
    assert(o1.pos.y == 2)
    assert(o1.color == 0xff0000)
    
    var p1 : point = {-x, -y}
    o1.pos = p1
    assert(o1.pos.x == -1)
    assert(o1.pos.y == -2)

    var o2 : object = o1
    assert(o2.pos.x == -1)
    assert(o2.pos.y == -2)
    assert(o2.color == 0xff0000)

    print(hello.len, hello)
    loop {
        print(prompt1.len, prompt1)
        var len = read(input.len, input) - 1    # -1 don't include the '\n'
        if len == 0 {
            break
        } else if len <= 4 {
            print(prompt2.len, prompt2)
            continue
        } else {
            print(prompt3.len, prompt3)
            print(len, input)
            print(dot.len, dot)
            print(nl.len, nl)
        }
    }
}

Generates

; generated by baz

section .bss
stk resd 1024
stk.end:

true equ 1
false equ 0

section .data
;[1:1] field hello = "hello world from baz\n"
hello: db 'hello world from baz',10,''
hello.len equ $-hello
;[2:1] field input = "............................................................"
input: db '............................................................'
input.len equ $-input
;[3:1] field prompt1 = "enter name:\n"
prompt1: db 'enter name:',10,''
prompt1.len equ $-prompt1
;[4:1] field prompt2 = "that is not a name.\n"
prompt2: db 'that is not a name.',10,''
prompt2.len equ $-prompt2
;[5:1] field prompt3 = "hello "
prompt3: db 'hello '
prompt3.len equ $-prompt3
;[6:1] field dot = "."
dot: db '.'
dot.len equ $-dot
;[7:1] field nl = "\n"
nl: db '',10,''
nl.len equ $-nl

section .text
bits 64
global _start
_start:
mov rsp,stk.end
; program
;[9:1] # all functions are inlined
;[11:1]  # arguments can be placed in specified register using `reg_...` syntax
;[39:1]  # user types are defined using keyword `type`
;[41:1]  # default type is `i64` and does not need to be specified
;[46:1]  # function arguments are equivalent to mutable references
;[52:1]  # default argument type is `i64`
;[58:1]  # return target is specified as a variable, in this case `res`
main:
;    var p: point @ qword[rsp-16]
;    [64:5]  var p : point = {0, 0}
;    [64:9] p : point = {0, 0}
;    [64:21]  {0, 0}
;    [64:21] {0, 0}
;    [64:22] 0
;    [64:22] 0
;    [64:22] p.x = 0
    mov qword[rsp-16], 0
;    [64:25]  0
;    [64:25] 0
;    [64:25] p.y = 0
    mov qword[rsp-8], 0
;    [65:5]  foo(p)
;    foo(pt : point) 
    foo_65_5:
;        alias pt -> p
;        [48:5]  pt.x = 0b10
;        [48:12]  0b10
;        [48:12] 0b10
;        [48:12] pt.x = 0b10
        mov qword[rsp-16], 0b10
;        [48:20] # binary value 2
;        [49:5]  pt.y = 0xb
;        [49:12]  0xb
;        [49:12] 0xb
;        [49:12] pt.y = 0xb
        mov qword[rsp-8], 0xb
;        [49:20] # hex value 11
    foo_65_5_end:
;    [66:5] assert(p.x == 2)
;    alloc r15
;    [66:12] p.x == 2
;    [66:12] ? p.x == 2
;    [66:12] ? p.x == 2
    cmp_66_12:
    cmp qword[rsp-16], 2
    jne bool_false_66_12
    bool_true_66_12:  ; opt1
    mov r15, true
    jmp bool_end_66_12
    bool_false_66_12:
    mov r15, false
    bool_end_66_12:
;    assert(expr : bool) 
    assert_66_5:
;        alias expr -> r15
        if_36_8_66_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_66_5:
        cmp r15, false
        jne if_36_5_66_5_end
        if_36_8_66_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_66_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_66_5_end:
        if_36_5_66_5_end:
;        free r15
    assert_66_5_end:
;    [67:5] assert(p.y == 0xb)
;    alloc r15
;    [67:12] p.y == 0xb
;    [67:12] ? p.y == 0xb
;    [67:12] ? p.y == 0xb
    cmp_67_12:
    cmp qword[rsp-8], 0xb
    jne bool_false_67_12
    bool_true_67_12:  ; opt1
    mov r15, true
    jmp bool_end_67_12
    bool_false_67_12:
    mov r15, false
    bool_end_67_12:
;    assert(expr : bool) 
    assert_67_5:
;        alias expr -> r15
        if_36_8_67_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_67_5:
        cmp r15, false
        jne if_36_5_67_5_end
        if_36_8_67_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_67_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_67_5_end:
        if_36_5_67_5_end:
;        free r15
    assert_67_5_end:
;    var i: i64 @ qword[rsp-24]
;    [69:5] var i = 0
;    [69:9] i = 0
;    [69:13]  0
;    [69:13] 0
;    [69:13] i = 0
    mov qword[rsp-24], 0
;    [70:5] bar(i)
;    bar(arg) 
    bar_70_5:
;        alias arg -> i
        if_54_8_70_5:
;        [54:8] ? arg == 0
;        [54:8] ? arg == 0
        cmp_54_8_70_5:
        cmp qword[rsp-24], 0
        jne if_54_5_70_5_end
        if_54_8_70_5_code:  ; opt1
;            [54:17] return
            jmp bar_70_5_end
        if_54_5_70_5_end:
;        [55:5] arg = 0xff
;        [55:11]  0xff
;        [55:11] 0xff
;        [55:11] arg = 0xff
        mov qword[rsp-24], 0xff
    bar_70_5_end:
;    [71:5] assert(i == 0)
;    alloc r15
;    [71:12] i == 0
;    [71:12] ? i == 0
;    [71:12] ? i == 0
    cmp_71_12:
    cmp qword[rsp-24], 0
    jne bool_false_71_12
    bool_true_71_12:  ; opt1
    mov r15, true
    jmp bool_end_71_12
    bool_false_71_12:
    mov r15, false
    bool_end_71_12:
;    assert(expr : bool) 
    assert_71_5:
;        alias expr -> r15
        if_36_8_71_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_71_5:
        cmp r15, false
        jne if_36_5_71_5_end
        if_36_8_71_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_71_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_71_5_end:
        if_36_5_71_5_end:
;        free r15
    assert_71_5_end:
;    [73:5] i = 1
;    [73:9]  1
;    [73:9] 1
;    [73:9] i = 1
    mov qword[rsp-24], 1
;    [74:5] bar(i)
;    bar(arg) 
    bar_74_5:
;        alias arg -> i
        if_54_8_74_5:
;        [54:8] ? arg == 0
;        [54:8] ? arg == 0
        cmp_54_8_74_5:
        cmp qword[rsp-24], 0
        jne if_54_5_74_5_end
        if_54_8_74_5_code:  ; opt1
;            [54:17] return
            jmp bar_74_5_end
        if_54_5_74_5_end:
;        [55:5] arg = 0xff
;        [55:11]  0xff
;        [55:11] 0xff
;        [55:11] arg = 0xff
        mov qword[rsp-24], 0xff
    bar_74_5_end:
;    [75:5] assert(i == 0xff)
;    alloc r15
;    [75:12] i == 0xff
;    [75:12] ? i == 0xff
;    [75:12] ? i == 0xff
    cmp_75_12:
    cmp qword[rsp-24], 0xff
    jne bool_false_75_12
    bool_true_75_12:  ; opt1
    mov r15, true
    jmp bool_end_75_12
    bool_false_75_12:
    mov r15, false
    bool_end_75_12:
;    assert(expr : bool) 
    assert_75_5:
;        alias expr -> r15
        if_36_8_75_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_75_5:
        cmp r15, false
        jne if_36_5_75_5_end
        if_36_8_75_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_75_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_75_5_end:
        if_36_5_75_5_end:
;        free r15
    assert_75_5_end:
;    var j: i64 @ qword[rsp-32]
;    [77:5] var j = 1
;    [77:9] j = 1
;    [77:13]  1
;    [77:13] 1
;    [77:13] j = 1
    mov qword[rsp-32], 1
;    var k: i64 @ qword[rsp-40]
;    [78:5] var k = baz(j)
;    [78:9] k = baz(j)
;    [78:13]  baz(j)
;    [78:13] baz(j)
;    [78:13] k = baz(j)
;    [78:13] baz(j)
;    baz(arg) : i64 res 
    baz_78_13:
;        alias res -> k
;        alias arg -> j
;        [60:5]  res = arg * 2
;        [60:11]  arg * 2
;        [60:11] arg * 2
;        [60:11] res = arg
;        alloc r15
        mov r15, qword[rsp-32]
        mov qword[rsp-40], r15
;        free r15
;        [60:17] res * 2
;        alloc r15
        mov r15, qword[rsp-40]
        imul r15, 2
        mov qword[rsp-40], r15
;        free r15
    baz_78_13_end:
;    [79:5] assert(k == 2)
;    alloc r15
;    [79:12] k == 2
;    [79:12] ? k == 2
;    [79:12] ? k == 2
    cmp_79_12:
    cmp qword[rsp-40], 2
    jne bool_false_79_12
    bool_true_79_12:  ; opt1
    mov r15, true
    jmp bool_end_79_12
    bool_false_79_12:
    mov r15, false
    bool_end_79_12:
;    assert(expr : bool) 
    assert_79_5:
;        alias expr -> r15
        if_36_8_79_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_79_5:
        cmp r15, false
        jne if_36_5_79_5_end
        if_36_8_79_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_79_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_79_5_end:
        if_36_5_79_5_end:
;        free r15
    assert_79_5_end:
;    [81:5] k = baz(1)
;    [81:9]  baz(1)
;    [81:9] baz(1)
;    [81:9] k = baz(1)
;    [81:9] baz(1)
;    baz(arg) : i64 res 
    baz_81_9:
;        alias res -> k
;        alias arg -> 1
;        [60:5]  res = arg * 2
;        [60:11]  arg * 2
;        [60:11] arg * 2
;        [60:11] res = arg
        mov qword[rsp-40], 1
;        [60:17] res * 2
;        alloc r15
        mov r15, qword[rsp-40]
        imul r15, 2
        mov qword[rsp-40], r15
;        free r15
    baz_81_9_end:
;    [82:5] assert(k == 2)
;    alloc r15
;    [82:12] k == 2
;    [82:12] ? k == 2
;    [82:12] ? k == 2
    cmp_82_12:
    cmp qword[rsp-40], 2
    jne bool_false_82_12
    bool_true_82_12:  ; opt1
    mov r15, true
    jmp bool_end_82_12
    bool_false_82_12:
    mov r15, false
    bool_end_82_12:
;    assert(expr : bool) 
    assert_82_5:
;        alias expr -> r15
        if_36_8_82_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_82_5:
        cmp r15, false
        jne if_36_5_82_5_end
        if_36_8_82_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_82_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_82_5_end:
        if_36_5_82_5_end:
;        free r15
    assert_82_5_end:
;    var p0: point @ qword[rsp-56]
;    [84:5] var p0 : point = {baz(2), 0}
;    [84:9] p0 : point = {baz(2), 0}
;    [84:22]  {baz(2), 0}
;    [84:22] {baz(2), 0}
;    [84:23] baz(2)
;    [84:23] baz(2)
;    [84:23] p0.x = baz(2)
;    [84:23] baz(2)
;    baz(arg) : i64 res 
    baz_84_23:
;        alias res -> p0.x
;        alias arg -> 2
;        [60:5]  res = arg * 2
;        [60:11]  arg * 2
;        [60:11] arg * 2
;        [60:11] res = arg
        mov qword[rsp-56], 2
;        [60:17] res * 2
;        alloc r15
        mov r15, qword[rsp-56]
        imul r15, 2
        mov qword[rsp-56], r15
;        free r15
    baz_84_23_end:
;    [84:31]  0
;    [84:31] 0
;    [84:31] p0.y = 0
    mov qword[rsp-48], 0
;    [85:5]  assert(p0.x == 4)
;    alloc r15
;    [85:12] p0.x == 4
;    [85:12] ? p0.x == 4
;    [85:12] ? p0.x == 4
    cmp_85_12:
    cmp qword[rsp-56], 4
    jne bool_false_85_12
    bool_true_85_12:  ; opt1
    mov r15, true
    jmp bool_end_85_12
    bool_false_85_12:
    mov r15, false
    bool_end_85_12:
;    assert(expr : bool) 
    assert_85_5:
;        alias expr -> r15
        if_36_8_85_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_85_5:
        cmp r15, false
        jne if_36_5_85_5_end
        if_36_8_85_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_85_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_85_5_end:
        if_36_5_85_5_end:
;        free r15
    assert_85_5_end:
;    var x: i64 @ qword[rsp-64]
;    [87:5] var x = 1
;    [87:9] x = 1
;    [87:13]  1
;    [87:13] 1
;    [87:13] x = 1
    mov qword[rsp-64], 1
;    var y: i64 @ qword[rsp-72]
;    [88:5] var y = 2
;    [88:9] y = 2
;    [88:13]  2
;    [88:13] 2
;    [88:13] y = 2
    mov qword[rsp-72], 2
;    var o1: object @ qword[rsp-92]
;    [90:5] var o1 : object = {{x * 10, y}, 0xff0000}
;    [90:9] o1 : object = {{x * 10, y}, 0xff0000}
;    [90:23]  {{x * 10, y}, 0xff0000}
;    [90:23] {{x * 10, y}, 0xff0000}
;        [90:24] {x * 10, y}
;        [90:25] x * 10
;        [90:25] x * 10
;        [90:25] o1.pos.x = x
;        alloc r15
        mov r15, qword[rsp-64]
        mov qword[rsp-92], r15
;        free r15
;        [90:29] o1.pos.x * 10
;        alloc r15
        mov r15, qword[rsp-92]
        imul r15, 10
        mov qword[rsp-92], r15
;        free r15
;        [90:33]  y
;        [90:33] y
;        [90:33] o1.pos.y = y
;        alloc r15
        mov r15, qword[rsp-72]
        mov qword[rsp-84], r15
;        free r15
;    [90:37]  0xff0000
;    [90:37] 0xff0000
;    [90:37] o1.color = 0xff0000
    mov dword[rsp-76], 0xff0000
;    [91:5]  assert(o1.pos.x == 10)
;    alloc r15
;    [91:12] o1.pos.x == 10
;    [91:12] ? o1.pos.x == 10
;    [91:12] ? o1.pos.x == 10
    cmp_91_12:
    cmp qword[rsp-92], 10
    jne bool_false_91_12
    bool_true_91_12:  ; opt1
    mov r15, true
    jmp bool_end_91_12
    bool_false_91_12:
    mov r15, false
    bool_end_91_12:
;    assert(expr : bool) 
    assert_91_5:
;        alias expr -> r15
        if_36_8_91_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_91_5:
        cmp r15, false
        jne if_36_5_91_5_end
        if_36_8_91_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_91_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_91_5_end:
        if_36_5_91_5_end:
;        free r15
    assert_91_5_end:
;    [92:5] assert(o1.pos.y == 2)
;    alloc r15
;    [92:12] o1.pos.y == 2
;    [92:12] ? o1.pos.y == 2
;    [92:12] ? o1.pos.y == 2
    cmp_92_12:
    cmp qword[rsp-84], 2
    jne bool_false_92_12
    bool_true_92_12:  ; opt1
    mov r15, true
    jmp bool_end_92_12
    bool_false_92_12:
    mov r15, false
    bool_end_92_12:
;    assert(expr : bool) 
    assert_92_5:
;        alias expr -> r15
        if_36_8_92_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_92_5:
        cmp r15, false
        jne if_36_5_92_5_end
        if_36_8_92_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_92_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_92_5_end:
        if_36_5_92_5_end:
;        free r15
    assert_92_5_end:
;    [93:5] assert(o1.color == 0xff0000)
;    alloc r15
;    [93:12] o1.color == 0xff0000
;    [93:12] ? o1.color == 0xff0000
;    [93:12] ? o1.color == 0xff0000
    cmp_93_12:
    cmp dword[rsp-76], 0xff0000
    jne bool_false_93_12
    bool_true_93_12:  ; opt1
    mov r15, true
    jmp bool_end_93_12
    bool_false_93_12:
    mov r15, false
    bool_end_93_12:
;    assert(expr : bool) 
    assert_93_5:
;        alias expr -> r15
        if_36_8_93_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_93_5:
        cmp r15, false
        jne if_36_5_93_5_end
        if_36_8_93_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_93_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_93_5_end:
        if_36_5_93_5_end:
;        free r15
    assert_93_5_end:
;    var p1: point @ qword[rsp-108]
;    [95:5] var p1 : point = {-x, -y}
;    [95:9] p1 : point = {-x, -y}
;    [95:22]  {-x, -y}
;    [95:22] {-x, -y}
;    [95:23] -x
;    [95:23] -x
;    [95:24] p1.x = -x
;    alloc r15
    mov r15, qword[rsp-64]
    mov qword[rsp-108], r15
;    free r15
    neg qword[rsp-108]
;    [95:27]  -y
;    [95:27] -y
;    [95:28] p1.y = -y
;    alloc r15
    mov r15, qword[rsp-72]
    mov qword[rsp-100], r15
;    free r15
    neg qword[rsp-100]
;    [96:5]  o1.pos = p1
;    [96:14]  p1
;    [96:14] p1
;    alloc r15
    mov r15, qword[rsp-108]
    mov qword[rsp-92], r15
;    free r15
;    alloc r15
    mov r15, qword[rsp-100]
    mov qword[rsp-84], r15
;    free r15
;    [97:5] assert(o1.pos.x == -1)
;    alloc r15
;    [97:12] o1.pos.x == -1
;    [97:12] ? o1.pos.x == -1
;    [97:12] ? o1.pos.x == -1
    cmp_97_12:
    cmp qword[rsp-92], -1
    jne bool_false_97_12
    bool_true_97_12:  ; opt1
    mov r15, true
    jmp bool_end_97_12
    bool_false_97_12:
    mov r15, false
    bool_end_97_12:
;    assert(expr : bool) 
    assert_97_5:
;        alias expr -> r15
        if_36_8_97_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_97_5:
        cmp r15, false
        jne if_36_5_97_5_end
        if_36_8_97_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_97_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_97_5_end:
        if_36_5_97_5_end:
;        free r15
    assert_97_5_end:
;    [98:5] assert(o1.pos.y == -2)
;    alloc r15
;    [98:12] o1.pos.y == -2
;    [98:12] ? o1.pos.y == -2
;    [98:12] ? o1.pos.y == -2
    cmp_98_12:
    cmp qword[rsp-84], -2
    jne bool_false_98_12
    bool_true_98_12:  ; opt1
    mov r15, true
    jmp bool_end_98_12
    bool_false_98_12:
    mov r15, false
    bool_end_98_12:
;    assert(expr : bool) 
    assert_98_5:
;        alias expr -> r15
        if_36_8_98_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_98_5:
        cmp r15, false
        jne if_36_5_98_5_end
        if_36_8_98_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_98_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_98_5_end:
        if_36_5_98_5_end:
;        free r15
    assert_98_5_end:
;    var o2: object @ qword[rsp-128]
;    [100:5] var o2 : object = o1
;    [100:9] o2 : object = o1
;    [100:23]  o1
;    [100:23] o1
;        [100:23] o1
;        alloc r15
        mov r15, qword[rsp-92]
        mov qword[rsp-128], r15
;        free r15
;        alloc r15
        mov r15, qword[rsp-84]
        mov qword[rsp-120], r15
;        free r15
;    alloc r15
    mov r15d, dword[rsp-76]
    mov dword[rsp-112], r15d
;    free r15
;    [101:5] assert(o2.pos.x == -1)
;    alloc r15
;    [101:12] o2.pos.x == -1
;    [101:12] ? o2.pos.x == -1
;    [101:12] ? o2.pos.x == -1
    cmp_101_12:
    cmp qword[rsp-128], -1
    jne bool_false_101_12
    bool_true_101_12:  ; opt1
    mov r15, true
    jmp bool_end_101_12
    bool_false_101_12:
    mov r15, false
    bool_end_101_12:
;    assert(expr : bool) 
    assert_101_5:
;        alias expr -> r15
        if_36_8_101_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_101_5:
        cmp r15, false
        jne if_36_5_101_5_end
        if_36_8_101_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_101_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_101_5_end:
        if_36_5_101_5_end:
;        free r15
    assert_101_5_end:
;    [102:5] assert(o2.pos.y == -2)
;    alloc r15
;    [102:12] o2.pos.y == -2
;    [102:12] ? o2.pos.y == -2
;    [102:12] ? o2.pos.y == -2
    cmp_102_12:
    cmp qword[rsp-120], -2
    jne bool_false_102_12
    bool_true_102_12:  ; opt1
    mov r15, true
    jmp bool_end_102_12
    bool_false_102_12:
    mov r15, false
    bool_end_102_12:
;    assert(expr : bool) 
    assert_102_5:
;        alias expr -> r15
        if_36_8_102_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_102_5:
        cmp r15, false
        jne if_36_5_102_5_end
        if_36_8_102_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_102_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_102_5_end:
        if_36_5_102_5_end:
;        free r15
    assert_102_5_end:
;    [103:5] assert(o2.color == 0xff0000)
;    alloc r15
;    [103:12] o2.color == 0xff0000
;    [103:12] ? o2.color == 0xff0000
;    [103:12] ? o2.color == 0xff0000
    cmp_103_12:
    cmp dword[rsp-112], 0xff0000
    jne bool_false_103_12
    bool_true_103_12:  ; opt1
    mov r15, true
    jmp bool_end_103_12
    bool_false_103_12:
    mov r15, false
    bool_end_103_12:
;    assert(expr : bool) 
    assert_103_5:
;        alias expr -> r15
        if_36_8_103_5:
;        [36:8] ? not expr
;        [36:8] ? not expr
        cmp_36_8_103_5:
        cmp r15, false
        jne if_36_5_103_5_end
        if_36_8_103_5_code:  ; opt1
;            [36:17] exit(1)
;            alloc rdi
            mov rdi, 1
;            exit(v : reg_rdi) 
            exit_36_17_103_5:
;                alias v -> rdi
;                [13:5]  mov(rax, 60)
                mov rax, 60
;                [13:19] # exit system call
;                [14:5]  mov(rdi, v)
;                [14:19] # return code
;                [15:5]  syscall()
                syscall
;                free rdi
            exit_36_17_103_5_end:
        if_36_5_103_5_end:
;        free r15
    assert_103_5_end:
;    [105:5] print(hello.len, hello)
;    alloc rdx
    mov rdx, hello.len
;    alloc rsi
    mov rsi, hello
;    print(len : reg_rdx, ptr : reg_rsi) 
    print_105_5:
;        alias len -> rdx
;        alias ptr -> rsi
;        [19:5]  mov(rax, 1)
        mov rax, 1
;        [19:19] # write system call
;        [20:5]  mov(rdi, 1)
        mov rdi, 1
;        [20:19] # file descriptor for standard out
;        [21:5]  mov(rsi, ptr)
;        [21:19] # buffer address
;        [22:5]  mov(rdx, len)
;        [22:19] # buffer size
;        [23:5]  syscall()
        syscall
;        free rsi
;        free rdx
    print_105_5_end:
;    [106:5] loop
    loop_106_5:
;        [107:9]  print(prompt1.len, prompt1)
;        alloc rdx
        mov rdx, prompt1.len
;        alloc rsi
        mov rsi, prompt1
;        print(len : reg_rdx, ptr : reg_rsi) 
        print_107_9:
;            alias len -> rdx
;            alias ptr -> rsi
;            [19:5]  mov(rax, 1)
            mov rax, 1
;            [19:19] # write system call
;            [20:5]  mov(rdi, 1)
            mov rdi, 1
;            [20:19] # file descriptor for standard out
;            [21:5]  mov(rsi, ptr)
;            [21:19] # buffer address
;            [22:5]  mov(rdx, len)
;            [22:19] # buffer size
;            [23:5]  syscall()
            syscall
;            free rsi
;            free rdx
        print_107_9_end:
;        var len: i64 @ qword[rsp-136]
;        [108:9] var len = read(input.len, input) - 1
;        [108:13] len = read(input.len, input) - 1
;        [108:19]  read(input.len, input) - 1
;        [108:19] read(input.len, input) - 1
;        [108:19] len = read(input.len, input)
;        [108:19] read(input.len, input)
;        alloc rdx
        mov rdx, input.len
;        alloc rsi
        mov rsi, input
;        read(len : reg_rdx, ptr : reg_rsi) : i64 nbytes 
        read_108_19:
;            alias nbytes -> len
;            alias len -> rdx
;            alias ptr -> rsi
;            [27:5]  mov(rax, 0)
            mov rax, 0
;            [27:19] # read system call
;            [28:5]  mov(rdi, 0)
            mov rdi, 0
;            [28:19] # file descriptor for standard input
;            [29:5]  mov(rsi, ptr)
;            [29:19] # buffer address
;            [30:5]  mov(rdx, len)
;            [30:19] # buffer size
;            [31:5]  syscall()
            syscall
;            [32:5] mov(nbytes, rax)
            mov qword[rsp-136], rax
;            [32:22] # return value
;            free rsi
;            free rdx
        read_108_19_end:
;        [108:44] len - 1
        sub qword[rsp-136], 1
;        [108:49] # -1 don't include the '\n'
        if_109_12:
;        [109:12] ? len == 0
;        [109:12] ? len == 0
        cmp_109_12:
        cmp qword[rsp-136], 0
        jne if_111_19
        if_109_12_code:  ; opt1
;            [110:13]  break
            jmp loop_106_5_end
        jmp if_109_9_end
        if_111_19:
;        [111:19] ? len <= 4
;        [111:19] ? len <= 4
        cmp_111_19:
        cmp qword[rsp-136], 4
        jg if_else_109_9
        if_111_19_code:  ; opt1
;            [112:13]  print(prompt2.len, prompt2)
;            alloc rdx
            mov rdx, prompt2.len
;            alloc rsi
            mov rsi, prompt2
;            print(len : reg_rdx, ptr : reg_rsi) 
            print_112_13:
;                alias len -> rdx
;                alias ptr -> rsi
;                [19:5]  mov(rax, 1)
                mov rax, 1
;                [19:19] # write system call
;                [20:5]  mov(rdi, 1)
                mov rdi, 1
;                [20:19] # file descriptor for standard out
;                [21:5]  mov(rsi, ptr)
;                [21:19] # buffer address
;                [22:5]  mov(rdx, len)
;                [22:19] # buffer size
;                [23:5]  syscall()
                syscall
;                free rsi
;                free rdx
            print_112_13_end:
;            [113:13] continue
            jmp loop_106_5
        jmp if_109_9_end
        if_else_109_9:
;            [115:13]  print(prompt3.len, prompt3)
;            alloc rdx
            mov rdx, prompt3.len
;            alloc rsi
            mov rsi, prompt3
;            print(len : reg_rdx, ptr : reg_rsi) 
            print_115_13:
;                alias len -> rdx
;                alias ptr -> rsi
;                [19:5]  mov(rax, 1)
                mov rax, 1
;                [19:19] # write system call
;                [20:5]  mov(rdi, 1)
                mov rdi, 1
;                [20:19] # file descriptor for standard out
;                [21:5]  mov(rsi, ptr)
;                [21:19] # buffer address
;                [22:5]  mov(rdx, len)
;                [22:19] # buffer size
;                [23:5]  syscall()
                syscall
;                free rsi
;                free rdx
            print_115_13_end:
;            [116:13] print(len, input)
;            alloc rdx
            mov rdx, qword[rsp-136]
;            alloc rsi
            mov rsi, input
;            print(len : reg_rdx, ptr : reg_rsi) 
            print_116_13:
;                alias len -> rdx
;                alias ptr -> rsi
;                [19:5]  mov(rax, 1)
                mov rax, 1
;                [19:19] # write system call
;                [20:5]  mov(rdi, 1)
                mov rdi, 1
;                [20:19] # file descriptor for standard out
;                [21:5]  mov(rsi, ptr)
;                [21:19] # buffer address
;                [22:5]  mov(rdx, len)
;                [22:19] # buffer size
;                [23:5]  syscall()
                syscall
;                free rsi
;                free rdx
            print_116_13_end:
;            [117:13] print(dot.len, dot)
;            alloc rdx
            mov rdx, dot.len
;            alloc rsi
            mov rsi, dot
;            print(len : reg_rdx, ptr : reg_rsi) 
            print_117_13:
;                alias len -> rdx
;                alias ptr -> rsi
;                [19:5]  mov(rax, 1)
                mov rax, 1
;                [19:19] # write system call
;                [20:5]  mov(rdi, 1)
                mov rdi, 1
;                [20:19] # file descriptor for standard out
;                [21:5]  mov(rsi, ptr)
;                [21:19] # buffer address
;                [22:5]  mov(rdx, len)
;                [22:19] # buffer size
;                [23:5]  syscall()
                syscall
;                free rsi
;                free rdx
            print_117_13_end:
;            [118:13] print(nl.len, nl)
;            alloc rdx
            mov rdx, nl.len
;            alloc rsi
            mov rsi, nl
;            print(len : reg_rdx, ptr : reg_rsi) 
            print_118_13:
;                alias len -> rdx
;                alias ptr -> rsi
;                [19:5]  mov(rax, 1)
                mov rax, 1
;                [19:19] # write system call
;                [20:5]  mov(rdi, 1)
                mov rdi, 1
;                [20:19] # file descriptor for standard out
;                [21:5]  mov(rsi, ptr)
;                [21:19] # buffer address
;                [22:5]  mov(rdx, len)
;                [22:19] # buffer size
;                [23:5]  syscall()
                syscall
;                free rsi
;                free rdx
            print_118_13_end:
        if_109_9_end:
    jmp loop_106_5
    loop_106_5_end:
    ; system call: exit 0
    mov rax, 60
    mov rdi, 0
    syscall

; max scratch registers in use: 3
;            max frames in use: 7
;               max stack size: 136 B

About

experimental compiler of minimalistic language to nasm x86_64 for linux

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages