;;; -*-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 (assoc x a) ;; ;;(stderr "assoc x=~a\n" x) ;; ;;(debug "assoc x=~a a=~a\n" x a) ;; (cond ;; ((null a) #f) ;; ((eq (caar a) x) (car a)) ;; (#t (assoc x (cdr a))))) ;; ;; Page 13 ;; (define (eval-quote fn x) ;; ;(debug "eval-quote fn=~a x=~a" fn x) ;; (apply fn x '())) (define (evcon c a) ;;(debug "evcon c=~a a=~a\n" c a) (cond ;; 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 fn x a) ;; (display 'mes-apply:) ;; (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) ;; FIXME (c:apply current-module '() a)) ((builtin fn) (call fn x)) (#t (apply (eval fn a) x a)))) ((eq (car fn) 'lambda) (cond ((null (cdr (cddr fn))) (eval (caddr fn) (pairlis (cadr fn) x a))) (#t (eval (caddr fn) (pairlis (cadr fn) x a)) (apply (cons (car fn) (cons (cadr fn) (cdddr fn))) x (pairlis (cadr fn) x a))))) ((eq (car fn) 'label) (apply (caddr fn) x (cons (cons (cadr fn) (caddr fn)) a))))) (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 ((number e) e) ((eq e #t) #t) ((eq e #f) #f) ((atom e) (cdr (assoc e a))) ((builtin e) e) ((atom (car e)) (cond ((eq (car e) 'quote) (cadr e)) ((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 (assoc (car e) (cdr (assoc '*macro* a)))) (c:eval (c:apply (cdr (assoc (car e) (cdr (assoc '*macro* a)))) (cdr e) a) a)) (#t (apply (car e) (evlis (cdr e) a) a)))) (#t (apply (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 '()) (readlis 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)) (#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 (readlis a) ;; (display 'mes-readlis:) ;; (newline) (eat-whitespace) (cond ((eq (peekchar) 41) ;; ) (getchar) '()) ;; TODO *dot* (#t (cons (readword (getchar) '() a) (readlis a))))) (define (readcomment c) (cond ((eq c 10) ;; \n c) (#t (readcomment (getchar)))))