Closed dvanhorn closed 3 years ago
I made some changes after the Calling convention: return address over args #46 pull request merge.
Here is what I have for compile-apply
:
;; Apply Func Expr CEnv -> Asm
(define (compile-apply f e c)
(let ((ret (gensym 'ret))
(loop (gensym 'loop)))
(seq (Lea r8 ret)
(Push r8)
(compile-e-nontail e c)
(assert-cons rax c)
(Mov rcx (imm->bits 0))
(Label loop)
(assert-cons rax c) ; must be cons type
(Xor rax type-cons) ; convert to pointer
(Mov r8 (Offset rax 8)) ; get first element
(Push r8) ; push on to stack
(Add rcx (imm->bits 1)) ; increment count
(Mov rax (Offset rax 0)) ; get second
(Cmp rax (imm->bits '()))
(Jne loop)
; rcx already has argument count
(Jmp (symbol->label f)) ; result should be in rax
(Label ret)
)))
And I added [(Apply f e) (compile-apply f e c)]
in compile-e
.
Testing with
#lang racket
(begin
(define (plus . xs)
(match xs
['() 0]
[(cons x xs) (+ x (apply plus xs))]))
(apply plus (cons 4 (cons 5 '())))
)
failed with err
as output.
I tried to debug the executable using gdb
. It was jumping to raise_error
within a matchclause
label which I think is the match (cons x xs)
part.
Yeah, that's because you have assert-cons
in the code, but it should be acceptable to apply to an empty list too, and in your example, eventually xs will be empty in the second match clause, which then results in an error.
@minghui-liu can you submit a PR with whatever you have so I can fix it up if needed and merge? I'd like to use this feature in some libraries.
Closed by #51
In addition to variable-arity functions, we need the
apply
operation which has a single subexpression which is expected to produce a list. It runs the list, traverses it, pushing elements on to the stack, then calls the function.