;Global Variables (define listOfOperators '(+ - * / %)) (define listOfArithmeticBooleanOperators '(< > <= >= == !=)) (define listOfLogicalBooleanOperators '(&& ||)) ;Not added to language yet (define listOfReservedWords '(if let while set block)) ;generic helper functions ;returns true if val is found in lst (define contains (lambda (val lst) (cond ((null? lst) #f) ((eq? (car lst) val) #t) (else (contains val (cdr lst)))))) ;Functions related to the variable environment (define empty-env (lambda () '())) (define empty-scope (lambda () '())) (define extend-scope (lambda (var val scope) (cons (list var val) scope))) (define extend-env (lambda (scope env) (cons scope env))) (define apply-scope (lambda (var scope) (cond ((null? scope) #f) ((eq? (caar scope) var) (cadar scope)) (else (apply-scope var (cdr scope)))))) (define apply-env (lambda (var env) (cond ((null? env) #f) (else (let ((resolved (apply-scope var (car env)))) (if (eq? resolved #f) (apply-env var (cdr env)) resolved)))))) (define extend-env-4-lambda-helper (lambda (lovars lovals scope) (cond ((not (null? lovars)) (extend-env-4-lambda-helper (cdr lovars) (cdr lovals) (extend-scope (car lovars) (car lovals) scope))) (else scope)))) (define update-scope (lambda (var val scope) (map (lambda (lst) (if (eq? (car lst) var) (list var val) lst)) scope))) (define update-env (lambda (var val env) (cond ((null? env) #F) (else (let ((currScope (car env))) (if (not (eqv? (apply-scope var currScope) #f)) (cons (update-scope var val currScope) (cdr env)) (cons currScope (update-env var val (cdr env))))))))) (define extend-env-4-lambda (lambda (lovars lovals env) (extend-env (extend-env-4-lambda-helper lovars lovals (empty-scope)) env))) (define extend-env-4-let (lambda (loexp env) (if (null? loexp) env (extend-env-4-let (cdr loexp) (extend-env-4-lambda (list (cadr (car (cdr (car loexp))))) (list (if (eq? (caadr (cdr (car loexp))) 'lambda-exp) (cadr (cdr (car loexp))) (eval-exp (cadr (cdr (car loexp))) env))) env))))) ;Constructors related to the LCE types (define lit-exp (lambda (lit) lit)) (define var-exp (lambda (id) id)) (define lambda-exp (lambda (params body) (list 'lambda params body))) (define app-exp (lambda (rator rands) (append (list rator) rands))) ;return true if the given symbol is a reserved op and false otherwise ;Parser Helper Functions ;returns true is s is an operator and false otherwise (define op? (lambda (s) (contains s listOfOperators))) ;returns true is s is an arithmetic boolean operator and false otherwise (define boolean-arithmetic-op? (lambda (s) (contains s listOfArithmeticBooleanOperators))) ;returns true is s is a reserved word and false otherwise (define reservedWord? (lambda (s) (contains s listOfReservedWords))) ;Core Parser Functions (define parse-exp (lambda (lcExp) (cond ((boolean? lcExp) (list 'bool-exp lcExp)) ((number? lcExp) (list 'lit-exp lcExp)) ((symbol? lcExp) (cond ((op? lcExp) (list 'op-exp lcExp)) ((boolean-arithmetic-op? lcExp) (list 'bool-arith-op-exp lcExp)) ((reservedWord? lcExp) (cond ((eq? lcExp 'if) (list 'if-exp)) ((eq? lcExp 'let) (list 'let-exp)) ((eq? lcExp 'set) (list 'set-exp)) ((eq? lcExp 'block) (list 'block-exp)) ((eq? lcExp 'while) (list 'while-exp)))) (else (list 'var-exp lcExp)))) ((eq? (car lcExp) 'lambda) (list 'lambda-exp (cadr lcExp) (parse-exp (caddr lcExp)))) (else (cons 'app-exp (append (list (parse-exp (car lcExp))) (map parse-exp (cdr lcExp)))))))) ;evaluates an app expression whose car is a arithmetic boolean operator (define eval-bool-arith-op-exp (lambda (appExp env) (let ((op1 (eval-exp (cadr appExp) env)) (op2 (eval-exp (caddr appExp) env)) (theOp (cadar appExp))) (cond ((eq? theOp '<) (< op1 op2)) ((eq? theOp '<=) (<= op1 op2)) ((eq? theOp '>) (> op1 op2)) ((eq? theOp '>=) (>= op1 op2)) ((eq? theOp '==) (= op1 op2)) ((eq? theOp '!=) (not(= op1 op2))))))) ;evaluates an app expression whose car is an operator (define eval-op-exp (lambda (appExp env) (let ((op1 (eval-exp (cadr appExp) env)) (op2 (eval-exp (caddr appExp) env)) (theOp (cadar appExp))) (cond ((eq? theOp '+) (+ op1 op2)) ((eq? theOp '-) (- op1 op2)) ((eq? theOp '*) (* op1 op2)) ((eq? theOp '/) (/ op1 op2)) ((eq? theOp '%) (modulo op1 op2)) (else #f))))) ;evaluates an app expression whose car is an if-exp ;(trueExp (eval-exp (cadr appExp) env)) ;(falseExp (eval-exp (caddr appExp) env))) (define eval-if-exp (lambda (appExp env) (let ((boolExp (eval-exp (car appExp) env))) (if boolExp (eval-exp (cadr appExp) env) (eval-exp (caddr appExp) env))))) (define eval-while-exp (lambda (appExp env) (let ((boolExp (eval-exp (car appExp) env))) (if boolExp (list (eval-exp (cadr appExp) env) (eval-while-exp appExp env)) #F)))) (define eval-block-exp (lambda (listOfExprs env) (if (null? listOfExprs) '() (let ((result (eval-exp (car listOfExprs) env))) (if (list? result) (eval-block-exp (cdr listOfExprs) result) (cons result (eval-block-exp (cdr listOfExprs) env))))))) ;(define anExp '(let ((a 5)) (while (!= a 0) (block (set a (- a 1)))))) (define eval-exp (lambda (lce env) (cond ((eq? (car lce) 'bool-exp) (cadr lce)) ((eq? (car lce) 'lit-exp) (cadr lce)) ((eq? (car lce) 'var-exp) (apply-env (cadr lce) env)) ((eq? (car lce) 'lambda-exp) (eval-exp (caddr lce) env)) (else (cond ((eq? (list-ref (list-ref lce 1) 0) 'lambda-exp) ;first element of app-exp is a lambda (eval-exp (list-ref (list-ref lce 1) 2) (extend-env-4-lambda (list-ref (list-ref lce 1) 1) (map (lambda (x) (if (eq? (car x) 'lambda-exp) x (eval-exp x env))) (cddr lce)) env))) ((eq? (list-ref (list-ref lce 1) 0) 'op-exp) ;first element of app-exp is a op-exp (eval-op-exp (cdr lce) env)) ((eq? (list-ref (list-ref lce 1) 0) 'bool-arith-op-exp) ;first element of app-exp is a bool-arith-op-exp (eval-bool-arith-op-exp (cdr lce) env)) ((eq? (list-ref (list-ref lce 1) 0) 'if-exp) ;first element of app-exp is an if-exp (eval-if-exp (cddr lce) env)) ((eq? (list-ref (list-ref lce 1) 0) 'set-exp) ;first element of app-exp is an set-exp (update-env (list-ref (list-ref lce 2) 1) (eval-exp (list-ref lce 3) env) env)) ((eq? (list-ref (list-ref lce 1) 0) 'block-exp) ;first element of app-exp is an block-exp (let ((listOfExprs (cdr (list-ref lce 2)))) (eval-block-exp listOfExprs env))) ((eq? (list-ref (list-ref lce 1) 0) 'while-exp) ;first element of app-exp is an while-exp (eval-while-exp (cddr lce) env)) ((eq? (list-ref (list-ref lce 1) 0) 'let-exp) ;first element of app-exp is an let-exp (eval-exp (list-ref lce 3) (extend-env-4-let (cdr (list-ref lce 2)) env))) (else ;first element of app-exp is a var-exp (let ((theLambda (eval-exp (list-ref lce 1) env)) (theInputs (map (lambda (x) (if (eq? (car x) 'lambda-exp) x (eval-exp x env))) (cddr lce)))) (eval-exp theLambda (extend-env-4-lambda (list-ref theLambda 1) theInputs env))))))))) (define run-program (lambda (lce) (eval-exp lce (empty-env)))) (define anExp '(let ((a 5) (b 4) (c 5)) (while (!= a 0) (block (a (set a (- a 1))))))) ;(define anExp '(let ((i 0)) (while (< i 5) (block i (set i (+ i 1)))))) ;(define anExp '(let ((fact (lambda (x) (if (== x 1) 1 (* x (fact (- x 1))))))) (fact 4))) ;(define anExp '((lambda (a b) (a b)) (lambda (x) (* x 2)) 5)) (parse-exp anExp) (run-program (parse-exp anExp)) ;(map (lambda (lst) (list-ref (list-ref lst 1) 1)) val) Status API Training Shop Blog About Pricing © 2015 GitHub, Inc. Terms Privacy Security Contact Help