Question
PLAI HW (&DrRacket) I. Functions with Multiple Arguments Start with the FWAE interpreter, and extend the implementation to support any number of arguments to a
PLAI HW (&DrRacket)
I. Functions with Multiple Arguments Start with the FWAE interpreter, and extend the implementation to support any number of arguments to a function (including zero), and any number of arguments (including zero) in a function application:
Adding Records Extend your interpreter to support the construction of records with named fields, and to support field selection from a record:
My code so far(Needs modification, please help me):
#lang plai (require (for-syntax racket/base) racket/match racket/list racket/string (only-in mzlib/string read-from-string-all))
;build a regexp that matches restricted character expressions, can use only ;{}s for lists, and limited strings that use '...' (normal racket escapes ;like , and '' for a single ') (define good-char "(?:[ \t a-zA-Z0-9_{}!?*/<=>:+-]|[.][.][.])") ;this would make it awkward for students to use \" for strings ;(define good-string "\"[^\"\\]*(?:\\\\.[^\"\\]*)*\"") (define good-string "[^\"\\']*(?:''[^\"\\']*)*") (define expr-re (regexp (string-append "^" good-char"*" "(?:'"good-string"'"good-char"*)*" "$"))) (define string-re (regexp (string-append "'("good-string")'")))
(define (string->sexpr str) (unless (string? str) (error 'string->sexpr "expects argument of type
;; FWAE abstract syntax trees (define-type FWAE [num (n number?)] [id (name symbol?)] [add (left FWAE?)(right FWAE?)] [sub (left FWAE?)(right FWAE?)] [with (name id?)(named-expr FWAE?)(body FWAE?)] [fun (param FWAE?) (body FWAE?)] [app (fun-expr FWAE?) (arg-expr FWAE?)] [record (name id?)(expr FWAE?)] [getField (expr FWAE?)(name id?)])
(define-type DefrdSub [mtSub] [aSub (name symbol?) (value FWAE-Value?) (ds DefrdSub?)])
(define-type FWAE-Value [numV (n number?)] [closureV (param list?) (body FWAE?) (ds DefrdSub?)])
; lookup: symbol DefrdSub -> FWAE-Value (define (lookup name ds) (type-case DefrdSub ds [mtSub () (error 'lookup "no binding for identifier ~a" name)] [aSub (bound-name bound-value rest-ds) (if (symbol=? bound-name name) bound-value (lookup name rest-ds))]))
;; parse: S-exp --> FWAE ;; ;; Converts S-expressions into FWAEs. We use infix notation just ;; for fun. Parsing infix can look a little bit tricky, sorry for ;; this. (define (parse-sexpr sexp) (match sexp [(? number?) (num sexp)] [(? symbol?) (id sexp)] [(list '+ l r) (add (parse-sexpr l)(parse-sexpr r))] [(list '- l r) (sub (parse-sexpr l)(parse-sexpr r))] [(list 'with (list x i) b) (with x (parse-sexpr i) (parse-sexpr b))] [(list 'fun p b) (fun p (parse-sexpr b))] [(list 'app f a) (app (parse-sexpr f) (map parse-sexpr a))] [else (error 'parse "bad syntax: ~a" sexp)] ))
(define (parse string) (parse-sexpr (string->sexpr string)))
; add-numbers: numV numV -> numV ; ; Helper function for adding numbers. (define (add-numbers x y) (numV (+ (numV-n x) (numV-n y)))) (define (sub-numbers x y) (numV (- (numV-n x) (numV-n y))))
;;update-env: (listof symbols) (listof FWAE) DefrdSub -> DefrdSub ;; ;;Helper function to match function's formal parameter list with ;;actual parameters, resulting in an environment. (define (update-env formal-params actual-params ds) (cond [(not (equal? (length formal-params) (length actual-params))) (error 'interp "formal parameter length (~a) is not equal to actual parameter length (~a)" (length formal-params) (length actual-params))] [(empty? formal-params) ds] (else (aSub (first formal-params) (first actual-params) (update-env (rest formal-params) (rest actual-params) ds)))))
;; interp : FWAE DefrdSub ? FWAE ;; evaluates FWAE expressions by reducing them to their corresponding values ;; return values are either num or fun (define (interp expr [ds (mtSub)]) (type-case FWAE expr [num (n) (numV n)] [add (l r) (add-numbers (interp l ds) (interp r ds))] [sub (l r) (sub-numbers (interp l ds) (interp r ds))] [id (v) (lookup v ds)] [fun (bound-id bound-body) (closureV bound-id bound-body ds)] [app (fun-expr arg-expr) (local ([define fun-val (interp fun-expr ds)]) (interp (closureV-body fun-val) (update-env (closureV-param fun-val) (map (lambda (x) (interp x ds)) arg-expr) (closureV-ds fun-val))) )] [else (error 'interp "undifined AST: ~a" expr)]))
(define (run string) (interp (parse string)))
(test (run "{fun {a} {+ a 3} 1}") (numV 4))
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started