alists and plists now
This commit is contained in:
+71
-17
@@ -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"))
|
||||
|
||||
Reference in New Issue
Block a user