can codegen if/else
This commit is contained in:
parent
4f5579b6fd
commit
0e25f627a8
161
lang/src/ast.asm
161
lang/src/ast.asm
|
|
@ -4,11 +4,16 @@ default rel
|
||||||
%include "src/ast.inc"
|
%include "src/ast.inc"
|
||||||
|
|
||||||
section .rdata
|
section .rdata
|
||||||
|
PRECEDENCE_PIPE2 dw 10
|
||||||
|
PRECEDENCE_AMP2 dw 20
|
||||||
|
PRECEDENCE_PIPE dw 30
|
||||||
|
PRECEDENCE_CARET dw 40
|
||||||
|
PRECEDENCE_AMP dw 50
|
||||||
|
PRECEDENCE_EQ dw 60
|
||||||
|
PRECEDENCE_CMP dw 70
|
||||||
|
PRECEDENCE_SHIFT dw 80
|
||||||
PRECEDENCE_ADD dw 90
|
PRECEDENCE_ADD dw 90
|
||||||
PRECEDENCE_SUB dw 90
|
|
||||||
PRECEDENCE_MUL dw 100
|
PRECEDENCE_MUL dw 100
|
||||||
PRECEDENCE_DIV dw 100
|
|
||||||
PRECEDENCE_REM dw 100
|
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
extern vec_init_with
|
extern vec_init_with
|
||||||
|
|
@ -42,6 +47,7 @@ global parse_args
|
||||||
global parse_expr
|
global parse_expr
|
||||||
global parse_binary_expr
|
global parse_binary_expr
|
||||||
global parse_primary_expr
|
global parse_primary_expr
|
||||||
|
global parse_if_expr
|
||||||
global parse_statement
|
global parse_statement
|
||||||
global parse_block
|
global parse_block
|
||||||
global ast_build_symtable
|
global ast_build_symtable
|
||||||
|
|
@ -446,11 +452,15 @@ parse_binary_expr:
|
||||||
cmp al, TOKEN_PLUS
|
cmp al, TOKEN_PLUS
|
||||||
cmove bx, word [rel PRECEDENCE_ADD]
|
cmove bx, word [rel PRECEDENCE_ADD]
|
||||||
cmp al, TOKEN_MINUS
|
cmp al, TOKEN_MINUS
|
||||||
cmove bx, word [rel PRECEDENCE_SUB]
|
cmove bx, word [rel PRECEDENCE_ADD]
|
||||||
cmp al, TOKEN_STAR
|
cmp al, TOKEN_STAR
|
||||||
cmove bx, word [rel PRECEDENCE_MUL]
|
cmove bx, word [rel PRECEDENCE_MUL]
|
||||||
cmp al, TOKEN_SLASH
|
cmp al, TOKEN_SLASH
|
||||||
cmove bx, word [rel PRECEDENCE_DIV]
|
cmove bx, word [rel PRECEDENCE_MUL]
|
||||||
|
cmp al, TOKEN_EQEQ
|
||||||
|
cmove bx, word [rel PRECEDENCE_EQ]
|
||||||
|
cmp al, TOKEN_BANGEQ
|
||||||
|
cmove bx, word [rel PRECEDENCE_EQ]
|
||||||
cmp bx, -1
|
cmp bx, -1
|
||||||
je .done
|
je .done
|
||||||
mov byte [rsp + 18], bl
|
mov byte [rsp + 18], bl
|
||||||
|
|
@ -557,10 +567,20 @@ parse_statement:
|
||||||
call peek_expect_token ; parse_block expects lbrace to still be there
|
call peek_expect_token ; parse_block expects lbrace to still be there
|
||||||
test rax, rax
|
test rax, rax
|
||||||
jnz .block
|
jnz .block
|
||||||
|
mov dil, TOKEN_IF
|
||||||
|
call peek_expect_token
|
||||||
|
test rax, rax
|
||||||
|
jnz .if_expr
|
||||||
mov rdi, [rsp] ; Ast
|
mov rdi, [rsp] ; Ast
|
||||||
call parse_expr
|
call parse_expr
|
||||||
jmp .epilogue
|
jmp .epilogue
|
||||||
|
|
||||||
|
.if_expr:
|
||||||
|
mov rdi, [rsp] ; Ast
|
||||||
|
call ast_parse_if_expr
|
||||||
|
; If expressions don't require a trailing semicolon
|
||||||
|
jmp .epilogue
|
||||||
|
|
||||||
.block:
|
.block:
|
||||||
mov rdi, [rsp] ; Ast
|
mov rdi, [rsp] ; Ast
|
||||||
call parse_block
|
call parse_block
|
||||||
|
|
@ -576,6 +596,12 @@ parse_statement:
|
||||||
.return:
|
.return:
|
||||||
mov rdi, [rsp] ; Ast
|
mov rdi, [rsp] ; Ast
|
||||||
call parse_expr
|
call parse_expr
|
||||||
|
; return expression requires a value
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; Ast
|
||||||
|
mov rsi, rax ; expr
|
||||||
|
call ast_place_to_value
|
||||||
|
|
||||||
mov byte [rsp + 8], AST_RETURN_STATEMENT ; AstNode.kind
|
mov byte [rsp + 8], AST_RETURN_STATEMENT ; AstNode.kind
|
||||||
mov [rsp + 16], rax ; AstNode.data
|
mov [rsp + 16], rax ; AstNode.data
|
||||||
mov qword [rsp + 24], 0 ; AstNode.extra
|
mov qword [rsp + 24], 0 ; AstNode.extra
|
||||||
|
|
@ -859,6 +885,116 @@ parse_assignment_expr:
|
||||||
pop rbp
|
pop rbp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;; rdi: *mut Ast
|
||||||
|
;; define-fn: fn ast_parse_switch_expr(ast: *mut Ast) -> (u64, bool)
|
||||||
|
ast_parse_switch_expr:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
|
; start-structs
|
||||||
|
; struct AstSwitch {
|
||||||
|
; expr: u64,
|
||||||
|
; cases: *const u64,
|
||||||
|
; cases_len: usize,
|
||||||
|
; }
|
||||||
|
;
|
||||||
|
; struct AstSwitchCase {
|
||||||
|
; pattern: u64,
|
||||||
|
; expr: u64,
|
||||||
|
; }
|
||||||
|
; end-structs
|
||||||
|
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
||||||
|
;; rdi: *mut Ast
|
||||||
|
;; define-fn: fn ast_parse_if_expr(ast: *mut Ast) -> (u64, bool)
|
||||||
|
ast_parse_if_expr:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
|
; start-structs
|
||||||
|
; struct AstIfExpr {
|
||||||
|
; condition: u64,
|
||||||
|
; then: u64,
|
||||||
|
; else_: u64,
|
||||||
|
; }
|
||||||
|
; end-structs
|
||||||
|
|
||||||
|
; ast [0..8]
|
||||||
|
sub rsp, 40
|
||||||
|
mov [rsp], rdi ; Ast
|
||||||
|
|
||||||
|
call tokeniser_get_cursor
|
||||||
|
mov [rsp + 32], rax ; span
|
||||||
|
|
||||||
|
mov dil, TOKEN_IF
|
||||||
|
call unwrap_token
|
||||||
|
|
||||||
|
mov dil, TOKEN_LPARENS
|
||||||
|
call unwrap_token
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; Ast
|
||||||
|
call parse_expr
|
||||||
|
mov [rsp + 8], rax ; condition
|
||||||
|
|
||||||
|
mov dil, TOKEN_RPARENS
|
||||||
|
call unwrap_token
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; Ast
|
||||||
|
call parse_block
|
||||||
|
mov [rsp + 16], rax ; then
|
||||||
|
|
||||||
|
mov dil, TOKEN_ELSE
|
||||||
|
call expect_token
|
||||||
|
test rax, rax
|
||||||
|
jz .no_else
|
||||||
|
|
||||||
|
mov dil, TOKEN_IF
|
||||||
|
call peek_expect_token
|
||||||
|
test rax, rax
|
||||||
|
jnz .else_if
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; Ast
|
||||||
|
call parse_block
|
||||||
|
mov [rsp + 24], rax ; else
|
||||||
|
jmp .after_else
|
||||||
|
|
||||||
|
.else_if:
|
||||||
|
mov rdi, [rsp] ; Ast
|
||||||
|
call ast_parse_if_expr
|
||||||
|
mov [rsp + 24], rax ; else
|
||||||
|
jmp .after_else
|
||||||
|
|
||||||
|
.no_else:
|
||||||
|
mov qword [rsp + 24], -1 ; else = None
|
||||||
|
|
||||||
|
.after_else:
|
||||||
|
mov rdi, 24 ; size_of::<AstIfExpr>
|
||||||
|
mov rsi, 8 ; align_of::<AstIfExpr>
|
||||||
|
call bump_alloc
|
||||||
|
|
||||||
|
mov rdi, rax ; AstIfExpr ptr
|
||||||
|
lea rsi, [rsp + 8] ; &AstIfExpr
|
||||||
|
mov rdx, 24 ; size_of::<AstIfExpr>
|
||||||
|
call memcpy
|
||||||
|
|
||||||
|
mov qword [rsp + 8], AST_IF ; AstNode.kind
|
||||||
|
mov [rsp + 16], rdi ; AstNode.data
|
||||||
|
mov qword [rsp + 24], 0 ; AstNode.extra
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; Ast
|
||||||
|
lea rsi, [rsp + 8] ; &AstNode
|
||||||
|
call vec_push
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; Ast
|
||||||
|
mov rax, [rdi + 8] ; Ast.nodes.len()
|
||||||
|
dec rax
|
||||||
|
|
||||||
|
add rsp, 40
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
||||||
;; rdi: *mut Ast
|
;; rdi: *mut Ast
|
||||||
;; define-fn: fn ast_parse_let(ast: *mut Ast) -> (u64, bool)
|
;; define-fn: fn ast_parse_let(ast: *mut Ast) -> (u64, bool)
|
||||||
ast_parse_let:
|
ast_parse_let:
|
||||||
|
|
@ -1441,6 +1577,8 @@ ast_walk_for_each:
|
||||||
je .address_of
|
je .address_of
|
||||||
cmp bl, AST_RETURN_STATEMENT
|
cmp bl, AST_RETURN_STATEMENT
|
||||||
je .return_statement
|
je .return_statement
|
||||||
|
cmp bl, AST_IF
|
||||||
|
je .if_expr
|
||||||
jmp .check_scope
|
jmp .check_scope
|
||||||
|
|
||||||
.func:
|
.func:
|
||||||
|
|
@ -1496,6 +1634,19 @@ ast_walk_for_each:
|
||||||
push rdx ; push left index
|
push rdx ; push left index
|
||||||
jmp .check_scope
|
jmp .check_scope
|
||||||
|
|
||||||
|
.if_expr:
|
||||||
|
mov rbx, [rax + 8] ; AstNode.data
|
||||||
|
mov rdx, [rbx + 16] ; else index
|
||||||
|
cmp rdx, -1
|
||||||
|
je .no_else
|
||||||
|
push rdx ; push else index
|
||||||
|
.no_else:
|
||||||
|
mov rdx, [rbx + 8] ; then index
|
||||||
|
push rdx ; push then index
|
||||||
|
mov rdx, [rbx + 0] ; condition index
|
||||||
|
push rdx ; push condition index
|
||||||
|
jmp .check_scope
|
||||||
|
|
||||||
.assignment:
|
.assignment:
|
||||||
mov rbx, [rax + 8] ; AstNode.data = dest
|
mov rbx, [rax + 8] ; AstNode.data = dest
|
||||||
mov rdx, [rax + 16] ; AstNode.extra = source
|
mov rdx, [rax + 16] ; AstNode.extra = source
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@ section .rdata
|
||||||
AST_VAR_DECL equ 12 ; :u8
|
AST_VAR_DECL equ 12 ; :u8
|
||||||
AST_VAR_REF equ 13 ; :u8
|
AST_VAR_REF equ 13 ; :u8
|
||||||
AST_ARG equ 14 ; :u8
|
AST_ARG equ 14 ; :u8
|
||||||
|
AST_SWITCH equ 15 ; :u8
|
||||||
|
AST_IF equ 16 ; :u8
|
||||||
|
AST_ELSE equ 17 ; :u8
|
||||||
|
AST_CALL equ 18 ; :u8
|
||||||
|
|
||||||
TYPE_VOID equ 1 ; :u8
|
TYPE_VOID equ 1 ; :u8
|
||||||
TYPE_BOOL equ 2 ; :u8
|
TYPE_BOOL equ 2 ; :u8
|
||||||
|
|
@ -21,4 +25,4 @@ section .rdata
|
||||||
TYPE_U32 equ 4 ; :u8
|
TYPE_U32 equ 4 ; :u8
|
||||||
TYPE_STR equ 5 ; :u8
|
TYPE_STR equ 5 ; :u8
|
||||||
TYPE_POINTER equ 6 ; :u8
|
TYPE_POINTER equ 6 ; :u8
|
||||||
;; end-consts
|
;; end-consts
|
||||||
|
|
|
||||||
|
|
@ -1020,8 +1020,210 @@ codegen_expr:
|
||||||
je .deref
|
je .deref
|
||||||
cmp bl, AST_ADDRESS_OF
|
cmp bl, AST_ADDRESS_OF
|
||||||
je .address_of
|
je .address_of
|
||||||
|
cmp bl, AST_IF
|
||||||
|
je .if_expr
|
||||||
jmp .panic
|
jmp .panic
|
||||||
|
|
||||||
|
.if_expr:
|
||||||
|
mov rbx, [rax + 8] ; AstNode.data = *AstIfExpr
|
||||||
|
mov [rsp + 16], rax ; scratch = AstNode
|
||||||
|
|
||||||
|
mov rdx, [rbx] ; AstIfExpr.cond
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
mov rsi, [rsp + 8] ; &function_ctx
|
||||||
|
call codegen_expr
|
||||||
|
mov [rsp + 24], rax ; cond operand
|
||||||
|
mov [rsp + 32], rdx
|
||||||
|
|
||||||
|
; cmp cond, 0
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
lea rsi, [rsp + 24] ; left = cond
|
||||||
|
lea rdx, [rel OPERAND_ZERO] ; right = 0
|
||||||
|
mov rcx, 'cmp '
|
||||||
|
call codegen_binary_op_unchecked
|
||||||
|
|
||||||
|
; free cond
|
||||||
|
mov rdi, [rsp + 8] ; &function_ctx
|
||||||
|
lea rsi, [rsp + 24] ; cond operand
|
||||||
|
call codegen_free_operand
|
||||||
|
|
||||||
|
; je .branch_{else_}
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
lea rsi, [rel JE_B]
|
||||||
|
mov rdx, JE_B_len
|
||||||
|
call vec_extend
|
||||||
|
|
||||||
|
mov rdi, [rbx + 16] ; AstIfExpr.else
|
||||||
|
lea rsi, [rsp + 24] ; scratch
|
||||||
|
mov rdx, 30
|
||||||
|
mov rcx, 16
|
||||||
|
call int_to_str2
|
||||||
|
mov byte [rax + rdx], 10
|
||||||
|
inc rdx
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
mov rsi, rax
|
||||||
|
call vec_extend
|
||||||
|
|
||||||
|
; codegen then branch
|
||||||
|
mov rdx, [rbx + 8] ; AstIfExpr.then
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
mov rsi, [rsp + 8] ; &function_ctx
|
||||||
|
call codegen_expr
|
||||||
|
mov [rsp + 24], rax ; then
|
||||||
|
mov [rsp + 32], rdx
|
||||||
|
|
||||||
|
cmp rax, 0
|
||||||
|
je .if_skip_phi
|
||||||
|
; mov rax, then
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
lea rsi, [rel OPERAND_RAX]
|
||||||
|
lea rdx, [rsp + 24] ; src
|
||||||
|
call codegen_move_dst_src
|
||||||
|
|
||||||
|
; free then
|
||||||
|
mov rdi, [rsp + 8] ; &function_ctx
|
||||||
|
lea rsi, [rsp + 24] ; then operand
|
||||||
|
call codegen_free_operand
|
||||||
|
|
||||||
|
.if_skip_phi:
|
||||||
|
; jmp .branch_{if}
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
lea rsi, [rel JMP_PHI]
|
||||||
|
mov rdx, JMP_PHI_len
|
||||||
|
call vec_extend
|
||||||
|
|
||||||
|
mov rdi, [rbx + 0] ; AstIfExpr.cond
|
||||||
|
lea rsi, [rsp + 24] ; scratch
|
||||||
|
mov rdx, 30
|
||||||
|
mov rcx, 16
|
||||||
|
call int_to_str2
|
||||||
|
mov byte [rax + rdx], 10
|
||||||
|
inc rdx
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
mov rsi, rax
|
||||||
|
call vec_extend
|
||||||
|
|
||||||
|
; .branch_{else_}:
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
lea rsi, [rel JE_B]
|
||||||
|
add rsi, 3
|
||||||
|
mov rdx, 2
|
||||||
|
call vec_extend
|
||||||
|
|
||||||
|
mov rdi, [rbx + 16] ; AstIfExpr.else
|
||||||
|
lea rsi, [rsp + 24] ; scratch
|
||||||
|
mov rdx, 30
|
||||||
|
mov rcx, 16
|
||||||
|
call int_to_str2
|
||||||
|
mov byte [rax + rdx], ':'
|
||||||
|
inc rdx
|
||||||
|
mov byte [rax + rdx], 10
|
||||||
|
inc rdx
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
mov rsi, rax
|
||||||
|
call vec_extend
|
||||||
|
|
||||||
|
; codegen else branch
|
||||||
|
mov rdx, [rbx + 16] ; AstIfExpr.else
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
mov rsi, [rsp + 8] ; &function_ctx
|
||||||
|
call codegen_expr
|
||||||
|
mov [rsp + 24], rax ; else
|
||||||
|
mov [rsp + 32], rdx
|
||||||
|
|
||||||
|
cmp rax, 0
|
||||||
|
je .if_skip_phi2
|
||||||
|
; mov rax, else
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
lea rsi, [rel OPERAND_RAX]
|
||||||
|
lea rdx, [rsp + 24] ; src
|
||||||
|
call codegen_move_dst_src
|
||||||
|
|
||||||
|
; free else
|
||||||
|
mov rdi, [rsp + 8] ; &function_ctx
|
||||||
|
lea rsi, [rsp + 24] ; else operand
|
||||||
|
call codegen_free_operand
|
||||||
|
|
||||||
|
.if_skip_phi2:
|
||||||
|
; .branch_{if}
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
lea rsi, [rel JMP_PHI]
|
||||||
|
add rsi, 4
|
||||||
|
mov rdx, 4
|
||||||
|
call vec_extend
|
||||||
|
|
||||||
|
mov rdi, [rbx + 0] ; AstIfExpr.cond
|
||||||
|
lea rsi, [rsp + 32] ; scratch
|
||||||
|
mov rdx, 30
|
||||||
|
mov rcx, 16
|
||||||
|
call int_to_str2
|
||||||
|
mov byte [rax + rdx], ':'
|
||||||
|
inc rdx
|
||||||
|
mov byte [rax + rdx], 10
|
||||||
|
inc rdx
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
mov rsi, rax
|
||||||
|
call vec_extend
|
||||||
|
|
||||||
|
mov rax, qword [rsp + 24]
|
||||||
|
cmp rax, 0
|
||||||
|
je .if_no_value
|
||||||
|
|
||||||
|
; dst = allocate_value
|
||||||
|
mov rdi, [rsp + 8] ; &function_ctx
|
||||||
|
mov rsi, 8 ; width
|
||||||
|
call codegen_allocate_value
|
||||||
|
mov [rsp + 40], rax
|
||||||
|
mov [rsp + 48], rdx
|
||||||
|
|
||||||
|
cmp byte [rsp + 24], OPERAND_LAST_VALUE
|
||||||
|
ja .if_phi_place
|
||||||
|
|
||||||
|
; preserve width of then/else value
|
||||||
|
mov ax, word [rsp + 24 + 2] ; Operand.width
|
||||||
|
mov word [rsp + 40 + 2], ax
|
||||||
|
jmp .if_value
|
||||||
|
|
||||||
|
.if_phi_place:
|
||||||
|
; turn dst into it's place equivalent
|
||||||
|
cmp byte [rsp + 40], OPERAND_REGISTER
|
||||||
|
cmove ax, word [rel OPERAND_REGISTER_PLACE]
|
||||||
|
cmp byte [rsp + 40], OPERAND_RBP_VALUE
|
||||||
|
cmove ax, word [rel OPERAND_RBP_PLACE]
|
||||||
|
mov byte [rsp + 40], al
|
||||||
|
|
||||||
|
.if_value:
|
||||||
|
; mov dst, rax
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
lea rsi, [rsp + 40] ; dst
|
||||||
|
lea rdx, [rel OPERAND_RAX] ; rax (phi)
|
||||||
|
call codegen_move_dst_src
|
||||||
|
|
||||||
|
mov rax, [rsp + 40]
|
||||||
|
mov rdx, [rsp + 48]
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.if_no_value:
|
||||||
|
xor rax, rax
|
||||||
|
xor rdx, rdx
|
||||||
|
jmp .done
|
||||||
|
|
||||||
.block:
|
.block:
|
||||||
mov rbx, [rax + 8] ; AstNode.data
|
mov rbx, [rax + 8] ; AstNode.data
|
||||||
mov r15, [rax + 16] ; AstNode.extra
|
mov r15, [rax + 16] ; AstNode.extra
|
||||||
|
|
@ -1154,6 +1356,10 @@ codegen_expr:
|
||||||
cmove rbx, [rel SUB_]
|
cmove rbx, [rel SUB_]
|
||||||
cmp rbx, -1
|
cmp rbx, -1
|
||||||
jne .gen_op
|
jne .gen_op
|
||||||
|
cmp al, TOKEN_EQEQ
|
||||||
|
je .binop_cmp
|
||||||
|
cmp al, TOKEN_BANGEQ
|
||||||
|
je .binop_cmp
|
||||||
cmp al, TOKEN_STAR
|
cmp al, TOKEN_STAR
|
||||||
cmove rbx, [rel MUL_]
|
cmove rbx, [rel MUL_]
|
||||||
cmp al, TOKEN_SLASH
|
cmp al, TOKEN_SLASH
|
||||||
|
|
@ -1161,7 +1367,73 @@ codegen_expr:
|
||||||
cmp al, TOKEN_PERCENT
|
cmp al, TOKEN_PERCENT
|
||||||
cmove rbx, [rel DIV_]
|
cmove rbx, [rel DIV_]
|
||||||
cmp rbx, -1
|
cmp rbx, -1
|
||||||
je .panic ; unknown operator
|
jne .mul_div
|
||||||
|
jmp .panic ; unknown operator
|
||||||
|
|
||||||
|
.binop_cmp:
|
||||||
|
mov bl, al ; operator
|
||||||
|
mov rdi, [rsp + 8] ; &function_ctx
|
||||||
|
mov rsi, [rsp] ; ctx
|
||||||
|
lea rsi, [rsi + 8] ; &ctx.text
|
||||||
|
lea rdx, [rsp + 32] ; left operand
|
||||||
|
lea rcx, [rsp + 48] ; right operand
|
||||||
|
mov r8, 'cmp '
|
||||||
|
mov r9, 1
|
||||||
|
call codegen_binary_op_rm64_rm64
|
||||||
|
mov [rsp + 32], rax
|
||||||
|
mov [rsp + 40], rdx
|
||||||
|
|
||||||
|
; free operand
|
||||||
|
mov rdi, [rsp + 8] ; &function_ctx
|
||||||
|
lea rsi, [rsp + 32] ; left operand
|
||||||
|
call codegen_free_operand
|
||||||
|
|
||||||
|
; dst = allocate_value(1)
|
||||||
|
mov rdi, [rsp + 8] ; &function_ctx
|
||||||
|
mov rsi, 1 ; width
|
||||||
|
call codegen_allocate_value
|
||||||
|
mov [rsp + 32], rax
|
||||||
|
mov [rsp + 40], rdx
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
cmp bl, TOKEN_EQEQ
|
||||||
|
cmove rax, [rel SETE_]
|
||||||
|
cmp bl, TOKEN_BANGEQ
|
||||||
|
cmove rax, [rel SETNE_]
|
||||||
|
cmp bl, TOKEN_LEQ
|
||||||
|
cmove rax, [rel SETBE_]
|
||||||
|
cmp bl, TOKEN_LT
|
||||||
|
cmove rax, [rel SETB_]
|
||||||
|
cmp bl, TOKEN_GEQ
|
||||||
|
cmove rax, [rel SETAE_]
|
||||||
|
cmp bl, TOKEN_GT
|
||||||
|
cmove rax, [rel SETA_]
|
||||||
|
cmp rax, 0
|
||||||
|
je .panic ; unknown cmp operator
|
||||||
|
mov [rsp + 48], rax
|
||||||
|
|
||||||
|
; "{rax} dst\n"
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
lea rsi, [rsp + 48] ; op
|
||||||
|
mov rdx, 6
|
||||||
|
call vec_extend
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
lea rsi, [rsp + 32] ; dst
|
||||||
|
call codegen_write_operand
|
||||||
|
|
||||||
|
mov rdi, [rsp] ; ctx
|
||||||
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
|
mov byte [rsp + 48], 10 ; newline
|
||||||
|
lea rsi, [rsp + 48]
|
||||||
|
call vec_push
|
||||||
|
|
||||||
|
mov rax, [rsp + 32]
|
||||||
|
mov rdx, [rsp + 40]
|
||||||
|
jmp .done
|
||||||
|
|
||||||
.mul_div:
|
.mul_div:
|
||||||
; mul/div need to clobber rax:rdx
|
; mul/div need to clobber rax:rdx
|
||||||
|
|
||||||
|
|
@ -1316,6 +1588,7 @@ codegen_expr:
|
||||||
lea rdx, [rsp + 32] ; left operand
|
lea rdx, [rsp + 32] ; left operand
|
||||||
lea rcx, [rsp + 48] ; right operand
|
lea rcx, [rsp + 48] ; right operand
|
||||||
mov r8, rbx ; operation
|
mov r8, rbx ; operation
|
||||||
|
mov r9, 0
|
||||||
call codegen_binary_op_rm64_rm64
|
call codegen_binary_op_rm64_rm64
|
||||||
jmp .done
|
jmp .done
|
||||||
|
|
||||||
|
|
@ -1612,6 +1885,8 @@ section .rdata
|
||||||
OPERAND_RBP_V dq 0x0008_0002, 0
|
OPERAND_RBP_V dq 0x0008_0002, 0
|
||||||
align 8
|
align 8
|
||||||
OPERAND_RBP_P dq 0x0008_0009, 0
|
OPERAND_RBP_P dq 0x0008_0009, 0
|
||||||
|
align 8
|
||||||
|
OPERAND_ZERO dq 0x0001_000b, 0
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|
||||||
|
|
@ -1836,19 +2111,23 @@ codegen_write_width:
|
||||||
;; rdx: lhs: *Operand
|
;; rdx: lhs: *Operand
|
||||||
;; rcx: rhs: *Operand
|
;; rcx: rhs: *Operand
|
||||||
;; r8: op: [u8; 8]
|
;; r8: op: [u8; 8]
|
||||||
|
;; r9: discard_result
|
||||||
;; Generates: {op} {lhs}, {rhs} for a binary operation that has the encodings rN, rmN and rmN, rN
|
;; Generates: {op} {lhs}, {rhs} for a binary operation that has the encodings rN, rmN and rmN, rN
|
||||||
|
;; define-fn: fn codegen_binary_op_rm64_rm64(function_ctx: *mut FunctionCtx, text: *mut BlobVec, lhs: *const Operand, rhs: *const Operand, op: [u8; 8], discard_result: bool) -> *const Operand
|
||||||
codegen_binary_op_rm64_rm64:
|
codegen_binary_op_rm64_rm64:
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
push rbx
|
push rbx
|
||||||
|
|
||||||
; dst [32..48]
|
; discard_result [56..57]
|
||||||
sub rsp, 56
|
; dst [40..56]
|
||||||
|
sub rsp, 64
|
||||||
mov [rsp], rdi ; *function_ctx
|
mov [rsp], rdi ; *function_ctx
|
||||||
mov [rsp + 8], rsi ; *text
|
mov [rsp + 8], rsi ; *text
|
||||||
mov [rsp + 16], rdx ; lhs
|
mov [rsp + 16], rdx ; lhs
|
||||||
mov [rsp + 24], rcx ; rhs
|
mov [rsp + 24], rcx ; rhs
|
||||||
mov [rsp + 32], r8 ; op
|
mov [rsp + 32], r8 ; op
|
||||||
|
mov byte [rsp + 48], r9b ; discard_result
|
||||||
|
|
||||||
; match (lhs.kind, rhs.kind) {
|
; match (lhs.kind, rhs.kind) {
|
||||||
cmp byte [rdx + 0], OPERAND_REGISTER
|
cmp byte [rdx + 0], OPERAND_REGISTER
|
||||||
|
|
@ -1961,6 +2240,15 @@ codegen_binary_op_rm64_rm64:
|
||||||
mov rsi, [rsp + 16] ; lhs
|
mov rsi, [rsp + 16] ; lhs
|
||||||
call codegen_free_operand
|
call codegen_free_operand
|
||||||
|
|
||||||
|
cmp byte [rsp + 56], 0
|
||||||
|
je .rax_rhs_done
|
||||||
|
; mov rhs, rax
|
||||||
|
mov rdi, [rsp + 8] ; *text
|
||||||
|
mov rsi, [rsp + 24] ; rhs
|
||||||
|
lea rdx, [rel OPERAND_RAX]
|
||||||
|
call codegen_move_dst_src
|
||||||
|
|
||||||
|
.rax_rhs_done:
|
||||||
; ret rhs
|
; ret rhs
|
||||||
mov rbx, [rsp + 24] ; rhs
|
mov rbx, [rsp + 24] ; rhs
|
||||||
mov rax, [rbx]
|
mov rax, [rbx]
|
||||||
|
|
@ -2007,13 +2295,13 @@ codegen_binary_op_rm64_rm64:
|
||||||
call codegen_free_operand
|
call codegen_free_operand
|
||||||
|
|
||||||
; ret dst
|
; ret dst
|
||||||
mov rax, [rsp + 32] ; dst
|
mov rax, [rsp + 40] ; dst
|
||||||
mov rdx, [rsp + 40]
|
mov rdx, [rsp + 48]
|
||||||
; }
|
; }
|
||||||
|
|
||||||
|
|
||||||
.epilogue:
|
.epilogue:
|
||||||
add rsp, 56
|
add rsp, 64
|
||||||
pop rbx
|
pop rbx
|
||||||
pop rbp
|
pop rbp
|
||||||
ret
|
ret
|
||||||
|
|
@ -2243,4 +2531,18 @@ section .rdata
|
||||||
SUB_ dq "sub "
|
SUB_ dq "sub "
|
||||||
MUL_ dq "mul "
|
MUL_ dq "mul "
|
||||||
DIV_ dq "div "
|
DIV_ dq "div "
|
||||||
|
SETE_ dq "sete "
|
||||||
|
SETNE_ dq "setne "
|
||||||
|
SETA_ dq "seta "
|
||||||
|
SETAE_ dq "setae "
|
||||||
|
SETB_ dq "setb "
|
||||||
|
SETBE_ dq "setbe "
|
||||||
|
SETL_ dq "setl "
|
||||||
|
SETLE_ dq "setle "
|
||||||
|
SETG_ dq "setg "
|
||||||
|
SETGE_ dq "setge "
|
||||||
|
JE_B dq "je .B"
|
||||||
|
JE_B_len equ $ - JE_B
|
||||||
|
JMP_PHI dq "jmp .PHI"
|
||||||
|
JMP_PHI_len equ $ - JMP_PHI
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,11 @@ LEXEMES:
|
||||||
dq LEX_DOT2
|
dq LEX_DOT2
|
||||||
dq LEX_DOT
|
dq LEX_DOT
|
||||||
dq LEX_BACKTICK
|
dq LEX_BACKTICK
|
||||||
|
dq LEX_SWITCH
|
||||||
|
dq LEX_AS
|
||||||
|
dq LEX_MATCH
|
||||||
|
dq LEX_WHILE
|
||||||
|
dq LEX_FOR
|
||||||
|
|
||||||
align 8
|
align 8
|
||||||
TOKENS:
|
TOKENS:
|
||||||
|
|
@ -126,6 +131,11 @@ TOKENS:
|
||||||
db TOKEN_DOT2 ;; 53
|
db TOKEN_DOT2 ;; 53
|
||||||
db TOKEN_DOT ;; 52
|
db TOKEN_DOT ;; 52
|
||||||
db TOKEN_BACKTICK ;; 55
|
db TOKEN_BACKTICK ;; 55
|
||||||
|
db TOKEN_SWITCH
|
||||||
|
db TOKEN_AS
|
||||||
|
db TOKEN_MATCH
|
||||||
|
db TOKEN_WHILE
|
||||||
|
db TOKEN_FOR
|
||||||
|
|
||||||
align 8
|
align 8
|
||||||
LEXEME_LENS:
|
LEXEME_LENS:
|
||||||
|
|
@ -190,9 +200,14 @@ LEXEME_LENS:
|
||||||
dq LEX_DOT2_len
|
dq LEX_DOT2_len
|
||||||
dq LEX_DOT_len
|
dq LEX_DOT_len
|
||||||
dq LEX_BACKTICK_len
|
dq LEX_BACKTICK_len
|
||||||
|
dq LEX_SWITCH_len
|
||||||
|
dq LEX_AS_len
|
||||||
|
dq LEX_MATCH_len
|
||||||
|
dq LEX_WHILE_len
|
||||||
|
dq LEX_FOR_len
|
||||||
|
|
||||||
align 8
|
align 8
|
||||||
NUM_LEXEMES: dq 61
|
NUM_LEXEMES: dq 66
|
||||||
|
|
||||||
LEX_NOT_A_LEXEME db "<not a lexeme>", 0
|
LEX_NOT_A_LEXEME db "<not a lexeme>", 0
|
||||||
LEX_LET db "let"
|
LEX_LET db "let"
|
||||||
|
|
@ -315,6 +330,16 @@ NUM_LEXEMES: dq 61
|
||||||
LEX_DOT_len equ $ - LEX_DOT
|
LEX_DOT_len equ $ - LEX_DOT
|
||||||
LEX_BACKTICK db "`"
|
LEX_BACKTICK db "`"
|
||||||
LEX_BACKTICK_len equ $ - LEX_BACKTICK
|
LEX_BACKTICK_len equ $ - LEX_BACKTICK
|
||||||
|
LEX_SWITCH db "switch"
|
||||||
|
LEX_SWITCH_len equ $ - LEX_SWITCH
|
||||||
|
LEX_AS db "as"
|
||||||
|
LEX_AS_len equ $ - LEX_AS
|
||||||
|
LEX_MATCH db "match"
|
||||||
|
LEX_MATCH_len equ $ - LEX_MATCH
|
||||||
|
LEX_WHILE db "while"
|
||||||
|
LEX_WHILE_len equ $ - LEX_WHILE
|
||||||
|
LEX_FOR db "for"
|
||||||
|
LEX_FOR_len equ $ - LEX_FOR
|
||||||
LEX_IDENT db "<identifier>"
|
LEX_IDENT db "<identifier>"
|
||||||
LEX_IDENT_len equ $ - LEX_IDENT
|
LEX_IDENT_len equ $ - LEX_IDENT
|
||||||
LEX_NUMBER db "<number>"
|
LEX_NUMBER db "<number>"
|
||||||
|
|
@ -386,8 +411,13 @@ NUM_LEXEMES: dq 61
|
||||||
TOKEN_DOT2 equ 58 ; :u8
|
TOKEN_DOT2 equ 58 ; :u8
|
||||||
TOKEN_DOT equ 59 ; :u8
|
TOKEN_DOT equ 59 ; :u8
|
||||||
TOKEN_BACKTICK equ 60 ; :u8
|
TOKEN_BACKTICK equ 60 ; :u8
|
||||||
TOKEN_IDENT equ 61 ; :u8
|
TOKEN_SWITCH equ 61 ; :u8
|
||||||
TOKEN_NUMBER equ 62 ; :u8
|
TOKEN_AS equ 62 ; :u8
|
||||||
TOKEN_STRING equ 63 ; :u8
|
TOKEN_MATCH equ 63 ; :u8
|
||||||
TOKEN_COMMENT equ 64 ; :u8
|
TOKEN_WHILE equ 64 ; :u8
|
||||||
|
TOKEN_FOR equ 65 ; :u8
|
||||||
|
TOKEN_IDENT equ 66 ; :u8
|
||||||
|
TOKEN_NUMBER equ 67 ; :u8
|
||||||
|
TOKEN_STRING equ 68 ; :u8
|
||||||
|
TOKEN_COMMENT equ 69 ; :u8
|
||||||
;; end-consts
|
;; end-consts
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ unsafe extern "C" {
|
||||||
unsafe fn tokeniser_init_buf(bytes: *const u8, len: usize) -> ();
|
unsafe fn tokeniser_init_buf(bytes: *const u8, len: usize) -> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
use util::defs::{parse_func, Ast};
|
use util::defs::{parse_expr, parse_func, Ast};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -58,57 +58,67 @@ fn main() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// print_ast(
|
print_ast(
|
||||||
// b"fn main() -> void { return 1 * 2 + 3 * 4; }",
|
b"fn main() -> void { return 1 * 2 + 3 * 4; }",
|
||||||
// |ast| unsafe { parse_func(ast) },
|
|ast| unsafe { parse_func(ast) },
|
||||||
// );
|
);
|
||||||
|
|
||||||
// print_ast(b"3 + 4", |ast| unsafe { parse_expr(ast) });
|
print_ast(b"3 + 4", |ast| unsafe { parse_expr(ast) });
|
||||||
// print_ast(b"fn main() -> void { return 1 + 2; }", |ast| unsafe {
|
print_ast(b"fn main() -> void { return 1 + 2; }", |ast| unsafe {
|
||||||
// parse_func(ast)
|
parse_func(ast)
|
||||||
// });
|
});
|
||||||
// print_ast(
|
print_ast(
|
||||||
// b"fn main() -> void { ;;;return (1 + (2)); }",
|
b"fn main() -> void { ;;;return (1 + (2)); }",
|
||||||
// |ast| unsafe { parse_func(ast) },
|
|ast| unsafe { parse_func(ast) },
|
||||||
// );
|
);
|
||||||
// print_ast(
|
print_ast(
|
||||||
// b"fn main() -> void { return (1 + (2 * 3)) / 4; }",
|
b"fn main() -> void { return (1 + (2 * 3)) / 4; }",
|
||||||
// |ast| unsafe { parse_func(ast) },
|
|ast| unsafe { parse_func(ast) },
|
||||||
// );
|
);
|
||||||
// print_ast(b"fn main() -> void { return 1 + 2 * 3; }", |ast| unsafe {
|
print_ast(b"fn main() -> void { return 1 + 2 * 3; }", |ast| unsafe {
|
||||||
// parse_func(ast)
|
parse_func(ast)
|
||||||
// });
|
});
|
||||||
|
|
||||||
// print_ast(b"fn main() -> void { let x: u32 = 4; }", |ast| unsafe {
|
print_ast(b"fn main() -> void { let x: u32 = 4; }", |ast| unsafe {
|
||||||
// parse_func(ast)
|
parse_func(ast)
|
||||||
// });
|
});
|
||||||
// print_ast(
|
print_ast(
|
||||||
// b"fn main(a: u32) -> void { let x: u32 = a + 4; }",
|
b"fn main(a: u32) -> void { let x: u32 = a + 4; }",
|
||||||
// |ast| unsafe { parse_func(ast) },
|
|ast| unsafe { parse_func(ast) },
|
||||||
// );
|
);
|
||||||
// print_ast(
|
print_ast(
|
||||||
// b"fn main(a: u32) -> void {
|
b"fn main(a: u32) -> void {
|
||||||
// let y: u32 = a + 4;
|
let y: u32 = a + 4;
|
||||||
// let y: *u32 = &y;
|
let y: *u32 = &y;
|
||||||
// return *y;
|
return *y;
|
||||||
// }",
|
}",
|
||||||
// |ast| unsafe { parse_func(ast) },
|
|ast| unsafe { parse_func(ast) },
|
||||||
// );
|
);
|
||||||
// print_ast(
|
print_ast(
|
||||||
// b"fn main(a: u32) -> void {
|
b"fn main(a: u32) -> void {
|
||||||
// let y: u32 = a + 4;
|
let y: u32 = a + 4;
|
||||||
// {
|
{
|
||||||
// let y: u32 = 10;
|
let y: u32 = 10;
|
||||||
// }
|
}
|
||||||
// let y: *u32 = &y;
|
let y: *u32 = &y;
|
||||||
// return *y;
|
return *y;
|
||||||
// }",
|
}",
|
||||||
// |ast| unsafe { parse_func(ast) },
|
|ast| unsafe { parse_func(ast) },
|
||||||
// );
|
);
|
||||||
print_ast(
|
print_ast(
|
||||||
b"fn main(a: *u32, b: u32) -> void {
|
b"fn main(a: *u32, b: u32) -> void {
|
||||||
*a = b;
|
*a = b;
|
||||||
a = &b;
|
a = &b;
|
||||||
|
}",
|
||||||
|
|ast| unsafe { parse_func(ast) },
|
||||||
|
);
|
||||||
|
print_ast(
|
||||||
|
b"fn main(a: u32) -> void {
|
||||||
|
if (a == 0) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}",
|
}",
|
||||||
|ast| unsafe { parse_func(ast) },
|
|ast| unsafe { parse_func(ast) },
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -91,10 +91,23 @@ fn main() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print_ast(
|
||||||
|
// b"fn main(a: u32) -> void {
|
||||||
|
// let b: *u32 = &a;
|
||||||
|
// return 5 + *b;
|
||||||
|
// }",
|
||||||
|
// |ast| unsafe { parse_func(ast) },
|
||||||
|
// );
|
||||||
|
|
||||||
print_ast(
|
print_ast(
|
||||||
b"fn main(a: u32) -> void {
|
b"fn main(a: u32) -> void {
|
||||||
let b: *u32 = &a;
|
let x: u32 = 10;
|
||||||
return 5 + *b;
|
if (a == 42) {
|
||||||
|
x = 7;
|
||||||
|
} else {
|
||||||
|
x = 8;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
}",
|
}",
|
||||||
|ast| unsafe { parse_func(ast) },
|
|ast| unsafe { parse_func(ast) },
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ impl core::fmt::Display for util::defs::AstNode {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
use util::defs::{
|
use util::defs::{
|
||||||
BinaryExpr, AST_ADDRESS_OF, AST_ARG, AST_ASSIGNMENT, AST_BINARY_OP, AST_BLOCK,
|
BinaryExpr, AST_ADDRESS_OF, AST_ARG, AST_ASSIGNMENT, AST_BINARY_OP, AST_BLOCK,
|
||||||
AST_DEREF, AST_FUNCTION, AST_NUMBER, AST_PLACE_TO_VALUE, AST_RETURN_STATEMENT,
|
AST_DEREF, AST_FUNCTION, AST_IF, AST_NUMBER, AST_PLACE_TO_VALUE, AST_RETURN_STATEMENT,
|
||||||
AST_VALUE_TO_PLACE, AST_VAR_DECL, AST_VAR_REF,
|
AST_VALUE_TO_PLACE, AST_VAR_DECL, AST_VAR_REF,
|
||||||
};
|
};
|
||||||
match self.kind {
|
match self.kind {
|
||||||
|
|
@ -98,6 +98,19 @@ impl core::fmt::Display for util::defs::AstNode {
|
||||||
std::slice::from_raw_parts(self.data.cast::<u64>(), self.extra as usize)
|
std::slice::from_raw_parts(self.data.cast::<u64>(), self.extra as usize)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
AST_IF => {
|
||||||
|
let if_node = unsafe { self.data.cast::<util::defs::AstIfExpr>().read() };
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"If(cond: {}, then_branch: {}, else_branch: {:?})",
|
||||||
|
if_node.condition,
|
||||||
|
if_node.then,
|
||||||
|
match if_node.else_ {
|
||||||
|
u64::MAX => None,
|
||||||
|
v => Some(v),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
AST_PLACE_TO_VALUE => {
|
AST_PLACE_TO_VALUE => {
|
||||||
write!(f, "PlaceToValue(place: {})", self.data as usize)
|
write!(f, "PlaceToValue(place: {})", self.data as usize)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ unsafe extern "C" {
|
||||||
pub unsafe fn parse_type(ast: *mut Ast) -> Type;
|
pub unsafe fn parse_type(ast: *mut Ast) -> Type;
|
||||||
pub unsafe fn parse_prefix_expr(ast: *mut Ast) -> (u64, bool);
|
pub unsafe fn parse_prefix_expr(ast: *mut Ast) -> (u64, bool);
|
||||||
pub unsafe fn parse_assignment(ast: *mut Ast) -> (u64, bool);
|
pub unsafe fn parse_assignment(ast: *mut Ast) -> (u64, bool);
|
||||||
|
pub unsafe fn ast_parse_switch_expr(ast: *mut Ast) -> (u64, bool);
|
||||||
|
pub unsafe fn ast_parse_if_expr(ast: *mut Ast) -> (u64, bool);
|
||||||
pub unsafe fn ast_parse_let(ast: *mut Ast) -> (u64, bool);
|
pub unsafe fn ast_parse_let(ast: *mut Ast) -> (u64, bool);
|
||||||
pub unsafe fn symkey_cmp(a: *const SymKey, b: *const SymKey) -> i32;
|
pub unsafe fn symkey_cmp(a: *const SymKey, b: *const SymKey) -> i32;
|
||||||
pub unsafe fn ast_build_symtable(ast: *mut Ast, root_index: u64, symtable: *mut core::mem::MaybeUninit<SymbolTable>);
|
pub unsafe fn ast_build_symtable(ast: *mut Ast, root_index: u64, symtable: *mut core::mem::MaybeUninit<SymbolTable>);
|
||||||
|
|
@ -27,6 +29,7 @@ unsafe extern "C" {
|
||||||
pub unsafe fn codegen_function(ast: *const CodegenCtx, func_idx: u64) -> ();
|
pub unsafe fn codegen_function(ast: *const CodegenCtx, func_idx: u64) -> ();
|
||||||
pub unsafe fn codegen_push_pop_used_registers(text: *mut Vec<u8>, function_ctx: &FunctionCtx, pop: bool) -> u8;
|
pub unsafe fn codegen_push_pop_used_registers(text: *mut Vec<u8>, function_ctx: &FunctionCtx, pop: bool) -> u8;
|
||||||
pub unsafe fn codegen_expr(ctx: *const CodegenCtx, function_ctx: &FunctionCtx, expr_idx: u64) -> (u64, bool);
|
pub unsafe fn codegen_expr(ctx: *const CodegenCtx, function_ctx: &FunctionCtx, expr_idx: u64) -> (u64, bool);
|
||||||
|
pub unsafe fn codegen_binary_op_rm64_rm64(function_ctx: *mut FunctionCtx, text: *mut BlobVec, lhs: *const Operand, rhs: *const Operand, op: [u8; 8], discard_result: bool) -> *const Operand;
|
||||||
pub unsafe fn vec_insert_many(vec: *mut BlobVec, index: usize, data: *const u8, count: usize);
|
pub unsafe fn vec_insert_many(vec: *mut BlobVec, index: usize, data: *const u8, count: usize);
|
||||||
pub unsafe fn vec_extend(vec: *mut BlobVec, elements: *const u8, count: usize) -> ();
|
pub unsafe fn vec_extend(vec: *mut BlobVec, elements: *const u8, count: usize) -> ();
|
||||||
}
|
}
|
||||||
|
|
@ -52,6 +55,10 @@ pub const AST_ADDRESS_OF: u8 = 11;
|
||||||
pub const AST_VAR_DECL: u8 = 12;
|
pub const AST_VAR_DECL: u8 = 12;
|
||||||
pub const AST_VAR_REF: u8 = 13;
|
pub const AST_VAR_REF: u8 = 13;
|
||||||
pub const AST_ARG: u8 = 14;
|
pub const AST_ARG: u8 = 14;
|
||||||
|
pub const AST_SWITCH: u8 = 15;
|
||||||
|
pub const AST_IF: u8 = 16;
|
||||||
|
pub const AST_ELSE: u8 = 17;
|
||||||
|
pub const AST_CALL: u8 = 18;
|
||||||
pub const TYPE_VOID: u8 = 1;
|
pub const TYPE_VOID: u8 = 1;
|
||||||
pub const TYPE_BOOL: u8 = 2;
|
pub const TYPE_BOOL: u8 = 2;
|
||||||
pub const TYPE_I32: u8 = 3;
|
pub const TYPE_I32: u8 = 3;
|
||||||
|
|
@ -132,10 +139,15 @@ pub const TOKEN_DOT3: u8 = 57;
|
||||||
pub const TOKEN_DOT2: u8 = 58;
|
pub const TOKEN_DOT2: u8 = 58;
|
||||||
pub const TOKEN_DOT: u8 = 59;
|
pub const TOKEN_DOT: u8 = 59;
|
||||||
pub const TOKEN_BACKTICK: u8 = 60;
|
pub const TOKEN_BACKTICK: u8 = 60;
|
||||||
pub const TOKEN_IDENT: u8 = 61;
|
pub const TOKEN_SWITCH: u8 = 61;
|
||||||
pub const TOKEN_NUMBER: u8 = 62;
|
pub const TOKEN_AS: u8 = 62;
|
||||||
pub const TOKEN_STRING: u8 = 63;
|
pub const TOKEN_MATCH: u8 = 63;
|
||||||
pub const TOKEN_COMMENT: u8 = 64;
|
pub const TOKEN_WHILE: u8 = 64;
|
||||||
|
pub const TOKEN_FOR: u8 = 65;
|
||||||
|
pub const TOKEN_IDENT: u8 = 66;
|
||||||
|
pub const TOKEN_NUMBER: u8 = 67;
|
||||||
|
pub const TOKEN_STRING: u8 = 68;
|
||||||
|
pub const TOKEN_COMMENT: u8 = 69;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -194,6 +206,29 @@ pub struct BinaryExpr {
|
||||||
pub right: u64,
|
pub right: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AstSwitch {
|
||||||
|
pub expr: u64,
|
||||||
|
pub cases: *const u64,
|
||||||
|
pub cases_len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AstSwitchCase {
|
||||||
|
pub pattern: u64,
|
||||||
|
pub expr: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AstIfExpr {
|
||||||
|
pub condition: u64,
|
||||||
|
pub then: u64,
|
||||||
|
pub else_: u64,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AstVarDecl {
|
pub struct AstVarDecl {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue