Compare commits

...

2 Commits

Author SHA1 Message Date
Macoy Madson 65c52d9ac5 Replace printf with fprintf 1 month ago
Macoy Madson 9bc2531d47 Organized Metadata a bit more 1 month ago
  1. 4
      doc/Cakelisp.org
  2. 2
      doc/NeatUses.org
  3. 4
      doc/Roadmap.org
  4. 6
      runtime/HotReloading.cake
  5. 8
      runtime/HotReloadingCodeModifier.cake
  6. 20
      runtime/TextAdventure.cake
  7. 245
      src/Metadata.cpp
  8. 4
      test/BuildHelpers.cake
  9. 24
      test/CodeModification.cake
  10. 4
      test/Defines.cake
  11. 2
      test/Execute.cake
  12. 4
      test/Hello.cake
  13. 8
      test/MultiLineStrings.cake
  14. 12
      test/SimpleMacros.cake
  15. 2
      test/TestPaths.cake
  16. 2
      test/dir/Test.cpp

4
doc/Cakelisp.org

@ -51,7 +51,7 @@ This also means that adding Cakelisp to an existing C/C++ project should be virt
Here are some example imports:
#+BEGIN_SRC lisp
(c-import "<vector>") ;; now just e.g. (var my-vec (<> std::vector int) (array 1 2 3))
(c-import "<cstdio.h>") ;; (printf "Hello %s!\n" "Cakelisp")
(c-import "<cstdio.h>") ;; (fprintf stderr "Hello %s!\n" "Cakelisp")
(c-import "MyHeader.hpp") ;; (call-on updateState myGlobalVar 0.016)
;; Multiple imports are allowed per call:
@ -131,7 +131,7 @@ The keyword ~&variable-arguments can be used to create a function with variadic
(var list va_list)
(va_start list num-args)
(each-in-range num-args i
(printf "%d\n" (va_arg list int)))
(fprintf stderr "%d\n" (va_arg list int)))
(va_end list))
(defun main (&return int)

2
doc/NeatUses.org

@ -25,7 +25,7 @@ chmod +x MyScript.cake
(c-import "<stdio.h>")
(defun main (&return int)
(printf "Hello, execute!\n")
(fprintf stderr "Hello, execute!\n")
(return 0))
#+END_SRC
* No more build system woes

4
doc/Roadmap.org

@ -68,7 +68,7 @@ class MyWindowEventListener : public Ogre::WindowEventListener
public:
virtual void windowClosed(Ogre::Window* window)
{
printf("Window closed!\n");
fprintf(stderr, "Window closed!\n");
g_ogre_window_should_quit = true;
}
};
@ -117,7 +117,7 @@ In GameLib, almost all loops would be fine with a number range, e.g. here are so
;; Pointer types, end as an expression
;; This is a little bit too clunky for this construct
(each-range (:iter c (* char) buffer (- (+ buffer (array-size buffer)) 1))
(printf "Char is '%c'\n" (deref c)))
(fprintf stderr "Char is '%c'\n" (deref c)))
#+END_SRC
I'm open to input on the topic. I'm not sure I want to take much from ~dolist~ and such.

6
runtime/HotReloading.cake

@ -114,7 +114,7 @@
(scope
(def-function-signature global-initializer-signature ())
(call (type-cast global-initializer global-initializer-signature)))
(printf "warning: global initializer 'hotReloadInitializeState' not found!"))
(fprintf stderr "warning: global initializer 'hotReloadInitializeState' not found!"))
(for-in function-referent-it (& FunctionReferenceMapPair) registered-functions
(var loaded-symbol (* void)
@ -145,10 +145,10 @@
(unless (!= find-it (call-on end registered-state-variables))
(set variable-address-out nullptr)
(when verbose-variables
(printf "Did not find variable %s\n" name))
(fprintf stderr "Did not find variable %s\n" name))
(return false))
(when verbose-variables
(printf "Found variable %s at %p.\n" name (path find-it > second)))
(fprintf stderr "Found variable %s at %p.\n" name (path find-it > second)))
(set (deref variable-address-out) (path find-it > second))
(return true))

8
runtime/HotReloadingCodeModifier.cake

@ -65,8 +65,8 @@
(return true))
(set (deref modified-vars) true)
(printf "HotReloading: Modifying code for hot-reloading.\n")
(printf "Subsequent modifications will not be hot-reloading safe\n")
(fprintf stderr "HotReloading: Modifying code for hot-reloading.\n")
(fprintf stderr "Subsequent modifications will not be hot-reloading safe\n")
(get-or-create-comptime-var modules-with-import (<> std::unordered_map std::string int))
@ -98,7 +98,7 @@
((= 0 (call-on compare (path top-level-type > contents) "const"))
(continue))))
(when verbose (printf ">>> Variable %s\n" (call-on c_str (field definition-pair first))))
(when verbose (fprintf stderr ">>> Variable %s\n" (call-on c_str (field definition-pair first))))
(var definition (& ObjectDefinition) (field definition-pair second))
(var var-to-modify modify-definition)
(unless (CreateDefinitionCopyMacroExpanded definition
@ -135,7 +135,7 @@
(unless reference-found
(continue))
(when verbose (printf ">>> Reference(s) found in %s\n"
(when verbose (fprintf stderr ">>> Reference(s) found in %s\n"
(call-on c_str (field definition-pair first))))
(set (field def-to-modify module) (field definition context module))

20
runtime/TextAdventure.cake

@ -24,30 +24,30 @@
(var num-times-loaded int 0)
(defun print-help ()
(printf "At any point, enter 'r' to reload the code, 'h' for help, or 'q' to quit\n")
(printf "Enter room number for desired room\n\n"))
(fprintf stderr "At any point, enter 'r' to reload the code, 'h' for help, or 'q' to quit\n")
(fprintf stderr "Enter room number for desired room\n\n"))
(defun print-room (room-to-print (* (const room)))
(printf "You are at: %s.\n%s\n"
(fprintf stderr "You are at: %s.\n%s\n"
(path room-to-print > name)
(path room-to-print > description))
(var room-index int 0)
(for-in connected-room (& (const room)) (path room-to-print > connected-rooms)
(printf "%d: %s\n" room-index (field connected-room name))
(fprintf stderr "%d: %s\n" room-index (field connected-room name))
(incr room-index))
(when (call-on empty (path room-to-print > connected-rooms))
(printf "There are no connected rooms. This must be the end of the game!\n")))
(fprintf stderr "There are no connected rooms. This must be the end of the game!\n")))
;; Return true to hot-reload, or false to exit
(defun reloadable-entry-point (&return bool)
(printf "CAKE ADVENTURE\n\n")
(fprintf stderr "CAKE ADVENTURE\n\n")
(print-help)
(var current-room (* (const room)) (addr (at 0 rooms)))
(print-room current-room)
(incr num-times-loaded)
(printf "Loaded %d times\n" num-times-loaded)
(fprintf stderr "Loaded %d times\n" num-times-loaded)
(var input char 0)
(var previous-room (* (const room)) current-room)
@ -56,7 +56,7 @@
(set previous-room current-room)
(print-room current-room))
(printf "> ")
(fprintf stderr "> ")
(set input (getchar))
(cond
@ -68,9 +68,9 @@
(var room-request int (atoi (addr input)))
(var num-rooms int (call-on size (path current-room > connected-rooms)))
(unless (and num-rooms (< room-request num-rooms))
(printf "I don't know where that is. There are %d rooms\n" num-rooms)
(fprintf stderr "I don't know where that is. There are %d rooms\n" num-rooms)
(continue))
(printf "Going to room %d\n" room-request)
(fprintf stderr "Going to room %d\n" room-request)
(set current-room (addr (at room-request
(path current-room > connected-rooms)))))
(true

245
src/Metadata.cpp

@ -33,6 +33,7 @@ enum GeneratorCategory
GeneratorCategory_Build,
GeneratorCategory_ControlFlow,
GeneratorCategory_Memory,
GeneratorCategory_Definitions,
};
struct GeneratorMetadata
@ -81,7 +82,7 @@ GeneratorMetadata g_generatorMetadata[] = {
{
"add-build-options-global",
},
{
{
"add-cpp-build-dependency",
},
{
@ -96,9 +97,35 @@ GeneratorMetadata g_generatorMetadata[] = {
{
"add-compile-time-hook-module",
},
{
{
"add-linker-options",
},
{
"add-compiler-link-options",
},
{
"add-build-config-label",
},
{
"add-library-dependency",
},
{
"import",
},
{
"c-import",
},
{
"comptime-define-symbol",
},
{
"comptime-cond",
},
{
"ignore",
},
//
// Math
@ -147,6 +174,9 @@ GeneratorMetadata g_generatorMetadata[] = {
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 2,
"Shift the bits in the first argument to the right by the number indicated by the second "
"argument. E.g. (bit->> 4 2) = 1."},
{
"bit-or",
},
{
"bit-ones-complement",
},
@ -167,28 +197,33 @@ GeneratorMetadata g_generatorMetadata[] = {
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 2,
"Evaluate if the two arguments are not equal. Evaluates as true if not equal or false if "
"equal."},
{
">=",
},
{
"<=",
},
{
">",
},
{
"<",
},
{">=", GeneratorCategory_Relational, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 2,
"Evaluate if the first argument is greater than or equal to the second argument."},
{"<=", GeneratorCategory_Relational, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 2,
"Evaluate if the first argument is less than or equal to the second argument."},
{">", GeneratorCategory_Relational, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 2,
"Evaluate if the first argument is greater than the second argument."},
{"<", GeneratorCategory_Relational, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 2,
"Evaluate if the first argument is less than the second argument."},
//
// Logical
//
{
"and",
},
{
"or",
},
{"and", GeneratorCategory_Logic, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, MaxArgumentsUnlimited,
"Evaluate to true if all the expression arguments result in true. Lazily evaluates, "
"i.e. evaluation will stop as soon as any expression evaluates to false."},
{"or", GeneratorCategory_Logic, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, MaxArgumentsUnlimited,
"Evaluate to true if any of the expression arguments result in true. Lazily evaluates, "
"i.e. evaluation will stop as soon as any expression evaluates to true."},
{"not", GeneratorCategory_Logic, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 1, 1,
"Invert the boolean result of the argument. E.g. (not true) = false, (not false) = true"},
//
// Control flow
@ -197,170 +232,157 @@ GeneratorMetadata g_generatorMetadata[] = {
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 0, 1,
"Return from the current function. If a return value is specified, return that value to the "
"caller."},
{"if", GeneratorCategory_ControlFlow, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 3,
"If the first argument (condition) evaluates to true, execute the second argument (true "
"block). If the first argument evaluates to false, execute the third argument (false block), "
"if specified. Use (scope) in order to specify more than one statement in the true or false "
"blocks."},
{"when", GeneratorCategory_ControlFlow, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 2,
"If the first argument (condition) evaluates to true, execute the second argument (true "
"block). This is a way to write e.g. (if condition (do-thing))"},
{"unless", GeneratorCategory_ControlFlow, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 2,
"If the first argument (condition) evaluates to false, execute the second argument (false "
"block). This is a cleaner way to write e.g. (if (not condition) (do-thing))"},
{
"tokenize-push",
},
{
"if",
"cond",
},
{
"var-static",
"break",
},
{
"at",
"while",
},
{
"defmacro",
"?",
},
{
"nth",
"for-in",
},
{
"not",
"continue",
},
{
"type-cast",
},
{
"path",
"call-on",
},
{
"var-global",
"scope",
},
{
"defun-local",
"rename-builtin",
},
{
"bit-or",
"block",
},
{
"import",
"type",
},
{
"var",
"call",
},
{
"in",
"call-on-ptr",
},
{
"break",
"comptime-error",
},
//
// Definitions
//
{"var", GeneratorCategory_Definitions, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 3,
"Define a variable. The first argument is the name, the second is the type, and the optional "
"third argument is the initial value. When used in module scope (i.e., not within any "
"function), the variable will be local to the module and initialized on application startup."},
{"var-global", GeneratorCategory_Definitions, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 3,
"Define a global variable. The first argument is the name, the second is the type, and the "
"optional third argument is the initial value. This is only valid in module scope (i.e., not "
"within any function). The variable will be exposed to other modules which import the current "
"module. It is initialized on application startup."},
{"var-static", GeneratorCategory_Definitions, LanguageRequirement_C,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 2, 3,
"Define a static variable. The first argument is the name, the second is the type, and the "
"optional third argument is the initial value. This is only valid in body scope (i.e., within "
"a function). The variable will retain its value since the previous execution of the "
"function. It is initialized the first time the declaration is hit at runtime."},
{
"c-import",
"defgenerator",
},
{
"defun",
"defmacro",
},
{
"add-library-dependency",
"defstruct",
},
{
"defstruct-local",
},
{
"defun-nodecl",
},
{
"add-compiler-link-options",
},
{
"add-build-config-label",
},
{
"cond",
},
{
"defun-comptime",
},
{
"while",
},
{
"def-function-signature",
},
{
"defgenerator",
},
{
"?",
},
{
"call-on",
},
{
"when",
},
{
"def-type-alias-global",
},
{
"def-function-signature-global",
},
{
"scope",
},
{
"rename-builtin",
"defun",
},
{
"comptime-cond",
"defun-local",
},
{
"ignore",
"defun-nodecl",
},
{
"comptime-define-symbol",
{
"defun-comptime",
},
{
"def-type-alias",
},
{
"array",
},
{
"set",
},
{
"for-in",
},
{
"continue",
"def-type-alias-global",
},
{
"unless",
"array",
},
//
// Definitions
//
//
// Memory
//
{
"defstruct",
},
{
"block",
"set",
},
{
"type",
"field",
},
{
"call",
"path",
},
{
"call-on-ptr",
"addr",
},
{
"field",
{
"deref",
},
{
"deref",
"at",
},
{
"addr",
"nth",
},
{
"comptime-error",
//
// Code generation
//
{
"tokenize-push",
},
//
@ -374,8 +396,11 @@ GeneratorMetadata g_generatorMetadata[] = {
},
//
// C++ helpers. TODO: Move to CppHelpers.cake instead
// C++ helpers. TODO: Move to CppHelpers.cake instead?
//
{
"in",
},
{"new", GeneratorCategory_Memory, LanguageRequirement_Cpp,
(EvaluationTime_CompileTime | EvaluationTime_Runtime), 1, 1,
"Run new on the first argument, a type. Returns a pointer to the memory allocated after the "

4
test/BuildHelpers.cake

@ -4,10 +4,10 @@
(c-import "<stdio.h>")
(defun-nodecl my-test ()
(printf "Does nothing\n"))
(fprintf stderr "Does nothing\n"))
(defun main (&return int)
(printf "Hello, build tools!\n")
(fprintf stderr "Hello, build tools!\n")
(return 0))
(defun-comptime run-3rd-party-build (manager (& ModuleManager) module (* Module) &return bool)

24
test/CodeModification.cake

@ -4,10 +4,10 @@
(defun secret-print ()
(if false
(return))
(printf "I got away\n"))
(fprintf stderr "I got away\n"))
(defun main (&return int)
(printf "Hello Code modification!\n")
(fprintf stderr "Hello Code modification!\n")
(simple-macro)
(secret-print)
@ -22,8 +22,8 @@
(return (/ (- 4 2) 2)))
(defmacro simple-macro ()
(printf "simple-macro: %d, %d!\n" (compile-time-call) (compile-time-call-before))
(tokenize-push output (printf "Hello, macros!\n") (magic-number))
(fprintf stderr "simple-macro: %d, %d!\n" (compile-time-call) (compile-time-call-before))
(tokenize-push output (fprintf stderr "Hello, macros!\n") (magic-number))
(return true))
(defun-comptime compile-time-call (&return int)
@ -38,14 +38,14 @@
(get-or-create-comptime-var test-var std::string)
(get-or-create-comptime-var test-crazy-var (* (const (* (<> std::vector int)))))
(set (deref test-var) "Yeah")
(tokenize-push output (printf "The magic number is 42\n"))
(tokenize-push output (fprintf stderr "The magic number is 42\n"))
(return true))
(defun-comptime sabotage-main-printfs (environment (& EvaluatorEnvironment)
was-code-modified (& bool)
&return bool)
(get-or-create-comptime-var test-var std::string)
(printf "%s is the message\n" (call-on-ptr c_str test-var))
(fprintf stderr "%s is the message\n" (call-on-ptr c_str test-var))
(var old-definition-tags (<> std::vector std::string))
;; Scope to ensure that definition-it and definition are not referred to after
;; ReplaceAndEvaluateDefinition is called, because they will be invalid
@ -53,14 +53,14 @@
(var definition-it (in ObjectDefinitionMap iterator)
(call-on find (field environment definitions) "main"))
(when (= definition-it (call-on end (field environment definitions)))
(printf "sabotage-main-printfs: could not find main!\n")
(fprintf stderr "sabotage-main-printfs: could not find main!\n")
(return false))
(printf "sabotage-main-printfs: found main\n")
(fprintf stderr "sabotage-main-printfs: found main\n")
(var definition (& ObjectDefinition) (path definition-it > second))
(when (!= (FindInContainer (field definition tags) "sabotage-main-printfs-done")
(call-on end (field definition tags)))
(printf "sabotage-main-printfs: already modified\n")
(fprintf stderr "sabotage-main-printfs: already modified\n")
(return true))
;; Other modification functions should do this lazily, i.e. only create the expanded definition
@ -80,12 +80,12 @@
(var prev-token (* Token) null)
(for-in token (& Token) (deref modified-main-tokens)
(when (and prev-token
(= 0 (call-on compare (path prev-token > contents) "printf"))
(= 0 (call-on compare (path prev-token > contents) "stderr"))
(ExpectTokenType "sabotage-main-printfs" token TokenType_String))
(set (field token contents) "I changed your print! Mwahahaha!\\n"))
(set prev-token (addr token)))
(printf "sabotage-main-printfs: modified main!\n")
(fprintf stderr "sabotage-main-printfs: modified main!\n")
;; After
(prettyPrintTokens (deref modified-main-tokens))
@ -102,7 +102,7 @@
(var definition-it (in ObjectDefinitionMap iterator)
(call-on find (field environment definitions) "main"))
(when (= definition-it (call-on end (field environment definitions)))
(printf "sabotage-main-printfs: could not find main after replacement!\n")
(fprintf stderr "sabotage-main-printfs: could not find main after replacement!\n")
(return false))
(PushBackAll (path definitionIt > second . tags) old-definition-tags)
(call-on push_back (path definitionIt > second . tags) "sabotage-main-printfs-done")

4
test/Defines.cake

@ -20,10 +20,10 @@
(const (* (<> (in std vector) (<> (in std vector) int)))))
(defun main (&return int)
(printf "Path length: %d\n" MAX_PATH_LENGTH)
(fprintf stderr "Path length: %d\n" MAX_PATH_LENGTH)
(def-type-alias my-type int)
(var a-thing my-type 0)
(printf "Thing: %d\n" a-thing)
(fprintf stderr "Thing: %d\n" a-thing)
(return 0))

2
test/Execute.cake

@ -2,7 +2,7 @@
(c-import "<stdio.h>")
(defun main (&return int)
(printf "Hello, execute!\n")
(fprintf stderr "Hello, execute!\n")
(return 0))
(set-cakelisp-option executable-output "test/ExecuteMe")

4
test/Hello.cake

@ -6,10 +6,10 @@
(var list va_list)
(va_start list num-args)
(each-in-range num-args i
(printf "%d\n" (va_arg list int)))
(fprintf stderr "%d\n" (va_arg list int)))
(va_end list))
(defun main (&return int)
(printf "Hello, world! From Cakelisp!\n")
(fprintf stderr "Hello, world! From Cakelisp!\n")
(varargs 3 1 2 3)
(return 0))

8
test/MultiLineStrings.cake

@ -1,7 +1,7 @@
(c-import "<stdio.h>")
(defun main (&return int)
(printf "Hello, execute!\n" \
(fprintf stderr "Hello, execute!\n" \
"This is a long message, broken " \
"across multiple lines. " \ ;; Here's a comment on the same line
"We can also just insert newlines,
@ -12,15 +12,15 @@ though
there
are
newlines. It's a trade-off.\n")
(printf "%d. How about That?
(fprintf stderr "%d. How about That?
" 42)
(printf "\nMy shopping list:\n
(fprintf stderr "\nMy shopping list:\n
eggs\n
bacon\n
sword\n
"
)
(printf #"#This is a "here-string". All the characters that I type should literally appear,
(fprintf stderr #"#This is a "here-string". All the characters that I type should literally appear,
including that indentation#"#)
(return 0))

12
test/SimpleMacros.cake

@ -5,19 +5,19 @@
(return true))
(defmacro my-print (message string)
(printf "Compile-time print!\n")
(tokenize-push output (printf "%s\n" (token-splice message)))
(fprintf stderr "Compile-time print!\n")
(tokenize-push output (fprintf stderr "%s\n" (token-splice message)))
(tokenize-push output
(printf "%s\n" (token-splice message))
(printf "Second one %s\n" (token-splice message)))
(fprintf stderr "%s\n" (token-splice message))
(fprintf stderr "Second one %s\n" (token-splice message)))
(var numbers (<> (in std vector) Token))
(tokenize-push numbers 1 2 3)
(tokenize-push output (printf "%d %d %d\n" (token-splice-array numbers)))
(tokenize-push output (fprintf stderr "%d %d %d\n" (token-splice-array numbers)))
(return true))
(defun main (&return int)
(printf "Hello, world! From Cakelisp!\n")
(fprintf stderr "Hello, world! From Cakelisp!\n")
(my-print "Printed thanks to a macro!")
(argument-indices "test")
(argument-indices "test" "test 2")

2
test/TestPaths.cake

@ -19,7 +19,7 @@
(perror "realpath: ")
(incr i)
(continue))
(printf "%s = %s\n" (at i path-tests) result)
(fprintf stderr "%s = %s\n" (at i path-tests) result)
(free (type-cast result (* void)))
(incr i))
(return 0))

2
test/dir/Test.cpp

@ -8,5 +8,5 @@
DEPENDENCY_API void test()
{
printf("Hello from C!\n");
fprintf(stderr, "Hello from C!\n");
}

Loading…
Cancel
Save