-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pattern matching 3 #45
base: main
Are you sure you want to change the base?
Changes from all commits
be35888
6d34d77
ec76b66
ce983ce
d8c37a3
ad88d0b
c9c26ff
c116205
123d5bd
3bee18f
290c6bf
af487e7
8db0039
4609eb2
ee720b2
0739d44
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,8 +12,8 @@ | |
;; | (Int Integer) | ||
;; | (Bool Boolean) | ||
;; | (Char Character) | ||
;; | (String) | ||
;; | (Symbol Symbol) | ||
;; | (String s) | ||
;; | (Symbol s) | ||
;; | (Prim0 Op0) | ||
;; | (Prim1 Op1 Expr) | ||
;; | (Prim2 Op2 Expr Expr) | ||
|
@@ -23,7 +23,7 @@ | |
;; | (Let Id Expr Expr) | ||
;; | (Var Id) | ||
;; | (App Id (Listof Expr)) | ||
;; | (Match Expr (Listof Pat)) | ||
;; | (Match Expr (Listof Clause)) | ||
;; type Id = Symbol | ||
;; type Op0 = 'read-byte | 'void | 'collect-garbage | ||
;; type Op1 = 'add1 | 'sub1 | 'zero? | ||
|
@@ -34,13 +34,18 @@ | |
;; | 'empty? | ||
;; type Op2 = '+ | '- | 'eq? | ||
;; | 'cons | 'string-ref | ||
;; type Op3 = 'string-set! | ||
;; type Op3 = 'string-set! | ||
;; type Pat = (Wild) | ||
;; | (Var Id) | ||
;; | (Lit Literal) | ||
;; | (Float f) | ||
;; | (String s) | ||
;; | (Symbol s) | ||
;; | (Cons Id Id) | ||
;; | (Box Id) | ||
;; type Litral = Boolean | '() | Char | Integer | ||
;; type Litral = Boolean | '() | Char | Integer | Symbol | String | Float | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Symbol and String should not be in this list. |
||
;; type Clause = (Pairof Pat Expr) | ||
|
||
|
||
(struct Eof () #:prefab) | ||
(struct Empty () #:prefab) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,8 +13,8 @@ | |
; string-set!, make-string, | ||
(define rsp 'rsp) ; stack | ||
(define rdi 'rdi) ; arg | ||
(define r10 'r10) ; scratch in compile-prim3, make-string, string-set! | ||
(define rcx 'rcx) ; arity indicator | ||
(define r10 'r10) ; scratch in compile-prim3, make-string, string-set!, match | ||
(define rcx 'rcx) ; arity indicator, match | ||
|
||
;; type CEnv = [Listof Variable] | ||
|
||
|
@@ -488,7 +488,7 @@ | |
(compile-match-clauses cs return c) | ||
(Label return)))) | ||
|
||
;; [Listof Clauses] Symbol CEnv -> Asm | ||
;;[Listof Clauses] Symbol CEnv -> Asm | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add back to the space at the front so this doesn't show up in the diff. |
||
(define (compile-match-clauses cs return c) | ||
(match cs | ||
['() (seq (Jmp (error-label c)))] | ||
|
@@ -498,7 +498,7 @@ | |
(Label next) | ||
(compile-match-clauses cs return c)))])) | ||
|
||
;; Clause Symbol Symbol CEnv -> Asm | ||
;;Clause Symbol Symbol CEnv -> Asm | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add space at front back. |
||
(define (compile-match-clause cl next return c) | ||
(match cl | ||
[(Clause p e) | ||
|
@@ -508,11 +508,55 @@ | |
(compile-e e (cons x c)) | ||
(Add rsp 8) | ||
(Jmp return))] | ||
[(Lit l) | ||
(seq (Cmp rax (imm->bits l)) | ||
[(Lit i) | ||
(seq | ||
(Mov r8 (imm->bits i)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems needless to go through a register here. |
||
(Cmp rax r8) | ||
(Jne next) | ||
(compile-e e c) | ||
(Jmp return))] | ||
[(String s) | ||
(let ((true (gensym "true")) | ||
(false (gensym "false"))) | ||
(seq | ||
(Mov r8 rax) | ||
(And r8 ptr-mask) | ||
(Cmp r8 type-string) | ||
(Jne next) | ||
(Push rax) | ||
(compile-string s) | ||
(Push rax) | ||
(compile-string/symbol-eq type-string true false (cons #f (cons #f c))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm surprised the code for strings and symbols is so similar. Symbols should be a pointer comparison. Strings need to traverse the string for structural equality. (Although it may be useful to do a quick pointer equality test and fall back on the structural one when the pointers are unequal.) |
||
(Label true) | ||
(Pop r8) | ||
(Pop r8) | ||
(compile-e e c) | ||
(Jmp return) | ||
(Label false) | ||
(Pop r8) | ||
(Pop r8) | ||
(Jmp next)))] | ||
[(Symbol s) | ||
(let ((true (gensym "true")) | ||
(false (gensym "false"))) | ||
(seq | ||
(Mov r8 rax) | ||
(And r8 ptr-mask) | ||
(Cmp r8 type-symbol) | ||
(Jne next) | ||
(Push rax) | ||
(compile-symbol s (cons #f c)) | ||
(Push rax) | ||
(compile-string/symbol-eq type-symbol true false (cons #f (cons #f c))) | ||
(Label true) | ||
(Pop r8) | ||
(Pop r8) | ||
(compile-e e c) | ||
(Jmp return) | ||
(Label false) | ||
(Pop r8) | ||
(Pop r8) | ||
(Jmp next)))] | ||
[(Box x) | ||
(seq (Mov r8 rax) | ||
(And r8 ptr-mask) | ||
|
@@ -538,6 +582,40 @@ | |
(Add rsp 16) | ||
(Jmp return))])])) | ||
|
||
;;Symbol Symbol CEnv -> ASM | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't how you should compare symbols. |
||
;;This function determines if the two strings on top of the stack are structurally equal | ||
(define (compile-string/symbol-eq tag true false c) | ||
(let ((loop (gensym "loop"))) | ||
(seq | ||
(Mov rax (Offset rsp 0)) ;;First string | ||
(Mov r8 (Offset rsp 8)) ;;Second string | ||
|
||
;;Untag the strings | ||
(Xor rax tag) | ||
(Xor r8 tag) | ||
(Mov r9 (Offset r8 0)) | ||
|
||
;;If they don't have the same length, they cannot be equal | ||
(Cmp r9 (Offset rax 0)) | ||
(Jne false) | ||
|
||
(Mov r10 0) ;;Keep track of how many characters have been compared | ||
(Sar r9 int-shift) ;;Get the integer value of the length | ||
|
||
;;Compare each word for equality | ||
(Label loop) | ||
(Cmp r10 r9) ;;Check if the length has been exhausted | ||
(Je true) | ||
(Jg true) | ||
|
||
(Add r8 8) | ||
(Add rax 8) | ||
(Mov rcx (Offset r8 0)) | ||
(Cmp rcx (Offset rax 0)) | ||
(Jne false) | ||
(Add r10 3) ;;3 chars have been checked | ||
(Jmp loop)))) | ||
|
||
;; CEnv -> Asm | ||
;; Pad the stack to be aligned for a call with stack arguments | ||
(define (pad-stack-call c i) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,7 +100,19 @@ | |
[(Wild) (interp-env e r ds)] | ||
[(Var x) (interp-env e (ext r x v) ds)] | ||
[(Lit l) | ||
(if (eq? l v) | ||
(if (and (number? l) (number? v)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be better to expand out a mach on |
||
(if (= l v) | ||
(interp-env e r ds) | ||
(interp-match v cs r ds)) | ||
(if (equal? l v) | ||
(interp-env e r ds) | ||
(interp-match v cs r ds)))] | ||
[(String s) | ||
(if (equal? v s) | ||
(interp-env e r ds) | ||
(interp-match v cs r ds))] | ||
[(Symbol s) | ||
(if (equal? v s) | ||
(interp-env e r ds) | ||
(interp-match v cs r ds))] | ||
[(Box x) | ||
|
@@ -123,7 +135,7 @@ | |
|
||
;; Defns Symbol -> Defn | ||
(define (defns-lookup ds f) | ||
(findf (match-lambda [(Defn g _ _) (eq? f g)]) | ||
(findf (match-lambda [(Defn g _ _) (equal? f g)]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like a search/replace bug. It should remain |
||
ds)) | ||
|
||
(define (zip xs ys) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,7 @@ void error_exit() { | |
} | ||
|
||
void raise_error() { | ||
return error_handler(); | ||
return error_handler(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove space so this doesn't show up in the diff. |
||
} | ||
|
||
int main(int argc, char** argv) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s
should beString
here andSymbol
below. (It's a little weird since the name of the constructor and the type of the argument are the same, but sayings
doesn't make sense.)