alists and plists now

This commit is contained in:
FelixBrendel
2019-07-05 01:26:00 +02:00
parent d576e7324f
commit e0aaf351c5
14 changed files with 646 additions and 106 deletions
+71 -17
View File
@@ -17,8 +17,8 @@ condition is true.
{{{example_end}}}
"
(if (= (rest body) ())
`(if ,condition @body)
`(if ,condition (begin @body))))
`(if ,condition @body nil)
`(if ,condition (begin @body) nil)))
(define-syntax (unless condition :rest body)
"Special form for when multiple actions should be done if a
@@ -57,13 +57,28 @@ condition is false."
nil
(if (= (first (first clauses)) 'else)
(begin
(if (not (= () (rest clauses)))
(if (not (= (rest clauses) ()))
(error "There are additional clauses after the else clause!")
(pair 'begin (rest (first clauses)))))
`(if ,(first (first clauses))
(begin @(rest (first clauses)))
,(rec (rest clauses))))))
(rec clauses))
(begin @(rest (first clauses)))
,(rec (rest clauses))))))
(rec clauses))
(define-syntax (case var :rest clauses)
(define (rec clauses)
(if (= nil clauses)
nil
(if (= (first (first clauses)) 'else)
(begin
(if (not (= (rest clauses) ()))
(error "There are additional clauses after the else clause!")
(pair 'begin (rest (first clauses)))))
`(if (member? ,var ',(first (first clauses)))
(begin @(rest (first clauses)))
,(rec (rest clauses))))))
(rec clauses))
(define-syntax (define-special name-and-args :rest body)
`(define ,(first name-and-args) (special-lambda ,(rest name-and-args) @body)))
@@ -110,10 +125,24 @@ condition is false."
(rec body))
(define-syntax (apply fun seq)
"Applies the funciton to the sequence, as in calls the function with
"Applies the function to the sequence, as in calls the function with
ithe sequence as arguemens."
`(eval (pair ,fun ,seq)))
(define-syntax (define-typed args :rest body)
(define (get-arg-names args)
(when args
(pair (first args)
(get-arg-names (rest (rest args))))))
(let ((name (first args))
(lambda-list (rest args))
(arg-names (get-arg-names (rest args))))
`(define (,name @arg-names)
(assert-types= @lambda-list)
@body)))
(define-typed (ttt a :number b :alist)
(printf a b))
(define-syntax (define-package name :rest body)
`(define ,(string->symbol (concat-strings (symbol->string name) "->"))
@@ -131,43 +160,62 @@ ithe sequence as arguemens."
(define (null? x)
"Checks if the argument is =nil=."
(= x nil))
(= x ()))
(define (type=? obj typ)
"Checks if the argument =obj= is of type =typ="
(= (type obj) typ))
(define (types=? :rest objs)
;; TODO make inner rec functoin to avoid evalutating every time
(if objs
(begin
(assert (keyword? (first (rest objs))))
(if (type=? (first objs) (first (rest objs)))
(apply types=? (rest (rest objs)))
()))
t))
(define (assert-types= :rest objs)
(break)
(unless (apply types=? objs)
(error "assert-types=: types do not match")))
(define (number? x)
"Checks if the argument is a number."
(= (type x) :number))
(type=? x :number))
(define (symbol? x)
"Checks if the argument is a symbol."
(= (type x) :symbol))
(type=? x :symbol))
(define (keyword? x)
"Checks if the argument is a keyword."
(= (type x) :keyword))
(type=? x :keyword))
(define (pair? x)
"Checks if the argument is a pair."
(= (type x) :pair))
(type=? x :pair))
(define (string? x)
"Checks if the argument is a string."
(= (type x) :string))
(type=? x :string))
(define (lambda? x)
"Checks if the argument is a function."
(= (type x) :lambda))
(type=? x :lambda))
(define (macro? x)
"Checks if the argument is a macro."
(= (type x) :macro))
(type=? x :macro))
(define (special-lambda? x)
"Checks if the argument is a special-lambda."
(= (type x) :dynamic-macro))
(type=? x :dynamic-macro))
(define (built-in-function? x)
"Checks if the argument is a built-in function."
(= (type x) :built-in-function))
(type=? x :built-in-function))
(define (callable? x)
(or (lambda? x)
@@ -229,6 +277,12 @@ with (pair elem nil)."
0
(+ 1 (length (rest seq)))))
(define (member? elem seq)
(when (pair? seq)
(if (= elem (first seq))
t
(member? elem (rest seq)))))
(define (sublist-starting-at-index seq index)
(cond ((< index 0)
(error "sublist-starting-at-index: index must be positive"))