-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpresentation.txt
106 lines (92 loc) · 3.73 KB
/
presentation.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
Outline:
Our project:
Implement case matching and pattern matching definitions
Success!
Failed attempts:
Macros
Nope, didn't work. Problems were that could only access the
code in the macro, couldn't see/access things that
were outside the macro (couldn't take car of things, etc)
This was a shame, as we had match-define, match-named-let,
match-letrec, match-let, and match-let* all mostly working, except
when we wanted to use things that were outside the macro (where it
failed)
(define-syntax match-let
(sc-macro-transformer
(lambda (exp env)
(let* ((body (cddr exp))
(dict (assign-iter (cadr exp) '())))
`(let ( ,@(map (lambda(entry)
`(,(car entry) ,(cadr entry)))
dict))
(begin ,@(map (lambda (statement)
statement)
body)))
))))
(match-let ((((? y) (? x)) ((1 2)))
(d 5))
(+ d x y))
sample-output from match-let
(let ((x 2) (y 1) (d 5))
(begin (+ d x y)))
And it output 8 if you removed the call to print. It even worked with
multi-line body in the print call.
But the problem was, it actually mutated the code to be evaluated. So
if something were defined outside of the macro, it broke, because the
macro couldn't manipulate it.
ex:
(define failList '((1 2) 3))
(match-letrec ((((? y) (? x)) (car failList)))
(+ x y))
We get the error "Unbound variable: y" because we can't match (even
though y should match 1 and x should match 2, we can't because the
macro can't lookup what failList actually is.
Environment problems
1) Generate the string and eval it (needed access
to env, didn't have it)
2) directly writing definitions to the environment (again,
needed access to the environment).
We tried numerous hacks to try to get the environment,
including
making our own and trying to pass it around, but it didn't work.
Because of compiler optimizations, scheme only lets you get the
top level environment. Our approach required us to get the
current environment (and the parent), which you can't do.
REPL
We wrote our own repl. It worked pretty well, except that it
didn't know how to handle quasi-quote, so we couldn't do
predicates (if you remember from pset 4, our matcher would
allow conditions of the form: `(? x ,number?) where we require
the match to x to be a number. Our repl couldn't do
quasi-quotes, so we couldn't do this. It did, however, allow
us to solve our previous environment definition problems,
and otherwise worked quite well. If we wanted to drop
predicate functionality, it would have been fine.
ex:
(define (parse-token token)
(match-case token
((bin-op (? op) (? a1) (? a2)) (op a1 a2))
((un-op (? op) (? a)) (op a))
((?? a) (pp a))))
(parse-token '(bin-op + 1 3)) ;4
(parse-token '(un-op - 4)) ; -4
(parse-token '(+ 1 2)) ;((+ 1 2)) #!unspecific
(parse-token '(goto 0x3453))
;((goto 0x3453))
;#!unspecific
(parse-token '(2 3 4 5))
;((2 3 4 5))
;#!unspecific
But if we try to add in predicates, we got the error:
";Variable reference to a syntactic keyword: quasiquote"
Successful attempt:
At this point, you may be saying: well, the quasi-quote
problem shouldn't be that hard, why didn't you just fix it?
And we could have, but a) that looked hard, and b) we had
another idea of how to do case matching in the actual scheme
repl, not our own one, so we went back to the original scheme
repl.
Fill in more on the last attempt once we actually finish it.
Match-let works. Top-level match-define works. For non-top-level
match-defines, just use match-let (they're functionally the
same thing anyway).