Plai 5: Adding functions to languae

#lang plai-typed

(define-type ExprC
  [numC (n : number)]
  [idC (s : symbol)]
  [plusC (l : ExprC) (r : ExprC)]
  [multC (l : ExprC) (r : ExprC)]
  [appC (fun : symbol) (arg : ExprC)])

(define-type ExprS
  [numS (n : number)]
  [idS (s : symbol)]
  [plusS (l : ExprS) (r : ExprS)]
  [uminusS (e : ExprS)]
  [bminusS (l : ExprS) (r : ExprS)]
  [multS (l : ExprS) (r : ExprS)]
  [appS (fun : symbol) (arg : ExprS)])

(define (desugar [as : ExprS]) : ExprC
  (type-case ExprS as
    [numS (n) (numC n)]
    [idS (s) (idC s)]
    [plusS (l r) (plusC (desugar l) (desugar r))]
    [multS (l r) (multC (desugar l) (desugar r))]
    [uminusS (e) (desugar (multS (numS -1) e))]
    [bminusS (l r) (plusC (desugar l) (multC (numC -1) (desugar r)))]
    [appS (f a) (appC f (desugar a))]))

(define (parseS [s : s-expression]) : ExprS
  (cond
    [(s-exp-number? s) (numS (s-exp->number s))]
    [(s-exp-symbol? s) (idS (s-exp->symbol s))]
    [(s-exp-list? s)
     (let ([sl (s-exp->list s)])
       (case (s-exp->symbol (first sl))
         [(+) (plusS (parseS (second sl)) (parseS (third sl)))]
         [(*) (multS (parseS (second sl)) (parseS (third sl)))]
         [(u-) (uminusS (parseS (second sl)))]
         [(-) (bminusS (parseS (second sl)) (parseS (third sl)))]
         [else (appS (s-exp->symbol (first sl)) (parseS (second sl)))]))]
    [else (error ‘parseS "invalid input")]))

(define-type FunDefC [fdC (name : symbol) (arg : symbol) (body : ExprC)])

(define (get-fundef [n : symbol] [fds : (listof FunDefC)]) : FunDefC
  (cond
    [(empty? fds) (error ‘get-fundef "reference to undefined function")]
    [(cons? fds) (cond
                   [(equal? n (fdC-name (first fds))) (first fds)]
                   [else (get-fundef n (rest fds))])]))

(define (parse-fundef [s : s-expression]) : FunDefC
  (cond
    [(s-exp-list? s)
     (let ([sl (s-exp->list s)])
       (case (s-exp->symbol (first sl))
         [(define) (fdC (s-exp->symbol (first (s-exp->list (second sl))))
                        (s-exp->symbol (second (s-exp->list (second sl))))
                        (desugar (parseS (third sl))))]
         [else (error ‘parse-fundef "invalid list")]))]
     [else (error ‘parse-fundef "invalid input")]))

(define (subst [what : ExprC] [for : symbol] [in : ExprC]) : ExprC
  (type-case ExprC in
    [numC (n) in]
    [idC (s) (cond
               [(symbol=? s for) what]
               [else in])]
    [appC (f a) (appC f (subst what for a))]
    [plusC (l r) (plusC (subst what for l) (subst what for r))]
    [multC (l r) (multC (subst what for l) (subst what for r))]))
(define (interp [e : ExprC] [fds : (listof FunDefC)]) : number
  (type-case ExprC e
    [numC (n) n]
    [idC (_) (error ‘interpC "shouldn‘t get here")]
    [appC (f a) (local ([define fd (get-fundef f fds)])
                  (interp (subst a (fdC-arg fd) (fdC-body fd)) fds))]
    [plusC (l r) (+ (interp l fds) (interp r fds))]
    [multC (l r) (* (interp l fds) (interp r fds))]))

(define (parse [s : s-expression]) : ExprC
  (desugar (parseS s)))

(define (main [s : s-expression] [fs : (listof s-expression)]) : number
  (interp (parse s) (map parse-fundef fs)))

(define l (list `(define (f x) (+ x x)) `(define (g x) (* x 3))))

(define s1 ‘(+ (f 2) (* 2 3)))
(main s1 l)

(define s2 ‘(+ (u- (f 2)) (- (g 5) (* 2 (+ 2 4)))))
(main s2 l)

参考了知乎的这篇文章:https://zhuanlan.zhihu.com/p/20475329

时间: 2024-08-14 21:26:18

Plai 5: Adding functions to languae的相关文章

web storm使用和配置

官网:http://www.jetbrains.com/webstorm/ webStorm,File=>setting=>JavaScript-Libraries How WebStorm Works: Completion for JavaScript Libraries One of the essential features of WebStorm’s editor is code completion. The way it is implemented in WebStorm i

Adding New Functions to MySQL(User-Defined Function Interface UDF、Native Function)

catalog 1. How to Add New Functions to MySQL 2. Features of the User-Defined Function Interface 3. User-Defined Function 4. UDF Argument Processing 5. UDF Return Values and Error Handling 6. UDF Compiling and Installing 7. Adding a New Native Functio

5.24 Declaring Attributes of Functions【转】

转自:https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html 5.24 Declaring Attributes of Functions In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your

Exercise 21: Functions Can Return Something

def add(a, b): print "ADDING %d + %d" % (a, b) return a + b def subtract(a, b): print "SUBTRACTING %d - %d" % (a, b) return a - b def multiply(a, b): print "MULTIPLYING %d * %d" % (a, b) return a * b def divide(a, b): print &

Use apply to Call Functions with Different

Item 21: Use apply to Call Functions with DifferentNumbers of ArgumentsImagine that someone provides us with a function that calculates theaverage of any number of values: average(1, 2, 3); // 2 average(1); // 1 average(3, 1, 4, 1, 5, 9, 2, 6, 5); //

Analytic Functions in Oracle

Contents Overview and IntroductionHow Analytic Functions WorkThe SyntaxExamplesCalculate a running TotalTop-N Queries    Example 1    Example 2Windows    Range Windows    Compute average salary for defined range    Row Windows    Accessing Rows Aroun

Adding an On/Off switch to your Raspberry Pi

http://www.raspberry-pi-geek.com/Archive/2013/01/Adding-an-On-Off-switch-to-your-Raspberry-Pi#article_f5 Which Switch? Aaron Shaw Pulling the plug on your Pi without an orderly shutdown can corrupt the SD card. Also, many users prefer a convenient sw

POJ 1080 Human Gene Functions(LCS)

Description It is well known that a human gene can be considered as a sequence, consisting of four nucleotides, which are simply denoted by four letters, A, C, G, and T. Biologists have been interested in identifying human genes and determining their

vue报错/ style-loader: Adds some css to the DOM by adding a <style> tag

1.1.1.   vue-cli搭建的项目引入.styl/css文件报错 http://blog.csdn.net/z852064121/article/details/72660327 / style-loader: Adds some css to the DOM by adding a <style> tag webpack.base.conf.js文件下的加上黄色区域就不报错了 可以参考如下文章,http://blog.csdn.net/z852064121/article/detai