Ver a proveniência

auto doc generation

master
Felix Brendel há 7 anos
ascendente
cometimento
6f5ecc87b0
22 ficheiros alterados com 2383 adições e 237 eliminações
  1. +5
    -0
      .gitignore
  2. +4
    -0
      bin/generate-docs.slime
  3. +49
    -46
      bin/math.slime
  4. +14
    -10
      bin/oo.slime
  5. +16
    -27
      bin/pre.slime
  6. +11
    -9
      bin/pre.slime.expanded
  7. +21
    -17
      bin/tests/class_macro.slime
  8. +5
    -1
      bin/tests/class_macro.slime.expanded
  9. +4
    -0
      build.sh
  10. +955
    -0
      manual/built-in-docs.org
  11. +1014
    -0
      manual/built-in-docs.tex
  12. +7
    -52
      manual/manual.org
  13. +98
    -61
      src/built_ins.cpp
  14. +160
    -0
      src/docgeneration.cpp
  15. +5
    -5
      src/env.cpp
  16. +2
    -1
      src/forward_decls.cpp
  17. +4
    -0
      src/io.cpp
  18. +1
    -3
      src/main.cpp
  19. +2
    -1
      src/memory.cpp
  20. +4
    -3
      src/parse.cpp
  21. +1
    -0
      src/slime.h
  22. +1
    -1
      src/structs.cpp

+ 5
- 0
.gitignore Ver ficheiro

@@ -1,6 +1,11 @@
/vs/*/*
/build
*.ilk
*.aux
*.fls
*.log
*.toc
*.fdb_latexmk
*.pdb
*.exe
*.user


+ 4
- 0
bin/generate-docs.slime Ver ficheiro

@@ -0,0 +1,4 @@
(import "oo.slime")
(import "math.slime")

(generate-docs "../manual/built-in-docs.org")

+ 49
- 46
bin/math.slime Ver ficheiro

@@ -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 ")"))))

+ 14
- 10
bin/oo.slime Ver ficheiro

@@ -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))



+ 16
- 27
bin/pre.slime Ver ficheiro

@@ -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))



+ 11
- 9
bin/pre.slime.expanded Ver ficheiro

@@ -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


+ 21
- 17
bin/tests/class_macro.slime Ver ficheiro

@@ -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)))

+ 5
- 1
bin/tests/class_macro.slime.expanded Ver ficheiro

@@ -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)))


+ 4
- 0
build.sh Ver ficheiro

@@ -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

+ 955
- 0
manual/built-in-docs.org Ver ficheiro

@@ -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

+ 1014
- 0
manual/built-in-docs.tex
A apresentação das diferenças no ficheiro foi suprimida por ser demasiado grande
Ver ficheiro


+ 7
- 52
manual/manual.org Ver ficheiro

@@ -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


+ 98
- 61
src/built_ins.cpp Ver ficheiro

@@ -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);



+ 160
- 0
src/docgeneration.cpp Ver ficheiro

@@ -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*)"");
}

+ 5
- 5
src/env.cpp Ver ficheiro

@@ -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]);


+ 2
- 1
src/forward_decls.cpp Ver ficheiro

@@ -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;


+ 4
- 0
src/io.cpp Ver ficheiro

@@ -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)


+ 1
- 3
src/main.cpp Ver ficheiro

@@ -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) {


+ 2
- 1
src/memory.cpp Ver ficheiro

@@ -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;
}



+ 4
- 3
src/parse.cpp Ver ficheiro

@@ -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);
}



+ 1
- 0
src/slime.h Ver ficheiro

@@ -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"


+ 1
- 1
src/structs.cpp Ver ficheiro

@@ -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;


Carregando…
Cancelar
Guardar