| @@ -1,6 +1,11 @@ | |||
| /vs/*/* | |||
| /build | |||
| *.ilk | |||
| *.aux | |||
| *.fls | |||
| *.log | |||
| *.toc | |||
| *.fdb_latexmk | |||
| *.pdb | |||
| *.exe | |||
| *.user | |||
| @@ -0,0 +1,4 @@ | |||
| (import "oo.slime") | |||
| (import "math.slime") | |||
| (generate-docs "../manual/built-in-docs.org") | |||
| @@ -2,56 +2,59 @@ | |||
| (define-package math | |||
| (define pi 3.14159265) | |||
| (define pi | |||
| "Tha famous circle constant." | |||
| 3.14159265) | |||
| (define (abs x) | |||
| "Accepts one argument and returns the absoulte value of it" | |||
| (if (> x 0) x (- x))) | |||
| (define (sqrt x) | |||
| "Accepts one argument and returns the square root of it" | |||
| (** x 0.5)) | |||
| ;; (define-class vector3 (x y z) | |||
| ;; (define (get-x) x) | |||
| ;; (define (get-y) y) | |||
| ;; (define (get-z) z) | |||
| ;; (define (set-x new-x) (mutate x new-x)) | |||
| ;; (define (set-y new-y) (mutate y new-y)) | |||
| ;; (define (set-z new-z) (mutate z new-z)) | |||
| ;; (define (length) | |||
| ;; (** (+ (* x x) (* y y) (* z z)) 0.5)) | |||
| ;; (define (scale fac) | |||
| ;; (mutate x (* fac x)) | |||
| ;; (mutate y (* fac y)) | |||
| ;; (mutate z (* fac z)) | |||
| ;; fac) | |||
| ;; (define (add other) | |||
| ;; (make-vector3 | |||
| ;; (+ x (other get-x)) | |||
| ;; (+ y (other get-y)) | |||
| ;; (+ z (other get-z)))) | |||
| ;; (define (subtract other) | |||
| ;; (make-vector3 | |||
| ;; (- x (other get-x)) | |||
| ;; (- y (other get-y)) | |||
| ;; (- z (other get-z)))) | |||
| ;; (define (scalar-product other) | |||
| ;; (+ (* x (other get-x)) | |||
| ;; (* y (other get-y)) | |||
| ;; (* z (other get-z)))) | |||
| ;; (define (cross-product other) | |||
| ;; (make-vector3 | |||
| ;; (- (* y (other get-z)) (* z (other get-y))) | |||
| ;; (- (* z (other get-x)) (* x (other get-z))) | |||
| ;; (- (* x (other get-y)) (* y (other get-x))))) | |||
| ;; (define (print) | |||
| ;; (printf :sep "" "[vector3] (" x y z ")")) | |||
| ;; ) | |||
| ) | |||
| (define-class (vector3 x y z) | |||
| (define (set-x new-x) (mutate x new-x)) | |||
| (define (set-y new-y) (mutate y new-y)) | |||
| (define (set-z new-z) (mutate z new-z)) | |||
| (define (length) | |||
| (** (+ (* x x) (* y y) (* z z)) 0.5)) | |||
| (define (scale fac) | |||
| (mutate x (* fac x)) | |||
| (mutate y (* fac y)) | |||
| (mutate z (* fac z)) | |||
| fac) | |||
| (define (add other) | |||
| (make-vector3 | |||
| (+ (-> other x) x) | |||
| (+ (-> other y) y) | |||
| (+ (-> other z) z))) | |||
| (define (subtract other) | |||
| (make-vector3 | |||
| (- (-> other x) x) | |||
| (- (-> other y) y) | |||
| (- (-> other z) z))) | |||
| (define (equal? other) | |||
| (and (= (-> other x) x) | |||
| (= (-> other y) y) | |||
| (= (-> other z) z))) | |||
| (define (scalar-product other) | |||
| (+ (* (-> other x) x) | |||
| (* (-> other y) y) | |||
| (* (-> other z) z))) | |||
| (define (cross-product other) | |||
| (make-vector3 | |||
| (- (* (-> other z) y) (* (-> other y) z)) | |||
| (- (* (-> other x) z) (* (-> other z) x)) | |||
| (- (* (-> other y) x) (* (-> other x) y)))) | |||
| (define (print) | |||
| (printf :sep "" "[vector3] (" x " " y " " z ")")))) | |||
| @@ -2,22 +2,26 @@ | |||
| "Macro for creating simple classes." | |||
| (let ((name (first name-and-members)) | |||
| (members (rest name-and-members))) | |||
| `(define | |||
| ;; The function definition | |||
| (,(string->symbol (concat-strings "make-" (symbol->string name))) @members) | |||
| ;; The docstring | |||
| ,(concat-strings "This is the handle to an object of the class " (symbol->string name)) | |||
| ;; the body | |||
| (let ,(zip members members) | |||
| @body | |||
| (set-type | |||
| `(set-type | |||
| (define | |||
| ;; The function definition | |||
| (,(string->symbol (concat-strings "make-" (symbol->string name))) @members) | |||
| ;; The docstring | |||
| ,(concat-strings "This is the handle to an object of the class " (symbol->string name)) | |||
| ;; the body | |||
| @body | |||
| (let ,(zip members members) | |||
| (set-type | |||
| (lambda (:rest args) | |||
| "This is the docs for the handle" | |||
| (let ((op (eval (first args)))) | |||
| (if (callable? op) | |||
| (eval args) | |||
| (eval (first args))))) | |||
| ,(symbol->keyword name)))))) | |||
| ,(symbol->keyword name)))) | |||
| :constructor))) | |||
| (define-syntax (-> obj meth :rest args) | |||
| `(,obj ',meth @args)) | |||
| @@ -107,14 +107,14 @@ ithe sequence as arguemens." | |||
| (special-lambda (:rest args) | |||
| (let ((op (first args)) | |||
| (args (rest args))) | |||
| (cond ((= op 'pi) 3.14159265) | |||
| (else (try (apply op args) | |||
| (error "The package does not contain this operation")))))) | |||
| (if (callable? (eval op)) | |||
| (apply op args) | |||
| (eval op)))) | |||
| :package))))) | |||
| (define (nil? x) | |||
| "Checks if the argument is nil." | |||
| "Checks if the argument is =nil=." | |||
| (= x nil)) | |||
| (define (number? x) | |||
| @@ -141,8 +141,12 @@ ithe sequence as arguemens." | |||
| "Checks if the argument is a function." | |||
| (= (type x) :lambda)) | |||
| (define (special-lambda? x) | |||
| (define (macro? x) | |||
| "Checks if the argument is a macro." | |||
| (= (type x) :macro)) | |||
| (define (special-lambda? x) | |||
| "Checks if the argument is a special-lambda." | |||
| (= (type x) :dynamic-macro)) | |||
| (define (built-in-function? x) | |||
| @@ -152,6 +156,7 @@ ithe sequence as arguemens." | |||
| (define (callable? x) | |||
| (or (lambda? x) | |||
| (special-lambda? x) | |||
| (macro? x) | |||
| (built-in-function? x))) | |||
| (define (end seq) | |||
| @@ -204,25 +209,9 @@ with (pair elem nil)." | |||
| "Subtracts one from the argument." | |||
| (- val 1)) | |||
| ;; (defmacro for (@symbol @from @to :rest @for-body) | |||
| ;; "Designed to resemble a C style for loop. It takes a symbol as | |||
| ;; well as its starting number and end number and executes the | |||
| ;; @for-body with the defined symbol for all numbers between @from | |||
| ;; to @to, where @to is exclusive." | |||
| ;; (if (< (eval @from) (eval @to)) | |||
| ;; (macro-define @op incr) | |||
| ;; (if (> (eval @from) (eval @to)) | |||
| ;; (macro-define @op decr) | |||
| ;; (macro-define @op nil))) | |||
| ;; (when @op | |||
| ;; (macro-define (eval @symbol) (eval @from)) | |||
| ;; (eval (pair begin @for-body)) | |||
| ;; (eval (extend (list for @symbol (@op @from) @to) @for-body)))) | |||
| (define (range :keys from :defaults-to 0 to) | |||
| "Returns a sequence of numbers starting with the number defined | |||
| by the key 'from' and ends with the number defined in 'to'." | |||
| "Returns a sequence of numbers starting with the number defined by the | |||
| key =from= and ends with the number defined in =to=." | |||
| (when (< from to) | |||
| (pair from (range :from (+ 1 from) :to to)))) | |||
| @@ -249,10 +238,10 @@ elemens as argument to that function." | |||
| (map fun (rest seq))))) | |||
| (define (reduce fun seq) | |||
| "Takes a function and a sequence as arguments and applies the | |||
| function to the argument sequence. This only works correctly if | |||
| the given function accepts a variable amount of parameters. If | |||
| your funciton is limited to two arguments, use `reduce-binary' | |||
| "Takes a function and a sequence as arguments and applies the | |||
| function to the argument sequence. This only works correctly if the | |||
| given function accepts a variable amount of parameters. If your | |||
| funciton is limited to two arguments, use [[=reduce-binary=]] | |||
| instead." | |||
| (apply fun seq)) | |||
| @@ -1,4 +1,4 @@ | |||
| (define (nil? x) "Checks if the argument is nil." (= x nil)) | |||
| (define (nil? x) "Checks if the argument is =nil=." (= x nil)) | |||
| (define (number? x) "Checks if the argument is a number." (= (type x) :number)) | |||
| @@ -12,11 +12,13 @@ | |||
| (define (lambda? x) "Checks if the argument is a function." (= (type x) :lambda)) | |||
| (define (special-lambda? x) "Checks if the argument is a macro." (= (type x) :dynamic-macro)) | |||
| (define (macro? x) "Checks if the argument is a macro." (= (type x) :macro)) | |||
| (define (special-lambda? x) "Checks if the argument is a special-lambda." (= (type x) :dynamic-macro)) | |||
| (define (built-in-function? x) "Checks if the argument is a built-in function." (= (type x) :built-in-function)) | |||
| (define (callable? x) (or (lambda? x) (special-lambda? x) (built-in-function? x))) | |||
| (define (callable? x) (or (lambda? x) (special-lambda? x) (macro? x) (built-in-function? x))) | |||
| (define (end seq) "Returns the last pair in the sqeuence." (if (or (nil? seq) (not (pair? (rest seq)))) seq (end (rest seq)))) | |||
| @@ -37,8 +39,8 @@ with (pair elem nil)." (extend seq (pair elem ()))) | |||
| (define (decrement val) "Subtracts one from the argument." (- val 1)) | |||
| (define (range :keys from :defaults-to 0 to) "Returns a sequence of numbers starting with the number defined | |||
| by the key 'from' and ends with the number defined in 'to'." (when (< from to) (pair from (range :from (+ 1 from) :to to)))) | |||
| (define (range :keys from :defaults-to 0 to) "Returns a sequence of numbers starting with the number defined by the | |||
| key =from= and ends with the number defined in =to=." (when (< from to) (pair from (range :from (+ 1 from) :to to)))) | |||
| (define (range-while :keys from :defaults-to 0 to) "Returns a sequence of numbers starting with the number defined | |||
| by the key 'from' and ends with the number defined in 'to'." (define result (list (copy from))) (define head result) (mutate from (increment from)) (while (< from to) (begin (mutate head (pair (first head) (pair (copy from) nil))) (define head (rest head)) (mutate from (increment from)))) result) | |||
| @@ -47,10 +49,10 @@ by the key 'from' and ends with the number defined in 'to'." (define result (lis | |||
| sequence which contains the results of using the first sequences | |||
| elemens as argument to that function." (if (nil? seq) seq (pair (fun (first seq)) (map fun (rest seq))))) | |||
| (define (reduce fun seq) "Takes a function and a sequence as arguments and applies the | |||
| function to the argument sequence. This only works correctly if | |||
| the given function accepts a variable amount of parameters. If | |||
| your funciton is limited to two arguments, use `reduce-binary' | |||
| (define (reduce fun seq) "Takes a function and a sequence as arguments and applies the | |||
| function to the argument sequence. This only works correctly if the | |||
| given function accepts a variable amount of parameters. If your | |||
| funciton is limited to two arguments, use [[=reduce-binary=]] | |||
| instead." (apply fun seq)) | |||
| (define (reduce-binary fun seq) "Takes a function and a sequence as arguments and applies the | |||
| @@ -1,10 +1,6 @@ | |||
| (import "oo.slime") | |||
| (define-class (vector3 x y z) | |||
| (define (get-x) x) | |||
| (define (get-y) y) | |||
| (define (get-z) z) | |||
| (define (set-x new-x) (mutate x new-x)) | |||
| (define (set-y new-y) (mutate y new-y)) | |||
| (define (set-z new-z) (mutate z new-z)) | |||
| @@ -20,26 +16,31 @@ | |||
| (define (add other) | |||
| (make-vector3 | |||
| (+ x (other 'get-x)) | |||
| (+ y (other 'get-y)) | |||
| (+ z (other 'get-z)))) | |||
| (+ (-> other x) x) | |||
| (+ (-> other y) y) | |||
| (+ (-> other z) z))) | |||
| (define (subtract other) | |||
| (make-vector3 | |||
| (- x (other 'get-x)) | |||
| (- y (other 'get-y)) | |||
| (- z (other 'get-z)))) | |||
| (- (-> other x) x) | |||
| (- (-> other y) y) | |||
| (- (-> other z) z))) | |||
| (define (equal? other) | |||
| (and (= (-> other x) x) | |||
| (= (-> other y) y) | |||
| (= (-> other z) z))) | |||
| (define (scalar-product other) | |||
| (+ (* x (other 'get-x)) | |||
| (* y (other 'get-y)) | |||
| (* z (other 'get-z)))) | |||
| (+ (* (-> other x) x) | |||
| (* (-> other y) y) | |||
| (* (-> other z) z))) | |||
| (define (cross-product other) | |||
| (make-vector3 | |||
| (- (* y (other 'get-z)) (* z (other 'get-y))) | |||
| (- (* z (other 'get-x)) (* x (other 'get-z))) | |||
| (- (* x (other 'get-y)) (* y (other 'get-x))))) | |||
| (- (* (-> other z) y) (* (-> other y) z)) | |||
| (- (* (-> other x) z) (* (-> other z) x)) | |||
| (- (* (-> other y) x) (* (-> other x) y)))) | |||
| (define (print) | |||
| (printf :sep " " "[vector3] (" x y z ")")) | |||
| @@ -49,4 +50,7 @@ | |||
| (define v2 (make-vector3 3 2 1)) | |||
| (assert (= (type v1) (type v2) :vector3)) | |||
| ;; (assert (= (v1 'scalar-product v2) 10)) | |||
| (assert (= (v1 'scalar-product v2) 10)) | |||
| (assert (-> (-> v1 cross-product v2) | |||
| equal? | |||
| (make-vector3 -4 8 -4))) | |||
| @@ -1,6 +1,6 @@ | |||
| (import "oo.slime") | |||
| (define-class (vector3 x y z) (define (get-x) x) (define (get-y) y) (define (get-z) z) (define (set-x new-x) (mutate x new-x)) (define (set-y new-y) (mutate y new-y)) (define (set-z new-z) (mutate z new-z)) (define (length) (** (+ (* x x) (* y y) (* z z)) 0.500000)) (define (scale fac) (mutate x (* fac x)) (mutate y (* fac y)) (mutate z (* fac z)) fac) (define (add other) (make-vector3 (+ x (other 'get-x)) (+ y (other 'get-y)) (+ z (other 'get-z)))) (define (subtract other) (make-vector3 (- x (other 'get-x)) (- y (other 'get-y)) (- z (other 'get-z)))) (define (scalar-product other) (+ (* x (other 'get-x)) (* y (other 'get-y)) (* z (other 'get-z)))) (define (cross-product other) (make-vector3 (- (* y (other 'get-z)) (* z (other 'get-y))) (- (* z (other 'get-x)) (* x (other 'get-z))) (- (* x (other 'get-y)) (* y (other 'get-x))))) (define (print) (printf :sep " " "[vector3] (" x y z ")"))) | |||
| (define-class (vector3 x y z) (define (set-x new-x) (mutate x new-x)) (define (set-y new-y) (mutate y new-y)) (define (set-z new-z) (mutate z new-z)) (define (length) (** (+ (* x x) (* y y) (* z z)) 0.500000)) (define (scale fac) (mutate x (* fac x)) (mutate y (* fac y)) (mutate z (* fac z)) fac) (define (add other) (make-vector3 (+ (-> other x) x) (+ (-> other y) y) (+ (-> other z) z))) (define (subtract other) (make-vector3 (- (-> other x) x) (- (-> other y) y) (- (-> other z) z))) (define (equal? other) (and (= (-> other x) x) (= (-> other y) y) (= (-> other z) z))) (define (scalar-product other) (+ (* (-> other x) x) (* (-> other y) y) (* (-> other z) z))) (define (cross-product other) (make-vector3 (- (* (-> other z) y) (* (-> other y) z)) (- (* (-> other x) z) (* (-> other z) x)) (- (* (-> other y) x) (* (-> other x) y)))) (define (print) (printf :sep " " "[vector3] (" x y z ")"))) | |||
| (define v1 (make-vector3 1 2 3)) | |||
| @@ -8,3 +8,7 @@ | |||
| (assert (= (type v1) (type v2) :vector3)) | |||
| (assert (= (v1 'scalar-product v2) 10)) | |||
| (assert (-> (-> v1 cross-product v2) equal? (make-vector3 -4 8 -4))) | |||
| @@ -9,6 +9,10 @@ echo "" | |||
| pushd ./bin > /dev/null | |||
| time ./slime --run-tests | |||
| echo "" | |||
| echo "generating docs" | |||
| time ./slime generate-docs.slime | |||
| popd > /dev/null | |||
| popd > /dev/null | |||
| unset TIMEFORMAT | |||
| @@ -0,0 +1,955 @@ | |||
| * === | |||
| - defined in :: =src/./built_ins.cpp:158:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Takes 0 or more arguments and returns =t= if all arguments are equal and =()= otherwise. | |||
| #+END: | |||
| * =>= | |||
| - defined in :: =src/./built_ins.cpp:175:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =>== | |||
| - defined in :: =src/./built_ins.cpp:193:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =<= | |||
| - defined in :: =src/./built_ins.cpp:211:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =<== | |||
| - defined in :: =src/./built_ins.cpp:231:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =+= | |||
| - defined in :: =src/./built_ins.cpp:249:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =-= | |||
| - defined in :: =src/./built_ins.cpp:262:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =*= | |||
| - defined in :: =src/./built_ins.cpp:285:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =/= | |||
| - defined in :: =src/./built_ins.cpp:306:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =**= | |||
| - defined in :: =src/./built_ins.cpp:327:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =%= | |||
| - defined in :: =src/./built_ins.cpp:343:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =assert= | |||
| - defined in :: =src/./built_ins.cpp:359:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =define= | |||
| - defined in :: =src/./built_ins.cpp:371:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =mutate= | |||
| - defined in :: =src/./built_ins.cpp:433:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =if= | |||
| - defined in :: =src/./built_ins.cpp:458:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =quote= | |||
| - defined in :: =src/./built_ins.cpp:480:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =quasiquote= | |||
| - defined in :: =src/./built_ins.cpp:485:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =and= | |||
| - defined in :: =src/./built_ins.cpp:583:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =or= | |||
| - defined in :: =src/./built_ins.cpp:594:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =not= | |||
| - defined in :: =src/./built_ins.cpp:605:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =while= | |||
| - defined in :: =src/./built_ins.cpp:615:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =lambda= | |||
| - defined in :: =src/./built_ins.cpp:693:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =special-lambda= | |||
| - defined in :: =src/./built_ins.cpp:705:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =eval= | |||
| - defined in :: =src/./built_ins.cpp:713:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =begin= | |||
| - defined in :: =src/./built_ins.cpp:725:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =list= | |||
| - defined in :: =src/./built_ins.cpp:741:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =pair= | |||
| - defined in :: =src/./built_ins.cpp:745:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =first= | |||
| - defined in :: =src/./built_ins.cpp:755:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =rest= | |||
| - defined in :: =src/./built_ins.cpp:766:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =set-type= | |||
| - defined in :: =src/./built_ins.cpp:777:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =delete-type= | |||
| - defined in :: =src/./built_ins.cpp:789:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =type= | |||
| - defined in :: =src/./built_ins.cpp:796:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =info= | |||
| - defined in :: =src/./built_ins.cpp:828:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =show= | |||
| - defined in :: =src/./built_ins.cpp:910:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =addr-of= | |||
| - defined in :: =src/./built_ins.cpp:922:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =generate-docs= | |||
| - defined in :: =src/./built_ins.cpp:928:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =print= | |||
| - defined in :: =src/./built_ins.cpp:937:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =read= | |||
| - defined in :: =src/./built_ins.cpp:945:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =exit= | |||
| - defined in :: =src/./built_ins.cpp:962:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =break= | |||
| - defined in :: =src/./built_ins.cpp:973:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =memstat= | |||
| - defined in :: =src/./built_ins.cpp:978:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =try= | |||
| - defined in :: =src/./built_ins.cpp:982:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =load= | |||
| - defined in :: =src/./built_ins.cpp:997:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =import= | |||
| - defined in :: =src/./built_ins.cpp:1008:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =copy= | |||
| - defined in :: =src/./built_ins.cpp:1019:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =error= | |||
| - defined in :: =src/./built_ins.cpp:1027:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =symbol->keyword= | |||
| - defined in :: =src/./built_ins.cpp:1034:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =string->symbol= | |||
| - defined in :: =src/./built_ins.cpp:1043:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =symbol->string= | |||
| - defined in :: =src/./built_ins.cpp:1055:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =concat-strings= | |||
| - defined in :: =src/./built_ins.cpp:1064:0= | |||
| - type :: =:cfunction= | |||
| - docu :: | |||
| #+BEGIN: | |||
| TODO | |||
| #+END: | |||
| * =pe= | |||
| - defined in :: =pre.slime:2:40= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =expr= | |||
| - docu :: none | |||
| * =when= | |||
| - defined in :: =pre.slime:8:37= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =condition=: | |||
| - rest :: =body= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Doc String for `when' | |||
| #+END: | |||
| * =unless= | |||
| - defined in :: =pre.slime:13:41= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =condition=: | |||
| - rest :: =body= | |||
| - docu :: none | |||
| * =n-times= | |||
| - defined in :: =pre.slime:20:35= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =times=, =action= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Executes action times times. | |||
| #+END: | |||
| * =let= | |||
| - defined in :: =pre.slime:37:64= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =bindings=: | |||
| - rest :: =body= | |||
| - docu :: none | |||
| * =cond= | |||
| - defined in :: =pre.slime:51:19= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - rest :: =clauses= | |||
| - docu :: none | |||
| * =define-special= | |||
| - defined in :: =pre.slime:54:81= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =name-and-args=: | |||
| - rest :: =body= | |||
| - docu :: none | |||
| * =construct-list= | |||
| - defined in :: =pre.slime:94:14= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - rest :: =body= | |||
| - docu :: | |||
| #+BEGIN: | |||
| (construct-list | |||
| i <- '(1 2 3 4 5) | |||
| yield (* i i)) | |||
| (construct-list | |||
| i <- '(1 2 3 4) | |||
| j <- '(A B) | |||
| yield (pair i j)) | |||
| (construct-list | |||
| i <- '(1 2 3 4 5 6 7 8) | |||
| when (evenp i) | |||
| yield i) | |||
| #+END: | |||
| * =apply= | |||
| - defined in :: =pre.slime:99:28= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =fun=, =seq= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Applies the funciton to the sequence, as in calls the function with | |||
| ithe sequence as arguemens. | |||
| #+END: | |||
| * =define-package= | |||
| - defined in :: =pre.slime:113:24= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =name=: | |||
| - rest :: =body= | |||
| - docu :: none | |||
| * =nil?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Checks if the argument is =nil=. | |||
| #+END: | |||
| * =number?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Checks if the argument is a number. | |||
| #+END: | |||
| * =symbol?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Checks if the argument is a symbol. | |||
| #+END: | |||
| * =keyword?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Checks if the argument is a keyword. | |||
| #+END: | |||
| * =pair?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Checks if the argument is a pair. | |||
| #+END: | |||
| * =string?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Checks if the argument is a string. | |||
| #+END: | |||
| * =lambda?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Checks if the argument is a function. | |||
| #+END: | |||
| * =macro?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Checks if the argument is a macro. | |||
| #+END: | |||
| * =special-lambda?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Checks if the argument is a special-lambda. | |||
| #+END: | |||
| * =built-in-function?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Checks if the argument is a built-in function. | |||
| #+END: | |||
| * =callable?= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: none | |||
| * =end= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =seq= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Returns the last pair in the sqeuence. | |||
| #+END: | |||
| * =last= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =seq= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Returns the (first) of the last (pair) of the given sequence. | |||
| #+END: | |||
| * =extend= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =seq=, =elem= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Extends a list with the given element, by putting it in | |||
| the (rest) of the last element of the sequence. | |||
| #+END: | |||
| * =extend2= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =seq=, =elem= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Extends a list with the given element, by putting it in | |||
| the (rest) of the last element of the sequence. | |||
| #+END: | |||
| * =append= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =seq=, =elem= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Appends an element to a sequence, by extendeing the list | |||
| with (pair elem nil). | |||
| #+END: | |||
| * =length= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =seq= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Returns the length of the given sequence. | |||
| #+END: | |||
| * =increment= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =val= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Adds one to the argument. | |||
| #+END: | |||
| * =decrement= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =val= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Subtracts one from the argument. | |||
| #+END: | |||
| * =range= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - keyword :: =from= =(0)=, =to= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Returns a sequence of numbers starting with the number defined by the | |||
| key =from= and ends with the number defined in =to=. | |||
| #+END: | |||
| * =range-while= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - keyword :: =from= =(0)=, =to= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Returns a sequence of numbers starting with the number defined | |||
| by the key 'from' and ends with the number defined in 'to'. | |||
| #+END: | |||
| * =map= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =fun=, =seq= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Takes a function and a sequence as arguments and returns a new | |||
| sequence which contains the results of using the first sequences | |||
| elemens as argument to that function. | |||
| #+END: | |||
| * =reduce= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =fun=, =seq= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Takes a function and a sequence as arguments and applies the | |||
| function to the argument sequence. This only works correctly if the | |||
| given function accepts a variable amount of parameters. If your | |||
| funciton is limited to two arguments, use [[=reduce-binary=]] | |||
| instead. | |||
| #+END: | |||
| * =reduce-binary= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =fun=, =seq= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Takes a function and a sequence as arguments and applies the | |||
| function to the argument sequence. reduce-binary applies the | |||
| arguments `pair-wise' which means it works with binary functions | |||
| as compared to `reduce'. | |||
| #+END: | |||
| * =filter= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =fun=, =seq= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Takes a function and a sequence as arguments and applies the | |||
| function to every value in the sequence. If the result of that | |||
| funciton application returns a truthy value, the original value is | |||
| added to a list, which in the end is returned. | |||
| #+END: | |||
| * =zip= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =l1=, =l2= | |||
| - docu :: none | |||
| * =unzip= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =lists= | |||
| - docu :: none | |||
| * =enumerate= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =seq= | |||
| - docu :: none | |||
| * =printf= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - keyword :: =sep= =(" ")=, =end= =(" | |||
| ")=: | |||
| - rest :: =args= | |||
| - docu :: | |||
| #+BEGIN: | |||
| A wrapper for the built-in (print) that accepts a variable number | |||
| of arguments and also provides keywords for specifying the printed | |||
| separators between the arguments and what should be printed after the | |||
| las argument. | |||
| #+END: | |||
| * =define-class= | |||
| - defined in :: =oo.slime:22:22= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =name-and-members=: | |||
| - rest :: =body= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Macro for creating simple classes. | |||
| #+END: | |||
| * =->= | |||
| - defined in :: =oo.slime:25:24= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =obj=, =meth=: | |||
| - rest :: =args= | |||
| - docu :: none | |||
| * =math->= | |||
| - type :: =:package= | |||
| - arguments :: : | |||
| - rest :: =args= | |||
| - docu :: none | |||
| * =math-> pi= | |||
| - defined in :: =math.slime:5:4= | |||
| - type :: =:number= | |||
| - value :: =3.141593= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Tha famous circle constant. | |||
| #+END: | |||
| * =math-> abs= | |||
| - defined in :: =math.slime:9:4= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Accepts one argument and returns the absoulte value of it | |||
| #+END: | |||
| * =math-> sqrt= | |||
| - defined in :: =math.slime:13:4= | |||
| - type :: =:lambda= | |||
| - arguments :: : | |||
| - postitional :: =x= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Accepts one argument and returns the square root of it | |||
| #+END: | |||
| * =math-> make-vector3= | |||
| - defined in :: =pre.slime:37:63= | |||
| - type :: =:constructor= | |||
| - arguments :: : | |||
| - postitional :: =x=, =y=, =z= | |||
| - docu :: | |||
| #+BEGIN: | |||
| This is the handle to an object of the class vector3 | |||
| #+END: | |||
| * =math-> make-vector3 define-class= | |||
| - defined in :: =oo.slime:22:22= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =name-and-members=: | |||
| - rest :: =body= | |||
| - docu :: | |||
| #+BEGIN: | |||
| Macro for creating simple classes. | |||
| #+END: | |||
| * =math-> make-vector3 ->= | |||
| - defined in :: =oo.slime:25:24= | |||
| - type :: =:macro= | |||
| - arguments :: : | |||
| - postitional :: =obj=, =meth=: | |||
| - rest :: =args= | |||
| - docu :: none | |||
| @@ -410,6 +410,11 @@ other argument types, regular arguments and keyword arguments. | |||
| * Environments | |||
| * Macros | |||
| * Built-in functions | |||
| :PROPERTIES: | |||
| :UNNUMBERED: t | |||
| :END: | |||
| #+include: "./built-in-docs.org" | |||
| * COMMENT Built-in functions | |||
| This section provides a comprehensive list of the built in functions for Slime. Some of them are | |||
| defined in =C++= source code, some are themselves written in Slime. The cool thing about Slime is | |||
| that it is really easy to extend and adapt it for many purposes by writing new functions in =C++= | |||
| @@ -873,7 +878,7 @@ embedded scripting language. | |||
| : 3 | |||
| : (+ 2 3) | |||
| - =extend= :: (=regular function [Slime]=) Takes a list and any | |||
| - =extend= :: (=regular function [Slime]=) Takes a list and any | |||
| - =append= :: (=regular function [Slime]=) | |||
| @@ -930,57 +935,7 @@ embedded scripting language. | |||
| - =mutate= :: (=regular function [C++]=) | |||
| - =define= :: (=special form [C++]=) See the section about =define= in [[Define]]. | |||
| - =assert= :: (=regular function [C++]=) | |||
| * testbox :noexport: | |||
| #+BEGIN_SRC ditaa :file diagrams/test.eps :cmdline --no-separation --no-shadows | |||
| +-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+ | |||
| | | | | | | | | | | | | | |||
| | | |--->| | |--->| | |--->| | / | | |||
| | | | | | | | | | | | | | |||
| +-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+ | |||
| | | |||
| | | |||
| V | |||
| +-----+-----+ | |||
| | | | | |||
| | | / | | |||
| | | | | |||
| +-----+-----+ | |||
| #+END_SRC | |||
| #+RESULTS: | |||
| [[file:diagrams/test.eps]] | |||
| {{{slime_header}}} | |||
| #+caption: Some text to illustrate | |||
| #+begin_src slime | |||
| (define (fib x) | |||
| (cond ((< x 1) 0) | |||
| ((= x 1) 1) | |||
| (else (+ (fib (- x 1)) | |||
| (fib (- x 2)))))) | |||
| (print (if (> (fib 3) 1) | |||
| "Hello World\n" | |||
| "Goodbye World\n")) | |||
| (fib 12) | |||
| #+end_src | |||
| #+RESULTS: | |||
| : => Hello Felixses | |||
| : 144.000000 | |||
| {{{slime_header}}} | |||
| #+caption: Some text to illustrate | |||
| #+begin_src slime | |||
| ;; Comment here | |||
| (print "String here") | |||
| (+ 1 2 3) | |||
| #+end_src | |||
| #+RESULTS: | |||
| : => String here6.000000 | |||
| * COMMENT testbox | |||
| * meta :noexport: | |||
| # local variables: | |||
| # org-confirm-babel-evaluate: nil | |||
| @@ -32,6 +32,8 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { | |||
| proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* { | |||
| // char* full_file_name = find_slime_file(file_name); | |||
| char* file_content; | |||
| char fullpath[4096]; | |||
| sprintf(fullpath, "%s", Memory::get_c_str(file_name)); | |||
| file_content = read_entire_file(Memory::get_c_str(file_name)); | |||
| if (!file_content) { | |||
| @@ -43,8 +45,8 @@ proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* { | |||
| defer { | |||
| free(exe_path); | |||
| }; | |||
| char fullpath[4096]; | |||
| fullpath[0] = '\0'; | |||
| sprintf(fullpath, "%s%s", exe_path, Memory::get_c_str(file_name)); | |||
| // printf("Fullpath: %s\n", fullpath); | |||
| file_content = read_entire_file(fullpath); | |||
| @@ -59,7 +61,7 @@ proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* { | |||
| Lisp_Object* result = Memory::nil; | |||
| Lisp_Object_Array_List* program; | |||
| try program = Parser::parse_program(file_name, file_content); | |||
| try program = Parser::parse_program(Memory::create_string(fullpath), file_content); | |||
| for (int i = 0; i < program->next_index; ++i) { | |||
| try result = eval_expr(program->data[i], env); | |||
| @@ -86,13 +88,20 @@ proc built_in_import(String* file_name, Environment* env) -> Lisp_Object* { | |||
| proc load_built_ins_into_environment(Environment* env) -> void { | |||
| int arguments_length; | |||
| Lisp_Object* evaluated_arguments; | |||
| String* file_name_built_ins = Memory::create_string(__FILE__); | |||
| #define cLambda [=](Lisp_Object* arguments, Environment* env) mutable -> Lisp_Object* | |||
| proc defun = [&](const char* name, auto fun) { | |||
| // TODO(Felix): inline the params again after debugging | |||
| proc defun = [&](const char* name, const char* docs, int linenum, auto fun) { | |||
| auto sym = Memory::get_or_create_lisp_object_symbol(name); | |||
| auto sfun = Memory::create_lisp_object_cfunction(fun); | |||
| sfun->sourceCodeLocation = new(Source_Code_Location); | |||
| sfun->sourceCodeLocation->file = file_name_built_ins; | |||
| sfun->sourceCodeLocation->line = linenum; | |||
| sfun->sourceCodeLocation->column = 0; | |||
| sfun->docstring = Memory::create_string(docs); | |||
| define_symbol(sym, sfun, env); | |||
| }; | |||
| @@ -126,10 +135,10 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| arguments = arguments->value.pair.rest; | |||
| // if there is a docstring, use it | |||
| if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::String) { | |||
| ret->value.function.docstring = arguments->value.pair.first->value.string; | |||
| ret->docstring = arguments->value.pair.first->value.string; | |||
| arguments = arguments->value.pair.rest; | |||
| } else { | |||
| ret->value.function.docstring = nullptr; | |||
| ret->docstring = nullptr; | |||
| } | |||
| // we are now in the function body, just wrap it in an | |||
| @@ -143,7 +152,10 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return ret; | |||
| }; | |||
| defun("=", cLambda { | |||
| defun("=", | |||
| "Takes 0 or more arguments and returns =t= if all arguments are equal " | |||
| "and =()= otherwise.", | |||
| __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -160,7 +172,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::t; | |||
| }); | |||
| defun(">", cLambda { | |||
| defun(">", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -178,7 +190,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::t; | |||
| }); | |||
| defun(">=", cLambda { | |||
| defun(">=", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -196,7 +208,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::t; | |||
| }); | |||
| defun("<", cLambda { | |||
| defun("<", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try { | |||
| arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -216,7 +228,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::t; | |||
| }); | |||
| defun("<=", cLambda { | |||
| defun("<=", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -234,7 +246,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::t; | |||
| }); | |||
| defun("+", cLambda { | |||
| defun("+", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -247,7 +259,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| return Memory::create_lisp_object_number(sum); | |||
| }); | |||
| defun("-", cLambda { | |||
| defun("-", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -270,7 +282,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| return Memory::create_lisp_object_number(difference); | |||
| }); | |||
| defun("*", cLambda { | |||
| defun("*", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -291,7 +303,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| return Memory::create_lisp_object_number(product); | |||
| }); | |||
| defun("/", cLambda { | |||
| defun("/", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -312,7 +324,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| return Memory::create_lisp_object_number(quotient); | |||
| }); | |||
| defun("**", cLambda { | |||
| defun("**", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(2, arguments_length); | |||
| @@ -328,7 +340,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::create_lisp_object_number(pow(base, exponent)); | |||
| }); | |||
| defun("%", cLambda { | |||
| defun("%", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(2, arguments_length); | |||
| @@ -344,7 +356,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::create_lisp_object_number((int)a % (int)b); | |||
| }); | |||
| defun("assert", cLambda { | |||
| defun("assert", "TODO", __LINE__, cLambda { | |||
| int arguments_length; | |||
| try arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -356,7 +368,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| create_generic_error("Userland assertion."); | |||
| return nullptr; | |||
| }); | |||
| defun("define", cLambda { | |||
| defun("define", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| try assert_arguments_length_greater_equal(2, arguments_length); | |||
| @@ -396,19 +408,29 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| value = parse_lambda_starting_from_args(fake_lambda, env); | |||
| symbol = real_symbol; | |||
| } else { | |||
| try assert_arguments_length_less_equal(2, arguments_length); | |||
| try assert_arguments_length_greater_equal(2, arguments_length); | |||
| try assert_arguments_length_less_equal(3, arguments_length); | |||
| String* doc = nullptr; | |||
| if (arguments_length == 3) { | |||
| try assert_type(arguments->value.pair.rest->value.pair.first, Lisp_Object_Type::String); | |||
| doc = arguments->value.pair.rest->value.pair.first->value.string; | |||
| arguments = arguments->value.pair.rest; | |||
| } | |||
| try assert_type(symbol, Lisp_Object_Type::Symbol); | |||
| value = arguments->value.pair.rest->value.pair.first; | |||
| try value = eval_expr(value, env); | |||
| if (doc) | |||
| value->docstring = doc; | |||
| } | |||
| define_symbol(symbol, value, env); | |||
| return value; | |||
| }); | |||
| defun("mutate", cLambda { | |||
| defun("mutate", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(2, arguments_length); | |||
| Lisp_Object* target = evaluated_arguments->value.pair.first; | |||
| @@ -433,7 +455,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| *target = *source; | |||
| return target; | |||
| }); | |||
| defun("if", cLambda { | |||
| defun("if", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| try assert_arguments_length_greater_equal(2, arguments_length); | |||
| try assert_arguments_length_less_equal(3, arguments_length); | |||
| @@ -455,12 +477,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return result; | |||
| }); | |||
| defun("quote", cLambda { | |||
| defun("quote", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| try assert_arguments_length(1, arguments_length); | |||
| return arguments->value.pair.first; | |||
| }); | |||
| defun("quasiquote", cLambda { | |||
| defun("quasiquote", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| try assert_arguments_length(1, arguments_length); | |||
| @@ -558,7 +580,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| ret = unquoteSomeExpressions(ret); | |||
| return ret; | |||
| }); | |||
| defun("and", cLambda { | |||
| defun("and", "TODO", __LINE__, cLambda { | |||
| bool result = true; | |||
| while (arguments != Memory::nil) { | |||
| try assert_type(arguments, Lisp_Object_Type::Pair); | |||
| @@ -569,7 +591,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| return Memory::t; | |||
| }); | |||
| defun("or", cLambda { | |||
| defun("or", "TODO", __LINE__, cLambda { | |||
| bool result = false; | |||
| while (arguments != Memory::nil) { | |||
| try assert_type(arguments, Lisp_Object_Type::Pair); | |||
| @@ -580,7 +602,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| return Memory::nil; | |||
| }); | |||
| defun("not", cLambda { | |||
| defun("not", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| try assert_arguments_length(1, arguments_length); | |||
| @@ -590,7 +612,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return (truthy) ? Memory::nil : Memory::t; | |||
| }); | |||
| defun("while", cLambda { | |||
| defun("while", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| try assert(arguments_length >= 2); | |||
| @@ -616,7 +638,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return result; | |||
| }); | |||
| // defun("let", cLambda { | |||
| // defun("let", "TODO", __LINE__, cLambda { | |||
| // // (let ((a 10)(b 20)) (body1) (body2)) | |||
| // try arguments_length = list_length(arguments); | |||
| // try assert_arguments_length_greater_equal(1, arguments_length); | |||
| @@ -668,7 +690,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| // } | |||
| // return evaluated_arguments->value.pair.first; | |||
| // }); | |||
| defun("lambda", cLambda { | |||
| defun("lambda", "TODO", __LINE__, cLambda { | |||
| /* TODO(Felix): first one crashes | |||
| * (lambda ()) | |||
| * (lambda (x d) (+ 1 2) (- 1 2) (* 1 2)) | |||
| @@ -680,7 +702,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return function; | |||
| }); | |||
| defun("special-lambda", cLambda { | |||
| defun("special-lambda", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| try assert_arguments_length_greater_equal(1, arguments_length); | |||
| @@ -688,7 +710,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return function; | |||
| }); | |||
| defun("eval", cLambda { | |||
| defun("eval", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| @@ -700,11 +722,11 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| }); | |||
| defun("begin", cLambda { | |||
| defun("begin", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| if (evaluated_arguments == Memory::nil) | |||
| return evaluated_arguments; | |||
| return Memory::nil; | |||
| // skip to the last evaluated operand and return it, | |||
| // we use eval_arguments here instead of doing it | |||
| @@ -716,11 +738,11 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| return evaluated_arguments->value.pair.first; | |||
| }); | |||
| defun("list", cLambda { | |||
| defun("list", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| return evaluated_arguments; | |||
| }); | |||
| defun("pair", cLambda { | |||
| defun("pair", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(2, arguments_length); | |||
| @@ -730,7 +752,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| evaluated_arguments->value.pair.rest->value.pair.first); | |||
| return ret; | |||
| }); | |||
| defun("first", cLambda { | |||
| defun("first", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| @@ -741,7 +763,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return evaluated_arguments->value.pair.first->value.pair.first; | |||
| }); | |||
| defun("rest", cLambda { | |||
| defun("rest", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| @@ -752,7 +774,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return evaluated_arguments->value.pair.first->value.pair.rest; | |||
| }); | |||
| defun("set-type", cLambda { | |||
| defun("set-type", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(2, arguments_length); | |||
| @@ -764,14 +786,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| object->userType = type; | |||
| return object; | |||
| }); | |||
| defun("delete-type", cLambda { | |||
| defun("delete-type", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| evaluated_arguments->value.pair.first->userType = nullptr; | |||
| return Memory::t; | |||
| }); | |||
| defun("type", cLambda { | |||
| defun("type", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| @@ -803,7 +825,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| return Memory::get_or_create_lisp_object_keyword("unknown"); | |||
| }); | |||
| defun("info", cLambda { | |||
| defun("info", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| try assert_arguments_length(1, arguments_length); | |||
| @@ -817,9 +839,15 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| env); | |||
| if (type) { | |||
| Lisp_Object* val = eval_expr(arguments->value.pair.first, env); | |||
| printf(" is of type "); | |||
| print(type); | |||
| printf("\n\n"); | |||
| printf("\nand is printed as: "); | |||
| print(val); | |||
| printf("\n\ndocs: \n %s\n", | |||
| (val->docstring) | |||
| ? Memory::get_c_str(val->docstring) | |||
| : "No docs avaliable"); | |||
| // TODO(Felix): Maybe don't compare strings here?? Wtf | |||
| if (Memory::get_type(type) == Lisp_Object_Type::Keyword && | |||
| @@ -829,8 +857,8 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| { | |||
| Lisp_Object* fun = eval_expr(arguments->value.pair.first, env); | |||
| if (fun->value.function.docstring) | |||
| printf("Docstring:\n==========\n%s\n\n", Memory::get_c_str(fun->value.function.docstring)); | |||
| if (fun->docstring) | |||
| printf("Docstring:\n==========\n%s\n\n", Memory::get_c_str(fun->docstring)); | |||
| else | |||
| printf("No docstring avaliable\n"); | |||
| @@ -879,7 +907,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::nil; | |||
| }); | |||
| defun("show", cLambda { | |||
| defun("show", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Function); | |||
| @@ -891,13 +919,22 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::nil; | |||
| }); | |||
| defun("addr-of", cLambda { | |||
| defun("addr-of", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| return Memory::create_lisp_object_number((u64)&(evaluated_arguments->value.pair.first->value)); | |||
| }); | |||
| defun("print", cLambda { | |||
| defun("generate-docs", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| try assert_arguments_length(1, arguments_length); | |||
| try assert_type(arguments->value.pair.first, Lisp_Object_Type::String); | |||
| generate_docs(env, arguments->value.pair.first->value.string); | |||
| return Memory::t; | |||
| }); | |||
| defun("print", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| @@ -905,7 +942,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::nil; | |||
| }); | |||
| defun("read", cLambda { | |||
| defun("read", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length_less_equal(1, arguments_length); | |||
| @@ -922,7 +959,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| String* strLine = Memory::create_string(line); | |||
| return Memory::create_lisp_object_string(strLine); | |||
| }); | |||
| defun("exit", cLambda { | |||
| defun("exit", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length_less_equal(1, arguments_length); | |||
| @@ -933,16 +970,16 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| exit(0); | |||
| }); | |||
| defun("break", cLambda { | |||
| defun("break", "TODO", __LINE__, cLambda { | |||
| print_environment(env); | |||
| debug_break(); | |||
| return Memory::nil; | |||
| }); | |||
| defun("memstat", cLambda { | |||
| defun("memstat", "TODO", __LINE__, cLambda { | |||
| Memory::print_status(); | |||
| return Memory::nil; | |||
| }); | |||
| defun("try", cLambda { | |||
| defun("try", "TODO", __LINE__, cLambda { | |||
| try arguments_length = list_length(arguments); | |||
| try assert_arguments_length(2, arguments_length); | |||
| @@ -957,7 +994,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| } | |||
| return result; | |||
| }); | |||
| defun("load", cLambda { | |||
| defun("load", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::String); | |||
| @@ -968,7 +1005,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return result; | |||
| }); | |||
| defun("import", cLambda { | |||
| defun("import", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::String); | |||
| @@ -979,7 +1016,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return result; | |||
| }); | |||
| defun("copy", cLambda { | |||
| defun("copy", "TODO", __LINE__, cLambda { | |||
| // TODO(Felix): if we are copying string nodes, then | |||
| // shouldn't the string itself also get copied?? | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| @@ -987,14 +1024,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::copy_lisp_object(evaluated_arguments->value.pair.first); | |||
| }); | |||
| defun("error", cLambda { | |||
| defun("error", "TODO", __LINE__, cLambda { | |||
| // TODO(Felix): make the error function useful | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(0, arguments_length); | |||
| create_generic_error("Userlanderror"); | |||
| return nullptr; | |||
| }); | |||
| defun("symbol->keyword", cLambda { | |||
| defun("symbol->keyword", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Symbol); | |||
| @@ -1003,7 +1040,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::get_or_create_lisp_object_keyword(source->value.symbol.identifier); | |||
| }); | |||
| defun("string->symbol", cLambda { | |||
| defun("string->symbol", "TODO", __LINE__, cLambda { | |||
| // TODO(Felix): do some sanity checks on the string. For | |||
| // example, numbers are not valid symbols. | |||
| @@ -1015,7 +1052,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::get_or_create_lisp_object_symbol(Memory::duplicate_string(source->value.string)); | |||
| }); | |||
| defun("symbol->string", cLambda { | |||
| defun("symbol->string", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length(1, arguments_length); | |||
| try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Symbol); | |||
| @@ -1024,7 +1061,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { | |||
| return Memory::create_lisp_object_string(Memory::duplicate_string(source->value.symbol.identifier)); | |||
| }); | |||
| defun("concat-strings", cLambda { | |||
| defun("concat-strings", "TODO", __LINE__, cLambda { | |||
| try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | |||
| try assert_arguments_length_greater_equal(1, arguments_length); | |||
| @@ -0,0 +1,160 @@ | |||
| proc generate_docs(Environment* env, String* path) -> void { | |||
| // save the current working directory | |||
| char cwd[1024]; | |||
| getcwd(cwd, 1024); | |||
| // get the direction of the exe | |||
| char* exe_path = exe_dir(); | |||
| chdir(exe_path); | |||
| free(exe_path); | |||
| defer { | |||
| // switch back to the users directory | |||
| chdir(cwd); | |||
| }; | |||
| FILE *f = fopen(Memory::get_c_str(path), "w"); | |||
| if (!f) { | |||
| create_generic_error("The file for writing the documentation " | |||
| "could not be opened for writing."); | |||
| return; | |||
| } | |||
| defer { | |||
| fclose(f); | |||
| }; | |||
| Environment_Array_List* visited = create_Environment_array_list(); | |||
| std::function<void(Environment*, char* prefix)> print_this_env; | |||
| print_this_env = [&](Environment* env, char* prefix) -> void { | |||
| bool we_already_printed = false; | |||
| // TODO(Felix): Make a generic array_list_contains function | |||
| for (int i = 0; i < visited->next_index; ++i) { | |||
| if (visited->data[i] == env) { | |||
| we_already_printed = true; | |||
| break; | |||
| } | |||
| } | |||
| if (!we_already_printed) { | |||
| append_to_array_list(visited, env); | |||
| for (int i = 0; i < env->next_index; ++i) { | |||
| fprintf(f, "\n* =%s%s= \n" | |||
| // " :PROPERTIES:\n" | |||
| // " :UNNUMBERED: t\n" | |||
| // " :END:" | |||
| ,prefix, env->keys[i]); | |||
| /* | |||
| * sourcecodeLocation | |||
| */ | |||
| if (env->values[i]->sourceCodeLocation) { | |||
| fprintf(f, "\n - defined in :: =%s:%d:%d=", | |||
| Memory::get_c_str(env->values[i]->sourceCodeLocation->file), | |||
| env->values[i]->sourceCodeLocation->line, | |||
| env->values[i]->sourceCodeLocation->column); | |||
| } | |||
| /* | |||
| * type | |||
| */ | |||
| Lisp_Object_Type type = Memory::get_type(env->values[i]); | |||
| Lisp_Object* LOtype; | |||
| try_void LOtype = eval_expr(Memory::create_list( | |||
| Memory::get_or_create_lisp_object_symbol("type"), | |||
| env->values[i]), env); | |||
| fprintf(f, "\n - type :: ="); | |||
| print(LOtype, true, f); | |||
| fprintf(f, "="); | |||
| /* | |||
| * if printable value -> print it | |||
| */ | |||
| switch (type) { | |||
| case(Lisp_Object_Type::Nil): | |||
| case(Lisp_Object_Type::T): | |||
| case(Lisp_Object_Type::Number): | |||
| case(Lisp_Object_Type::String): | |||
| case(Lisp_Object_Type::Pair): | |||
| case(Lisp_Object_Type::Symbol): | |||
| case(Lisp_Object_Type::Keyword): { | |||
| fprintf(f, "\n - value :: ="); | |||
| print(env->values[i], true, f); | |||
| fprintf(f, "="); | |||
| } break; | |||
| default: break; | |||
| } | |||
| /* | |||
| * if function then print arguments | |||
| */ | |||
| if (type == Lisp_Object_Type::Function) { | |||
| Lisp_Object* fun = env->values[i]; | |||
| bool printed_at_least_some_args = false; | |||
| fprintf(f, "\n - arguments :: "); | |||
| if (fun->value.function.positional_arguments->next_index != 0) { | |||
| if (!printed_at_least_some_args) | |||
| fprintf(f, ":"); | |||
| fprintf(f, "\n - postitional :: "); | |||
| fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.positional_arguments->identifiers[0])); | |||
| for (int i = 1; i < fun->value.function.positional_arguments->next_index; ++i) { | |||
| fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.positional_arguments->identifiers[i])); | |||
| } | |||
| } | |||
| if (fun->value.function.keyword_arguments->next_index != 0) { | |||
| if (!printed_at_least_some_args) | |||
| fprintf(f, ":"); | |||
| fprintf(f, "\n - keyword :: "); | |||
| fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.keyword_arguments->identifiers[0])); | |||
| if (fun->value.function.keyword_arguments->values->data[0]) { | |||
| fprintf(f, " =("); | |||
| print(fun->value.function.keyword_arguments->values->data[0], true, f); | |||
| fprintf(f, ")="); | |||
| } | |||
| for (int i = 1; i < fun->value.function.keyword_arguments->next_index; ++i) { | |||
| fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.keyword_arguments->identifiers[i])); | |||
| if (fun->value.function.keyword_arguments->values->data[i]) { | |||
| fprintf(f, " =("); | |||
| print(fun->value.function.keyword_arguments->values->data[i], true, f); | |||
| fprintf(f, ")="); | |||
| } | |||
| } | |||
| } | |||
| if (fun->value.function.rest_argument) { | |||
| if (!printed_at_least_some_args) | |||
| fprintf(f, ":"); | |||
| fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(fun->value.function.rest_argument)); | |||
| } | |||
| // if no args at all | |||
| if (fun->value.function.positional_arguments->next_index == 0 && | |||
| fun->value.function.keyword_arguments->next_index == 0 && | |||
| !fun->value.function.rest_argument) | |||
| { | |||
| fprintf(f, "none."); | |||
| } | |||
| } | |||
| fprintf(f, "\n - docu :: "); | |||
| if (env->values[i]->docstring) | |||
| fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n", | |||
| Memory::get_c_str(env->values[i]->docstring)); | |||
| else | |||
| fprintf(f, "none\n"); | |||
| if (Memory::get_type(env->values[i]) == Lisp_Object_Type::Function && | |||
| env->values[i]->userType && | |||
| (string_equal(env->values[i]->userType->value.symbol.identifier, "package") || | |||
| string_equal(env->values[i]->userType->value.symbol.identifier, "constructor"))) | |||
| { | |||
| char new_prefix[200]; | |||
| strcpy(new_prefix, prefix); | |||
| strcat(new_prefix, env->keys[i]); | |||
| strcat(new_prefix, " "); | |||
| print_this_env(env->values[i]->value.function.parent_environment, new_prefix); | |||
| } | |||
| } | |||
| } | |||
| for (int i = 0; i < env->parents->next_index; ++i) { | |||
| print_this_env(env->parents->data[i], prefix); | |||
| } | |||
| }; | |||
| print_this_env(env, (char*)""); | |||
| } | |||
| @@ -68,11 +68,11 @@ proc print_indent(int indent) -> void { | |||
| } | |||
| proc print_environment_indent(Environment* env, int indent) -> void { | |||
| // if(env == Globals::root_environment) { | |||
| // print_indent(indent); | |||
| // printf("[built-ins]-Environment (%lld)\n", (long long)env); | |||
| // return; | |||
| // } | |||
| if(env == Globals::root_environment) { | |||
| print_indent(indent); | |||
| printf("[built-ins]-Environment (%lld)\n", (long long)env); | |||
| return; | |||
| } | |||
| for (int i = 0; i < env->next_index; ++i) { | |||
| print_indent(indent); | |||
| print(env->values[i]); | |||
| @@ -17,6 +17,7 @@ proc exe_dir() -> char*; | |||
| proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char*; | |||
| proc visualize_lisp_machine() -> void; | |||
| proc generate_docs(Environment* env, String* path) -> void; | |||
| namespace Memory { | |||
| proc create_built_ins_environment() -> Environment*; | |||
| @@ -27,7 +28,7 @@ namespace Memory { | |||
| namespace Parser { | |||
| extern Environment* environment_for_macros; | |||
| extern String* standard_in; | |||
| extern String* parser_file; | |||
| extern int parser_line; | |||
| @@ -260,6 +260,10 @@ proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) -> | |||
| fputs(Memory::get_c_str(node->value.string), file); | |||
| } break; | |||
| case (Lisp_Object_Type::Function): { | |||
| if (node->userType) { | |||
| fprintf(file, "[%s]", Memory::get_c_str(node->userType->value.symbol.identifier)); | |||
| break; | |||
| } | |||
| if (node->value.function.type == Function_Type::Lambda) | |||
| fputs("[lambda]", file); | |||
| else if (node->value.function.type == Function_Type::Special_Lambda) | |||
| @@ -5,9 +5,7 @@ int main(int argc, char* argv[]) { | |||
| if (argc > 1) { | |||
| if (Slime::string_equal(argv[1], "--run-tests")) { | |||
| return Slime::run_all_tests() ? 0 : 1; | |||
| } else if (Slime::string_equal(argv[1], "--run-as-emacs-repl")) { | |||
| Slime::interprete_stdin(true); | |||
| } | |||
| } | |||
| Slime::interprete_file(argv[1]); | |||
| if (Slime::Globals::error) { | |||
| @@ -154,7 +154,8 @@ namespace Memory { | |||
| Lisp_Object* object = object_memory+index; | |||
| object->flags = 0; | |||
| object->sourceCodeLocation = nullptr; | |||
| object->userType = nullptr; | |||
| object->userType = nullptr; | |||
| object->docstring = nullptr; | |||
| return object; | |||
| } | |||
| @@ -412,10 +412,10 @@ namespace Parser { | |||
| // arguments = arguments->value.pair.rest; | |||
| // if there is a docstring, use it | |||
| if (Memory::get_type(body->value.pair.first) == Lisp_Object_Type::String) { | |||
| macro->value.function.docstring = body->value.pair.first->value.string; | |||
| macro->docstring = body->value.pair.first->value.string; | |||
| body = body->value.pair.rest; | |||
| } else { | |||
| macro->value.function.docstring = nullptr; | |||
| macro->docstring = nullptr; | |||
| } | |||
| // we are now in the function body, just wrap it in an | |||
| @@ -424,6 +424,7 @@ namespace Parser { | |||
| Memory::get_or_create_lisp_object_symbol("begin"), | |||
| body); | |||
| inject_scl(macro); | |||
| // macro->value.function = function; | |||
| define_symbol(symbol_for_macro, macro, environment_for_macros); | |||
| @@ -567,7 +568,7 @@ namespace Parser { | |||
| }; | |||
| if (f == NULL) { | |||
| printf("Error opening file!\n"); | |||
| printf("Error opening .expanded file for writing!\n"); | |||
| exit(1); | |||
| } | |||
| @@ -27,6 +27,7 @@ namespace Slime { | |||
| # include "./parse.cpp" | |||
| # include "./eval.cpp" | |||
| # include "./visualization.cpp" | |||
| # include "./docgeneration.cpp" | |||
| # include "./built_ins.cpp" | |||
| # include "./testing.cpp" | |||
| # include "./undefines.cpp" | |||
| @@ -93,7 +93,6 @@ struct Keyword_Arguments { | |||
| struct Function { | |||
| Function_Type type; | |||
| String* docstring; | |||
| Positional_Arguments* positional_arguments; | |||
| Keyword_Arguments* keyword_arguments; | |||
| // rest_argument will be nullptr if no rest argument is declared | |||
| @@ -110,6 +109,7 @@ struct Lisp_Object { | |||
| Source_Code_Location* sourceCodeLocation; | |||
| u64 flags; | |||
| Lisp_Object* userType; | |||
| String* docstring; | |||
| union { | |||
| Symbol symbol; // used for symbols and keywords | |||
| double number; | |||