;;; -*-scheme-*- ;;; Mes --- Maxwell Equations of Software ;;; Copyright © 2016 Jan Nieuwenhuizen ;;; ;;; mes.mes: This file is part of Mes. ;;; ;;; Mes is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; Mes is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with Mes. If not, see . ;; The Maxwell Equations of Software -- John McCarthy page 13 ;; http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf ;; (define (caar x) (car (car x))) ;; (define (cadr x) (car (cdr x))) ;; (define (cdar x) (cdr (car x))) ;; (define (cddr x) (cdr (cdr x))) ;; (define (caadr x) (car (car (cdr x)))) ;; (define (caddr x) (car (cdr (cdr x)))) ;; (define (cddar x) (cdr (cdr (car x)))) ;; (define (cdadr x) (cdr (car (cdr x)))) ;; (define (cadar x) (car (cdr (car x)))) ;; (define (cdddr x) (cdr (cdr (cdr x)))) ;; ;; Page 12 ;; (define (pairlis x y a) ;; ;;(debug "pairlis x=~a y=~a a=~a\n" x y a) ;; (cond ;; ((null? x) a) ;; ((atom? x) (cons (cons x y) a)) ;; (#t (cons (cons (car x) (car y)) ;; (pairlis (cdr x) (cdr y) a))))) ;; (define (assq x a) ;; ;;(stderr "assq x=~a\n" x) ;; ;;(debug "assq x=~a a=~a\n" x a) ;; (cond ;; ((null? a) #f) ;; ((eq? (caar a) x) (car a)) ;; (#t (assq x (cdr a))))) ;; ;; Page 13 ;; (define (eval-quote fn x) ;; ;(debug "eval-quote fn=~a x=~a" fn x) ;; (apply-env fn x '())) (define (evcon c a) ;;(debug "evcon c=~a a=~a\n" c a) (cond ((null? c) *unspecified*) ;; single-statement cond ;; ((eval (caar c) a) (eval (cadar c) a)) ((eval (caar c) a) (cond ((null? (cddar c)) (eval (cadar c) a)) (#t (eval (cadar c) a) (evcon (cons (cons #t (cddar c)) '()) a)))) (#t (evcon (cdr c) a)))) (define (evlis m a) ;;(debug "evlis m=~a a=~a\n" m a) ;; (display 'mes-evlis:) ;; (display m) ;; (newline) (cond ((null? m) '()) (#t (cons (eval (car m) a) (evlis (cdr m) a))))) (define (apply-env fn x a) ;; (display 'mes-apply-env:) ;; (newline) ;; (display 'fn:) ;; (display fn) ;; (newline) ;; (display 'builtin:) ;; (display (builtin? fn)) ;; (newline) ;; (display 'x:) ;; (display x) ;; (newline) (cond ((atom? fn) (cond ((eq? fn 'current-module) (c:apply-env current-module '() a)) ((eq? fn 'call-with-values) (c:apply-env 'call-with-values x a)) ((builtin? fn) (call fn x)) (#t (apply-env (eval fn a) x a)))) ((eq? (car fn) 'lambda) (begin-env (cddr fn) (pairlis (cadr fn) x a))) ((eq? (car fn) 'label) (apply-env (caddr fn) x (cons (cons (cadr fn) (caddr fn)) a))))) (define (begin-env body a) (cond ((null? body) *unspecified*) ((null? (cdr body)) (eval (car body) a)) (#t (eval (car body) a) (begin-env (cdr body) a)))) (define (set-env! x e a) (set-cdr! (assq x a) e)) (define (eval e a) ;;(debug "eval e=~a a=~a\n" e a) ;;(debug "eval (atom? ~a)=~a\n" e (atom? e)) ;; (display 'mes-eval:) ;; (display e) ;; (newline) ;; (display 'a:) ;; (display a) ;; (newline) (cond ((eq? e #t) #t) ((eq? e #f) #f) ((char? e) e) ((number? e) e) ((string? e) e) ((vector? e) e) ((atom? e) (cdr (assq e a))) ((builtin? e) e) ((atom? (car e)) (cond ((eq? (car e) 'quote) (cadr e)) ((eq? (car e) 'lambda) e) ((eq? (car e) 'set!) (set-env! (cadr e) (caddr e) a)) ((eq? (car e) 'unquote) (eval (cadr e) a)) ((eq? (car e) 'quasiquote) (eval-quasiquote (cadr e) a)) ((eq? (car e) 'cond) (evcon (cdr e) a)) ((pair? (assq (car e) (cdr (assq '*macro* a)))) (c:eval (c:apply-env (cdr (assq (car e) (cdr (assq '*macro* a)))) (cdr e) a) a)) (#t (apply-env (car e) (evlis (cdr e) a) a)))) (#t (apply-env (car e) (evlis (cdr e) a) a)))) (define (eval-quasiquote e a) ;; (display 'mes-eval-quasiquote:) ;; (display e) ;; (newline) (cond ((null? e) e) ((atom? e) e) ((atom? (car e)) (cons (car e) (eval-quasiquote (cdr e) a))) ((eq? (caar e) 'unquote) (cons (eval (cadar e) a) '())) ((eq? (caar e) 'quote) (cons (cadar e) '())) ((eq? (caar e) 'quasiquote) (cons (cadar e) '())) (#t (cons (car e) (eval-quasiquote (cdr e) a))))) ;; readenv et al works, but slows down dramatically (define (DISABLED-readenv a) (readword (getchar) '() a)) (define (readword c w a) ;; (display 'mes-readword:) ;; (display c) ;; (newline) (cond ((eq? c -1) ;; eof (cond ((eq? w '()) '()) (#t (lookup w a)))) ((eq? c 10) ;; \n (cond ((eq? w '()) (readword (getchar) w a)) ;; DOT ((eq? w '(*dot*)) (car (readword (getchar) '() a))) (#t (lookup w a)))) ((eq? c 32) ;; \space (readword 10 w a)) ((eq? c 40) ;; ( (cond ((eq? w '()) (readlist a)) (#t (ungetchar c) (lookup w a)))) ((eq? c 41) ;; ) (cond ((eq? w '()) (ungetchar c) w) (#t (ungetchar c) (lookup w a)))) ((eq? c 39) ;; ' (cond ((eq? w '()) (cons (lookup (cons c '()) a) (cons (readword (getchar) w a) '()))) (#t (ungetchar c) (lookup w a)))) ((eq? c 59) ;; ; (readcomment c) (readword 10 w a)) ((eq? c 35) ;; # (cond ((eq? (peekchar) 33) ;; ! (getchar) (readblock (getchar)) (readword 10 w a)) ;; TODO: char, vector (#t (readword (getchar) (append w (cons c '())) a)))) (#t (readword (getchar) (append w (cons c '())) a)))) (define (readblock c) ;; (display 'mes-readblock:) ;; (display c) ;; (newline) (cond ((eq? c 33) (cond ((eq? (peekchar) 35) (getchar)) (#t (readblock (getchar))))) (#t (readblock (getchar))))) (define (eat-whitespace) (cond ((eq? (peekchar) 10) (getchar) (eat-whitespace)) ((eq? (peekchar) 32) (getchar) (eat-whitespace)) ((eq? (peekchar) 35) (getchar) (eat-whitespace)) (#t #t))) (define (readlist a) ;; (display 'mes-readlist:) ;; (newline) (eat-whitespace) (cond ((eq? (peekchar) 41) ;; ) (getchar) '()) ;; TODO *dot* (#t (cons (readword (getchar) '() a) (readlist a))))) (define (readcomment c) (cond ((eq? c 10) ;; \n c) (#t (readcomment (getchar)))))