adding lisp-interpreter
Meson Build and Deploy / build (push) Failing after 29s

This commit is contained in:
Arthur Barraux
2025-09-24 10:58:09 +02:00
parent ab482df604
commit d8fc7d2d67
57 changed files with 30702 additions and 5 deletions
+90
View File
@@ -0,0 +1,90 @@
(define-macro lambda (/\_ args
(if (pair? args)
(if (pair? (cdr args))
(if (pair? (cdr (cdr args)))
`(/\_ ,(car args) ,(cons 'BEGIN (cdr args)))
`(/\_ ,(car args) ,(car (cdr args))))
(syntax-error "lambda missing body expressions: (lambda (args) body)"))
(syntax-error "lambda missing argument: (lambda (args) body)"))))
(define-macro set! (lambda (var x)
(begin
(if (not (symbol? var)) (syntax-error "set! not a variable"))
`(_SET! ,var ,x))))
(define-macro define
(lambda (var . exprs)
(if (symbol? var)
(if (pair? (cdr exprs))
(syntax-error "define: (define var x)")
`(_DEF ,var ,(car exprs)))
(if (pair? var)
`(_DEF ,(car var)
(LAMBDA ,(cdr var)
,(if (null? (cdr exprs)) (car exprs) (cons 'BEGIN exprs))))
(syntax-error "define: not a symbol") ))))
(define (first x) (car x))
(define (second x) (car (cdr x)))
(define (third x) (car (cdr (cdr x))))
(define (some? pred l)
(if (null? l) #f
(if (pred (car l)) #t
(some? pred (cdr l)))))
(define (_map1-helper proc l result)
(if (null? l)
(reverse! result)
(_map1-helper proc
(cdr l)
(cons (proc (car l)) result))))
(define (map1 proc l) (_map1-helper proc l '()))
(define (for-each1 proc l)
(if (null? l) '()
(begin (proc (car l)) (for-each1 proc (cdr l )))))
(define (reverse! l) (append-reverse! l '()))
(define (reverse l) (reverse! (list-copy l)))
(define (last-pair x)
(if (pair? (cdr x))
(last-pair (cdr x)) x))
(define (list-tail x k)
(if (zero? k) x
(list-tail (cdr x) (- k 1))))
(define (fold-left op acc lst)
(if (null? lst) acc
(fold-left op (op acc (car lst)) (cdr lst))))
(define (_expand-shorthand-body path)
(if (null? path) (cons 'pair '())
(list (if (char=? (car path) #\A)
(cons 'CAR (_expand-shorthand-body (cdr path)))))))
(define (_expand-shorthand text)
(cons 'DEFINE (cons (list (string->symbol (string-append "C" text "R")) 'pair)
(_expand-shorthand-body (string->list text)))))
(define-macro _shorthand-accessors (lambda args (cons 'BEGIN (map1 _expand-shorthand args))))
(define (vector . args) (list->vector args))
(define (vector-copy v) (subvector v 0 (vector-length v)))
(define (vector-head v end) (subvector v 0 end))
(define (vector-tail v start) (subvector v start (vector-length v)))
(define (string . chars) (list->string chars))
(define (string>=? a b) (not (string<? a b)))
(define (string>? a b) (string<? b a))
(define (string<=? a b) (not (string<? b a)))
(define (string-copy s) (substring s 0 (string-length v)))
(define (string-head s end) (subvector s 0 end))
(define (string-tail s start) (subvector s start (string-length v)))
+78
View File
@@ -0,0 +1,78 @@
(define (_make-lambda args body)
(list 'LAMBDA args (if (null? (cdr body)) (car body) (cons 'BEGIN body))))
; (LET <name> ((<var0> <expr0>) ... (<varN> <expr1>)) <body0> ... <bodyN>)
; => ((LAMBDA (<var0> ... <varN>) (BEGIN <body0> ... <bodyN>)) <expr0> ... <expr1>)
; => named
; ((lambda ()
; (define <name> (LAMBDA (<var0> ... <varN>) (BEGIN <body0> ... <bodyN>)))
; (<name> <expr0> ... <exprN>)))
(define (_check-binding-list bindings)
(for-each1 (lambda (entry)
(if (not (pair? entry)) (syntax-error "bad let binding" entry))
(if (not (symbol? (first entry))) (syntax-error "let entry missing symbol" entry))) bindings))
(define (_let->combination var bindings body)
(_check-binding-list bindings)
(define body-func (_make-lambda (map1 (lambda (entry) (first entry)) bindings) body))
(define initial-args (map1 (lambda (entry) (second entry)) bindings))
(if (null? var)
(cons body-func initial-args)
(list (_make-lambda '() (list (list 'DEFINE var body-func) (cons var initial-args))))))
(define-macro let (lambda args
(if (pair? (first args))
(_let->combination '() (car args) (cdr args))
(_let->combination (first args) (second args) (cdr (cdr args))))))
(define (_let*-helper bindings body)
(if (null? bindings) (if (null? (cdr body)) (car body) (cons 'BEGIN body))
(list 'LET (list (car bindings)) (_let*-helper (cdr bindings) body))))
(define-macro let* (lambda (bindings . body)
(_check-binding-list bindings)
(_let*-helper bindings body)))
(define-macro letrec (lambda (bindings . body)
(_check-binding-list bindings)
(cons (_make-lambda (map1 (lambda (entry) (first entry)) bindings)
(append (map1 (lambda (entry) (list 'SET! (first entry) (second entry)))
bindings) body))
(map1 (lambda (entry) '()) bindings))))
; (COND (<pred0> <expr0>)
; (<pred1> <expr1>)
; ...
; (else <expr-1>))
; =>
; (IF <pred0> <expr0>
; (if <pred1> <expr1>
; ....
; (if <predN> <exprN> <expr-1>)) ... )
(define (_cond-check-clauses clauses)
(for-each1 (lambda (clause)
(if (not (pair? clause)) (syntax-error "cond: invalid clause"))
(if (null? (cdr clause)) (syntax-error "cond: clause missing expression")))
clauses))
(define (_cond-helper clauses)
(if (null? clauses) '()
(if (eq? (car (car clauses)) 'ELSE)
(cons 'BEGIN (cdr (car clauses)))
(list 'IF
(car (car clauses))
(cons 'BEGIN (cdr (car clauses)))
(_cond-helper (cdr clauses))))))
(define-macro cond (lambda clauses
(begin
(_cond-check-clauses clauses)
(_cond-helper clauses))))
+75
View File
@@ -0,0 +1,75 @@
(_shorthand-accessors "AA" "DD" "AD" "DA" "AAA" "AAD" "ADA" "DAA" "ADD" "DAD" "DDA" "DDD")
(define (_and-helper preds)
(cond ((null? preds) #t)
((null? (cdr preds)) (car preds))
(else
`(IF ,(car preds) ,(_and-helper (cdr preds)) #f))))
(define-macro and (lambda preds (_and-helper preds)))
(define (_or-helper preds var)
(cond ((null? preds) #f)
((null? (cdr preds)) (car preds))
(else
`(BEGIN (SET! ,var ,(car preds))
(IF ,var ,var ,(_or-helper (cdr preds) var))))))
(define-macro or (lambda preds
(let ((var (gensym)))
`(LET ((,var '())) ,(_or-helper preds var)))))
(define-macro case (lambda (key . clauses)
(let ((expr (gensym)))
`(LET ((,expr ,key))
,(cons 'COND (map1 (lambda (entry)
(cons (if (pair? (car entry))
`(MEMV ,expr (quote ,(car entry)))
(car entry))
(cdr entry))) clauses))))))
(define-macro push
(lambda (v l)
`(begin (set! ,l (cons ,v ,l)) ,l)))
; (DO ((<var0> <init0> <step0>) ...) (<test> <result>) <body>)
(define-macro do
(lambda (vars loop-check . loops)
(let ( (names '()) (inits '()) (steps '()) (f (gensym)) )
(for-each1 (lambda (var)
(push (car var) names)
(set! var (cdr var))
(push (car var) inits)
(set! var (cdr var))
(push (car var) steps)) vars)
`((LAMBDA ()
(DEFINE ,f (LAMBDA ,names
(IF ,(car loop-check)
,(if (pair? (cdr loop-check)) (car (cdr loop-check)) '())
,(cons 'BEGIN (append loops (list (cons f steps)))) )))
,(cons f inits)
)) )))
(define-macro dotimes
(lambda (form body)
(apply (lambda (i n . result)
`(DO ((,i 0 (+ ,i 1)))
((>= ,i ,n) ,(if (null? result) result (car result)) )
,body)
) form)))
(define-macro swap!
(lambda (x y)
(let ((temp (gensym)))
`(LET ((,temp ,x))
(SET! ,temp ,x)
(SET! ,x ,y)
(SET! ,y ,temp)))))
(define-macro inc! ; CL incf
(lambda (x)
`(SET! ,x (+ ,x 1))))
(define-macro dec! ; CL decf
(lambda (x)
`(SET! ,x (- ,x 1))))
+35
View File
@@ -0,0 +1,35 @@
(define (number? x) (real? x))
(define (odd? x) (not (even? x)))
(define (inexact? x) (not (exact? x)))
(define (zero? x) (= x 0))
(define (positive? x) (>= x 0))
(define (negative? x) (< x 0))
(define (>= a b) (not (< a b)))
(define (> a b) (< b a))
(define (<= a b) (not (< b a)))
(define (max . ls)
(fold-left (lambda (m x)
(if (> x m)
x
m)) (car ls) (cdr ls)))
(define (min . ls)
(fold-left (lambda (m x)
(if (< x m)
x
m)) (car ls) (cdr ls)))
(define (_gcd-helper a b)
(if (= b 0) a (_gcd-helper b (modulo a b))))
(define (gcd . args)
(if (null? args) 0
(_gcd-helper (car args) (car (cdr args)))))
(define (lcm . args)
(if (null? args) 1
(abs (* (/ (car args) (apply gcd args))
(apply * (cdr args))))))
+133
View File
@@ -0,0 +1,133 @@
(define (map proc . rest)
(define (helper lists result)
(if (some? null? lists)
(reverse! result)
(helper (map1 cdr lists)
(cons (apply proc (map1 car lists)) result))))
(helper rest '()))
(define (for-each proc . rest)
(define (helper lists)
(if (some? null? lists)
'()
(begin
(apply proc (map1 car lists))
(helper (map1 cdr lists)))))
(helper rest))
(define (filter pred l)
(define (helper l result)
(cond ((null? l) result)
((pred (car l))
(helper (cdr l) (cons (car l) result)))
(else
(helper (cdr l) result))))
(reverse! (helper l '())))
(define (reduce op default lst)
(if (null? lst)
default
(fold-left op (car lst) (cdr lst))))
(define (alist->hash-table alist)
(define h (make-hash-table))
(for-each1 (lambda (pair)
(hash-table-set! h (car pair) (cdr pair))) alist)
h)
(define (_assoc key list eq?)
(if (null? list) #f
(let ((pair (car list)))
(if (and (pair? pair) (eq? key (car pair)))
pair
(_assoc key (cdr list) eq?)))))
(define (assoc key list) (_assoc key list equal?))
(define (assq key list) (_assoc key list eq?))
(define (assv key list) (_assoc key list eqv?))
(define (_member x list eq?)
(cond ((null? list) #f)
((eq? (car list) x) list)
(else (_member x (cdr list) eq?))))
(define (member x list) (_member x list equal?))
(define (memq x list) (_member x list eq?))
(define (memv x list) (_member x list eqv?))
(define (make-initialized-vector l fn)
(let ((v (make-vector l '())))
(do ((i 0 (+ i 1)))
((>= i l) v)
(vector-set! v i (fn i)))))
(define (vector-map fn v)
(make-initialized-vector
(vector-length v)
(lambda (i) (fn (vector-ref v i)))))
(define (vector-binary-search v key< unwrap-key key)
(define (helper low high mid)
(if (<= (- high low) 1)
(if (key< (unwrap-key (vector-ref v low)) key) #f (vector-ref v low))
(begin
(set! mid (+ low (quotient (- high low) 2)))
(if (key< key (unwrap-key (vector-ref v mid)))
(helper low mid 0)
(helper mid high 0)))))
(helper 0 (vector-length v) 0))
(define (_insertsort v lo hi op)
(if (= (- hi lo) 0)
v
(do ((i (+ lo 1) (+ i 1)))
((= i hi) v)
(define x (vector-ref v i))
(do ((j i (- j 1)))
((or
(= j lo)
(not (op x (vector-ref v (- j 1)))))
(vector-set! v j x))
(vector-set! v j (vector-ref v (- j 1))))) ))
(define (_quicksort-partition v lo hi op)
(let ((pivot (vector-ref v (+ lo (/ (- hi lo) 2))))
(i (- lo 1))
(j (+ hi 1)))
(do ()
((>= i j) j)
(set! i (+ i 1))
(do ()
((not (op (vector-ref v i) pivot)) '())
(set! i (+ i 1)))
(set! j (- j 1))
(do ()
((not (op pivot (vector-ref v j))) '())
(set! j (- j 1)))
(if (< i j) (vector-swap! v i j))
)))
(define (_quicksort-vector v lo hi threshold op)
(if (and (>= lo 0) (>= hi 0) (< lo hi) (> (- hi lo) threshold))
(let ((p (_quicksort-partition v lo hi op)))
(_quicksort-vector v lo p threshold op)
(_quicksort-vector v (+ p 1) hi threshold op))))
(define (sort! v op)
; quicksort down to a certain level of recursion and
; then use insertion sort to finalize.
(_quicksort-vector v 0 (- (vector-length v) 1) 16 op)
(_insertsort v 0 (vector-length v) op)
v)
(define (sort list cmp) (vector->list (sort! (list->vector list) cmp)))
+58
View File
@@ -0,0 +1,58 @@
(define-macro delay (lambda (expr)
`(make-promise ,(cons 'LAMBDA
(cons '()
(cons expr '()))))))
(define (force promise)
(if (not (promise-forced? promise))
(_promise-store! promise ((_promise-procedure promise))))
(promise-value promise))
(define-macro cons-stream (lambda (x expr) `(cons ,x (delay ,expr))))
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
(define (stream-pair? x)
(and (pair? x) (promise? (cdr x))))
(define (stream-null? stream) (null? stream))
(define (stream->list-helper stream result)
(if (stream-null? stream)
(reverse! result)
(stream->list-helper
(force (cdr stream))
(cons (car stream) result))))
(define (stream->list stream)
(stream->list-helper stream '()))
(define (list->stream list)
(if (null? list)
'()
(cons-stream (car list) (list->stream (cdr list)))))
(define (stream . args) (list->stream args))
(define (stream-head-helper stream k result)
(if (= k 0)
(reverse! result)
(stream-head-helper (force (cdr stream)) (- k 1) (cons (car stream) result))))
(define (stream-head stream k)
(stream-head-helper stream k '()))
(define (stream-tail stream k)
(if (= k 0)
stream
(stream-tail (stream-cdr stream) (- k 1))))
(define (stream-filter pred stream)
(cond ((stream-null? stream) the-empty-stream)
((pred (stream-car stream))
(cons-stream (stream-car stream)
(stream-filter pred
(stream-cdr stream))))
(else (stream-filter pred (stream-cdr stream)))))
+63
View File
@@ -0,0 +1,63 @@
(define (char>=? a b) (not (char<? a b)))
(define (char>? a b) (char<? b a))
(define (char<=? a b) (not (char<? b a)))
(define (char-ci=? a b) (char=? (char-downcase a) (char-downcase b)))
(define (char-ci<? a b) (char<? (char-downcase a) (char-downcase b)))
(define (char-ci>=? a b) (not (char-ci<? a b)))
(define (char-ci>? a b) (char-ci<? b a))
(define (char-ci<=? a b) (not (char-ci<? b a)))
(define (char-lower-case? c)
(and (>= (char->integer c) (char->integer #\a))
(<= (char->integer c) (char->integer #\z))))
(define (char-upper-case? c)
(and (>= (char->integer c) (char->integer #\A))
(<= (char->integer c) (char->integer #\Z))))
(define (procedure? p) (or (compiled-procedure? p) (compound-procedure? p)))
(define (current-input-port) _current-input-port)
(define (current-output-port) _current-output-port)
(define (read . args)
(_read (if (null? args)
(current-input-port)
(car args))))
(define (write obj . args)
(_write obj (if (null? args)
(current-output-port)
(car args))))
(define (display obj . args)
(_display obj (if (null? args)
(current-output-port)
(car args))))
(define (write-char obj . args)
(_write-char obj (if (null? args)
(current-output-port)
(car args))))
(define (flush-output-port . args)
(_flush-output-port (if (null? args)
(current-output-port)
(car args))))
(define (newline) (write-char #\newline))
(define-macro assert (lambda (body)
`(if ,body '()
(begin
(display (quote ,body))
(error " assert failed")))))
(define-macro ==> (lambda (test expected)
`(assert (equal? ,test (quote ,expected))) ))
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
SRC=*.scm
cat lib.h
echo "// Generated from scheme source."
echo "#ifdef LISP_IMPLEMENTATION"
for FILE in $SRC
do
echo "static const char* lib_$(basename $FILE .scm)_src_ = "
cat $FILE | ./text2c.sh
echo ";"
echo ""
done
cat lib.c
echo "#endif"
File diff suppressed because it is too large Load Diff
+31
View File
@@ -0,0 +1,31 @@
/*
Created by: Justin Meiners
Repo; https://github.com/justinmeiners/lisp-interpreter
License: MIT (See end if file)
This file contains the scheme standard library.
See lisp.h for insructions.
*/
#ifndef LISP_LIB_H
#define LISP_LIB_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdint.h>
void lisp_lib_load(LispContext ctx);
// convenience for init and load
LispContext lisp_init_with_lib(void);
#ifdef __cplusplus
}
#endif
#endif
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
read -r -d '' content
content=${content//'\'/'\\'}
content=${content//$'\t'/'\t'}
content=${content//$'\n'/$' \\n\\\n'}
content=${content//$'\r'/'\r'}
content=${content//'"'/'\"'}
echo -n "\"$content\""