Browse Source

Renamed on-call to call-on, clean up

* This change is consistent with the syntax of call, and the overall
idea of emphasizing functions over objects
* Removed commented code
* Added notes on 3rd-party tools and Cakelisp integration
* Macro failure now includes macro name, in case source column isn't
obtainable (e.g. macro within macro)
precompiled-headers
Macoy Madson 4 months ago
parent
commit
ed10693994
12 changed files with 83 additions and 87 deletions
  1. +0
    -17
      CrossCompile_Windows.cake
  2. +17
    -6
      doc/Cakelisp.org
  3. +4
    -3
      runtime/BuildTools.cake
  4. +4
    -4
      runtime/DynamicLoader.cake
  5. +7
    -7
      runtime/HotReloading.cake
  6. +22
    -22
      runtime/HotReloadingCodeModifier.cake
  7. +10
    -10
      runtime/Macros.cake
  8. +2
    -2
      runtime/TextAdventure.cake
  9. +2
    -1
      src/Evaluator.cpp
  10. +5
    -5
      src/Generators.cpp
  11. +9
    -9
      test/CodeModification.cake
  12. +1
    -1
      test/RunTests.cake

+ 0
- 17
CrossCompile_Windows.cake View File

@ -22,23 +22,6 @@
(add-build-options "-DWINDOWS" "-DMINGW" "-DCAKELISP_EXPORTING")
;; (defun-comptime cakelisp-link-hook (manager (& ModuleManager)
;; linkCommand (& ProcessCommand)
;; linkTimeInputs (* ProcessCommandInput) numLinkTimeInputs int
;; &return bool)
;; (Log "Cakelisp: Adding link arguments\n")
;; ;; Dynamic loading
;; (on-call (field linkCommand arguments) push_back
;; (array ProcessCommandArgumentType_String
;; "-ldl"))
;; ;; Expose Cakelisp symbols for compile-time function symbol resolution
;; (on-call (field linkCommand arguments) push_back
;; (array ProcessCommandArgumentType_String
;; "-Wl,--export-dynamic"))
;; (return true))
;; (add-compile-time-hook pre-link cakelisp-link-hook)
(set-cakelisp-option build-time-compiler "/usr/bin/x86_64-w64-mingw32-g++")
(set-cakelisp-option build-time-compile-arguments
"-g" "-c" 'source-input "-o" 'object-output


+ 17
- 6
doc/Cakelisp.org View File

@ -80,7 +80,7 @@ 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 "MyHeader.hpp") ;; (on-call myGlobalVar updateState 0.016)
(c-import "MyHeader.hpp") ;; (call-on updateState myGlobalVar 0.016)
;; Multiple imports are allowed per call:
(c-import "<vector>" "<map>")
@ -231,9 +231,9 @@ Use the argument ~--list-built-ins~ to see an up-to-date list of all possible ex
- ~deref~: Return the value at the pointer's address
- ~addr~: Take the address of a variable/member
- ~field~: Access a struct/class member. For example, with struct ~(defstruct my-struct num int)~, and variable ~(var my-thing my-struct)~, access ~num~: ~(field my-thing num)~
- ~on-call~: Call a member function. For example, if I have a variable ~my-bar~ of type ~Bar~ with member function ~do-thing~, I can call it like so: ~(on-call my-bar do-thing arg-1 arg-2)~
- ~on-call-ptr~: Like ~on-call~, only it works on pointers, e.g. ~(var my-pointer-to-bar (* Bar) (addr a-bar))~, call its member: ~(on-call-ptr my-pointer-to-bar do-thing arg-1 arg-2)~. These can be nested as necessary
- ~call~: Call the first argument as a function. For example, to call a static member function: ~(call (in my-class do-static-thing) arg-1 arg-2)~
- ~call-on~: Call a member function. For example, if I have a variable ~my-bar~ of type ~Bar~ with member function ~do-thing~, I can call it like so: ~(call-on do-thing my-bar arg-1 arg-2)~
- ~call-on-ptr~: Like ~call-on~, only it works on pointers, e.g. ~(var my-pointer-to-bar (* Bar) (addr a-bar))~, call its member: ~(call-on-ptr do-thing my-pointer-to-bar arg-1 arg-2)~. These can be nested as necessary
- ~call~: Call the first argument as a function. This is necessary when you can't type the function's name directly, e.g. it is a function pointer. For example, to call a static member function: ~(call (in my-class do-static-thing) arg-1 arg-2)~
- ~in~: Scope resolution operator (~::~). Used for both namespaces and static member access. For e.g. ~(in SuperSpace SubSpace Thing)~ would generate ~SuperSpace::SubSpace::Thing~. ~in~ may be used within type signatures
- ~type-cast~: Cast the variable to given type, e.g. ~(var actually-int (* void) (get-stored-var-pointer "my-int"))~ could become an int via ~(type-cast actually-int (* int))~
- ~type~: Parse the first argument as a type. Types are a domain-specific language, so the evaluator needs to know when it should use that special evaluation mode
@ -487,11 +487,11 @@ There may be cases when you need to do complex logic or modifications of the lin
&return bool)
(Log "Cakelisp: Adding link arguments\n")
;; Dynamic loading
(on-call (field linkCommand arguments) push_back
(call-on push_back (field linkCommand arguments)
(array ProcessCommandArgumentType_String
"-ldl"))
;; Expose Cakelisp symbols for compile-time function symbol resolution
(on-call (field linkCommand arguments) push_back
(call-on push_back (field linkCommand arguments)
(array ProcessCommandArgumentType_String
"-Wl,--export-dynamic"))
(return true))
@ -578,3 +578,14 @@ It does have some nice properties: if you update a 3rd-party library, Cakelisp w
If you want to test a clean build, i.e. one which does not use any existing artifacts, you can do either of the following:
- Delete the ~cakelisp_cache~ directory in the same working directory you have been executing ~cakelisp~
- Pass the ~--ignore-cache~ argument, which will cause all artifacts to be marked stale and invalid
* External tools
** Counting lines of code
Use the following setup to [[https://github.com/AlDanial/cloc][cloc]]:
#+BEGIN_SRC sh
cloc --force-lang="Lisp",cake [dirs]
#+END_SRC
** Github syntax highlighting
Create a ~.gitattributes~ file in the project root, then add the following:
#+BEGIN_SRC sh
*.cake linguist-language=lisp
#+END_SRC

+ 4
- 3
runtime/BuildTools.cake View File

@ -39,7 +39,7 @@
((and (= TokenType_Symbol (path current-token > type))
(isSpecialSymbol (deref current-token)))
(cond
((= 0 (on-call (path current-token > contents) compare ":in-directory"))
((= 0 (call-on compare (path current-token > contents) ":in-directory"))
(var next-token (* (const Token)) (+ 1 current-token))
(unless (< next-token end-token)
(ErrorAtToken (deref next-token) "expected expression for working directory")
@ -61,7 +61,7 @@
;; (set (token-splice-addr working-dir-str-var) working-dir-alloc)
;; (free (type-cast working-dir-alloc (* void))))
(set (field (token-splice arguments-out-name) working-directory)
(on-call (token-splice-addr working-dir-str-var) c_str)))
(call-on c_str (token-splice-addr working-dir-str-var))))
;; Absorb src for incr
(set current-token next-token))
@ -72,7 +72,7 @@
;; Everything else is a argument to the command
(true
(on-call command-arguments push_back (deref current-token))))
(call-on push_back command-arguments (deref current-token))))
(incr current-token)))
(gen-unique-symbol resolved-executable-var "resolved-executable" (deref executable-name))
@ -116,6 +116,7 @@
;; status-int-ptr should be an address to an int variable which can be checked for process exit
;; code, but only after waitForAllProcessesClosed
;; TODO: Make run-process-start-or block based on number of cores?
(defmacro run-process-start-or (status-int-ptr any command array &rest on-failure-to-start array)
(var my-tokens (<> std::vector Token))
(tokenize-push


+ 4
- 4
runtime/DynamicLoader.cake View File

@ -134,15 +134,15 @@
(dlclose (field libraryPair second handle)))
('Windows
(FreeLibrary (type-cast (field libraryPair second handle) HMODULE)))))
(on-call dynamicLibraries clear))
(call-on clear dynamicLibraries))
(defun dynamic-library-close (handleToClose DynamicLibHandle)
(var libHandle DynamicLibHandle null)
(var libraryIt (in DynamicLibraryMap iterator) (on-call dynamicLibraries begin))
(while (!= libraryIt (on-call dynamicLibraries end))
(var libraryIt (in DynamicLibraryMap iterator) (call-on begin dynamicLibraries))
(while (!= libraryIt (call-on end dynamicLibraries))
(when (= handleToClose (path libraryIt > second . handle))
(set libHandle (path libraryIt > second . handle))
(on-call dynamicLibraries erase libraryIt)
(call-on erase dynamicLibraries libraryIt)
(break))
(incr libraryIt))


+ 7
- 7
runtime/HotReloading.cake View File

@ -36,16 +36,16 @@
(defun register-function-pointer (function-pointer (* (* void))
function-name (* (const char)))
(var findIt FunctionReferenceMapIterator
(on-call registered-functions find function-name))
(if (= findIt (on-call registered-functions end))
(call-on find registered-functions function-name))
(if (= findIt (call-on end registered-functions))
(block
(var new-function-pointer-array FunctionReferenceArray)
(on-call new-function-pointer-array push_back function-pointer)
(call-on push_back new-function-pointer-array function-pointer)
(set (at function-name registered-functions)
;; This could also be written as (std::move new-function-pointer-array)
;; I'm not sure how I want it to work
(call (in std move) new-function-pointer-array)))
(on-call (path findIt > second) push_back function-pointer)))
(call-on push_back (path findIt > second) function-pointer)))
(defun-local copy-binary-file-to (srcFilename (* (const char))
destFilename (* (const char)) &return bool)
@ -119,7 +119,7 @@
(for-in function-referent-it (& FunctionReferenceMapPair) registered-functions
(var loaded-symbol (* void)
(dynamic-library-get-symbol current-lib
(on-call (path function-referent-it . first) c_str)))
(call-on c_str (path function-referent-it . first))))
(unless loaded-symbol
(return false))
;; TODO: What will happen once modules are unloaded? We can't store pointers to their static memory
@ -141,8 +141,8 @@
(var verbose-variables bool false)
(defun hot-reload-find-variable (name (* (const char)) variable-address-out (* (* void)) &return bool)
(var find-it StateVariableMapIterator (on-call registered-state-variables find name))
(unless (!= find-it (on-call registered-state-variables end))
(var find-it StateVariableMapIterator (call-on find registered-state-variables name))
(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))


+ 22
- 22
runtime/HotReloadingCodeModifier.cake View File

@ -90,15 +90,15 @@
(var top-level-type (* (const Token)) (+ variable-type 1))
(cond
;; TODO: Add array support
((= 0 (on-call (path top-level-type > contents) compare "[]"))
((= 0 (call-on compare (path top-level-type > contents) "[]"))
(NoteAtToken (deref variable-start-invocation) "hot-reloadable arrays not supported yet")
(continue))
;; Constants cannot be changed, so do not need to be reloaded
;; What happens when you reload the lib? Do the constants get updated?
((= 0 (on-call (path top-level-type > contents) compare "const"))
((= 0 (call-on compare (path top-level-type > contents) "const"))
(continue))))
(when verbose (printf ">>> Variable %s\n" (on-call (field definition-pair first) c_str)))
(when verbose (printf ">>> 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
@ -107,7 +107,7 @@
(set (field var-to-modify name) (field definition-pair first))
(set (field var-to-modify module) (field definition context module))
(on-call variables-to-modify push_back (call (in std move) var-to-modify)))
(call-on push_back variables-to-modify (call (in std move) var-to-modify)))
;; Collect references to variables we're going to need to auto-deref
;; TODO: variables can have initializers which reference modded variables, which the init functions
@ -128,7 +128,7 @@
(unless (= (field token type) TokenType_Symbol)
(continue))
(for-in var-to-modify (& (const modify-definition)) variables-to-modify
(when (= 0 (on-call (field token contents) compare
(when (= 0 (call-on compare (field token contents)
(field (at 2 (field var-to-modify expanded-definition)) contents)))
(set reference-found true)
(break))))
@ -136,11 +136,11 @@
(continue))
(when verbose (printf ">>> Reference(s) found in %s\n"
(on-call (field definition-pair first) c_str)))
(call-on c_str (field definition-pair first))))
(set (field def-to-modify module) (field definition context module))
(set (field def-to-modify name) (field definition-pair first))
(on-call references-to-modify push_back (call (in std move) def-to-modify)))
(call-on push_back references-to-modify (call (in std move) def-to-modify)))
(var initializer-names (<> std::vector Token))
@ -157,7 +157,7 @@
(when verbose (prettyPrintTokens expanded-var-tokens))
(var start-token-index int 0)
(var end-invocation-index int (- (on-call expanded-var-tokens size) 1))
(var end-invocation-index int (- (call-on size expanded-var-tokens) 1))
(var var-name-index int
(getExpectedArgument "expected variable name"
expanded-var-tokens
@ -180,7 +180,7 @@
;; Pointerify, remove intializer
(var new-var-tokens (* (<> std::vector Token)) (new (<> std::vector Token)))
(on-call (field environment comptimeTokens) push_back new-var-tokens)
(call-on push_back (field environment comptimeTokens) new-var-tokens)
(tokenize-push (deref new-var-tokens)
((token-splice-addr var-invocation)
(token-splice-addr var-name)
@ -198,7 +198,7 @@
(var converted-name-buffer ([] 64 char) (array 0))
;; TODO: Need to pass this in somehow
(var name-style NameStyleSettings)
(lispNameStyleToCNameStyle (field name-style variableNameMode) (on-call (field var-name contents) c_str)
(lispNameStyleToCNameStyle (field name-style variableNameMode) (call-on c_str (field var-name contents))
converted-name-buffer (sizeof converted-name-buffer) var-name)
(var init-function-name-buffer ([] 256 char) (array 0))
@ -206,7 +206,7 @@
(set (field init-function-name contents) init-function-name-buffer))
;; Store it for making the global initializer, which will call all initializers
(on-call initializer-names push_back init-function-name)
(call-on push_back initializer-names init-function-name)
(set (at (path module > filename) modules-to-import) init-function-name)
(var assignment-tokens (<> std::vector Token))
@ -219,7 +219,7 @@
(set (deref (token-splice-addr var-name)) (token-splice assignment-token)))))
(var initializer-procedure-tokens (* (<> std::vector Token)) (new (<> std::vector Token)))
(on-call (field environment comptimeTokens) push_back initializer-procedure-tokens)
(call-on push_back (field environment comptimeTokens) initializer-procedure-tokens)
;; Note that we don't auto-deref this; this is the only place where that's the case
(tokenize-push
(deref initializer-procedure-tokens)
@ -240,7 +240,7 @@
;; Definition references invalid after this!
(unless (ReplaceAndEvaluateDefinition environment (on-call (field var-name contents) c_str)
(unless (ReplaceAndEvaluateDefinition environment (call-on c_str (field var-name contents))
(deref new-var-tokens))
(return false))
(set was-code-modified true)
@ -256,10 +256,10 @@
;; Make sure HotReloading header is included
(var module-filename (* (const char)) (path module > filename))
(when (= (on-call (deref modules-with-import) find module-filename)
(on-call-ptr modules-with-import end))
(when (= (call-on find (deref modules-with-import) module-filename)
(call-on-ptr end modules-with-import))
(var import-hot-reloading-tokens (* (<> std::vector Token)) (new (<> std::vector Token)))
(on-call (field environment comptimeTokens) push_back import-hot-reloading-tokens)
(call-on push_back (field environment comptimeTokens) import-hot-reloading-tokens)
;; Make sure we don't build our own version of this. The loader needs to manage it
(tokenize-push (deref import-hot-reloading-tokens) (import &decls-only "HotReloading.cake"))
(unless (= 0 (EvaluateGenerate_Recursive
@ -282,22 +282,22 @@
(field def-to-modify expanded-definition))
(var module (* Module) (field def-to-modify module))
(var new-definition (* (<> std::vector Token)) (new (<> std::vector Token)))
(on-call (field environment comptimeTokens) push_back new-definition)
(call-on push_back (field environment comptimeTokens) new-definition)
(for-in token (& (const Token)) expanded-def-tokens
(unless (= (field token type) TokenType_Symbol)
(on-call (deref new-definition) push_back token)
(call-on push_back (deref new-definition) token)
(continue))
;; Check for reference
(var reference-found bool false)
(for-in var-to-modify (& (const modify-definition)) variables-to-modify
(when (= 0 (on-call (field token contents) compare
(when (= 0 (call-on compare (field token contents)
(field (at 2 (field var-to-modify expanded-definition)) contents)))
(set reference-found true)
(break)))
;; Just an uninteresting symbol
(unless reference-found
(on-call (deref new-definition) push_back token)
(call-on push_back (deref new-definition) token)
(continue))
;; Insert the deref
@ -306,7 +306,7 @@
(PushBackAll (deref new-definition) auto-deref-tokens))
;; Replace it!
(unless (ReplaceAndEvaluateDefinition environment (on-call (field def-to-modify name) c_str)
(unless (ReplaceAndEvaluateDefinition environment (call-on c_str (field def-to-modify name))
(deref new-definition))
(return false))
(set was-code-modified true))
@ -319,7 +319,7 @@
(scope
(var new-initializer-def (* (<> std::vector Token)) (new (<> std::vector Token)))
;; Environment will handle freeing tokens for us
(on-call (field environment comptimeTokens) push_back new-initializer-def)
(call-on push_back (field environment comptimeTokens) new-initializer-def)
(var invocations (<> std::vector Token))
(for-in initializer-name (& Token) initializer-names


+ 10
- 10
runtime/Macros.cake View File

@ -1,7 +1,7 @@
(skip-build)
(defmacro std-str-equals (std-string-var any str any)
(tokenize-push output (= 0 (on-call (token-splice std-string-var) compare (token-splice str))))
(tokenize-push output (= 0 (call-on compare (token-splice std-string-var) (token-splice str))))
(return true))
;; This should evaluate its argument, but I'm just hacking it in right now anyways
@ -75,7 +75,7 @@
(return false)))
;; Type names
(true
(unless (writeStringToBufferErrorToken (on-call (path current-type-token > contents) c_str)
(unless (writeStringToBufferErrorToken (call-on c_str (path current-type-token > contents))
(addr type-name-string-write-head) type-to-name-string-buffer
(sizeof type-to-name-string-buffer) (deref current-type-token))
(return false)))))
@ -96,14 +96,14 @@
(set (field destroy-var-func-name-symbol type) TokenType_Symbol)
(var destroy-func-name (* (const char))
(on-call (field destroy-var-func-name-str contents) c_str))
(call-on c_str (field destroy-var-func-name-str contents)))
;; Define the destructor if one for this type isn't already defined
(unless (or (findCompileTimeFunction environment destroy-func-name)
(findObjectDefinition environment destroy-func-name))
(var destruction-func-def (* (<> std::vector Token)) (new (<> std::vector Token)))
;; Need to have the environment delete this once it's safe
(on-call (field environment comptimeTokens) push_back destruction-func-def)
(call-on push_back (field environment comptimeTokens) destruction-func-def)
(tokenize-push (deref destruction-func-def)
(defun-comptime (token-splice-addr destroy-var-func-name-symbol) (data (* void))
(delete (type-cast data (* (token-splice-addr var-type))))))
@ -119,7 +119,7 @@
;; built. This throwaway will essentially only have a splice to that output, so we don't really
;; need to keep track of it, except to destroy it once everything is done
(var throwaway-output (* GeneratorOutput) (new GeneratorOutput))
(on-call (field environment orphanedOutputs) push_back throwaway-output)
(call-on push_back (field environment orphanedOutputs) throwaway-output)
(unless (= 0 (EvaluateGenerate_Recursive environment
destruction-func-context
(deref destruction-func-def) 0
@ -208,7 +208,7 @@
(when (= TokenType_OpenParen (field current-token type))
(var invocation-token (& (const Token)) (at (+ 1 current-index) tokens))
(cond
((= 0 (on-call (field invocation-token contents) compare "namespace"))
((= 0 (call-on compare (field invocation-token contents) "namespace"))
(unless (< (+ 3 current-index) end-invocation-index)
(ErrorAtToken invocation-token "missing name or body arguments")
(return false))
@ -218,10 +218,10 @@
(addStringOutput output-dest (field namespace-name-token contents)
StringOutMod_None (addr namespace-name-token))
(addLangTokenOutput output-dest StringOutMod_OpenBlock (addr namespace-name-token))
(on-call namespace-stack push_back (FindCloseParenTokenIndex tokens current-index)))
(call-on push_back namespace-stack (FindCloseParenTokenIndex tokens current-index)))
((or (= 0 (on-call (field invocation-token contents) compare "class"))
(= 0 (on-call (field invocation-token contents) compare "struct")))
((or (= 0 (call-on compare (field invocation-token contents) "class"))
(= 0 (call-on compare (field invocation-token contents) "struct")))
(unless (< (+ 2 current-index) end-invocation-index)
(ErrorAtToken invocation-token "missing name argument")
(return false))
@ -249,7 +249,7 @@
(return true))
(defmacro command-add-string-argument (command any new-argument any)
(tokenize-push output (on-call (field (token-splice command) arguments) push_back
(tokenize-push output (call-on push_back (field (token-splice command) arguments)
(array ProcessCommandArgumentType_String
(token-splice new-argument))))
(return true))


+ 2
- 2
runtime/TextAdventure.cake View File

@ -35,7 +35,7 @@
(for-in connected-room (& (const room)) (path room-to-print > connected-rooms)
(printf "%d: %s\n" room-index (field connected-room name))
(incr room-index))
(when (on-call (path room-to-print > connected-rooms) empty)
(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")))
;; Return true to hot-reload, or false to exit
@ -66,7 +66,7 @@
(print-help))
((call (in std isdigit) input)
(var room-request int (atoi (addr input)))
(var num-rooms int (on-call (path current-room > connected-rooms) size))
(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)
(continue))


+ 2
- 1
src/Evaluator.cpp View File

@ -288,7 +288,8 @@ bool HandleInvocation_Recursive(EvaluatorEnvironment& environment, const Evaluat
// Don't even try to validate the code if the macro wasn't satisfied
if (!macroSucceeded)
{
ErrorAtToken(invocationName, "macro returned failure");
ErrorAtTokenf(invocationName, "macro '%s' returned failure",
invocationName.contents.c_str());
// Deleting these tokens is only safe at this point because we know we have not
// evaluated them. As soon as they are evaluated, they must be kept around


+ 5
- 5
src/Generators.cpp View File

@ -2634,12 +2634,12 @@ bool CStatementGenerator(EvaluatorEnvironment& environment, const EvaluatorConte
const CStatementOperation field[] = {{SpliceNoSpace, ".", 1}};
const CStatementOperation memberFunctionInvocation[] = {
{Expression, nullptr, 1}, {KeywordNoSpace, ".", -1}, {Expression, nullptr, 2},
{Expression, nullptr, 2}, {KeywordNoSpace, ".", -1}, {Expression, nullptr, 1},
{OpenParen, nullptr, -1}, {ExpressionList, nullptr, 3}, {CloseParen, nullptr, -1},
{SmartEndStatement, nullptr, -1}};
const CStatementOperation dereferenceMemberFunctionInvocation[] = {
{Expression, nullptr, 1}, {KeywordNoSpace, "->", -1}, {Expression, nullptr, 2},
{Expression, nullptr, 2}, {KeywordNoSpace, "->", -1}, {Expression, nullptr, 1},
{OpenParen, nullptr, -1}, {ExpressionList, nullptr, 3}, {CloseParen, nullptr, -1},
{SmartEndStatement, nullptr, -1}};
@ -2781,8 +2781,8 @@ bool CStatementGenerator(EvaluatorEnvironment& environment, const EvaluatorConte
{"deref", dereference, ArraySize(dereference)},
{"addr", addressOf, ArraySize(addressOf)},
{"field", field, ArraySize(field)},
{"on-call", memberFunctionInvocation, ArraySize(memberFunctionInvocation)},
{"on-call-ptr", dereferenceMemberFunctionInvocation,
{"call-on", memberFunctionInvocation, ArraySize(memberFunctionInvocation)},
{"call-on-ptr", dereferenceMemberFunctionInvocation,
ArraySize(dereferenceMemberFunctionInvocation)},
{"call", callFunctionInvocation, ArraySize(callFunctionInvocation)},
{"in", scopeResolution, ArraySize(scopeResolution)},
@ -2968,7 +2968,7 @@ void importFundamentalGenerators(EvaluatorEnvironment& environment)
// Pointers
"deref", "addr", "field",
// C++ support: calling members, calling namespace functions, scope resolution operator
"on-call", "on-call-ptr", "call", "in", "type-cast", "type",
"call-on", "call-on-ptr", "call", "in", "type-cast", "type",
// Boolean
"or", "and", "not",
// Bitwise


+ 9
- 9
test/CodeModification.cake View File

@ -45,21 +45,21 @@
was-code-modified (& bool)
&return bool)
(get-or-create-comptime-var test-var std::string)
(printf "%s is the message\n" (on-call-ptr test-var c_str))
(printf "%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
(scope
(var definition-it (in ObjectDefinitionMap iterator)
(on-call (field environment definitions) find "main"))
(when (= definition-it (on-call (field environment definitions) end))
(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")
(return false))
(printf "sabotage-main-printfs: found main\n")
(var definition (& ObjectDefinition) (path definition-it > second))
(when (!= (FindInContainer (field definition tags) "sabotage-main-printfs-done")
(on-call (field definition tags) end))
(call-on end (field definition tags)))
(printf "sabotage-main-printfs: already modified\n")
(return true))
@ -72,7 +72,7 @@
(return false))
;; Environment will handle freeing tokens for us
(on-call (field environment comptimeTokens) push_back modified-main-tokens)
(call-on push_back (field environment comptimeTokens) modified-main-tokens)
;; Before
(prettyPrintTokens (deref modified-main-tokens))
@ -80,7 +80,7 @@
(var prev-token (* Token) null)
(for-in token (& Token) (deref modified-main-tokens)
(when (and prev-token
(= 0 (on-call (path prev-token > contents) compare "printf"))
(= 0 (call-on compare (path prev-token > contents) "printf"))
(ExpectTokenType "sabotage-main-printfs" token TokenType_String))
(set (field token contents) "I changed your print! Mwahahaha!\\n"))
(set prev-token (addr token)))
@ -100,12 +100,12 @@
;; Find the new (replacement) definition and add a tag saying it is done replacement
;; Note that I also push the tags of the old definition
(var definition-it (in ObjectDefinitionMap iterator)
(on-call (field environment definitions) find "main"))
(when (= definition-it (on-call (field environment definitions) end))
(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")
(return false))
(PushBackAll (path definitionIt > second . tags) old-definition-tags)
(on-call (path definitionIt > second . tags) push_back "sabotage-main-printfs-done")
(call-on push_back (path definitionIt > second . tags) "sabotage-main-printfs-done")
(return true))
(add-compile-time-hook post-references-resolved sabotage-main-printfs)


+ 1
- 1
test/RunTests.cake View File

@ -37,7 +37,7 @@
(Logf "\n===============\n%s\n\n" test-name)
(run-process-sequential-or
(cakelisp-executable "--execute" test-file)
(Logf "error: test %s failed" test-name)
(Logf "error: test %s failed\n" test-name)
(return false))
(Logf "\n%s succeeded\n" test-name)
(incr i))


Loading…
Cancel
Save