From 5a117d94eefd1b4f47e717d13ff34c843ff46b94 Mon Sep 17 00:00:00 2001 From: Felix Brendel Date: Tue, 10 Sep 2019 09:46:29 +0200 Subject: [PATCH] better arguments struct, arraylists as values, fixed docgen --- build.bat | 15 +- manual/built-in-docs.org | 929 ++++++++++++++++++++++++++++++++++++--- src/built_ins.cpp | 55 +-- src/defines.cpp | 50 +-- src/docgeneration.cpp | 107 +++-- src/env.cpp | 24 +- src/error.cpp | 6 +- src/eval.cpp | 63 +-- src/forward_decls.cpp | 10 +- src/gc.cpp | 28 +- src/io.cpp | 8 +- src/lisp_object.cpp | 26 +- src/main.cpp | 4 +- src/memory.cpp | 62 +-- src/parse.cpp | 24 +- src/profiler.cpp | 0 src/slime.h | 1 - src/structs.cpp | 44 +- src/testing.cpp | 98 ++--- src/visualization.cpp | 110 ++--- vs/slime.vcxproj | 4 + 21 files changed, 1243 insertions(+), 425 deletions(-) delete mode 100644 src/profiler.cpp diff --git a/build.bat b/build.bat index 9e0c21a..435a8c6 100644 --- a/build.bat +++ b/build.bat @@ -1,28 +1,21 @@ @echo off @setlocal -pushd %~dp0 +pushd %~dp0\bin set exeName=slime.exe -pushd bin - taskkill /F /IM %exeName% > NUL 2> NUL echo ---------- Compiling ---------- -call ..\timecmd cl ../src/main.cpp /D_DEBUG /Zi /std:c++latest /Fe%exeName% /W3 /wd4003 /nologo /EHsc /link /NODEFAULTLIB:libucrt libucrtd.lib +call ..\timecmd cl ../src/main.cpp /D_PROFILING /D_DEBUG /D_DONT_BREAK_ON_ERRORS /Zi /std:c++latest /Fe%exeName% /W3 /wd4003 /nologo /EHsc /link /NODEFAULTLIB:libucrt libucrtd.lib rem call ..\timecmd clang-cl ../src/main.cpp -o %exeName% /O2 /std:c++latest /W3 /Zi /EHsc -popd + if %errorlevel% == 0 ( echo. echo ---- Running Tests ---- echo. - call timecmd bin\slime.exe --run-tests - echo. - echo ---- Genderating Docs ---- - echo. - call timecmd bin\slime generate-docs.slime - + call timecmd slime.exe --run-tests ) else ( echo. echo Fuckin' ell diff --git a/manual/built-in-docs.org b/manual/built-in-docs.org index 0dc4b00..77b4afc 100644 --- a/manual/built-in-docs.org +++ b/manual/built-in-docs.org @@ -1,7 +1,7 @@ \hrule * === - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:161:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:166:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -10,7 +10,7 @@ Takes 0 or more arguments and returns =t= if all arguments are equal and =()= ot \hrule * =>= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:177:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:182:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -19,7 +19,7 @@ TODO \hrule * =>== - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:194:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:199:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -28,7 +28,7 @@ TODO \hrule * =<= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:211:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:216:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -37,7 +37,7 @@ TODO \hrule * =<== - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:230:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:235:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -46,7 +46,7 @@ TODO \hrule * =+= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:247:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:252:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -55,7 +55,7 @@ TODO \hrule * =-= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:259:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:264:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -64,7 +64,7 @@ TODO \hrule * =*= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:281:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:286:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -73,7 +73,7 @@ TODO \hrule * =/= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:301:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:306:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -82,7 +82,7 @@ TODO \hrule * =**= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:321:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:326:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -91,7 +91,7 @@ TODO \hrule * =%= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:336:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:341:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -100,7 +100,7 @@ TODO \hrule * =assert= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:351:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:356:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -109,7 +109,7 @@ TODO \hrule * =define= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:362:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:367:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -118,7 +118,7 @@ TODO \hrule * =mutate= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:424:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:429:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -127,7 +127,7 @@ TODO \hrule * =vector-length= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:449:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:454:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -136,7 +136,7 @@ TODO \hrule * =vector-ref= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:457:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:462:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -145,7 +145,7 @@ TODO \hrule * =vector-set!= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:474:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:479:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -154,7 +154,7 @@ TODO \hrule * =set!= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:494:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:499:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -163,7 +163,7 @@ TODO \hrule * =set-car!= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:516:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:521:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -172,7 +172,7 @@ TODO \hrule * =set-cdr!= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:527:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:532:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -181,7 +181,7 @@ TODO \hrule * =if= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:538:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:543:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -190,7 +190,7 @@ TODO \hrule * =quote= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:558:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:563:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -199,7 +199,7 @@ TODO \hrule * =quasiquote= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:563:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:568:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -208,7 +208,7 @@ TODO \hrule * =and= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:660:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:665:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -217,7 +217,7 @@ TODO \hrule * =or= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:671:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:676:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -226,7 +226,7 @@ TODO \hrule * =not= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:682:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:687:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -235,7 +235,7 @@ TODO \hrule * =while= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:692:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:697:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -244,7 +244,7 @@ TODO \hrule * =lambda= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:770:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:775:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -253,7 +253,7 @@ TODO \hrule * =special-lambda= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:782:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:787:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -262,7 +262,7 @@ TODO \hrule * =eval= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:790:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:795:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -271,7 +271,7 @@ TODO \hrule * =begin= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:802:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:807:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -280,7 +280,7 @@ TODO \hrule * =list= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:818:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:823:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -289,7 +289,7 @@ TODO \hrule * =vector= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:822:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:827:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -298,7 +298,7 @@ TODO \hrule * =pair= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:828:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:833:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -307,7 +307,7 @@ TODO \hrule * =first= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:838:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:843:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -316,7 +316,7 @@ TODO \hrule * =rest= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:849:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:854:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -325,7 +325,7 @@ TODO \hrule * =set-type= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:860:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:865:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -334,7 +334,7 @@ TODO \hrule * =delete-type= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:872:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:877:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -343,7 +343,7 @@ TODO \hrule * =type= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:879:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:884:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -352,7 +352,7 @@ TODO \hrule * =info= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:913:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:918:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -361,7 +361,7 @@ TODO \hrule * =show= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:994:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:999:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -370,7 +370,7 @@ TODO \hrule * =addr-of= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1006:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1011:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -379,7 +379,7 @@ TODO \hrule * =generate-docs= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1012:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1017:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -388,7 +388,7 @@ TODO \hrule * =print= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1021:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1026:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -397,7 +397,7 @@ TODO \hrule * =read= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1029:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1034:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -406,7 +406,7 @@ TODO \hrule * =exit= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1046:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1051:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -415,7 +415,7 @@ TODO \hrule * =break= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1057:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1062:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -424,7 +424,7 @@ TODO \hrule * =memstat= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1062:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1067:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -433,7 +433,7 @@ TODO \hrule * =try= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1066:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1071:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -442,7 +442,7 @@ TODO \hrule * =load= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1081:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1086:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -451,7 +451,7 @@ TODO \hrule * =import= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1092:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1097:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -460,7 +460,7 @@ TODO \hrule * =copy= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1103:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1108:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -469,7 +469,7 @@ TODO \hrule * =error= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1111:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1116:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -478,7 +478,7 @@ TODO \hrule * =symbol->keyword= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1118:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1123:0= - type :: =:cfunction= - docu :: #+BEGIN: @@ -487,8 +487,825 @@ TODO \hrule * =string->symbol= - - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1127:0= + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1132:0= + - type :: =:cfunction= + - docu :: + #+BEGIN: +TODO + #+END: +\hrule +* =symbol->string= + + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1144:0= + - type :: =:cfunction= + - docu :: + #+BEGIN: +TODO + #+END: +\hrule +* =concat-strings= + + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:1153:0= + - type :: =:cfunction= + - docu :: + #+BEGIN: +TODO + #+END: +\hrule +* =pe= + + - defined in :: =pre.slime:4:40= + - type :: =:macro= + - arguments :: : + - postitional :: =expr= + - docu :: none +\hrule +* =when= + + - defined in :: =pre.slime:23:41= + - type :: =:macro= + - arguments :: : + - postitional :: =condition=: + - rest :: =body= + - docu :: + #+BEGIN: +Special form for when multiple actions should be done if a +condition is true. + +{{{example_start}}} +(when (not ()) + (print "Hello ") + (print "from ") + (print "when!")) + +(when () + (print "Goodbye ") + (print "World!")) +{{{example_end}}} + + #+END: +\hrule +* =unless= + + - defined in :: =pre.slime:30:41= + - type :: =:macro= + - arguments :: : + - postitional :: =condition=: + - rest :: =body= + - docu :: + #+BEGIN: +Special form for when multiple actions should be done if a +condition is false. + #+END: +\hrule +* =n-times= + + - defined in :: =pre.slime:37:35= + - type :: =:macro= + - arguments :: : + - postitional :: =times=, =action= + - docu :: + #+BEGIN: +Executes action times times. + #+END: +\hrule +* =let= + + - defined in :: =pre.slime:54:64= + - type :: =:macro= + - arguments :: : + - postitional :: =bindings=: + - rest :: =body= + - docu :: none +\hrule +* =cond= + + - defined in :: =pre.slime:68:17= + - type :: =:macro= + - arguments :: : + - rest :: =clauses= + - docu :: none +\hrule +* =case= + + - defined in :: =pre.slime:83:17= + - type :: =:macro= + - arguments :: : + - postitional :: =var=: + - rest :: =clauses= + - docu :: none +\hrule +* =define-special= + + - defined in :: =pre.slime:86:81= + - type :: =:macro= + - arguments :: : + - postitional :: =name-and-args=: + - rest :: =body= + - docu :: none +\hrule +* =construct-list= + + - defined in :: =pre.slime:127:14= + - type :: =:macro= + - arguments :: : + - rest :: =body= + - docu :: + #+BEGIN: + +{{{example_start}}} +(construct-list + i <- '(1 2 3 4 5) + yield (* i i)) +{{{example_end}}} + +(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) + if (= 0 (% i 2)) + yield i) + + #+END: +\hrule +* =apply= + + - defined in :: =pre.slime:132:28= + - type :: =:macro= + - arguments :: : + - postitional :: =fun=, =seq= + - docu :: + #+BEGIN: +Applies the function to the sequence, as in calls the function with +ithe sequence as arguemens. + #+END: +\hrule +* =define-typed= + + - defined in :: =pre.slime:144:16= + - type :: =:macro= + - arguments :: : + - postitional :: =args=: + - rest :: =body= + - docu :: none +\hrule +* =define-module= + + - defined in :: =pre.slime:158:27= + - type :: =:macro= + - arguments :: : + - postitional :: =module-name=: + - keyword :: =exports=: + - rest :: =body= + - docu :: none +\hrule +* =null?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Checks if the argument is =nil=. + #+END: +\hrule +* =type=?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =obj=, =typ= + - docu :: + #+BEGIN: +Checks if the argument =obj= is of type =typ= + #+END: +\hrule +* =types=?= + + - type :: =:lambda= + - arguments :: : + - rest :: =objs= + - docu :: none +\hrule +* =assert-types== + + - type :: =:lambda= + - arguments :: : + - rest :: =objs= + - docu :: none +\hrule +* =number?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Checks if the argument is a number. + #+END: +\hrule +* =symbol?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Checks if the argument is a symbol. + #+END: +\hrule +* =keyword?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Checks if the argument is a keyword. + #+END: +\hrule +* =pair?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Checks if the argument is a pair. + #+END: +\hrule +* =string?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Checks if the argument is a string. + #+END: +\hrule +* =lambda?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Checks if the argument is a function. + #+END: +\hrule +* =macro?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Checks if the argument is a macro. + #+END: +\hrule +* =special-lambda?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Checks if the argument is a special-lambda. + #+END: +\hrule +* =built-in-function?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Checks if the argument is a built-in function. + #+END: +\hrule +* =callable?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: none +\hrule +* =end= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: + #+BEGIN: +Returns the last pair in the sqeuence. + +{{{example_start}}} +(define a (list 1 2 3 4)) +(printf (end a)) +{{{example_end}}} + + #+END: +\hrule +* =last= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: + #+BEGIN: +Returns the (first) of the last (pair) of the given sequence. + +{{{example_start}}} +(define a (list 1 2 3 4)) +(printf (last a)) +{{{example_end}}} + + #+END: +\hrule +* =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: +\hrule +* =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: +\hrule +* =append= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq=, =elem= + - docu :: + #+BEGIN: +Appends an element to a sequence, by extendeing the list +with (pair elem nil). + #+END: +\hrule +* =length= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: + #+BEGIN: +Returns the length of the given sequence. + #+END: +\hrule +* =member?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =elem=, =seq= + - docu :: none +\hrule +* =sublist-starting-at-index= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq=, =index= + - docu :: none +\hrule +* =list-without-index= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq=, =index= + - docu :: none +\hrule +* =increment= + + - type :: =:lambda= + - arguments :: : + - postitional :: =val= + - docu :: + #+BEGIN: +Adds one to the argument. + #+END: +\hrule +* =decrement= + + - type :: =:lambda= + - arguments :: : + - postitional :: =val= + - docu :: + #+BEGIN: +Subtracts one from the argument. + #+END: +\hrule +* =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: +\hrule +* =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: +\hrule +* =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: +\hrule +* =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: +\hrule +* =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: +\hrule +* =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: +\hrule +* =zip= + + - type :: =:lambda= + - arguments :: : + - postitional :: =l1=, =l2= + - docu :: none +\hrule +* =unzip= + + - type :: =:lambda= + - arguments :: : + - postitional :: =lists= + - docu :: none +\hrule +* =enumerate= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =printf= + + - type :: =:lambda= + - arguments :: : + - keyword :: =sep= =(" ")=, =end= =("\n")=: + - rest :: =args= + - docu :: + #+BEGIN: +A wrapper for the built-in function [[=print=]] that accepts a +variable number of arguments and also provides keywords for specifying +the printed separators (=sep=) between the arguments and what should +be printed after the last argument (=end=). + #+END: +\hrule +* =key-not-found-index= + + - defined in :: =alist.slime:28:31= + - type :: =:number= + - value :: =-1= + - docu :: none +\hrule +* =make-alist= + + - type :: =:lambda= + - arguments :: none. + - docu :: none +\hrule +* =make-plist= + + - type :: =:lambda= + - arguments :: none. + - docu :: none +\hrule +* =pprint-alist= + + - type :: =:lambda= + - arguments :: : + - postitional :: =alist= + - docu :: none +\hrule +* =pprint-plist= + + - type :: =:lambda= + - arguments :: : + - postitional :: =plist= + - docu :: none +\hrule +* =alist-get= + + - type :: =:lambda= + - arguments :: : + - postitional :: =alist=, =key= + - docu :: none +\hrule +* =alist-find= + + - type :: =:lambda= + - arguments :: : + - postitional :: =alist=, =key= + - docu :: none +\hrule +* =alist-key-exists?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =alist=, =key= + - docu :: none +\hrule +* =alist-remove!= + + - type :: =:lambda= + - arguments :: : + - postitional :: =alist=, =key= + - docu :: none +\hrule +* =alist-set!= + + - type :: =:lambda= + - arguments :: : + - postitional :: =alist=, =key=, =value= + - docu :: none +\hrule +* =alist-set-overwrite!= + + - type :: =:lambda= + - arguments :: : + - postitional :: =alist=, =key=, =value= + - docu :: none +\hrule +* =plist-get= + + - type :: =:lambda= + - arguments :: : + - postitional :: =plist=, =prop= + - docu :: none +\hrule +* =plist-set!= + + - type :: =:lambda= + - arguments :: : + - postitional :: =plist=, =prop=, =value= + - docu :: none +\hrule +* =plist-set-overwrite!= + + - type :: =:lambda= + - arguments :: : + - postitional :: =plist=, =prop=, =value= + - docu :: none +\hrule +* =plist-find= + + - type :: =:lambda= + - arguments :: : + - postitional :: =plist=, =prop= + - docu :: none +\hrule +* =plist-prop-exists?= + + - type :: =:lambda= + - arguments :: : + - postitional :: =plist=, =prop= + - docu :: none +\hrule +* =plist-remove!= + + - type :: =:lambda= + - arguments :: : + - postitional :: =plist=, =prop= + - docu :: none +\hrule +* =cons= + + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:833:0= + - type :: =:cfunction= + - docu :: + #+BEGIN: +TODO + #+END: +\hrule +* =car= + + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:843:0= - type :: =:cfunction= - docu :: #+BEGIN: -TOD \ No newline at end of file +TODO + #+END: +\hrule +* =cdr= + + - defined in :: =d:\code\gitlab\slime\src\./built_ins.cpp:854:0= + - type :: =:cfunction= + - docu :: + #+BEGIN: +TODO + #+END: +\hrule +* =caar= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =cddr= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =cadr= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =cdar= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =caaar= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =caadr= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =cadar= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =caddr= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =cdaar= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =cdadr= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =cddar= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =cdddr= + + - type :: =:lambda= + - arguments :: : + - postitional :: =seq= + - docu :: none +\hrule +* =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: +\hrule +* =->= + + - defined in :: =oo.slime:25:24= + - type :: =:macro= + - arguments :: : + - postitional :: =obj=, =meth=: + - rest :: =args= + - docu :: none +\hrule +* =math::pi= + + - defined in :: =pre.slime:338:12= + - type :: =:number= + - value :: =3.141593= + - docu :: + #+BEGIN: +Tha famous circle constant. + #+END: +\hrule +* =math::abs= + + - defined in :: =pre.slime:338:12= + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Accepts one argument and returns the absoulte value of it + #+END: +\hrule +* =math::sqrt= + + - defined in :: =pre.slime:338:12= + - type :: =:lambda= + - arguments :: : + - postitional :: =x= + - docu :: + #+BEGIN: +Accepts one argument and returns the square root of it + #+END: +\hrule +* =math::make-vector3= + + - defined in :: =pre.slime:338:12= + - type :: =:constructor= + - arguments :: : + - postitional :: =x=, =y=, =z= + - docu :: + #+BEGIN: +This is the handle to an object of the class vector3 + #+END: diff --git a/src/built_ins.cpp b/src/built_ins.cpp index 61f222c..c69ea16 100644 --- a/src/built_ins.cpp +++ b/src/built_ins.cpp @@ -54,19 +54,24 @@ proc built_in_load(String* file_name) -> Lisp_Object* { file_content = read_entire_file(fullpath); if (!file_content) { - create_generic_error("The file '%s' was not found " - "(neither in the cwd nor in slime's bin dir)", - Memory::get_c_str(file_name)); + char* cwd = get_cwd(); + defer { + free(cwd); + }; + create_generic_error("The file to load '%s' was not found: " + "neither in the cwd (%s) " + "nor in slime's exe dir (%s)", + Memory::get_c_str(file_name), cwd, fullpath); return nullptr; } } Lisp_Object* result = Memory::nil; - Lisp_Object_Array_List* program; + Lisp_Object_Array_List program; 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]); + for (int i = 0; i < program.next_index; ++i) { + try result = eval_expr(program.data[i]); } return result; } @@ -75,7 +80,7 @@ proc built_in_import(String* file_name) -> Lisp_Object* { // create new empty environment Environment* new_env; try new_env = Memory::create_child_environment(get_root_environment()); - append_to_array_list(get_current_environment()->parents, new_env); + append_to_array_list(&get_current_environment()->parents, new_env); push_environment(new_env); defer { @@ -130,9 +135,9 @@ proc load_built_ins_into_environment() -> void { parse_argument_list(arguments->value.pair.first, &ret->value.function); } } else { - ret->value.function.positional_arguments = create_positional_argument_list(1); - ret->value.function.keyword_arguments = create_keyword_argument_list(1); - ret->value.function.rest_argument = nullptr; + ret->value.function.args.positional = create_positional_argument_list(1); + ret->value.function.args.keyword = create_keyword_argument_list(1); + ret->value.function.args.rest = nullptr; } arguments = arguments->value.pair.rest; @@ -948,39 +953,39 @@ proc load_built_ins_into_environment() -> void { printf("Arguments:\n==========\n"); printf("Postitional: {"); - if (fun->value.function.positional_arguments->next_index != 0) { + if (fun->value.function.args.positional.symbols.next_index != 0) { printf("%s", - Memory::get_c_str(fun->value.function.positional_arguments->symbols[0]->value.symbol.identifier)); - for (int i = 1; i < fun->value.function.positional_arguments->next_index; ++i) { + Memory::get_c_str(fun->value.function.args.positional.symbols.data[0]->value.symbol.identifier)); + for (int i = 1; i < fun->value.function.args.positional.symbols.next_index; ++i) { printf(", %s", - Memory::get_c_str(fun->value.function.positional_arguments->symbols[i]->value.symbol.identifier)); + Memory::get_c_str(fun->value.function.args.positional.symbols.data[i]->value.symbol.identifier)); } } printf("}\n"); printf("Keyword: {"); - if (fun->value.function.keyword_arguments->values->next_index != 0) { + if (fun->value.function.args.keyword.values.next_index != 0) { printf("%s", - Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[0]->value.symbol.identifier)); - if (fun->value.function.keyword_arguments->values->data[0]) { + Memory::get_c_str(fun->value.function.args.keyword.keywords.data[0]->value.symbol.identifier)); + if (fun->value.function.args.keyword.values.data[0]) { printf(" ("); - print(fun->value.function.keyword_arguments->values->data[0]); + print(fun->value.function.args.keyword.values.data[0]); printf(")"); } - for (int i = 1; i < fun->value.function.keyword_arguments->values->next_index; ++i) { + for (int i = 1; i < fun->value.function.args.keyword.values.next_index; ++i) { printf(", %s", - Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[i]->value.symbol.identifier)); - if (fun->value.function.keyword_arguments->values->data[i]) { + Memory::get_c_str(fun->value.function.args.keyword.keywords.data[i]->value.symbol.identifier)); + if (fun->value.function.args.keyword.values.data[i]) { printf(" ("); - print(fun->value.function.keyword_arguments->values->data[i]); + print(fun->value.function.args.keyword.values.data[i]); printf(")"); } } } printf("}\n"); printf("Rest: {"); - if (fun->value.function.rest_argument) + if (fun->value.function.args.rest) printf("%s", - Memory::get_c_str(fun->value.function.rest_argument)); + Memory::get_c_str(fun->value.function.args.rest)); printf("}\n"); } @@ -1014,7 +1019,7 @@ proc load_built_ins_into_environment() -> void { try assert_arguments_length(1, arguments_length); try assert_type(arguments->value.pair.first, Lisp_Object_Type::String); - generate_docs(arguments->value.pair.first->value.string); + try generate_docs(arguments->value.pair.first->value.string); return Memory::t; }); diff --git a/src/defines.cpp b/src/defines.cpp index e0478d6..deec26d 100644 --- a/src/defines.cpp +++ b/src/defines.cpp @@ -37,8 +37,9 @@ } \ else label(body,__LINE__): -#define try_void try_or_else_return() -#define try try_or_else_return(0) +#define try_struct try_or_else_return({}) +#define try_void try_or_else_return() +#define try try_or_else_return(0) #define dont_break_on_errors fluid_let(Globals::breaking_on_errors, false) #define ignore_logging fluid_let(Globals::log_level, Log_Level::None) @@ -53,16 +54,17 @@ \ proc remove_index_from_array_list(name##_Array_List* arraylist, int index) -> void { \ arraylist->data[index] = \ - arraylist->data[--arraylist->next_index]; \ + arraylist->data[--(arraylist->next_index)]; \ } \ \ proc append_to_array_list(name##_Array_List* arraylist, type element) -> void { \ - if (arraylist->next_index == arraylist->length) { \ - arraylist->length *= 2; \ - arraylist->data = \ + if (arraylist->next_index == arraylist->length) { \ + arraylist->length *= 2; \ + arraylist->data = \ (type*)realloc(arraylist->data, arraylist->length * sizeof(type)); \ } \ - arraylist->data[arraylist->next_index++] = element; \ + arraylist->data[arraylist->next_index] = element; \ + arraylist->next_index++; \ } \ \ proc _merge_array_lists(name##_Array_List* arr, int start, int mid, int end) -> void { \ @@ -99,7 +101,7 @@ \ proc sort_array_list(name##_Array_List* arraylist, int left=-1, int right=-1) -> void { \ if (left == -1) { \ - sort_array_list(arraylist, 0, arraylist->next_index - 1); \ + sort_array_list(arraylist, 0, arraylist->next_index - 1); \ return; \ } else if (left == right) { \ return; \ @@ -107,17 +109,17 @@ \ int middle = left + (right-left) / 2; \ \ - sort_array_list(arraylist, left, middle); \ - sort_array_list(arraylist, middle+1, right); \ + sort_array_list(arraylist, left, middle); \ + sort_array_list(arraylist, middle+1, right); \ \ - _merge_array_lists(arraylist, left, middle, right); \ + _merge_array_lists(arraylist, left, middle, right); \ } \ \ proc sorted_array_list_find(name##_Array_List* arraylist, type elem, int left=-1, int right=-1) -> int { \ if (left == -1) { \ return sorted_array_list_find(arraylist, elem, 0, arraylist->next_index - 1); \ } else if (left == right) { \ - if ((size_t)arraylist->data[left] == (size_t)elem) \ + if ((size_t)arraylist->data[left] == (size_t)elem) \ return left; \ return -1; \ } else if (right < left) \ @@ -125,18 +127,18 @@ \ int middle = left + (right-left) / 2; \ \ - if ((size_t)arraylist->data[middle] < (size_t)elem) \ + if ((size_t)arraylist->data[middle] < (size_t)elem) \ return sorted_array_list_find(arraylist, elem, middle+1, right); \ - if ((size_t)arraylist->data[middle] > (size_t)elem) \ + if ((size_t)arraylist->data[middle] > (size_t)elem) \ return sorted_array_list_find(arraylist, elem, left, middle-1); \ return middle; \ } \ \ - proc create_##name##_array_list(int initial_capacity = 16) -> name##_Array_List* { \ - name##_Array_List* ret = new(name##_Array_List); \ - ret->data = (type*)malloc(initial_capacity * sizeof(type)); \ - ret->next_index = 0; \ - ret->length = initial_capacity; \ + proc create_##name##_array_list(int initial_capacity = 16) -> name##_Array_List { \ + name##_Array_List ret; \ + ret.data = (type*)malloc(initial_capacity * sizeof(type)); \ + ret.next_index = 0; \ + ret.length = initial_capacity; \ return ret; \ } @@ -145,13 +147,11 @@ * iterate over array lists */ #define for_array_list(l) \ - if (!l); \ + if (int it_index = 0); \ else \ - if (int it_index = 0); \ - else \ - for (auto it = l->data[0]; \ - it_index < l->next_index; \ - it=l->data[++it_index]) + for (auto it = (l).data[0]; \ + it_index < (l).next_index; \ + it=(l).data[++it_index]) /* * iterate over lisp vectors diff --git a/src/docgeneration.cpp b/src/docgeneration.cpp index d8a2e2a..d258507 100644 --- a/src/docgeneration.cpp +++ b/src/docgeneration.cpp @@ -1,41 +1,38 @@ proc generate_docs(String* path) -> void { - // save the current working directory - char* cwd = get_cwd(); - // get the direction of the exe - char* exe_path = get_exe_dir(); - change_cwd(exe_path); - - defer { - // switch back to the users directory - change_cwd(cwd); - free(exe_path); - free(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."); + create_generic_error("The file for writing the documentation (%s) " + "could not be opened for writing.", Memory::get_c_str(path)); return; } defer { fclose(f); }; - Environment_Array_List* visited = create_Environment_array_list(); + Environment_Array_List visited = create_Environment_array_list(); + // recursive inner funciton std::function 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) { + for_array_list(visited) { + if (it == env) { we_already_printed = true; break; } } if (!we_already_printed) { - append_to_array_list(visited, env); + printf("Working ion env::::"); + print_environment(env); + printf("\n--------------------------------\n"); + append_to_array_list(&visited, env); + + push_environment(env); + defer { + pop_environment(); + }; + for (int i = 0; i < env->next_index; ++i) { fprintf(f, "\\hrule\n* =%s%s= \n" // " :PROPERTIES:\n" @@ -46,10 +43,10 @@ proc generate_docs(String* path) -> void { * 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); + try_void 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 @@ -57,8 +54,8 @@ proc generate_docs(String* path) -> void { 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])); + Memory::get_or_create_lisp_object_symbol("type"), + env->values[i])); fprintf(f, "\n - type :: ="); print(LOtype, true, f); @@ -89,43 +86,43 @@ proc generate_docs(String* path) -> void { 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 (fun->value.function.args.positional.symbols.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->symbols[0]->value.symbol.identifier)); - 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->symbols[i]->value.symbol.identifier)); + try_void fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.args.positional.symbols.data[0]->value.symbol.identifier)); + for (int i = 1; i < fun->value.function.args.positional.symbols.next_index; ++i) { + fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.args.positional.symbols.data[i]->value.symbol.identifier)); } } - if (fun->value.function.keyword_arguments->values->next_index != 0) { + if (fun->value.function.args.keyword.values.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->keywords->data[0]->value.symbol.identifier)); - if (fun->value.function.keyword_arguments->values->data[0]) { + fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.args.keyword.keywords.data[0]->value.symbol.identifier)); + if (fun->value.function.args.keyword.values.data[0]) { fprintf(f, " =("); - print(fun->value.function.keyword_arguments->values->data[0], true, f); + print(fun->value.function.args.keyword.values.data[0], true, f); fprintf(f, ")="); } - for (int i = 1; i < fun->value.function.keyword_arguments->values->next_index; ++i) { - fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords->data[i]->value.symbol.identifier)); - if (fun->value.function.keyword_arguments->values->data[i]) { + for (int i = 1; i < fun->value.function.args.keyword.values.next_index; ++i) { + fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.args.keyword.keywords.data[i]->value.symbol.identifier)); + if (fun->value.function.args.keyword.values.data[i]) { fprintf(f, " =("); - print(fun->value.function.keyword_arguments->values->data[i], true, f); + print(fun->value.function.args.keyword.values.data[i], true, f); fprintf(f, ")="); } } } - if (fun->value.function.rest_argument) { + if (fun->value.function.args.rest) { if (!printed_at_least_some_args) fprintf(f, ":"); - fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(fun->value.function.rest_argument)); + fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(fun->value.function.args.rest->value.symbol.identifier)); } // if no args at all - if (fun->value.function.positional_arguments->next_index == 0 && - fun->value.function.keyword_arguments->values->next_index == 0 && - !fun->value.function.rest_argument) + if (fun->value.function.args.positional.symbols.next_index == 0 && + fun->value.function.args.keyword.values.next_index == 0 && + !fun->value.function.args.rest) { fprintf(f, "none."); } @@ -137,22 +134,22 @@ proc generate_docs(String* path) -> void { 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); - } + // 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); + for (int i = 0; i < env->parents.next_index; ++i) { + print_this_env(env->parents.data[i], prefix); } }; diff --git a/src/env.cpp b/src/env.cpp index de95bef..9e03d11 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -31,9 +31,9 @@ proc environment_binds_symbol(String* identifier, Environment* env) -> bool { proc find_binding_environment(String* identifier, Environment* env) -> Environment* { if (environment_binds_symbol(identifier, env)) return env; - for (int i = 0; i < env->parents->next_index; ++i) { - if (environment_binds_symbol(identifier, env->parents->data[i])) - return env->parents->data[i]; + for (int i = 0; i < env->parents.next_index; ++i) { + if (environment_binds_symbol(identifier, env->parents.data[i])) + return env->parents.data[i]; } return get_root_environment(); } @@ -46,8 +46,8 @@ proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { if (result) return result; - for (int i = 0; i < env->parents->next_index; ++i) { - result = try_lookup_symbol(node, env->parents->data[i]); + for (int i = 0; i < env->parents.next_index; ++i) { + result = try_lookup_symbol(node, env->parents.data[i]); if (result) return result; @@ -65,22 +65,22 @@ proc try_lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { inline proc push_environment(Environment* env) -> void { using namespace Globals::Current_Execution; - append_to_array_list(envi_stack, env); + append_to_array_list(&envi_stack, env); } inline proc pop_environment() -> void { using namespace Globals::Current_Execution; - --envi_stack->next_index; + --envi_stack.next_index; } inline proc get_root_environment() -> Environment* { using namespace Globals::Current_Execution; - return envi_stack->data[0]; + return envi_stack.data[0]; } inline proc get_current_environment() -> Environment* { using namespace Globals::Current_Execution; - return envi_stack->data[envi_stack->next_index-1]; + return envi_stack.data[envi_stack.next_index-1]; } proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { @@ -115,11 +115,11 @@ proc print_environment_indent(Environment* env, int indent) -> void { printf(" (%lld)", (long long)env->values[i]); puts(""); } - for (int i = 0; i < env->parents->next_index; ++i) { + for (int i = 0; i < env->parents.next_index; ++i) { print_indent(indent); - printf("parent (%lld)", (long long)env->parents->data[i]); + printf("parent (%lld)", (long long)env->parents.data[i]); puts(":"); - print_environment_indent(env->parents->data[i], indent+4); + print_environment_indent(env->parents.data[i], indent+4); } } diff --git a/src/error.cpp b/src/error.cpp index 8bf7ef9..9b57dd5 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -9,8 +9,10 @@ proc delete_error() -> void { proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, String* message) -> void { - if (Globals::log_level > Log_Level::None) - printf("Error created in:\n%s:%d\n", c_file_name, c_file_line); + if (Globals::log_level > Log_Level::None) { + printf("Error created in:\n %s:%d\n", c_file_name, c_file_line); + printf(" -> %s\n", Memory::get_c_str(message)); + } delete_error(); if (Globals::breaking_on_errors) { diff --git a/src/eval.cpp b/src/eval.cpp index 79441eb..f1ad83f 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -9,19 +9,19 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> }; Lisp_Object* sym, *val; // used as temp storage to use `try` - String_Array_List* read_in_keywords; + String_Array_List read_in_keywords; int obligatory_keywords_count = 0; int read_obligatory_keywords_count = 0; proc read_positional_args = [&]() -> void { - for (int i = 0; i < function->positional_arguments->next_index; ++i) { + for (int i = 0; i < function->args.positional.symbols.next_index; ++i) { if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) { - create_wrong_number_of_arguments_error(function->positional_arguments->next_index, i); + create_wrong_number_of_arguments_error(function->args.positional.symbols.next_index, i); return; } // NOTE(Felix): We have to copy all the arguments, otherwise // we change the program code. - try_void sym = function->positional_arguments->symbols[i]; + try_void sym = function->args.positional.symbols.data[i]; define_symbol( sym, Memory::copy_lisp_object_except_pairs(arguments->value.pair.first)); @@ -41,8 +41,8 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> return; // find out how many keyword args we /have/ to read - for (int i = 0; i < function->keyword_arguments->values->next_index; ++i) { - if (function->keyword_arguments->values->data[i] == nullptr) + for (int i = 0; i < function->args.keyword.values.next_index; ++i) { + if (function->args.keyword.values.data[i] == nullptr) ++obligatory_keywords_count; else break; @@ -52,10 +52,10 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> while (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) { // check if this one is even an accepted keyword bool accepted = false; - for (int i = 0; i < function->keyword_arguments->values->next_index; ++i) { + for (int i = 0; i < function->args.keyword.values.next_index; ++i) { if (string_equal( arguments->value.pair.first->value.symbol.identifier, - function->keyword_arguments->keywords->data[i]->value.symbol.identifier)) + function->args.keyword.keywords.data[i]->value.symbol.identifier)) { accepted = true; break; @@ -77,10 +77,10 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> } // check if it was already read in - for (int i = 0; i < read_in_keywords->next_index; ++i) { + for (int i = 0; i < read_in_keywords.next_index; ++i) { if (string_equal( arguments->value.pair.first->value.symbol.identifier, - read_in_keywords->data[i])) + read_in_keywords.data[i])) { // NOTE(Felix): if we are actually done with all the // necessary keywords then we have to count the rest @@ -112,7 +112,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> sym, Memory::copy_lisp_object_except_pairs(arguments->value.pair.rest->value.pair.first)); - append_to_array_list(read_in_keywords, arguments->value.pair.first->value.symbol.identifier); + append_to_array_list(&read_in_keywords, arguments->value.pair.first->value.symbol.identifier); ++read_obligatory_keywords_count; // overstep both for next one @@ -126,20 +126,20 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> proc check_keyword_args = [&]() -> void { // check if all necessary keywords have been read in - for (int i = 0; i < function->keyword_arguments->values->next_index; ++i) { - String* defined_keyword = function->keyword_arguments->keywords->data[i]->value.symbol.identifier; + for (int i = 0; i < function->args.keyword.values.next_index; ++i) { + String* defined_keyword = function->args.keyword.keywords.data[i]->value.symbol.identifier; bool was_set = false; - for (int j = 0; j < read_in_keywords->next_index; ++j) { + for (int j = 0; j < read_in_keywords.next_index; ++j) { // TODO(Felix): Later compare the keywords, not their strings!! if (string_equal( - read_in_keywords->data[j], + read_in_keywords.data[j], defined_keyword)) { was_set = true; break; } } - if (function->keyword_arguments->values->data[i] == nullptr) { + if (function->args.keyword.values.data[i] == nullptr) { // if this one does not have a default value if (!was_set) { create_generic_error( @@ -153,7 +153,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> // to use it or if the user supplied his own if (!was_set) { try_void sym = Memory::get_or_create_lisp_object_symbol(defined_keyword); - try_void val = Memory::copy_lisp_object_except_pairs(function->keyword_arguments->values->data[i]); + try_void val = Memory::copy_lisp_object_except_pairs(function->args.keyword.values.data[i]); define_symbol(sym, val); } } @@ -162,13 +162,13 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> proc read_rest_arg = [&]() -> void { if (arguments == Memory::nil) { - if (function->rest_argument) { - define_symbol(function->rest_argument, Memory::nil); + if (function->args.rest) { + define_symbol(function->args.rest, Memory::nil); } } else { - if (function->rest_argument) { + if (function->args.rest) { define_symbol( - function->rest_argument, + function->args.rest, // NOTE(Felix): arguments will be a list, and I THINK // we do not need to copy it... arguments); @@ -201,9 +201,9 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> */ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { // first init the fields - function->positional_arguments = create_positional_argument_list(16); - function->keyword_arguments = create_keyword_argument_list(16); - function->rest_argument = nullptr; + function->args.positional = create_positional_argument_list(16); + function->args.keyword = create_keyword_argument_list(16); + function->args.rest = nullptr; // okay let's try to read some positional arguments while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) { @@ -228,7 +228,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { // okay wow we found an actual symbol append_to_positional_argument_list( - function->positional_arguments, + &function->args.positional, arguments->value.pair.first); arguments = arguments->value.pair.rest; @@ -294,7 +294,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { pop_environment(); }; try_void ret = eval_expr(next->value.pair.first); - append_to_keyword_argument_list(function->keyword_arguments, + append_to_keyword_argument_list(&function->args.keyword, arguments->value.pair.first, ret); arguments = next->value.pair.rest; @@ -304,7 +304,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { } } else { // No :defaults-to, so just add it to the list - append_to_keyword_argument_list(function->keyword_arguments, + append_to_keyword_argument_list(&function->args.keyword, arguments->value.pair.first, nullptr); arguments = next; @@ -331,7 +331,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { create_parsing_error("After the 'rest' marker there must follow a symbol."); return; } - function->rest_argument = arguments->value.pair.first; + function->args.rest = arguments->value.pair.first; if (arguments->value.pair.rest != Memory::nil) { create_parsing_error("The lambda list must end after the rest symbol"); } @@ -362,6 +362,7 @@ proc list_length(Lisp_Object* node) -> int { } proc eval_arguments(Lisp_Object* arguments, int *out_arguments_length) -> Lisp_Object* { + profile_this; int my_out_arguments_length = 0; if (arguments == Memory::nil) { *(out_arguments_length) = 0; @@ -396,15 +397,17 @@ proc eval_arguments(Lisp_Object* arguments, int *out_arguments_length) -> Lisp_O } proc eval_expr(Lisp_Object* node) -> Lisp_Object* { + profile_this; + using namespace Globals::Current_Execution; - append_to_array_list(call_stack, node); + append_to_array_list(&call_stack, node); defer { // NOTE(Felix): We only delete the current entry from the call // stack, if we did not encounter an error, otherwise we neet // to preserve the callstack to print it later. it will be // cleared in log_error(). if (!Globals::error) - --call_stack->next_index; + --call_stack.next_index; }; switch (Memory::get_type(node)) { diff --git a/src/forward_decls.cpp b/src/forward_decls.cpp index dabde4e..debe07b 100644 --- a/src/forward_decls.cpp +++ b/src/forward_decls.cpp @@ -39,14 +39,18 @@ namespace Parser { } namespace Globals { + char* bin_path = nullptr; Log_Level log_level = Log_Level::Debug; namespace Current_Execution { - Lisp_Object_Array_List* call_stack = create_Lisp_Object_array_list(); - Environment_Array_List* envi_stack = create_Environment_array_list(); + Lisp_Object_Array_List call_stack = create_Lisp_Object_array_list(); + Environment_Array_List envi_stack = create_Environment_array_list(); } +#ifdef _DONT_BREAK_ON_ERRORS + bool breaking_on_errors = false; +#else bool breaking_on_errors = true; +#endif Error* error = nullptr; - } diff --git a/src/gc.cpp b/src/gc.cpp index 3ee603c..cfed6a3 100644 --- a/src/gc.cpp +++ b/src/gc.cpp @@ -3,10 +3,10 @@ namespace GC { int current_mark; - Lisp_Object_Array_List* marked_objects; - String_Array_List* marked_strings; - Environment_Array_List* marked_environments; - Environment_Array_List* protected_environments; + Lisp_Object_Array_List marked_objects; + String_Array_List marked_strings; + Environment_Array_List marked_environments; + Environment_Array_List protected_environments; proc marked(Lisp_Object* node) -> bool { return false; @@ -20,8 +20,14 @@ namespace GC { if (marked(node)) return; - append_to_array_list(marked_objects, node); + // mark object itself + append_to_array_list(&marked_objects, node); + // mark docstring + if (node->docstring) + append_to_array_list(&marked_strings, node->docstring); + + // mark type specific data switch (Memory::get_type(node)) { case Lisp_Object_Type::Pair: { for_lisp_list (node) { @@ -34,11 +40,18 @@ namespace GC { } } break; case Lisp_Object_Type::String: { - append_to_array_list(marked_strings, node->value.string); + append_to_array_list(&marked_strings, node->value.string); } break; case Lisp_Object_Type::Function: { + // NOTE(Felix): We dont have to mark the symbols, keywords + // for parameter names, as symbols and keywords are never + // garbage collected maybe_mark(node->value.function.parent_environment); maybe_mark(node->value.function.body); + // mark the default arguemnt values: + for_array_list (node->value.function.args.keyword.values) { + if (it) maybe_mark(it); + } } break; } @@ -48,7 +61,7 @@ namespace GC { if (marked(env)) return; - append_to_array_list(marked_environments, env); + append_to_array_list(&marked_environments, env); for_array_list (env->parents) { maybe_mark(it); @@ -66,7 +79,6 @@ namespace GC { for_array_list (protected_environments) maybe_mark(it); for_array_list (Globals::Current_Execution::envi_stack) maybe_mark(it); - } proc gc_init_and_go() -> void { diff --git a/src/io.cpp b/src/io.cpp index 9591ba0..a3162c0 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -393,10 +393,10 @@ proc print_single_call(Lisp_Object* obj) -> void { proc print_call_stack() -> void { using Globals::Current_Execution::call_stack; - printf("callstack [%d] (most recent call last):\n", call_stack->next_index); - for (int i = 0; i < call_stack->next_index; ++i) { + printf("callstack [%d] (most recent call last):\n", call_stack.next_index); + for (int i = 0; i < call_stack.next_index; ++i) { printf("%2d -> ", i); - print_single_call(call_stack->data[i]); + print_single_call(call_stack.data[i]); printf("\n"); } } @@ -410,5 +410,5 @@ proc log_error() -> void { print_call_stack(); puts(console_normal); - Globals::Current_Execution::call_stack->next_index = 0; + Globals::Current_Execution::call_stack.next_index = 0; } diff --git a/src/lisp_object.cpp b/src/lisp_object.cpp index b1a6e75..6ebd9a5 100644 --- a/src/lisp_object.cpp +++ b/src/lisp_object.cpp @@ -26,26 +26,20 @@ proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char* { return "unknown"; } -proc create_positional_argument_list(int initial_capacity) -> Positional_Arguments* { - Positional_Arguments* ret = new(Positional_Arguments); - ret->symbols = (Lisp_Object**)malloc(initial_capacity * sizeof(Lisp_Object*)); - ret->next_index = 0; - ret->length = initial_capacity; +proc create_positional_argument_list(int initial_capacity) -> Positional_Arguments { + Positional_Arguments ret; + ret.symbols = create_Lisp_Object_array_list(initial_capacity); return ret; } proc append_to_positional_argument_list(Positional_Arguments* args, Lisp_Object* sym) -> void { - if (args->next_index == args->length) { - args->length *= 2; - args->symbols = (Lisp_Object**)realloc(args->symbols, args->length * sizeof(Lisp_Object*)); - } - args->symbols[args->next_index++] = sym; + append_to_array_list(&args->symbols, sym); } -proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments* { - Keyword_Arguments* ret = new(Keyword_Arguments); - ret->keywords = create_Lisp_Object_array_list(initial_capacity); - ret->values = create_Lisp_Object_array_list(initial_capacity); +proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments { + Keyword_Arguments ret; + ret.keywords = create_Lisp_Object_array_list(initial_capacity); + ret.values = create_Lisp_Object_array_list(initial_capacity); return ret; } @@ -53,6 +47,6 @@ proc append_to_keyword_argument_list(Keyword_Arguments* args, Lisp_Object* keyword, Lisp_Object* default_value) -> void { - append_to_array_list(args->keywords, keyword); - append_to_array_list(args->values, default_value); + append_to_array_list(&args->keywords, keyword); + append_to_array_list(&args->values, default_value); } diff --git a/src/main.cpp b/src/main.cpp index bead382..79561b3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,7 +3,9 @@ int main(int argc, char* argv[]) { if (argc > 1) { if (Slime::string_equal(argv[1], "--run-tests")) { - return Slime::run_all_tests() ? 0 : 1; + int res = Slime::run_all_tests(); + Slime::interprete_file("generate-docs.slime"); + return res ? 0 : 1; } Slime::interprete_file(argv[1]); diff --git a/src/memory.cpp b/src/memory.cpp index de076e5..801717a 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -4,7 +4,7 @@ namespace Memory { // lisp_objects // ------------------ int object_memory_size; - Int_Array_List* free_spots_in_object_memory; + Int_Array_List free_spots_in_object_memory; Lisp_Object* object_memory; int next_index_in_object_memory = 0; @@ -12,7 +12,7 @@ namespace Memory { // environments // ------------------ int environment_memory_size; - Int_Array_List* free_spots_in_environment_memory; + Int_Array_List free_spots_in_environment_memory; Environment* environment_memory; int next_index_in_environment_memory = 0; @@ -23,7 +23,7 @@ namespace Memory { // free_spots_in_string_memory is an arraylist of pointers into // the string_memory, where dead String objects live (which give // information about their size) - Void_Ptr_Array_List* free_spots_in_string_memory; + Void_Ptr_Array_List free_spots_in_string_memory; String* string_memory; String* next_free_spot_in_string_memory; @@ -38,15 +38,15 @@ namespace Memory { " - %f%% of the object_memory is used\n" " - %d of %d total Lisp_Objects are in use\n" " - %d holes in used memory (fragmentation)\n", - (1.0*next_index_in_object_memory - free_spots_in_object_memory->next_index)/object_memory_size, - next_index_in_object_memory - free_spots_in_object_memory->next_index, object_memory_size, - free_spots_in_object_memory->next_index); + (1.0*next_index_in_object_memory - free_spots_in_object_memory.next_index)/object_memory_size, + next_index_in_object_memory - free_spots_in_object_memory.next_index, object_memory_size, + free_spots_in_object_memory.next_index); printf("Memory Status:\n" " - %f%% of the string_memory is used\n" " - %d holes in used memory (fragmentation)\n", (1.0*(size_t)next_free_spot_in_string_memory - (size_t)string_memory)/string_memory_size, - free_spots_in_string_memory->next_index); + free_spots_in_string_memory.next_index); } inline proc get_c_str(String* str) -> char* { @@ -106,7 +106,7 @@ namespace Memory { } proc delete_string(String* str) { - append_to_array_list(free_spots_in_string_memory, (void*)str); + append_to_array_list(&free_spots_in_string_memory, (void*)str); } proc duplicate_string(String* str) -> String* { @@ -136,7 +136,7 @@ namespace Memory { proc create_lisp_object() -> Lisp_Object* { int index; // if we have no free spots then append at the end - if (free_spots_in_object_memory->next_index == 0) { + if (free_spots_in_object_memory.next_index == 0) { // if we still have space if (object_memory_size == next_index_in_object_memory) { create_out_of_memory_error( @@ -149,7 +149,7 @@ namespace Memory { index = next_index_in_object_memory++; } else { // else fill a free spot, and remove the free spot - index = free_spots_in_object_memory->data[free_spots_in_object_memory->next_index--]; + index = free_spots_in_object_memory.data[free_spots_in_object_memory.next_index--]; } Lisp_Object* object = object_memory+index; object->flags = 0; @@ -184,22 +184,22 @@ namespace Memory { try_void Parser::standard_in = create_string("stdin"); - try_void Globals::Current_Execution::envi_stack->data[0] = create_built_ins_environment(); - try_void Globals::Current_Execution::envi_stack->next_index = 1; + try_void Globals::Current_Execution::envi_stack.data[0] = create_built_ins_environment(); + try_void Globals::Current_Execution::envi_stack.next_index = 1; } proc reset() -> void { - free_spots_in_object_memory->next_index = 0; - free_spots_in_environment_memory->next_index = 0; - free_spots_in_string_memory->next_index = 0; + free_spots_in_object_memory.next_index = 0; + free_spots_in_environment_memory.next_index = 0; + free_spots_in_string_memory.next_index = 0; // because t and nil are always there we start the index at 2 next_index_in_object_memory = 2; next_index_in_environment_memory = 0; next_free_spot_in_string_memory = string_memory; - try_void Globals::Current_Execution::envi_stack->data[0] = create_built_ins_environment(); - try_void Globals::Current_Execution::envi_stack->next_index = 1; + try_void Globals::Current_Execution::envi_stack.data[0] = create_built_ins_environment(); + try_void Globals::Current_Execution::envi_stack.next_index = 1; } proc create_lisp_object_number(double number) -> Lisp_Object* { @@ -353,7 +353,7 @@ namespace Memory { int index; // if we have no free spots then append at the end - if (free_spots_in_environment_memory->next_index == 0) { + if (free_spots_in_environment_memory.next_index == 0) { // if we still have space if (environment_memory_size == next_index_in_environment_memory) { create_out_of_memory_error( @@ -366,7 +366,7 @@ namespace Memory { index = next_index_in_environment_memory++; } else { // else fill a free spot, and remove the free spot - index = free_spots_in_environment_memory->data[free_spots_in_environment_memory->next_index--]; + index = free_spots_in_environment_memory.data[free_spots_in_environment_memory.next_index--]; } @@ -376,7 +376,7 @@ namespace Memory { env->parents = create_Environment_array_list(); if (parent) - append_to_array_list(env->parents, parent); + append_to_array_list(&env->parents, parent); env->capacity = start_capacity; env->next_index = 0; @@ -402,17 +402,17 @@ namespace Memory { load_built_ins_into_environment(); - // save the current working directory - char* cwd = get_cwd(); - defer { - change_cwd(cwd); - free(cwd); - }; - - // get the direction of the exe - char* exe_path = get_exe_dir(); - change_cwd(exe_path); - free(exe_path); + // // save the current working directory + // char* cwd = get_cwd(); + // defer { + // change_cwd(cwd); + // free(cwd); + // }; + + // // get the direction of the exe + // char* exe_path = get_exe_dir(); + // change_cwd(exe_path); + // free(exe_path); built_in_load(Memory::create_string("pre.slime")); diff --git a/src/parse.cpp b/src/parse.cpp index 1672af6..b918c22 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -403,9 +403,9 @@ namespace Parser { try assert_type(arguments, Lisp_Object_Type::Pair); try parse_argument_list(arguments, ¯o->value.function); } else { - macro->value.function.positional_arguments = create_positional_argument_list(1); - macro->value.function.keyword_arguments = create_keyword_argument_list(1); - macro->value.function.rest_argument = nullptr; + macro->value.function.args.positional = create_positional_argument_list(1); + macro->value.function.args.keyword = create_keyword_argument_list(1); + macro->value.function.args.rest = nullptr; } // arguments = arguments->value.pair.rest; @@ -556,7 +556,7 @@ namespace Parser { } - proc write_expanded_file(String* file_name, Lisp_Object_Array_List* program) -> void { + proc write_expanded_file(String* file_name, Lisp_Object_Array_List program) -> void { const char* ext = ".expanded"; char* newName = (char*)calloc(10 + file_name->length, sizeof(char)); strcpy(newName, Memory::get_c_str(file_name)); @@ -573,21 +573,21 @@ namespace Parser { exit(1); } - for (int i = 0; i < program->next_index; ++i) { + for (int i = 0; i < program.next_index; ++i) { // a macro will parse as nil for now, so we skip those - if (program->data[i] == Memory::nil) + if (program.data[i] == Memory::nil) continue; - print(program->data[i], true, f); + print(program.data[i], true, f); fprintf(f, "\n\n"); } } - proc parse_program(String* file_name, char* text) -> Lisp_Object_Array_List* { + proc parse_program(String* file_name, char* text) -> Lisp_Object_Array_List { parser_file = file_name; parser_line = 1; parser_col = 0; - Lisp_Object_Array_List* program = create_Lisp_Object_array_list(); + Lisp_Object_Array_List program = create_Lisp_Object_array_list(); int index_in_text = 0; @@ -595,10 +595,10 @@ namespace Parser { switch (text[index_in_text]) { case '(': { Lisp_Object* parsed; - try { + try_struct { parsed = parse_expression(text, &index_in_text); } - append_to_array_list(program, parsed); + append_to_array_list(&program, parsed); } break; case ';': case ' ': @@ -611,7 +611,7 @@ namespace Parser { /* syntax error */ create_parsing_error("Garbage in file scope at %s:%d:%d", parser_file, parser_line, parser_col); - return nullptr; + return {}; } } diff --git a/src/profiler.cpp b/src/profiler.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/slime.h b/src/slime.h index d89dc98..da42636 100644 --- a/src/slime.h +++ b/src/slime.h @@ -32,7 +32,6 @@ namespace Slime { # include "./platform.cpp" # include "./structs.cpp" # include "./forward_decls.cpp" -# include "./profiler.cpp" # include "./memory.cpp" # include "./gc.cpp" # include "./lisp_object.cpp" diff --git a/src/structs.cpp b/src/structs.cpp index 69977ab..be58c2d 100644 --- a/src/structs.cpp +++ b/src/structs.cpp @@ -8,7 +8,6 @@ define_array_list(String*, String); define_array_list(int, Int); define_array_list(void*, Void_Ptr); - enum struct Thread_Type { Main, GarbageCollection @@ -91,37 +90,40 @@ struct Vector { }; struct Positional_Arguments { - Lisp_Object** symbols; // Array of Pointers to Lisp_Object - int next_index; - int length; + Lisp_Object_Array_List symbols; }; struct Keyword_Arguments { // Array of Pointers to Lisp_Object - Lisp_Object_Array_List* keywords; + Lisp_Object_Array_List keywords; // NOTE(Felix): values[i] will be nullptr if no defalut value was // declared for key identifiers[i] - Lisp_Object_Array_List* values; + Lisp_Object_Array_List values; }; struct Arguments { + Positional_Arguments positional; + Keyword_Arguments keyword; // NOTE(Felix): rest_argument will be nullptr if no rest argument // is declared otherwise its a symbol - Lisp_Object* rest_argument; - Keyword_Arguments keyword_arguments; - Positional_Arguments positional_arguments; + Lisp_Object* rest; }; +struct Environment { + Environment_Array_List parents; + int capacity; + int next_index; + + // TODO(Felix): Use a hashmap here. + char** keys; + Lisp_Object** values; +}; struct Function { Function_Type type; - Positional_Arguments* positional_arguments; - Keyword_Arguments* keyword_arguments; - // NOTE(Felix): rest_argument will be nullptr if no rest argument - // is declared otherwise its a symbol - Lisp_Object* rest_argument; + Arguments args; Lisp_Object* body; // implicit begin - Environment* parent_environment; // we are doing closures now!! + Environment* parent_environment; // we are doing closures now!! }; struct cFunction { @@ -131,7 +133,7 @@ struct cFunction { struct Lisp_Object { Source_Code_Location* sourceCodeLocation; u64 flags; - Lisp_Object* userType; + Lisp_Object* userType; // keyword String* docstring; union { Symbol symbol; // used for symbols and keywords @@ -145,16 +147,6 @@ struct Lisp_Object { } value; }; -struct Environment { - Environment_Array_List* parents; - int capacity; - int next_index; - - // TODO(Felix): Use a hashmap here. - char** keys; - Lisp_Object** values; -}; - struct Error { Lisp_Object* position; // type has to be a keyword diff --git a/src/testing.cpp b/src/testing.cpp index 2e1e62b..36e8483 100644 --- a/src/testing.cpp +++ b/src/testing.cpp @@ -115,79 +115,79 @@ proc test_array_lists_adding_and_removing() -> testresult { // test adding and removing - Int_Array_List* list = create_Int_array_list(); - append_to_array_list(list, 1); - append_to_array_list(list, 2); - append_to_array_list(list, 3); - append_to_array_list(list, 4); + Int_Array_List list = create_Int_array_list(); + append_to_array_list(&list, 1); + append_to_array_list(&list, 2); + append_to_array_list(&list, 3); + append_to_array_list(&list, 4); - assert_equal_int(list->next_index, 4); + assert_equal_int(list.next_index, 4); - remove_index_from_array_list(list, 0); + remove_index_from_array_list(&list, 0); - assert_equal_int(list->next_index, 3); - assert_equal_int(list->data[0], 4); - assert_equal_int(list->data[1], 2); - assert_equal_int(list->data[2], 3); + assert_equal_int(list.next_index, 3); + assert_equal_int(list.data[0], 4); + assert_equal_int(list.data[1], 2); + assert_equal_int(list.data[2], 3); - remove_index_from_array_list(list, 2); + remove_index_from_array_list(&list, 2); - assert_equal_int(list->next_index, 2); - assert_equal_int(list->data[0], 4); - assert_equal_int(list->data[1], 2); + assert_equal_int(list.next_index, 2); + assert_equal_int(list.data[0], 4); + assert_equal_int(list.data[1], 2); return pass; } proc test_array_lists_sorting() -> testresult { // test adding and removing - Int_Array_List* list = create_Int_array_list(); - append_to_array_list(list, 1); - append_to_array_list(list, 2); - append_to_array_list(list, 3); - append_to_array_list(list, 4); + Int_Array_List list = create_Int_array_list(); + append_to_array_list(&list, 1); + append_to_array_list(&list, 2); + append_to_array_list(&list, 3); + append_to_array_list(&list, 4); - sort_array_list(list); + sort_array_list(&list); - assert_equal_int(list->next_index, 4); + assert_equal_int(list.next_index, 4); - assert_equal_int(list->data[0], 1); - assert_equal_int(list->data[1], 2); - assert_equal_int(list->data[2], 3); - assert_equal_int(list->data[3], 4); + assert_equal_int(list.data[0], 1); + assert_equal_int(list.data[1], 2); + assert_equal_int(list.data[2], 3); + assert_equal_int(list.data[3], 4); - append_to_array_list(list, 0); - append_to_array_list(list, 5); + append_to_array_list(&list, 0); + append_to_array_list(&list, 5); - assert_equal_int(list->next_index, 6); + assert_equal_int(list.next_index, 6); - sort_array_list(list); + sort_array_list(&list); - assert_equal_int(list->data[0], 0); - assert_equal_int(list->data[1], 1); - assert_equal_int(list->data[2], 2); - assert_equal_int(list->data[3], 3); - assert_equal_int(list->data[4], 4); - assert_equal_int(list->data[5], 5); + assert_equal_int(list.data[0], 0); + assert_equal_int(list.data[1], 1); + assert_equal_int(list.data[2], 2); + assert_equal_int(list.data[3], 3); + assert_equal_int(list.data[4], 4); + assert_equal_int(list.data[5], 5); return pass; } proc test_array_lists_searching() -> testresult { - Int_Array_List* list = create_Int_array_list(); - append_to_array_list(list, 1); - append_to_array_list(list, 2); - append_to_array_list(list, 3); - append_to_array_list(list, 4); + Int_Array_List list = create_Int_array_list(); + append_to_array_list(&list, 1); + append_to_array_list(&list, 2); + append_to_array_list(&list, 3); + append_to_array_list(&list, 4); - int index = sorted_array_list_find(list, 3); + int index = sorted_array_list_find(&list, 3); assert_equal_int(index, 2); - index = sorted_array_list_find(list, 1); + index = sorted_array_list_find(&list, 1); assert_equal_int(index, 0); - index = sorted_array_list_find(list, 5); + index = sorted_array_list_find(&list, 5); assert_equal_int(index, -1); return pass; @@ -595,14 +595,6 @@ proc test_file(const char* file) -> testresult { } proc run_all_tests() -> bool { - Memory::init(4096 * 2000, 1024 * 32, 4096 * 16 * 10); - - // get the direction of the exe - char* exe_path = get_exe_dir(); - - // switch to the exe directory for loading pre.slime - change_cwd(exe_path); - free(exe_path); bool result = true; @@ -611,6 +603,8 @@ proc run_all_tests() -> bool { invoke_test(test_array_lists_sorting); invoke_test(test_array_lists_searching); + Memory::init(4096 * 2000, 1024 * 32, 4096 * 16 * 10); + printf("\n -- Parsing --\n"); invoke_test(test_parse_atom); invoke_test(test_parse_expression); diff --git a/src/visualization.cpp b/src/visualization.cpp index 7e2ee08..988bec8 100644 --- a/src/visualization.cpp +++ b/src/visualization.cpp @@ -305,8 +305,8 @@ proc visualize_lisp_machine() -> void { draw_new_line(); int free_string_memory = (int)(Memory::next_free_spot_in_string_memory - Memory::string_memory); - for (int i = 0; i < Memory::free_spots_in_string_memory->next_index; ++i) { - free_string_memory += ((String*)(Memory::free_spots_in_string_memory->data[i]))->length; + for (int i = 0; i < Memory::free_spots_in_string_memory.next_index; ++i) { + free_string_memory += ((String*)(Memory::free_spots_in_string_memory.data[i]))->length; } int used_string_memory = Memory::string_memory_size - free_string_memory; @@ -334,8 +334,8 @@ proc visualize_lisp_machine() -> void { // Object Memory // ------------------- - int free_object_memory_cells = Memory::object_memory_size - (Memory::next_index_in_object_memory - Memory::free_spots_in_object_memory->next_index); - int used_object_memory_cells = Memory::next_index_in_object_memory - Memory::free_spots_in_object_memory->next_index; + int free_object_memory_cells = Memory::object_memory_size - (Memory::next_index_in_object_memory - Memory::free_spots_in_object_memory.next_index); + int used_object_memory_cells = Memory::next_index_in_object_memory - Memory::free_spots_in_object_memory.next_index; write_x += draw_text("Object Memory:").width; draw_margin(); @@ -359,26 +359,26 @@ proc visualize_lisp_machine() -> void { draw_new_line(3); }; proc draw_symbols_keywords_and_numbers = [&]() { - Lisp_Object_Array_List* symbols = create_Lisp_Object_array_list(); - Lisp_Object_Array_List* keywords = create_Lisp_Object_array_list(); - Lisp_Object_Array_List* numbers = create_Lisp_Object_array_list(); - Lisp_Object_Array_List* strings = create_Lisp_Object_array_list(); - Lisp_Object_Array_List* pairs = create_Lisp_Object_array_list(); - Lisp_Object_Array_List* lists = create_Lisp_Object_array_list(); + Lisp_Object_Array_List symbols = create_Lisp_Object_array_list(); + Lisp_Object_Array_List keywords = create_Lisp_Object_array_list(); + Lisp_Object_Array_List numbers = create_Lisp_Object_array_list(); + Lisp_Object_Array_List strings = create_Lisp_Object_array_list(); + Lisp_Object_Array_List pairs = create_Lisp_Object_array_list(); + Lisp_Object_Array_List lists = create_Lisp_Object_array_list(); // loop over all used memory for (int i = 0; i < Memory::next_index_in_object_memory; ++i) { - for (int j = 0; j < Memory::free_spots_in_object_memory->next_index; ++j) { - if (i == Memory::free_spots_in_object_memory->data[j]) + for (int j = 0; j < Memory::free_spots_in_object_memory.next_index; ++j) { + if (i == Memory::free_spots_in_object_memory.data[j]) goto next; } switch (Memory::get_type(Memory::object_memory+i)) { - case Lisp_Object_Type::Symbol: append_to_array_list(symbols, Memory::object_memory+i); break; - case Lisp_Object_Type::String: append_to_array_list(strings, Memory::object_memory+i); break; - case Lisp_Object_Type::Keyword: append_to_array_list(keywords, Memory::object_memory+i); break; - case Lisp_Object_Type::Number : append_to_array_list(numbers, Memory::object_memory+i); break; - case Lisp_Object_Type::Pair : append_to_array_list(pairs, Memory::object_memory+i); break; + case Lisp_Object_Type::Symbol: append_to_array_list(&symbols, Memory::object_memory+i); break; + case Lisp_Object_Type::String: append_to_array_list(&strings, Memory::object_memory+i); break; + case Lisp_Object_Type::Keyword: append_to_array_list(&keywords, Memory::object_memory+i); break; + case Lisp_Object_Type::Number : append_to_array_list(&numbers, Memory::object_memory+i); break; + case Lisp_Object_Type::Pair : append_to_array_list(&pairs, Memory::object_memory+i); break; default: break; } @@ -386,36 +386,36 @@ proc visualize_lisp_machine() -> void { } // create the lists-list by filtering the pairs-list. - Lisp_Object_Array_List* pairs_to_filter = create_Lisp_Object_array_list(); + Lisp_Object_Array_List pairs_to_filter = create_Lisp_Object_array_list(); // helper lambda: - proc remove_doubles_from_lisp_object_array_list = [&](Lisp_Object_Array_List* list) -> void { - if (list->next_index == 0) + proc remove_doubles_from_lisp_object_array_list = [&](Lisp_Object_Array_List list) -> void { + if (list.next_index == 0) return; - sort_array_list(list); - Int_Array_List* indices_to_filter = create_Int_array_list(); + sort_array_list(&list); + Int_Array_List indices_to_filter = create_Int_array_list(); - size_t last = (size_t)list->data[0]; - for (int i = 1; i < list->next_index; ++i) { - if ((size_t)list->data[i] == last) - append_to_array_list(indices_to_filter, i); + size_t last = (size_t)list.data[0]; + for (int i = 1; i < list.next_index; ++i) { + if ((size_t)list.data[i] == last) + append_to_array_list(&indices_to_filter, i); else - last = (size_t)list->data[i]; + last = (size_t)list.data[i]; } - for (int i = indices_to_filter->next_index; i >= 0; --i) { - remove_index_from_array_list(list, indices_to_filter->data[i]); + for (int i = indices_to_filter.next_index; i >= 0; --i) { + remove_index_from_array_list(&list, indices_to_filter.data[i]); } // sort again as removing items destroys the order - sort_array_list(list); + sort_array_list(&list); }; // recursive lambda std::function filter_pair_and_children; filter_pair_and_children = [&](Lisp_Object* pair) { - append_to_array_list(pairs_to_filter, pair); + append_to_array_list(&pairs_to_filter, pair); if (Memory::get_type(pair->value.pair.first) == Lisp_Object_Type::Pair) filter_pair_and_children(pair->value.pair.first); @@ -423,12 +423,12 @@ proc visualize_lisp_machine() -> void { if (Memory::get_type(pair->value.pair.rest) == Lisp_Object_Type::Pair) filter_pair_and_children(pair->value.pair.rest); }; - for (int i = 0; i < pairs->next_index; ++i) { - if (Memory::get_type(pairs->data[i]->value.pair.first) == Lisp_Object_Type::Pair) - filter_pair_and_children(pairs->data[i]->value.pair.first); + for (int i = 0; i < pairs.next_index; ++i) { + if (Memory::get_type(pairs.data[i]->value.pair.first) == Lisp_Object_Type::Pair) + filter_pair_and_children(pairs.data[i]->value.pair.first); - if (Memory::get_type(pairs->data[i]->value.pair.rest) == Lisp_Object_Type::Pair) - filter_pair_and_children(pairs->data[i]->value.pair.rest); + if (Memory::get_type(pairs.data[i]->value.pair.rest) == Lisp_Object_Type::Pair) + filter_pair_and_children(pairs.data[i]->value.pair.rest); } @@ -436,9 +436,9 @@ proc visualize_lisp_machine() -> void { // fprintf(stderr, "removing %d pairs\n", pairs_to_filter->next_index); // okay, so pairs_to_filter now only the pairs once each that // we want to filter from the pairs list - for (int i = 0; i < pairs->next_index; ++i) { - if (sorted_array_list_find(pairs_to_filter, pairs->data[i]) == -1) { - append_to_array_list(lists, pairs->data[i]); + for (int i = 0; i < pairs.next_index; ++i) { + if (sorted_array_list_find(&pairs_to_filter, pairs.data[i]) == -1) { + append_to_array_list(&lists, pairs.data[i]); } } @@ -450,15 +450,15 @@ proc visualize_lisp_machine() -> void { start_y = write_y; write_x += draw_text("Symbols: ").width; - draw_integer(symbols->next_index); + draw_integer(symbols.next_index); draw_new_line(); write_x = start_x; - for (int i = 0; i < symbols->next_index; ++i) { + for (int i = 0; i < symbols.next_index; ++i) { draw_new_line(); write_x = start_x; - draw_text(&symbols->data[i]->value.symbol.identifier->data); + draw_text(&symbols.data[i]->value.symbol.identifier->data); } @@ -466,15 +466,15 @@ proc visualize_lisp_machine() -> void { write_y = start_y; write_x += draw_text("Keywords: ").width; - draw_integer(keywords->next_index); + draw_integer(keywords.next_index); draw_new_line(); write_x = start_x + 300; - for (int i = 0; i < keywords->next_index; ++i) { + for (int i = 0; i < keywords.next_index; ++i) { draw_new_line(); write_x = start_x + 300; - draw_lisp_object(keywords->data[i]); + draw_lisp_object(keywords.data[i]); } @@ -483,30 +483,30 @@ proc visualize_lisp_machine() -> void { write_y = start_y; write_x += draw_text("Numbers: ").width; - draw_integer(numbers->next_index); + draw_integer(numbers.next_index); draw_new_line(); write_x = start_x + 600; - for (int i = 0; i < numbers->next_index; ++i) { + for (int i = 0; i < numbers.next_index; ++i) { draw_new_line(); write_x = start_x + 600; - draw_float((float)(numbers->data[i]->value.number)); + draw_float((float)(numbers.data[i]->value.number)); } write_x = start_x + 900; write_y = start_y; write_x += draw_text("Strings: ").width; - draw_integer(strings->next_index); + draw_integer(strings.next_index); draw_new_line(); write_x = start_x + 900; - for (int i = 0; i < strings->next_index; ++i) { + for (int i = 0; i < strings.next_index; ++i) { draw_new_line(); write_x = start_x + 900; - draw_text(&strings->data[i]->value.string->data, "#2aa198", true, 75); + draw_text(&strings.data[i]->value.string->data, "#2aa198", true, 75); } @@ -514,17 +514,17 @@ proc visualize_lisp_machine() -> void { write_y = start_y; write_x += draw_text("Lists, Pairs: ").width; - write_x += draw_integer(lists->next_index).width; + write_x += draw_integer(lists.next_index).width; draw_margin(); - draw_integer(pairs->next_index); + draw_integer(pairs.next_index); draw_new_line(); write_x = start_x + 2000; - for (int i = 0; i < lists->next_index; ++i) { + for (int i = 0; i < lists.next_index; ++i) { draw_new_line(3); write_x = start_x + 2000; - write_y += draw_pair(lists->data[i]).height; + write_y += draw_pair(lists.data[i]).height; } }; diff --git a/vs/slime.vcxproj b/vs/slime.vcxproj index 64909c5..27f07f3 100644 --- a/vs/slime.vcxproj +++ b/vs/slime.vcxproj @@ -96,6 +96,9 @@ + + $(SolutionDir)$(Platform)\$(Configuration)\ + Level3 @@ -135,6 +138,7 @@ true Default stdcpplatest + _PROFILING;%(PreprocessorDefinitions) true