University stuff.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

oppgave.scm 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. (load "evaluator.scm")
  2. (set! the-global-environment (setup-environment))
  3. ;;;;;;;
  4. ;; 1 ;;
  5. ;;;;;;;
  6. ;; a
  7. ;; (foo 2 square)
  8. ;; -> 0
  9. ;; foo er en funksjon som tar to argumenter.
  10. ;; Hvis det første argumentet er 2, returnerer den 0.
  11. ;; Det første argumentet er her 2.
  12. ;; (foo 4 square)
  13. ;; -> 16
  14. ;; Hvis det første argumentet til foo ikke er 2,
  15. ;; kjører den funksjonen gitt som det andre argumentet
  16. ;; med det første argumentet og returnerer resultatet.
  17. ;; (cond ((= cond 2) 0) (else (else 4)))
  18. ;; -> 2
  19. ;; I mc-eval sjekker vi om uttrykket er en special form før vi sjekker
  20. ;; om det er et funksjonskall ("application"). Siden uttrykket starter med
  21. ;; symbolet cond, blir det tolket som en special form, og ikke et kall på
  22. ;; variabelen som heter cond.
  23. ;;
  24. ;; I ((= cond 2) 0) blir cond brukt som en variabel, siden vi vet at det
  25. ;; ikke er en special form (lista den er i starter med '=, ikke 'cond).
  26. ;; Siden cond er satt til 3, og 3 != 2, fortsetter vi til else-grenen
  27. ;; (cond ser ikke etter et funksjonskall her - `((else` hadde blitt tolket
  28. ;; som et funksjonskall, mens `(else` blir tolket som else-grenen).
  29. ;; I else-grenen er kallet på funksjonen else, med 4 som argument.
  30. ;; Siden else-funksjonen deler tallet på seg selv, returneres 4 / 2, eller 2.
  31. ;;;;;;;
  32. ;; 2 ;;
  33. ;;;;;;;
  34. ;; a
  35. (define-variable! '1+
  36. (list 'primitive
  37. (lambda (num) (+ num 1)))
  38. the-global-environment)
  39. (define-variable! '1-
  40. (list 'primitive
  41. (lambda (num) (- num 1)))
  42. the-global-environment)
  43. ;; b
  44. (define (install-primitive! name proc)
  45. (define-variable! name
  46. (list 'primitive proc)
  47. the-global-environment))
  48. (install-primitive! 'square (lambda (x) (* x x)))
  49. ;;;;;;;
  50. ;; 3 ;;
  51. ;;;;;;;
  52. ;; Legger modifikasjoner som er nødvendig for deloppgavene her
  53. ;; Jeg har valgt å ikke modifisere evaluator.scm, og heller
  54. ;; redefinere de prosedyrene som må endres.
  55. ;; Modifisert special-form? fra evaluator.scm
  56. (define (special-form? exp)
  57. (cond ((quoted? exp) #t)
  58. ((assignment? exp) #t)
  59. ((definition? exp) #t)
  60. ((if? exp) #t)
  61. ((lambda? exp) #t)
  62. ((begin? exp) #t)
  63. ((cond? exp) #t)
  64. ((and? exp) #t)
  65. ((or? exp) #t)
  66. ((let? exp) #t)
  67. ((while? exp) #t)
  68. (else #f)))
  69. ;; Modifisert eval-special-form fra evaluator.scm
  70. (define (eval-special-form exp env)
  71. (cond ((quoted? exp) (text-of-quotation exp))
  72. ((assignment? exp) (eval-assignment exp env))
  73. ((definition? exp) (eval-definition exp env))
  74. ((if? exp) (eval-if exp env))
  75. ((lambda? exp)
  76. (make-procedure (lambda-parameters exp)
  77. (lambda-body exp)
  78. env))
  79. ((begin? exp)
  80. (eval-sequence (begin-actions exp) env))
  81. ((cond? exp) (mc-eval (cond->if exp) env))
  82. ((or? exp) (eval-or exp env))
  83. ((and? exp) (eval-and exp env))
  84. ((let? exp) (eval-let exp env))
  85. ((while? exp) (eval-while exp env))))
  86. ;; a
  87. (define (and? exp)
  88. (tagged-list? exp 'and))
  89. (define (or? exp)
  90. (tagged-list? exp 'or))
  91. (define (eval-and exp env)
  92. (define (iter exps)
  93. (cond ((null? exps) #t)
  94. ((null? (cdr exps)) (mc-eval (car exps) env))
  95. ((false? (mc-eval (car exps) env)) #f)
  96. (else (iter (cdr exps)))))
  97. (iter (cdr exp)))
  98. (define (eval-or exp env)
  99. (define (iter exps)
  100. (cond ((null? exps) #f)
  101. (else
  102. (let ((res (mc-eval (car exps) env)))
  103. (if (true? res)
  104. res
  105. (iter (cdr exps)))))))
  106. (iter (cdr exp)))
  107. ;; b
  108. ;; Modifisert eval-if fra evaluator.scm
  109. (define (eval-if exp env)
  110. (define (tag exps) (car exps))
  111. (define (if-pred exps) (cadr exps))
  112. (define (if-then exps) (caddr exps))
  113. (define (if-conseq exps) (cadddr exps))
  114. (define (if-next exps) (cddddr exps))
  115. (define (else-conseq exps) (cadr exps))
  116. (define (iter-find-else exps)
  117. (cond ((null? exps) #f)
  118. ((eq? (tag exps) 'else) #t)
  119. (else (iter-find-else (if-next exps)))))
  120. (define (iter exps)
  121. (cond ((null? exps) #f)
  122. ((or (eq? (tag exps) 'if)
  123. (eq? (tag exps) 'elsif))
  124. (let ((pred (if-pred exps))
  125. (conseq (if-conseq exps)))
  126. (if (eq? 'then (if-then exps))
  127. (if (true? (mc-eval pred env))
  128. (mc-eval conseq env)
  129. (iter (if-next exps)))
  130. (error "Expected 'then', got:" (if-then exps)))))
  131. ((eq? (tag exps) 'else)
  132. (mc-eval (else-conseq exps) env))
  133. (else (error "Expected 'if', 'elsif', or 'else', got:" (tag exps)))))
  134. (if (iter-find-else exp)
  135. (iter exp)
  136. (error "Expected 'else' branch in if")))
  137. ;; c
  138. (define (let? exp)
  139. (tagged-list? exp 'let))
  140. (define (let->lambda exp)
  141. (define (get-param-names params)
  142. (if (null? params)
  143. '()
  144. (cons (caar params) (get-param-names (cdr params)))))
  145. (let ((names (get-param-names (cadr exp)))
  146. (body (cddr exp)))
  147. (make-lambda names body)))
  148. (define (eval-let exp env)
  149. (define (get-param-vals params)
  150. (if (null? params)
  151. '()
  152. (cons (mc-eval (cadar params) env)
  153. (get-param-vals (cdr params)))))
  154. (let ((vals (get-param-vals (cadr exp))))
  155. (mc-apply (mc-eval (let->lambda exp) env)
  156. vals)))
  157. ;; d
  158. ;; Dette overskriver let fra oppgave c, kommenter ut for å bekrefte
  159. ;; at oppgave c virker.
  160. (define (eval-let exp env)
  161. (define (let-name exps) (car exps))
  162. (define (let-equals exps) (cadr exps))
  163. (define (let-val exps) (caddr exps))
  164. (define (let-action exps) (cadddr exps))
  165. (define (let-next exps) (cddddr exps))
  166. (define names '())
  167. (define vals '())
  168. (define body '())
  169. (define (parse exps)
  170. (if (eq? (let-equals exps) '=)
  171. (begin
  172. (set! names (cons (let-name exps) names))
  173. (set! vals (cons (mc-eval (let-val exps) env)
  174. vals))
  175. (cond ((eq? (let-action exps) 'and)
  176. (parse (let-next exps)))
  177. ((eq? (let-action exps) 'in)
  178. (set! body (let-next exps)))
  179. (else (error "Expected 'and' or 'in', got:" (let-action exps)))))
  180. (error "Expected '=', got:" (let-equals exps))))
  181. (parse (cdr exp))
  182. (let ((names names)
  183. (vals vals)
  184. (body body))
  185. (mc-apply (mc-eval (make-lambda names body) env)
  186. vals)))
  187. ;; e
  188. ;; Eksempel: (while (= 1 1) (display "hello") (newline))
  189. ;; eller:
  190. ;; (define i 0)
  191. ;; (while (not (= i 10))
  192. ;; (display "i is ")
  193. ;; (display i)
  194. ;; (newline)
  195. ;; (set! i (+ i 1)))
  196. (define (while? exp)
  197. (tagged-list? exp 'while))
  198. (define (eval-while exp env)
  199. (define pred (cadr exp))
  200. (define body (mc-eval (make-lambda '() (cddr exp)) env))
  201. (define (iter)
  202. (if (mc-eval pred env)
  203. (begin
  204. (mc-apply body '())
  205. (iter))))
  206. (iter))
  207. (read-eval-print-loop)