事先道歉,因为这里会有一大块代码。我将首先发布代码,然后是问题。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; UTILITY FUNCTIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Converts a scheme-expression into a string
;; INPUT: a scheme-expression EXP
;; OUTPUT: a SCHEME String corresponding to EXP
(define (exp->string exp)
(cond ((number? exp) (number->string exp))
((symbol? exp) (symbol->string exp))
((list? exp) (exp->string (car exp)))))
;; INPUT: a list of lists
;; OUTPUT: a list containing all elements of the first-level lists
(define (flatten list-of-lists)
(cond ((null? list-of-lists) '())
(else (append (car list-of-lists) (flatten (cdr list-of-lists))))))
;; this is for all error handling.
;; programmers don't use this function but
;; the interpreter calls this function to
;; signal some type of programmer error
(define (error msg)
(display "ERROR: ")
(display msg)
(newline))
;; THERE ARE TWO SUPPORTED TYPES: 'int and 'boolean
;; INPUT: an element of the ART-C language
;; OUTPUT: the type of that element
(define (type-of val)
(cond ((number? val) 'int)
((boolean? val) 'boolean)))
;; A MAP is a list of key-value pairs
;; INPUT: a MAP and a KEY
;; OUTPUT: The value associated with the key or 'error
(define (map-get map x)
(cond ((null? map) 'error)
((equal? (car (car map)) x) (cadr (car map)))
(else (map-get (cdr map) x))))
;; INPUT : A MAP AND KEY
;; OUTPUT : true if the key is in the map and false otherwise
(define (map-contains map x)
(cond ((null? map) #f)
((equal? (car (car map)) x) #t)
(else (map-contains (cdr map) x))))
;; INPUT : A MAP, KEY and VALUE
;; OUTPUT: The map that results from replacing the key with the new value. If
;; the map doesn't contain KEY, then 'error is returned
(define (map-replace map key val)
(cond ((null? map) 'error)
((equal? (car (car map)) key)
(cons (list key val) (cdr map)))
(else
(cons (car map) (map-replace (cdr map) key val)))))
;; INPUT : A MAP, Key and Value
;; OUTPUT : The map that results from adding a key-value pair. This
;; allows for duplicate keys (the most-recently added is nearer the front of the list
(define (map-add map key val)
(cons (list key val) map))
;; INPUT: A MAP and KEY
;; OUTPUT: The map that results from deleting the key. No errors occur if the map
;; doesn't contain the key
(define (map-delete map key)
(cond ((null? map) map)
((equal? (car (car map)) key) (cdr map))
(else (cons (car map)
(map-delete (cdr map) key)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; TYPEMAP : A SEMANTIC DOMAIN DATA TYPE
;; A typemap is a list of block-level declarations.
;; FORM: ((var1 type1) (var2 type2) (var3 type3) ... )
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; INPUT: NONE
;; OUTPUT: AN empty typemap
(define (typemap-create-empty) '())
;; INPUT: A TYPEMAP
;; OUTPUT: The type of variable x
(define (typemap-type-of tm x)
(map-get tm x))
;; INPUT: A TYPEMAP
;; OUTPUT: THE TYPEMAP THAT RESULTS FROM INSERTING A DECLARATIONS
(define (typemap-add tm decl)
(map-add tm (car decl) (cadr decl)))
(define (typemap-delete tm key)
(map-delete tm key))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; STATE : A SEMANTIC DOMAIN DATA TYPE
;; A LIST OF (VAR, VALUE) pairs
;; FORM : ( (var1 val1) (var2 val2) ... )
;; NOTE: A map can contain duplicate keys but innermost KEYS occur
;; before outermost KEYS and hide them
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; INPUT : NONE
;; OUTPUT: AN EMPTY STATE
(define (state-create-empty) '())
;; INPUT: STATE and ID
;; OUTPUT: a new state such that the innermost scope now contains a
;; new binding for the specified ID. The bindings value is 'undefined.
(define (state-add state id)
(map-add state id 'undefined))
;; INPUT : STATE and ID
;; OUTPUT: A new state such that the innermost id is removed
(define (state-delete state id)
(map-delete state id))
;; INPUT: STATE and ID
;; OUTPUT: The value associated with the specified ID in the given state
(define (state-get-value state id)
(map-get state id))
;; INPUT: STATE and ID
;; OUTPUT: A new state that results from changing the mapping from id->value in
;; the specified state
(define (state-update state id value)
(map-replace state id value))
;; INPUT: STATE and LIST-OF-IDS (VARIABLES)
;; OUTPUT: A new state that results from deleting all ids (the variables) from
;; the specified state
(define (state-delete-all state variables)
(cond ((null? variables) state)
(else (state-delete-all (state-delete state (car variables)) (cdr variables)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; THESE CLASSES CORRESPOND TO THE ABSTRACT SYNTAX SUCH THAT A "PROGRAM"
;; REPRESENTS A PARSE-TREE. THESE FUNCTIONS OPERATE AT THE 'SYNTACTIC' LEVEL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (PROGRAM BODY)
(define (program-get-body stmt)
(cadr stmt))
;; (BLOCK S1...SN)
(define (block-get-body stmt)
(filter (lambda (x) (not (is-declaration? x))) (cdr stmt)))
(define (block-get-declarations stmt)
(filter (lambda (x) (is-declaration? x)) (cdr stmt)))
;; (DECLARE TYPE VAR)
(define (declaration-get-type stmt)
(cadr stmt))
(define (declaration-get-var stmt)
(caddr stmt))
(define (is-declaration? stmt)
(and (list? stmt)
(equal? (car stmt) 'declare)))
;; (:= VAR EXP)
(define (assignment-get-var stmt)
(cadr stmt))
(define (assignment-get-exp stmt)
(caddr stmt))
;; (IF TEST THEN [ELSE])
(define (if-get-test stmt)
(cadr stmt))
(define (if-get-then stmt)
(caddr stmt))
(define (if-has-else? stmt)
(= (length stmt) 4))
(define (if-get-else stmt)
(cadddr stmt))
;; (WHILE TEST BODY)
(define (while-get-test stmt)
(cadr stmt))
(define (while-get-body stmt)
(caddr stmt))
;; (SPRINT LABEL EXP)
(define (sprint-has-exp? stmt)
(and (list? stmt)
(= (length stmt) 3)))
(define (sprint-get-label? stmt)
(cadr stmt))
(define (sprint-get-exp stmt)
(caddr stmt))
;; INPUT: an expression EXP
;; OUTPUT: the operator of EXP (an element of ART-C)
(define (exp-get-operator exp)
(car exp))
;; INPUT: an expression EXP
;; OUTPUT: the left-operand (an expression) of EXP
(define (exp-get-left-operand exp)
(car (cdr exp)))
;; INPUT: an expression EXP
;; OUTPUT: the exp-get-right-operand (an expression) of EXP
(define (exp-get-right-operand exp)
(car (cdr (cdr exp))))
;; INPUT: an expression EXP
;; OUTPUT: #t if the expression is a boolean literal and #f otherwise
(define (bool? exp)
(or (equal? exp 'true)
(equal? exp 'false)))
;; INPUT: a symbol
;; OUTPUT: #t if the symbol is 'true and #f if it is 'false and 'void' if neither
(define (symbol->bool sym)
(cond ((equal? sym 'true) #t)
((equal? sym 'false) #f)))
;; INPUT: A PROGRAM
;; A PROGRAM has syntactic structure (program stmt)
;; OUTPUT: THE STATE that results from executing the program
;; in an empty state.
(define (interpret-program pgm)
(interpret (program-get-body pgm) (state-create-empty)))在这个任务中,我们被赋予了函数库作为起点,我只是在所有代码之后有一些理解问题。使用这个函数库,我们的任务是在以下解释函数中实现这些函数:
(define (interpret stmt state)
(display stmt) (newline) (display state) (newline)
(let ((kind (car stmt)))
(cond ((equal? kind 'block) (interpret-block stmt state))
((equal? kind 'declare) (interpret-declaration stmt state))
((equal? kind ':=) (interpret-assignment stmt state))
((equal? kind 'if) (interpret-if stmt state))
((equal? kind 'sprint) (interpret-sprint stmt state))
((equal? kind 'while) (interpret-while stmt state))
(else (error (string-append "statement expected but saw (" (exp->string stmt) "...) instead."))))))我目前正在研究解释块函数,但我没有完全了解这个函数的用途或如何实现它。在我看来,解释块只用于调用interpert-声明、解释-赋值等等,但这难道不是解释在做什么吗?所以我想我要问的是,解释块应该实现什么?
下面我已经包含了一个示例程序,这段代码是用来解释的。
(define pgm '(program
(block
(declare int n)
(declare boolean error)
(declare int result)
(:= error false)
(:= result 1)
(block
(declare int local)
(:= n 5)
(:= local n)
(while (> local 0)
(block
(:= result (* result local))
(:= local (- local 1)))))
(sprint "result: " result)
(if (! error) (sprint "a") (sprint "b")))))发布于 2018-03-14 23:50:31
这是有区别的:
intepret解释一个表达式。interpret-block在一个块表达式中接受几个语句,并在每个表达式上使用interpret。interpret将根据表达式的类型做“正确的事情”,比如调用interpret-declaration。interpret-block将在状态处理中扮演重要角色。例如:declare将返回一个新的状态,接下来的语句需要作为参数。我想所有对interpret的调用都会得到一个状态返回,而在interpret-block中,总是会返回传递的状态回显,以清除新绑定。
发布于 2018-03-14 23:16:11
在不详细阅读所有代码(或赋值)的情况下,我可以告诉您:是的,您的解释块函数将调用其他函数:解释-分配、赋值-声明等。解释块函数将需要以对您的语言有意义的方式组合这些函数的结果。
看起来您的语言都是关于状态及其操作的,所以我猜这些函数的结果将包含有关机器状态的信息,我可以看到状态被用作这些函数的参数。
你需要思考国家需要代表什么。我建议制定一个数据定义(在如何设计程序意义上)。
https://stackoverflow.com/questions/49288967
复制相似问题