728x90
728x90
#lang racket (provide (all-defined-out)) ;; exports the defined variables in this file. ;; definition of structures for MUPL programs - Do NOT change (struct var (string) #:transparent) ;; a variable, e.g., (var "foo") (struct int (num) #:transparent) ;; a constant number, e.g., (int 17) (struct add (e1 e2) #:transparent) ;; add two expressions (struct ifgreater (e1 e2 e3 e4) #:transparent) ;; if e1 > e2 then e3 else e4 (struct fun (nameopt formal body) #:transparent) ;; a recursive(?) 1-argument function (struct call (funexp actual) #:transparent) ;; function call (struct mlet (var e body) #:transparent) ;; a local binding (let var = e in body) (struct apair (e1 e2) #:transparent) ;; make a new pair (struct fst (e) #:transparent) ;; get first part of a pair (struct snd (e) #:transparent) ;; get second part of a pair (struct aunit () #:transparent) ;; unit value -- good for ending a list (struct isaunit (e) #:transparent) ;; evaluate to 1 if e is unit else 0 ;; a closure is not in "source" programs; it is what functions evaluate to (struct closure (env fun) #:transparent) ;; Problem 1 ;; CHANGE (put your solutions here) (define (racketlist->mupllist l) (cond [(null? l) (aunit)] [(pair? l) (apair (car l) (racketlist->mupllist (cdr l)))])) (define (mupllist->racketlist l) (cond [(aunit? l) null] [(apair? l) (cons (apair-e1 l) (mupllist->racketlist (apair-e2 l)))])) ;; Problem 2 ;; lookup a variable in an environment ;; Do NOT change this function (define (envlookup env str) (cond [(null? env) (error "unbound variable during evaluation" str)] [(equal? (car (car env)) str) (cdr (car env))] [#t (envlookup (cdr env) str)])) ;; Do NOT change the two cases given to you. ;; DO add more cases for other kinds of MUPL expressions. ;; We will test eval-under-env by calling it directly even though ;; "in real life" it would be a helper function of eval-exp. (define (eval-under-env e env) (cond [(var? e) (envlookup env (var-string e))] [(add? e) (let ([v1 (eval-under-env (add-e1 e) env)] [v2 (eval-under-env (add-e2 e) env)]) (if (and (int? v1) (int? v2)) (int (+ (int-num v1) (int-num v2))) (error "MUPL addition applied to non-number")))] ;; CHANGE add more cases here [(int? e) e] [(fun? e) (closure env e)] [(ifgreater? e) (letrec ([v1 (eval-under-env (ifgreater-e1 e) env)] [v2 (eval-under-env (ifgreater-e2 e) env)]) (if (and (int? v1) (int? v2)) (if (> (int-num v1) (int-num v2)) (eval-under-env (ifgreater-e3 e) env) (eval-under-env (ifgreater-e4 e) env)) (error "MUPL ifgreater applied to non-number")))] [(mlet? e) (let ([v (eval-under-env (mlet-e e) env)]) (eval-under-env (mlet-body e) (append (list (cons (mlet-var e) v)) env)))] [(call? e) (let ([v1 (eval-under-env (call-funexp e) env)] [v2 (eval-under-env (call-actual e) env)]) (if (closure? v1) (eval-under-env (fun-body (closure-fun v1)) (append (closure-env v1) (list (cons (fun-formal (closure-fun v1)) v2) (if (fun-nameopt (closure-fun v1)) (cons (fun-nameopt (closure-fun v1)) v1) '())))) (error "MUPL can't call a function that is non-closure")))] [(closure? e) e] [(apair? e) (letrec( [v1 (eval-under-env (apair-e1 e) env)] [v2 (eval-under-env (apair-e2 e) env)]) (apair v1 v2))] [(fst? e) (letrec ([v (eval-under-env (fst-e e) env)]) ( if (apair? v) (apair-e1 v) (error "fst applied to non-apair")))] [(snd? e) (letrec ([v (eval-under-env (snd-e e) env)]) (if (apair? v) (apair-e2 v) (error "snd applied to non_apair")))] [(isaunit? e) (letrec( [v (eval-under-env (isaunit-e e) env)]) (if (aunit? v) (int 1) (int 0)))] [(aunit? e) e] [#t (error (format "bad MUPL expression: ~v" e))])) ;; Do NOT change (define (eval-exp e) (eval-under-env e null)) ;; Problem 3 (define (ifaunit e1 e2 e3) (ifgreater (isaunit e1) (int 0) e2 e3)) (define (mlet* list e2) (if (null? list) e2 (mlet (car (car list)) (cdr (car list)) (mlet* (cdr list) e2)))) (define (ifeq e1 e2 e3 e4) (mlet* (list (cons "_x" e1) (cons "_y" e2)) (ifgreater (var "_x") (var "_y") e4 (ifgreater (var "_y") (var "_x") e4 e3)))) ;; Problem 4 (define mupl-map (fun "mupl-map-func" "func" (fun "mupl-map-list" "list" (ifaunit (var "list") (aunit) (apair (call (var "func") (fst (var "list"))) (call (var "mupl-map-list") (snd (var "list")))))))) (define mupl-mapAddN (mlet "map" mupl-map (fun "mupl-mapAddN-int" "i" (call (var "map") (fun "add-i" "x" (add (var "x") (var "i"))))))) (struct fun-challenge (nameopt formal body freevars) #:transparent) ;; a recursive(?) 1-argument function ;; We will test this function directly, so it must do ;; as described in the assignment (define (compute-free-vars e) "CHANGE") ;; Do NOT share code with eval-under-env because that will make grading ;; more difficult, so copy most of your interpreter here and make minor changes (define (eval-under-env-c e env) "CHANGE") ;; Do NOT change this (define (eval-exp-c e) (eval-under-env-c (compute-free-vars e) null)) (struct glet (var e body) #:transparent) ;; a global binding that overrides any local binding (let var = e in body) (struct num-array (size) #:transparent) ;; a number array (initialized to zeroes), e.g., (num-array 10) ;; e.g. (num-array 4) (struct num-array-at (e1 e2) #:transparent) ;; e1 evaluates to num-array and e2 evaluates to racket int (index of the value to access) index starts from 0 ;; (num-array-at (num-array 4) 3) ;; (num-array-at (num-array 4) 4) ; this should give a nice error message (like "array access out of bound") ;; (num-array-at (num-array 4) -1) ; this should give a nice error message (like "array access out of bound") (struct num-array-set (e1 e2 e3) #:transparent) ;; e1 evaluates to num-array-var, e2 evaluates to racket int (index of the value to access), and e3 evaluates to a MUPL int ;; (num-array-set (num-array 4) 0 (int 42)) ;; (num-array-set (num-array 4) 5 (int 42)) ; this should give a nice error message (like "array access out of bound") ;; (num-array-set (num-array 4) -1 (int 42)) ; this should give a nice error message (like "array access out of bound") (define (num-array-object? v) ;; hackish implementation of testing num-array object. We assume that if a value is mpair, it is a num-array object. (mpair? v)) (define (array-length array) (if (eq? (mcdr array) null) 1 (+ 1 (array-length (mcdr array))))) (define (make-array-object length) (if (= length 0) null (mcons (int 0) (make-array-object (- length 1))))) (define (set-array-val array index val) (if (= index 0) (set-mcar! array val) (set-array-val (mcdr array) (- index 1) val)))
728x90
728x90
'Computer Science > Programming Language' 카테고리의 다른 글
[프로그래밍 언어/ Racket] check_bst.rkt , apply.rkt, equals.rkt - Programming Language (0) | 2020.06.30 |
---|---|
[프로그래밍언어/ML] ML Modules - 컴도리돌이 (0) | 2020.06.16 |
[프로그래밍 언어론/ ML] Nested Patterns Exceptions tail Recursion -컴도리돌이 (0) | 2020.06.15 |
[프로그래밍 언어/ ML] Records, Datatypes, Case Expressions and more - 컴도리돌이 (0) | 2020.06.15 |
[프로그래밍언어/ML] pairs, lists, local bindings, benefit of no mutation - 컴도리돌이 (0) | 2020.06.15 |