Skip to content

Commit 52df8fa

Browse files
committed
Std lib etc for Outlaw.
1 parent 315d4ec commit 52df8fa

18 files changed

Lines changed: 2362 additions & 256 deletions

langs/outlaw/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ objs = \
1212
values.o \
1313
print.o \
1414
symbol.o \
15-
io.o
15+
string.o \
16+
io.o \
17+
stdlib.o
1618

1719
default: runtime.o
1820

@@ -28,6 +30,9 @@ runtime.o: $(objs)
2830
.s.o:
2931
nasm -g -f $(format) -o $@ $<
3032

33+
stdlib.s: stdlib.rkt
34+
racket -t compile-library.rkt -m stdlib.rkt > stdlib.s
35+
3136
%.s: %.rkt
3237
racket -t compile-file.rkt -m $< > $@
3338

langs/outlaw/ast.rkt

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,29 @@
44
;; type Prog = (Prog (Listof Defn) Expr)
55
(struct Prog (ds e) #:prefab)
66

7-
;; type Defn = (Defn Id (Listof Id) Expr)
8-
(struct Defn (f xs e) #:prefab)
7+
;; type Lib = (Lib (Listof Id) (Listof Defn))
8+
(struct Lib (ids ds) #:prefab)
99

10-
;; type Expr = (Eof)
11-
;; | (Quote Datum)
12-
;; | (Prim Op (Listof Expr))
13-
;; | (If Expr Expr Expr)
14-
;; | (Begin Expr Expr)
15-
;; | (Let Id Expr Expr)
16-
;; | (Var Id)
17-
;; | (Match Expr (Listof Pat) (Listof Expr))
18-
;; | (App Expr (Listof Expr))
19-
;; | (Lam Id (Listof Id) Expr)
10+
;; type Defn = (Defn Id Lambda)
11+
(struct Defn (f l) #:prefab)
12+
13+
;; type Expr = (Eof)
14+
;; | (Quote Datum)
15+
;; | (Prim Op (Listof Expr))
16+
;; | (If Expr Expr Expr)
17+
;; | (Begin Expr Expr)
18+
;; | (Let Id Expr Expr)
19+
;; | (Var Id)
20+
;; | (Match Expr (Listof Pat) (Listof Expr))
21+
;; | (App Expr (Listof Expr))
22+
;; | Lambda
23+
;; | (Apply Expr (Listof Expr))
24+
;; type Lambda = (Lam Id (Listof Id) Expr)
25+
;; | (LamRest Id (Listof Id) Id Expr)
26+
;; | (LamCase Id (Listof LamCaseClause))
27+
;; type LamCaseClause =
28+
;; | (Lam Id (Listof Id) Expr)
29+
;; | (LamRest Id (Listof Id) Expr)
2030
;; type Datum = Integer
2131
;; | Char
2232
;; | Boolean
@@ -58,16 +68,19 @@
5868
;; | Integer
5969
;; | '()
6070

61-
(struct Eof () #:prefab)
62-
(struct Prim (p es) #:prefab)
63-
(struct If (e1 e2 e3) #:prefab)
64-
(struct Begin (e1 e2) #:prefab)
65-
(struct Let (x e1 e2) #:prefab)
66-
(struct Var (x) #:prefab)
67-
(struct App (e es) #:prefab)
68-
(struct Lam (f xs e) #:prefab)
69-
(struct Quote (d) #:prefab)
70-
(struct Match (e ps es) #:prefab)
71+
(struct Eof () #:prefab)
72+
(struct Prim (p es) #:prefab)
73+
(struct If (e1 e2 e3) #:prefab)
74+
(struct Begin (e1 e2) #:prefab)
75+
(struct Let (x e1 e2) #:prefab)
76+
(struct Var (x) #:prefab)
77+
(struct App (e es) #:prefab)
78+
(struct Lam (f xs e) #:prefab)
79+
(struct LamRest (f xs x e) #:prefab)
80+
(struct LamCase (f cs) #:prefab)
81+
(struct Apply (e es el) #:prefab)
82+
(struct Quote (d) #:prefab)
83+
(struct Match (e ps es) #:prefab)
7184

7285
(struct PVar (x) #:prefab)
7386
(struct PWild () #:prefab)

langs/outlaw/compile-define.rkt

Lines changed: 90 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,63 +7,108 @@
77
"compile-expr.rkt"
88
a86/ast)
99

10+
(define r9 'r9)
11+
(define r15 'r15)
12+
1013
;; [Listof Defn] -> [Listof Id]
1114
(define (define-ids ds)
1215
(match ds
1316
['() '()]
14-
[(cons (Defn f xs e) ds)
17+
[(cons (Defn f l) ds)
1518
(cons f (define-ids ds))]))
1619

17-
;; [Listof Defn] -> Asm
18-
(define (compile-defines ds)
20+
;; [Listof Defn] GEnv -> Asm
21+
(define (compile-defines ds g)
1922
(match ds
2023
['() (seq)]
2124
[(cons d ds)
22-
(seq (compile-define d)
23-
(compile-defines ds))]))
25+
(seq (compile-define d g)
26+
(compile-defines ds g))]))
2427

25-
;; Defn -> Asm
26-
(define (compile-define d)
28+
;; Defn GEnv -> Asm
29+
(define (compile-define d g)
2730
(match d
28-
[(Defn f xs e)
29-
(compile-lambda-define (Lam f xs e))]))
30-
31-
;; Defns -> Asm
32-
;; Compile the closures for ds and push them on the stack
33-
(define (compile-defines-values ds)
34-
(seq (alloc-defines ds 0)
35-
(init-defines ds (reverse (define-ids ds)) 8)
36-
(add-rbx-defines ds 0)))
31+
[(Defn f e)
32+
(seq (%%% (symbol->string f))
33+
(Data)
34+
(Label (symbol->label f))
35+
(Dq 0)
36+
(Text)
37+
(compile-e e '() g #f)
38+
(Mov (Offset (symbol->label f) 0) rax))]))
3739

38-
;; Defns Int -> Asm
39-
;; Allocate closures for ds at given offset, but don't write environment yet
40-
(define (alloc-defines ds off)
41-
(match ds
40+
;; [Listof Lam] GEnv -> Asm
41+
(define (compile-lambda-defines ls g)
42+
(match ls
4243
['() (seq)]
43-
[(cons (Defn f xs e) ds)
44-
(let ((fvs (fv (Lam f xs e))))
45-
(seq (Lea rax (symbol->label f))
46-
(Mov (Offset rbx off) rax)
47-
(Mov rax rbx)
48-
(Add rax off)
49-
(Or rax type-proc)
50-
(Push rax)
51-
(alloc-defines ds (+ off (* 8 (add1 (length fvs)))))))]))
44+
[(cons l ls)
45+
(seq (compile-lambda-define l g)
46+
(compile-lambda-defines ls g))]))
5247

53-
;; Defns CEnv Int -> Asm
54-
;; Initialize the environment for each closure for ds at given offset
55-
(define (init-defines ds c off)
56-
(match ds
57-
['() (seq)]
58-
[(cons (Defn f xs e) ds)
59-
(let ((fvs (fv (Lam f xs e))))
60-
(seq (free-vars-to-heap fvs c off)
61-
(init-defines ds c (+ off (* 8 (add1 (length fvs)))))))]))
48+
;; Lambda GEnv -> Asm
49+
(define (compile-lambda-define l g)
50+
(let ((fvs (fv- l g)))
51+
(match l
52+
[(Lam f xs e)
53+
(let ((env (append (reverse fvs) (reverse xs) (list #f))))
54+
(seq (Label (symbol->label f))
55+
(Cmp r15 (length xs))
56+
(Jne 'raise_error_align)
57+
(Mov rax (Offset rsp (* 8 (length xs))))
58+
(Xor rax type-proc)
59+
(copy-env-to-stack fvs 8)
60+
(compile-e e env g #t)
61+
(Add rsp (* 8 (length env))) ; pop env
62+
(Ret)))]
63+
[(LamRest f xs x e)
64+
(let ((env (append (reverse fvs) (cons x (reverse xs)) (list #f))))
65+
(seq (Label (symbol->label f))
66+
(Cmp r15 (length xs))
67+
(Jl 'raise_error_align)
68+
69+
(Sub r15 (length xs))
70+
(Mov rax val-empty)
71+
(let ((loop (gensym))
72+
(done (gensym)))
73+
(seq (Label loop)
74+
(Cmp r15 0)
75+
(Je done)
76+
(Mov (Offset rbx 0) rax)
77+
(Pop rax)
78+
(Mov (Offset rbx 8) rax)
79+
(Mov rax rbx)
80+
(Or rax type-cons)
81+
(Add rbx 16)
82+
(Sub r15 1)
83+
(Jmp loop)
84+
(Label done)))
85+
(Push rax)
86+
87+
(Mov rax (Offset rsp (* 8 (add1 (length xs)))))
88+
(Xor rax type-proc)
89+
(copy-env-to-stack fvs 8)
90+
(compile-e e env g #t)
91+
(Add rsp (* 8 (length env))) ; pop env
92+
(Ret)))]
93+
[(LamCase f cs)
94+
(seq (%%% "lamcase code")
95+
(Label (symbol->label f))
96+
(compile-fun-case-select cs)
97+
(Jmp 'raise_error_align)
98+
(compile-fun-case-clauses cs g))])))
6299

63-
;; Defns Int -> Asm
64-
;; Compute adjustment to rbx for allocation of all ds
65-
(define (add-rbx-defines ds n)
66-
(match ds
67-
['() (seq (Add rbx (* n 8)))]
68-
[(cons (Defn f xs e) ds)
69-
(add-rbx-defines ds (+ n (add1 (length (fv (Lam f xs e))))))]))
100+
(define (compile-fun-case-clauses cs g)
101+
(append-map (lambda (c) (compile-lambda-define c g)) cs))
102+
103+
(define (compile-fun-case-select cs)
104+
(append-map compile-fun-case-selector cs))
105+
106+
(define (compile-fun-case-selector c)
107+
(match c
108+
[(Lam f xs e)
109+
(seq (Cmp r15 (length xs))
110+
(Je (symbol->label f)))]
111+
[(LamRest f xs x e)
112+
(seq (Mov r9 (sub1 (length xs)))
113+
(Cmp r9 r15)
114+
(Jl (symbol->label f)))]))

0 commit comments

Comments
 (0)