if!
This commit is contained in:
parent
db552a4dca
commit
6f1a085586
3 changed files with 806 additions and 98 deletions
861
04b/in03
861
04b/in03
|
@ -147,6 +147,20 @@ call :string=
|
|||
D=A
|
||||
?D!0:handle_string
|
||||
|
||||
I=:line
|
||||
J=:"goto"
|
||||
C=x20
|
||||
call :string=
|
||||
D=A
|
||||
?D!0:handle_goto
|
||||
|
||||
I=:line
|
||||
J=:"if"
|
||||
C=x20
|
||||
call :string=
|
||||
D=A
|
||||
?D!0:handle_if
|
||||
|
||||
; set delimiter to newline
|
||||
C=xa
|
||||
|
||||
|
@ -162,6 +176,18 @@ call :string=
|
|||
D=A
|
||||
?D!0:handle_return
|
||||
|
||||
; check if this is an assignment
|
||||
I=:line
|
||||
:assignment_check_loop
|
||||
C=1I
|
||||
D=xa
|
||||
?C=D:assignment_check_loop_end
|
||||
D='=
|
||||
?C=D:handle_assignment
|
||||
I+=d1
|
||||
!:assignment_check_loop
|
||||
:assignment_check_loop_end
|
||||
|
||||
; check if this is a function call (where we discard the return value)
|
||||
I=:line
|
||||
; (check for an opening bracket not preceded by a space)
|
||||
|
@ -458,7 +484,7 @@ align
|
|||
call :ident_copy
|
||||
R=J
|
||||
|
||||
; figure out where in the file we are
|
||||
; figure out where in the file we are (using lseek)
|
||||
J=d4
|
||||
I=d0
|
||||
D=d1
|
||||
|
@ -477,6 +503,496 @@ align
|
|||
; read the next line
|
||||
!:read_line
|
||||
|
||||
:handle_goto
|
||||
J=d4
|
||||
I=:jmp_prefix
|
||||
D=d1
|
||||
syscall x1
|
||||
I=:line
|
||||
; 5 = length of "goto "
|
||||
I+=d5
|
||||
call :emit_label_jump_address
|
||||
!:read_line
|
||||
:jmp_prefix
|
||||
xe9
|
||||
|
||||
:handle_if
|
||||
I=:line
|
||||
I+=d3
|
||||
; skip term 1
|
||||
call :go_to_space
|
||||
I+=d1
|
||||
; skip operator
|
||||
call :go_to_space
|
||||
I+=d1
|
||||
; put second operand in rsi
|
||||
call :set_rax_to_term
|
||||
call :set_rsi_to_rax
|
||||
|
||||
|
||||
I=:line
|
||||
; length of "if "
|
||||
I+=d3
|
||||
; put first operand in rax
|
||||
call :set_rax_to_term
|
||||
; put second operand in rbx
|
||||
call :set_rbx_to_rsi
|
||||
; emit cmp rax, rbx
|
||||
J=d4
|
||||
I=:cmp_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
|
||||
I=:line
|
||||
I+=d3
|
||||
call :go_to_space
|
||||
I+=d1
|
||||
R=I
|
||||
C=x20
|
||||
|
||||
I=R
|
||||
J=:"=="
|
||||
call :string=
|
||||
I=A
|
||||
?I!0:write_je
|
||||
|
||||
I=R
|
||||
J=:"!="
|
||||
call :string=
|
||||
I=A
|
||||
?I!0:write_jne
|
||||
|
||||
I=R
|
||||
J=:">"
|
||||
call :string=
|
||||
I=A
|
||||
?I!0:write_jg
|
||||
|
||||
I=R
|
||||
J=:"<"
|
||||
call :string=
|
||||
I=A
|
||||
?I!0:write_jl
|
||||
|
||||
I=R
|
||||
J=:">="
|
||||
call :string=
|
||||
I=A
|
||||
?I!0:write_jge
|
||||
|
||||
I=R
|
||||
J=:"<="
|
||||
call :string=
|
||||
I=A
|
||||
?I!0:write_jle
|
||||
|
||||
I=R
|
||||
J=:"]"
|
||||
call :string=
|
||||
I=A
|
||||
?I!0:write_ja
|
||||
|
||||
I=R
|
||||
J=:"["
|
||||
call :string=
|
||||
I=A
|
||||
?I!0:write_jb
|
||||
|
||||
I=R
|
||||
J=:"]="
|
||||
call :string=
|
||||
I=A
|
||||
?I!0:write_jae
|
||||
|
||||
I=R
|
||||
J=:"[="
|
||||
call :string=
|
||||
I=A
|
||||
?I!0:write_jbe
|
||||
|
||||
!:bad_jump
|
||||
|
||||
:write_je
|
||||
J=d4
|
||||
I=:je_prefix
|
||||
D=d2
|
||||
syscall x1
|
||||
!:if_continue
|
||||
|
||||
:write_jne
|
||||
J=d4
|
||||
I=:jne_prefix
|
||||
D=d2
|
||||
syscall x1
|
||||
!:if_continue
|
||||
|
||||
:write_jl
|
||||
J=d4
|
||||
I=:jl_prefix
|
||||
D=d2
|
||||
syscall x1
|
||||
!:if_continue
|
||||
|
||||
:write_jg
|
||||
J=d4
|
||||
I=:jg_prefix
|
||||
D=d2
|
||||
syscall x1
|
||||
!:if_continue
|
||||
|
||||
:write_jle
|
||||
J=d4
|
||||
I=:jle_prefix
|
||||
D=d2
|
||||
syscall x1
|
||||
!:if_continue
|
||||
|
||||
:write_jge
|
||||
J=d4
|
||||
I=:jge_prefix
|
||||
D=d2
|
||||
syscall x1
|
||||
!:if_continue
|
||||
|
||||
:write_jb
|
||||
J=d4
|
||||
I=:jb_prefix
|
||||
D=d2
|
||||
syscall x1
|
||||
!:if_continue
|
||||
|
||||
:write_ja
|
||||
J=d4
|
||||
I=:ja_prefix
|
||||
D=d2
|
||||
syscall x1
|
||||
!:if_continue
|
||||
|
||||
:write_jbe
|
||||
J=d4
|
||||
I=:jbe_prefix
|
||||
D=d2
|
||||
syscall x1
|
||||
!:if_continue
|
||||
|
||||
:write_jae
|
||||
J=d4
|
||||
I=:jae_prefix
|
||||
D=d2
|
||||
syscall x1
|
||||
!:if_continue
|
||||
|
||||
:if_continue
|
||||
I=:line
|
||||
I+=d3
|
||||
; skip term 1
|
||||
call :go_to_space
|
||||
I+=d1
|
||||
; skip operator
|
||||
call :go_to_space
|
||||
I+=d1
|
||||
; skip term 2
|
||||
call :go_to_space
|
||||
I+=d1
|
||||
J=:"goto"
|
||||
C=x20
|
||||
call :string=
|
||||
C=A
|
||||
; make sure word after term 2 is "goto"
|
||||
?C=0:bad_jump
|
||||
I+=d1
|
||||
call :emit_label_jump_address
|
||||
!:read_line
|
||||
|
||||
:je_prefix
|
||||
x0f
|
||||
x84
|
||||
:jne_prefix
|
||||
x0f
|
||||
x85
|
||||
:jl_prefix
|
||||
x0f
|
||||
x8c
|
||||
:jg_prefix
|
||||
x0f
|
||||
x8f
|
||||
:jle_prefix
|
||||
x0f
|
||||
x8e
|
||||
:jge_prefix
|
||||
x0f
|
||||
x8d
|
||||
:jb_prefix
|
||||
x0f
|
||||
x82
|
||||
:ja_prefix
|
||||
x0f
|
||||
x87
|
||||
:jbe_prefix
|
||||
x0f
|
||||
x86
|
||||
:jae_prefix
|
||||
x0f
|
||||
x83
|
||||
|
||||
:cmp_rax_rbx
|
||||
x48
|
||||
x39
|
||||
xd8
|
||||
|
||||
align
|
||||
:reladdr
|
||||
reserve d4
|
||||
|
||||
; emit relative address (for jumping) of label in rsi
|
||||
:emit_label_jump_address
|
||||
; address doesn't matter for first pass
|
||||
C=:second_pass
|
||||
C=1C
|
||||
?C=0:jump_ignore_address
|
||||
; look up label; store address in rbp
|
||||
J=:labels
|
||||
call :ident_lookup
|
||||
C=A
|
||||
?C=0:bad_label
|
||||
R=4C
|
||||
:jump_ignore_address
|
||||
|
||||
; first, figure out current address
|
||||
J=d4
|
||||
I=d0
|
||||
D=d1
|
||||
syscall x8
|
||||
C=A
|
||||
; add an additional 4 because the relative address is 4 bytes long
|
||||
C+=x400004
|
||||
|
||||
; compute relative address
|
||||
D=d0
|
||||
D-=C
|
||||
D+=R
|
||||
; store in :reladdr
|
||||
C=:reladdr
|
||||
4C=D
|
||||
; output
|
||||
J=d4
|
||||
I=:reladdr
|
||||
D=d4
|
||||
syscall x1
|
||||
return
|
||||
|
||||
align
|
||||
:assignment_type
|
||||
reserve d8
|
||||
:handle_assignment
|
||||
I-=d1
|
||||
C=:assignment_type
|
||||
8C=I
|
||||
|
||||
I+=d2
|
||||
C=1I
|
||||
D=x20
|
||||
; check for space after =
|
||||
?C!D:bad_assignment
|
||||
I+=d1
|
||||
|
||||
; set rdi to right-hand side of assignment
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rdi_to_rax
|
||||
|
||||
J=:assignment_type
|
||||
J=8J
|
||||
C=1J
|
||||
; put newline after lvalue to make parsing easier
|
||||
D=xa
|
||||
1J=D
|
||||
D=x20
|
||||
?C=D:handle_assignment_cont
|
||||
J-=d1
|
||||
D=xa
|
||||
1J=D
|
||||
:handle_assignment_cont
|
||||
D=x20
|
||||
?C=D:handle_plain_assignment
|
||||
D='+
|
||||
?C=D:handle_+=
|
||||
D='-
|
||||
?C=D:handle_-=
|
||||
D='*
|
||||
?C=D:handle_*=
|
||||
D='/
|
||||
?C=D:handle_/=
|
||||
D='%
|
||||
?C=D:handle_%=
|
||||
D='&
|
||||
?C=D:handle_&=
|
||||
D='|
|
||||
?C=D:handle_|=
|
||||
D='^
|
||||
?C=D:handle_^=
|
||||
D='<
|
||||
?C=D:handle_<=
|
||||
D='>
|
||||
?C=D:handle_>=
|
||||
|
||||
!:bad_assignment
|
||||
|
||||
:handle_plain_assignment
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
:handle_+=
|
||||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rbx_to_rdi
|
||||
call :emit_add_rax_rbx
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
:handle_-=
|
||||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rbx_to_rdi
|
||||
call :emit_sub_rax_rbx
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
:handle_*=
|
||||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rbx_to_rdi
|
||||
call :emit_imul_rbx
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
:handle_/=
|
||||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rbx_to_rdi
|
||||
call :emit_zero_rdx_idiv_rbx
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
:handle_%=
|
||||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rbx_to_rdi
|
||||
call :emit_zero_rdx_idiv_rbx
|
||||
call :set_rax_to_rdx
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
:handle_&=
|
||||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rbx_to_rdi
|
||||
call :emit_and_rax_rbx
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
:handle_|=
|
||||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rbx_to_rdi
|
||||
call :emit_or_rax_rbx
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
:handle_^=
|
||||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rbx_to_rdi
|
||||
call :emit_xor_rax_rbx
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
:handle_<=
|
||||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rcx_to_rdi
|
||||
call :emit_shl_rax_cl
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
:handle_>=
|
||||
I=:line
|
||||
call :set_rax_to_rvalue
|
||||
call :set_rcx_to_rdi
|
||||
call :emit_shr_rax_cl
|
||||
I=:line
|
||||
call :set_lvalue_to_rax
|
||||
!:read_line
|
||||
|
||||
align
|
||||
:lvalue
|
||||
reserve d8
|
||||
|
||||
; set the lvalue in rsi to <rax>
|
||||
:set_lvalue_to_rax
|
||||
C=:lvalue
|
||||
8C=I
|
||||
|
||||
; first, store away <rax> value in <rdi>
|
||||
R=I
|
||||
call :set_rdi_to_rax
|
||||
I=R
|
||||
|
||||
C=:lvalue
|
||||
I=8C
|
||||
C=1I
|
||||
D='*
|
||||
|
||||
?C=D:lvalue_deref
|
||||
; not a dereference; just a variable
|
||||
C=:lvalue
|
||||
I=8C
|
||||
call :set_rax_to_address_of_variable
|
||||
call :set_rbx_to_rax
|
||||
call :set_rax_to_rdi
|
||||
call :set_[rbx]_to_rax
|
||||
return
|
||||
:lvalue_deref
|
||||
C=:lvalue
|
||||
I=8C
|
||||
I+=d2
|
||||
call :set_rax_to_address_of_variable
|
||||
call :set_rbx_to_rax
|
||||
call :set_rax_to_[rbx]
|
||||
call :set_rbx_to_rax
|
||||
call :set_rax_to_rdi
|
||||
|
||||
C=:lvalue
|
||||
I=8C
|
||||
I+=d1
|
||||
C=1I
|
||||
|
||||
D='1
|
||||
?C=D:lvalue_deref1
|
||||
D='2
|
||||
?C=D:lvalue_deref2
|
||||
D='4
|
||||
?C=D:lvalue_deref4
|
||||
D='8
|
||||
?C=D:lvalue_deref8
|
||||
!:bad_assignment
|
||||
:lvalue_deref1
|
||||
!:set_[rbx]_to_al
|
||||
:lvalue_deref2
|
||||
!:set_[rbx]_to_ax
|
||||
:lvalue_deref4
|
||||
!:set_[rbx]_to_eax
|
||||
:lvalue_deref8
|
||||
!:set_[rbx]_to_rax
|
||||
|
||||
:handle_return
|
||||
I=:line
|
||||
|
@ -819,122 +1335,45 @@ align
|
|||
|
||||
:rvalue_add
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:add_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:add_rax_rbx
|
||||
x48
|
||||
x01
|
||||
xd8
|
||||
!:emit_add_rax_rbx
|
||||
|
||||
:rvalue_sub
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:sub_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:sub_rax_rbx
|
||||
x48
|
||||
x29
|
||||
xd8
|
||||
!:emit_sub_rax_rbx
|
||||
|
||||
:rvalue_mul
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:imul_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:imul_rbx
|
||||
x48
|
||||
xf7
|
||||
xeb
|
||||
!:emit_imul_rbx
|
||||
|
||||
:rvalue_div
|
||||
call :set_rbx_to_rsi
|
||||
call :zero_rdx
|
||||
J=d4
|
||||
I=:idiv_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:idiv_rbx
|
||||
x48
|
||||
xf7
|
||||
xfb
|
||||
!:emit_zero_rdx_idiv_rbx
|
||||
|
||||
:rvalue_rem
|
||||
call :set_rbx_to_rsi
|
||||
call :zero_rdx
|
||||
J=d4
|
||||
I=:idiv_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
call :emit_zero_rdx_idiv_rbx
|
||||
call :set_rax_to_rdx
|
||||
return
|
||||
|
||||
:rvalue_and
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:and_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:and_rax_rbx
|
||||
x48
|
||||
x21
|
||||
xd8
|
||||
!:emit_and_rax_rbx
|
||||
|
||||
:rvalue_or
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:or_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:or_rax_rbx
|
||||
x48
|
||||
x09
|
||||
xd8
|
||||
!:emit_or_rax_rbx
|
||||
|
||||
:rvalue_xor
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:xor_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:xor_rax_rbx
|
||||
x48
|
||||
x31
|
||||
xd8
|
||||
!:emit_xor_rax_rbx
|
||||
|
||||
:rvalue_shl
|
||||
call :set_rcx_to_rsi
|
||||
J=d4
|
||||
I=:shl_rax_cl
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:shl_rax_cl
|
||||
x48
|
||||
xd3
|
||||
xe0
|
||||
!:emit_shl_rax_cl
|
||||
|
||||
:rvalue_shr
|
||||
call :set_rcx_to_rsi
|
||||
J=d4
|
||||
I=:shr_rax_cl
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:shr_rax_cl
|
||||
x48
|
||||
xd3
|
||||
xe8
|
||||
!:emit_shr_rax_cl
|
||||
|
||||
:rvalue_addressof
|
||||
I+=d1
|
||||
|
@ -1204,6 +1643,15 @@ align
|
|||
:mov_rbx_rsi
|
||||
B=I
|
||||
|
||||
:set_rbx_to_rdi
|
||||
J=d4
|
||||
I=:mov_rbx_rdi
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_rbx_rdi
|
||||
B=J
|
||||
|
||||
:set_rcx_to_rsi
|
||||
J=d4
|
||||
I=:mov_rcx_rsi
|
||||
|
@ -1213,6 +1661,15 @@ align
|
|||
:mov_rcx_rsi
|
||||
C=I
|
||||
|
||||
:set_rcx_to_rdi
|
||||
J=d4
|
||||
I=:mov_rcx_rdi
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_rcx_rdi
|
||||
C=J
|
||||
|
||||
:set_rax_to_rdx
|
||||
J=d4
|
||||
I=:mov_rax_rdx
|
||||
|
@ -1222,6 +1679,15 @@ align
|
|||
:mov_rax_rdx
|
||||
A=D
|
||||
|
||||
:set_rax_to_rdi
|
||||
J=d4
|
||||
I=:mov_rax_rdi
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_rax_rdi
|
||||
A=J
|
||||
|
||||
:set_rsi_to_rax
|
||||
J=d4
|
||||
I=:mov_rsi_rax
|
||||
|
@ -1231,6 +1697,15 @@ align
|
|||
:mov_rsi_rax
|
||||
I=A
|
||||
|
||||
:set_rdi_to_rax
|
||||
J=d4
|
||||
I=:mov_rdi_rax
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_rdi_rax
|
||||
J=A
|
||||
|
||||
:set_rax_to_[rbx]
|
||||
J=d4
|
||||
I=:mov_rax_[rbx]
|
||||
|
@ -1272,13 +1747,156 @@ align
|
|||
:mov_al_[rbx]
|
||||
x8a
|
||||
x03
|
||||
|
||||
|
||||
:set_[rbx]_to_rax
|
||||
J=d4
|
||||
I=:mov_[rbx]_rax
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_[rbx]_rax
|
||||
x48
|
||||
x89
|
||||
x03
|
||||
|
||||
:set_[rbx]_to_eax
|
||||
J=d4
|
||||
I=:mov_[rbx]_eax
|
||||
D=d2
|
||||
syscall x1
|
||||
return
|
||||
:mov_[rbx]_eax
|
||||
x89
|
||||
x03
|
||||
|
||||
:set_[rbx]_to_ax
|
||||
J=d4
|
||||
I=:mov_[rbx]_ax
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_[rbx]_ax
|
||||
x66
|
||||
x89
|
||||
x03
|
||||
|
||||
:set_[rbx]_to_al
|
||||
J=d4
|
||||
I=:mov_[rbx]_al
|
||||
D=d2
|
||||
syscall x1
|
||||
return
|
||||
:mov_[rbx]_al
|
||||
x88
|
||||
x03
|
||||
|
||||
|
||||
:mov_rax_imm64_prefix
|
||||
x48
|
||||
xb8
|
||||
|
||||
align
|
||||
:emit_add_rax_rbx
|
||||
J=d4
|
||||
I=:add_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:add_rax_rbx
|
||||
x48
|
||||
x01
|
||||
xd8
|
||||
|
||||
:emit_sub_rax_rbx
|
||||
J=d4
|
||||
I=:sub_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:sub_rax_rbx
|
||||
x48
|
||||
x29
|
||||
xd8
|
||||
|
||||
:emit_and_rax_rbx
|
||||
J=d4
|
||||
I=:and_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:and_rax_rbx
|
||||
x48
|
||||
x21
|
||||
xd8
|
||||
|
||||
:emit_or_rax_rbx
|
||||
J=d4
|
||||
I=:or_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:or_rax_rbx
|
||||
x48
|
||||
x09
|
||||
xd8
|
||||
|
||||
:emit_xor_rax_rbx
|
||||
J=d4
|
||||
I=:xor_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:xor_rax_rbx
|
||||
x48
|
||||
x31
|
||||
xd8
|
||||
|
||||
:emit_shl_rax_cl
|
||||
J=d4
|
||||
I=:shl_rax_cl
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:shl_rax_cl
|
||||
x48
|
||||
xd3
|
||||
xe0
|
||||
|
||||
:emit_shr_rax_cl
|
||||
J=d4
|
||||
I=:shr_rax_cl
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:shr_rax_cl
|
||||
x48
|
||||
xd3
|
||||
xe8
|
||||
|
||||
:emit_imul_rbx
|
||||
J=d4
|
||||
I=:imul_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:imul_rbx
|
||||
x48
|
||||
xf7
|
||||
xeb
|
||||
|
||||
:emit_zero_rdx_idiv_rbx
|
||||
call :zero_rdx
|
||||
J=d4
|
||||
I=:idiv_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:idiv_rbx
|
||||
x48
|
||||
xf7
|
||||
xfb
|
||||
|
||||
align
|
||||
:imm64
|
||||
reserve d8
|
||||
|
||||
|
@ -1367,6 +1985,15 @@ align
|
|||
str Bad number.
|
||||
xa
|
||||
x0
|
||||
|
||||
:bad_assignment
|
||||
B=:bad_assignment_error_message
|
||||
!:program_error
|
||||
|
||||
:bad_assignment_error_message
|
||||
str Bad assignment.
|
||||
xa
|
||||
x0
|
||||
|
||||
:bad_term
|
||||
B=:bad_term_error_message
|
||||
|
@ -1376,6 +2003,15 @@ align
|
|||
str Bad term.
|
||||
xa
|
||||
x0
|
||||
|
||||
:bad_jump
|
||||
B=:bad_jump_error_message
|
||||
!:program_error
|
||||
|
||||
:bad_jump_error_message
|
||||
str Bad jump.
|
||||
xa
|
||||
x0
|
||||
|
||||
:bad_call
|
||||
B=:bad_call_error_message
|
||||
|
@ -1596,6 +2232,16 @@ align
|
|||
?D!C:memccpy
|
||||
return
|
||||
|
||||
; advance rsi to the next space or newline character
|
||||
:go_to_space
|
||||
C=1I
|
||||
D=xa
|
||||
?C=D:return_0
|
||||
D=x20
|
||||
?C=D:return_0
|
||||
I+=d1
|
||||
!:go_to_space
|
||||
|
||||
:"global"
|
||||
str global
|
||||
x20
|
||||
|
@ -1617,9 +2263,46 @@ align
|
|||
:"string"
|
||||
str string
|
||||
x20
|
||||
:"goto"
|
||||
str goto
|
||||
x20
|
||||
:"if"
|
||||
str if
|
||||
x20
|
||||
:"function"
|
||||
str function
|
||||
xa
|
||||
:"=="
|
||||
str ==
|
||||
x20
|
||||
:"!="
|
||||
str !=
|
||||
x20
|
||||
:">"
|
||||
str >
|
||||
x20
|
||||
:"<"
|
||||
str <
|
||||
x20
|
||||
:"<="
|
||||
str <=
|
||||
x20
|
||||
:">="
|
||||
str >=
|
||||
x20
|
||||
:"["
|
||||
str [
|
||||
x20
|
||||
:"]"
|
||||
str ]
|
||||
x20
|
||||
:"[="
|
||||
str [=
|
||||
x20
|
||||
:"]="
|
||||
str ]=
|
||||
x20
|
||||
|
||||
:zero
|
||||
x0
|
||||
|
||||
|
|
35
04b/in04b
35
04b/in04b
|
@ -3,9 +3,10 @@
|
|||
; local <name>
|
||||
; argument <name>
|
||||
; :<label>
|
||||
; .<label> (local label)
|
||||
; statement:
|
||||
; <declaration>
|
||||
; if <term> <==/</>/>=/<=/!=> <term> goto <label> NOTE: this uses signed comparisons
|
||||
; if <term> <==/</>/>=/<=/!=/[/]/[=/]=> <term> goto <label> NOTE: this uses signed comparisons
|
||||
; goto <label>
|
||||
; <lvalue> = <rvalue>
|
||||
; <lvalue> += <rvalue>
|
||||
|
@ -43,8 +44,24 @@
|
|||
; <term> < <term> (left shift)
|
||||
; <term> > <term> (unsigned right shift)
|
||||
|
||||
syscall(1, 1, .str_hw, 14)
|
||||
syscall(0x3c, 42)
|
||||
|
||||
if 0 > -1 goto main
|
||||
|
||||
syscall(0x3c, 0)
|
||||
|
||||
:main
|
||||
function
|
||||
global str
|
||||
global strp
|
||||
local offset
|
||||
strp = &str
|
||||
*8strp = .str_hw
|
||||
offset = 2
|
||||
offset &= offset
|
||||
offset %= 2
|
||||
*8strp += offset
|
||||
syscall(1, 1, str, 14)
|
||||
syscall(0x3c, 42)
|
||||
|
||||
:str_hw
|
||||
string Hello, world!
|
||||
|
@ -173,8 +190,8 @@ function
|
|||
len = 0
|
||||
:strlen_loop
|
||||
p = s + len
|
||||
c = *1 p
|
||||
if c == 0 goto strlen_loop_end
|
||||
c = *1p
|
||||
; if c == 0 goto strlen_loop_end
|
||||
len += 1
|
||||
goto strlen_loop
|
||||
:strlen_loop_end
|
||||
|
@ -196,7 +213,7 @@ function
|
|||
syscall(1, 1, s, len)
|
||||
return
|
||||
|
||||
:main
|
||||
:main2
|
||||
function
|
||||
puts(.str_hello_world)
|
||||
syscall(0x3c, 0)
|
||||
|
@ -213,9 +230,9 @@ function
|
|||
local p
|
||||
v = *4x
|
||||
p = *8y
|
||||
*4p = v
|
||||
if v == 0 goto something
|
||||
*1p = v + 1
|
||||
;*4p = v
|
||||
;if v == 0 goto something
|
||||
;*1p = v + 1
|
||||
v = *2p
|
||||
return v
|
||||
:something
|
||||
|
|
|
@ -105,10 +105,18 @@ jl rel32
|
|||
>0f 8c REL32
|
||||
jg rel32
|
||||
>0f 8f REL32
|
||||
jle rel32
|
||||
>0f 8e REL32
|
||||
jge rel32
|
||||
>0f 8d REL32
|
||||
jb rel32
|
||||
>0f 82 REL32
|
||||
ja rel32
|
||||
>0f 87 REL32
|
||||
jbe rel32
|
||||
>0f 86 REL32
|
||||
jae rel32
|
||||
>0f 83 REL32
|
||||
call rax
|
||||
>ff d0
|
||||
ret
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue