123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- #lang racket
- (require racket/match)
- (require racket/include)
- (require "parser.scm")
- ;; NOTE: lots of bugs in this: i8 fixes them
- ;;; data
- ;;
- (define (print s) (display s) (newline))
- (define builtins^
- `((cons . cons)
- ;;
- (print . print)))
- (define builtins
- `((cons . ,cons)
- (print . ,print)))
- (define specials '(lambda))
- (struct special ((id #:mutable) (metadata #:mutable)) #:transparent)
- ;;; resolve
- ;;
- (define (resolve-prg prg env^ spec)
- (if (null? prg)
- '()
- (match (car prg)
- (`(,(sid define meta) ,name ,source)
- (cons `(,(sid define meta) ,name ,(resolve-exp source env^ spec))
- (resolve-prg (cdr prg) env^ spec))))))
- (define (resolve-exp exp env^ spec)
- (cond ((or (number? exp) (boolean? exp) (string? exp)) exp)
- ((sid? exp)
- ;;
- ;; we see a variable
- ;; ensure that it is bound
- ;; and freshen it with a gensym if so
- ;;
- (cond ((assoc (sid-id exp) env^) => (lambda (i) (sid (cdr i) (sid-metadata exp))))
- (else (error "unbound variable" exp))))
- ((list? exp)
- (if (and (sid? (car exp)) (member (sid-id (car exp)) spec))
- (resolve-special exp env^ spec)
- (map (lambda (i) (resolve-exp i env^ spec)) exp)))
- (else (error "syntax error" exp))))
- (define (resolve-special exp env^ spec)
- (match exp
- (`(,(sid 'lambda m1) (,(sid x m2)) ,b)
- (let ((x^ (gensym x)))
- `(,(special 'lambda m1)
- (,x^)
- ,(resolve-exp b (cons (cons x x^) env^)
- (remove x spec)))))
- (else (error "invalid syntax" exp))))
- ;;; interpret
- ;;
- (define (interpret-prg prg env)
- (if (null? prg)
- #t
- (match (car prg)
- (`(,(sid define meta) ,name ,exp)
- (let ((value (interpret-exp exp env)))
- (interpret-prg (cdr prg)
- (cons (cons name value) env)))))))
- (define (interpret-exp exp env)
- (cond ((or (number? exp) (boolean? exp) (string? exp)) exp)
- ((sid? exp) (cdr (assoc (sid-id exp) env)))
- ((list? exp)
- (if (special? (car exp))
- (interpret-special exp env)
- (apply (interpret-exp (car exp) env)
- (map (lambda (i) (interpret-exp i env)) (cdr exp)))))
- (else (error "?" exp))))
- (define (interpret-special exp env)
- (match exp
- (`(,(special 'lambda meta) (,x) ,b)
- (lambda (x^)
- (interpret-exp b (cons x x^) env)))
- ))
- ;;; main
- ;;
- (define (check filename)
- (resolve-prg (parse-file filename) builtins^ specials))
- (define (go filename)
- (interpret-prg
- (resolve-prg (parse-file filename) builtins^ specials)
- builtins))
|