X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fscheme%2Fao_scheme_advanced_syntax.scheme;fp=src%2Fscheme%2Fao_scheme_advanced_syntax.scheme;h=0000000000000000000000000000000000000000;hp=4cddc8032b45cd6777044a81620e67d209311bad;hb=f26cc1a677f577da533425a15485fcaa24626b23;hpb=4b52fc6eea9a478cb3dd42dcd32c92838df39734 diff --git a/src/scheme/ao_scheme_advanced_syntax.scheme b/src/scheme/ao_scheme_advanced_syntax.scheme deleted file mode 100644 index 4cddc803..00000000 --- a/src/scheme/ao_scheme_advanced_syntax.scheme +++ /dev/null @@ -1,388 +0,0 @@ -; -; Copyright © 2018 Keith Packard -; -; This program 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 2 of the License, or -; (at your option) any later version. -; -; This program 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. -; -; Advanced syntax, including vectors and floats - -(begin - (def! equal? - (lambda (a b) - (cond ((eq? a b) #t) - ((and (pair? a) (pair? b)) - (and (equal? (car a) (car b)) - (equal? (cdr a) (cdr b))) - ) - ((and (vector? a) (vector? b) (= (vector-length a) (vector-length b))) - ((lambda (i l) - (while (and (< i l) - (equal? (vector-ref a i) - (vector-ref b i))) - (set! i (+ i 1))) - (eq? i l) - ) - 0 - (vector-length a) - ) - ) - (else #f) - ) - ) - ) - 'equal? - ) - -(equal? '(a b c) '(a b c)) -(equal? '(a b c) '(a b b)) -(equal? #(1 2 3) #(1 2 3)) -(equal? #(1 2 3) #(4 5 6)) - -(define quasiquote - (macro (x) - (define (constant? exp) - ; A constant value is either a pair starting with quote, - ; or anything which is neither a pair nor a symbol - - (cond ((pair? exp) - (eq? (car exp) 'quote) - ) - (else - (not (symbol? exp)) - ) - ) - ) - - (define (combine-skeletons left right exp) - (cond - ((and (constant? left) (constant? right)) - (cond ((and (eqv? (eval left) (car exp)) - (eqv? (eval right) (cdr exp))) - (list 'quote exp) - ) - (else - (list 'quote (cons (eval left) (eval right))) - ) - ) - ) - ((null? right) - (list 'list left) - ) - ((and (pair? right) (eq? (car right) 'list)) - (cons 'list (cons left (cdr right))) - ) - (else - (list 'cons left right) - ) - ) - ) - - (define (expand-quasiquote exp nesting) - (cond - - ; non cons -- constants - ; themselves, others are - ; quoted - - ((not (pair? exp)) - (cond ((constant? exp) - exp - ) - (else - (list 'quote exp) - ) - ) - ) - - ; check for an unquote exp and - ; add the param unquoted - - ((and (eq? (car exp) 'unquote) (= (length exp) 2)) - (cond ((= nesting 0) - (car (cdr exp)) - ) - (else - (combine-skeletons ''unquote - (expand-quasiquote (cdr exp) (- nesting 1)) - exp)) - ) - ) - - ; nested quasi-quote -- - ; construct the right - ; expression - - ((and (eq? (car exp) 'quasiquote) (= (length exp) 2)) - (combine-skeletons ''quasiquote - (expand-quasiquote (cdr exp) (+ nesting 1)) - exp)) - - ; check for an - ; unquote-splicing member, - ; compute the expansion of the - ; value and append the rest of - ; the quasiquote result to it - - ((and (pair? (car exp)) - (eq? (car (car exp)) 'unquote-splicing) - (= (length (car exp)) 2)) - (cond ((= nesting 0) - (list 'append (car (cdr (car exp))) - (expand-quasiquote (cdr exp) nesting)) - ) - (else - (combine-skeletons (expand-quasiquote (car exp) (- nesting 1)) - (expand-quasiquote (cdr exp) nesting) - exp)) - ) - ) - - ; for other lists, just glue - ; the expansion of the first - ; element to the expansion of - ; the rest of the list - - (else (combine-skeletons (expand-quasiquote (car exp) nesting) - (expand-quasiquote (cdr exp) nesting) - exp) - ) - ) - ) - (expand-quasiquote x 0) - ) - ) - - ; `q -> (quote q) - ; `(q) -> (append (quote (q))) - ; `(a ,(+ 1 2)) -> (append (quote (a)) (list (+ 1 2))) - ; `(a ,@(list 1 2 3) -> (append (quote (a)) (list 1 2 3)) - - -`(hello ,(+ 1 2) ,@(list 1 2 3) `foo) - - ; define a set of local - ; variables all at once and - ; then evaluate a list of - ; sexprs - ; - ; (let (var-defines) sexprs) - ; - ; where var-defines are either - ; - ; (name value) - ; - ; or - ; - ; (name) - ; - ; e.g. - ; - ; (let ((x 1) (y)) (set! y (+ x 1)) y) - -(define let - (macro (vars . exprs) - (define (make-names vars) - (cond ((not (null? vars)) - (cons (car (car vars)) - (make-names (cdr vars)))) - (else ()) - ) - ) - - ; the parameters to the lambda is a list - ; of nils of the right length - - (define (make-vals vars) - (cond ((not (null? vars)) - (cons (cond ((null? (cdr (car vars))) ()) - (else - (car (cdr (car vars)))) - ) - (make-vals (cdr vars)))) - (else ()) - ) - ) - ; prepend the set operations - ; to the expressions - - ; build the lambda. - - `((lambda ,(make-names vars) ,@exprs) ,@(make-vals vars)) - ) - ) - - -(let ((x 1) (y)) (set! y 2) (+ x y)) - -(define assv assq) - -(assv 'b '((a 1) (b 2) (c 3))) - -(define when (macro (test . l) `(cond (,test ,@l)))) - -(when #t (+ 1 2)) -(when #f (+ 1 2)) - -(define unless (macro (test . l) `(cond ((not ,test) ,@l)))) - -(unless #f (+ 2 3)) -(unless #t (+ 2 3)) - -(define (cdar l) (cdr (car l))) - -(cdar '((1 2) (3 4))) - -(define (cddr l) (cdr (cdr l))) - -(cddr '(1 2 3)) - -(define (caddr l) (car (cdr (cdr l)))) - -(caddr '(1 2 3 4)) - -(define (reverse list) - (define (_r old new) - (if (null? old) - new - (_r (cdr old) (cons (car old) new)) - ) - ) - (_r list ()) - ) - -(reverse '(1 2 3)) - -(define make-list - (lambda (a . b) - (define (_m a x) - (if (zero? a) - x - (_m (- a 1) (cons b x)) - ) - ) - (if (null? b) - (set! b #f) - (set! b (car b)) - ) - (_m a '()) - ) - ) - -(make-list 10 'a) - -(make-list 10) - -(define for-each - (lambda (proc . lists) - (define (_f lists) - (cond ((null? (car lists)) #t) - (else - (apply proc (map car lists)) - (_f (map cdr lists)) - ) - ) - ) - (_f lists) - ) - ) - -(let ((a 0)) - (for-each (lambda (b) (set! a (+ a b))) '(1 2 3)) - a - ) - -(call-with-current-continuation - (lambda (exit) - (for-each (lambda (x) - (if (negative? x) - (exit x))) - '(54 0 37 -3 245 19)) - #t)) - -(define case - (macro (test . l) - ; construct the body of the - ; case, dealing with the - ; lambda version ( => lambda) - - (define (_unarrow l) - (cond ((null? l) l) - ((eq? (car l) '=>) `(( ,(cadr l) __key__))) - (else l)) - ) - - ; Build the case elements, which is - ; simply a list of cond clauses - - (define (_case l) - - (cond ((null? l) ()) - - ; else case - - ((eq? (caar l) 'else) - `((else ,@(_unarrow (cdr (car l)))))) - - ; regular case - - (else - (cons - `((eqv? ,(caar l) __key__) - ,@(_unarrow (cdr (car l)))) - (_case (cdr l))) - ) - ) - ) - - ; now construct the overall - ; expression, using a lambda - ; to hold the computed value - ; of the test expression - - `((lambda (__key__) - (cond ,@(_case l))) ,test) - ) - ) - -(case 1 (1 "one") (2 "two") (3 => (lambda (x) (write (list "the value is" x)))) (12 "twelve") (else "else")) -(case 2 (1 "one") (2 "two") (3 => (lambda (x) (write (list "the value is" x)))) (12 "twelve") (else "else")) -(case 3 (1 "one") (2 "two") (3 => (lambda (x) (write (list "the value is" x)) "three")) (12 "twelve") (else "else")) -(case 4 (1 "one") (2 "two") (3 => (lambda (x) (write (list "the value is" x)))) (12 "twelve") (else "else")) -(case 12 (1 "one") (2 "two") (3 => (lambda (x) (write (list "the value is" x)))) (12 "twelve") (else "else")) - -(define do - (macro (vars test . cmds) - (define (_step v) - (if (null? v) - '() - (if (null? (cddr (car v))) - (_step (cdr v)) - (cons `(set! ,(caar v) ,(caddr (car v))) - (_step (cdr v)) - ) - ) - ) - ) - `(let ,(map (lambda (v) (list (car v) (cadr v))) vars) - (while (not ,(car test)) - ,@cmds - ,@(_step vars) - ) - ,@(cdr test) - ) - ) - ) - -(do ((x 1 (+ x 1)) - (y 0) - ) - ((= x 10) y) - (set! y (+ y x)) - )