From ddca30271e96273577d9f937e98885223f8ccb68 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Mon, 12 Dec 2016 15:41:48 +0100 Subject: [PATCH] Resurrect Mes in Guile. * guile/mes.mes: New file, from the archives. * guile/mes.scm: Updates. --- guile/mes.mes | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++ guile/mes.scm | 58 ++++++++------- 2 files changed, 222 insertions(+), 26 deletions(-) create mode 100644 guile/mes.mes diff --git a/guile/mes.mes b/guile/mes.mes new file mode 100644 index 00000000..41e160df --- /dev/null +++ b/guile/mes.mes @@ -0,0 +1,190 @@ +;;; -*-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) + (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) + (cond + ((null? a) #f) + ((eq? (caar a) x) (car a)) + (#t (assq x (cdr a))))) + +;; Page 13 +(define (evcon 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) + (cond + ((null? m) '()) + (#t (cons (eval (car m) a) (evlis (cdr m) a))))) + + +(define (apply-env fn x a) + (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) + (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) 'begin) (begin-env (cdr e) a)) + ((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) + (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))))) + +(define (readenv a) + (readword (read-byte) '() a)) + +(define (readword c w a) + (cond ((eq? c -1) ;; eof + (cond ((eq? w '()) '()) + (#t (lookup w a)))) + ((eq? c 10) ;; \n + (cond ((eq? w '()) (readword (read-byte) w a)) + ;; DOT ((eq? w '(*dot*)) (car (readword (read-byte) '() a))) + (#t (lookup w a)))) + ((eq? c 32) ;; \space + (readword 10 w a)) + ((eq? c 40) ;; ( + (cond ((eq? w '()) (readlist a)) + (#t (unread-byte c) (lookup w a)))) + ((eq? c 41) ;; ) + (cond ((eq? w '()) (unread-byte c) w) + (#t (unread-byte c) (lookup w a)))) + ((eq? c 39) ;; ' + (cond ((eq? w '()) + (cons (lookup (cons c '()) a) + (cons (readword (read-byte) w a) '()))) + (#t (unread-byte c) (lookup w a)))) + ((eq? c 59) ;; ; + (readcomment c) + (readword 10 w a)) + ((eq? c 35) ;; # + (cond ((eq? (peek-byte) 33) ;; ! + (read-byte) + (readblock (read-byte)) + (readword 10 w a)) + ;; TODO: char, vector + (#t (readword (read-byte) (append2 w (cons c '())) a)))) + (#t (readword (read-byte) (append2 w (cons c '())) a)))) + +(define (readblock c) + (cond ((eq? c 33) (cond ((eq? (peek-byte) 35) (read-byte)) + (#t (readblock (read-byte))))) + (#t (readblock (read-byte))))) + +(define (eat-whitespace) + (cond ((eq? (peek-byte) 10) (read-byte) (eat-whitespace)) + ((eq? (peek-byte) 32) (read-byte) (eat-whitespace)) + ((eq? (peek-byte) 35) (read-byte) (eat-whitespace)) + (#t #t))) + +(define (readlist a) + (eat-whitespace) + (cond ((eq? (peek-byte) 41) ;; ) + (read-byte) + '()) + ;; TODO *dot* + (#t (cons (readword (read-byte) '() a) (readlist a))))) + +(define (readcomment c) + (cond ((eq? c 10) ;; \n + c) + (#t (readcomment (read-byte))))) diff --git a/guile/mes.scm b/guile/mes.scm index 2794b077..df50b988 100755 --- a/guile/mes.scm +++ b/guile/mes.scm @@ -1,6 +1,6 @@ #! /bin/sh # -*-scheme-*- -exec guile -L $(pwd)/module -e '(mes)' -s "$0" "$@" +exec guile -L $(pwd) -e '(mes)' -s "$0" "$@" !# ;;; Mes --- The Maxwell Equations of Software @@ -49,7 +49,7 @@ exec guile -L $(pwd)/module -e '(mes)' -s "$0" "$@" module-define! resolve-interface - ;; PRIMITIVES + ;; PRIMITIVE BUILTINS car cdr cons @@ -57,9 +57,17 @@ exec guile -L $(pwd)/module -e '(mes)' -s "$0" "$@" null? pair? - ;; ADDITIONAL PRIMITIVES + ;; READER + char->integer + integer->char + read-char + unread-char + + ;; non-primitive BUILTINS + char? number? procedure? + string? < - ) @@ -94,37 +102,35 @@ exec guile -L $(pwd)/module -e '(mes)' -s "$0" "$@" (define null? guile:null?) (define pair? guile:pair?) (define builtin? guile:procedure?) +(define char? guile:char?) (define number? guile:number?) +(define string? guile:number?) (define call guile:apply) +(define (peek-byte) + (unread-byte (read-byte))) +(define (read-byte) + (guile:char->integer (guile:read-char))) +(define (unread-byte x) + (guile:unread-char (guile:integer->char x)) + x) +(define (lookup x a) + ;; TODO + (stderr "lookup x=~a\n" x) + x) -(include-from-path "mes/mes.mes") +(include "mes.mes") -(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))))) - -(define (append x y) +(define (append2 x y) (cond ((null? x) y) - (#t (cons (car x) (append (cdr x) y))))) + (#t (cons (car x) (append2 (cdr x) y))))) (define (eval-environment e a) - (eval e (append a environment))) + (eval e (append2 a environment))) (define (apply-environment fn e a) - (apply-env fn e (append a environment))) + (apply-env fn e (append2 a environment))) +;; READER: TODO lookup (define (readenv a) (let ((x (guile:read))) (if (guile:eof-object? x) '() @@ -180,7 +186,7 @@ exec guile -L $(pwd)/module -e '(mes)' -s "$0" "$@" (cddar . ,cddar) (cdddr . ,cdddr) - (append . ,append) + (append2 . ,append2) (exit . ,guile:exit) (*macro* . ()) @@ -215,7 +221,7 @@ exec guile -L $(pwd)/module -e '(mes)' -s "$0" "$@" (#t (loop (eval e a) (readenv a) a)))) (define (main arguments) - (let ((a (append environment `((*a* . ,environment))))) + (let ((a (append2 environment `((*a* . ,environment))))) ;;(guile:display (eval (readenv a) a)) (guile:display (loop *unspecified* (readenv a) a)) )