Skip to content

Commit

Permalink
Large change. Refactor inlined state to be stack-based
Browse files Browse the repository at this point in the history
 - State now uses retained frames instead of genenerated pack/unpack terms
  • Loading branch information
andyfischer committed Aug 30, 2013
1 parent 4103ee3 commit bf3de4d
Show file tree
Hide file tree
Showing 86 changed files with 1,883 additions and 2,565 deletions.
23 changes: 12 additions & 11 deletions BUILDING.txt
@@ -1,7 +1,7 @@
# Prerequisites #

- For just building, GCC and GNU make are required.
- For testing and development, Python2.6 and Premake4 are required.
- For just building, GCC and GNU Make are required.
- For testing and development, Python3 and Premake4 are required.

# Build Instructions #

Expand All @@ -23,16 +23,16 @@ Run: make <optional config> <optional target>
- (On Windows the suffix is .lib, as in: circa.lib)

command_line
- Command-line tool with REPL.
- Command-line tool with a REPL.
- Found at: build/circa_d (debug) or build/circa
- (On Windows the suffix is .exe, as in: circa.exe)

unit_tests
- App that runs C++-based unit tests.
- Found at: build/circa_test or build/circa_test_r (release)
- Not recommended to use config=release for unit tests.
- Should only be built using config=debug.

Example commands:
Example command:

make static_lib config=release
- Build static library in release mode
Expand All @@ -52,18 +52,19 @@ code or doing alternative builds.
Prebuild
The python script at tools/ca-prebuild.py serves to create some generated C++
files located at src/generated. The resulting files are checked in to source
control, so that folks can build straight from a clone.
control (so that users can build straight from a clone).

This script needs to be rerun whenever a cpp file is added or removed from
/src/functions or /src/types. It also needs to be run when /src/ca/stdlib.ca
is changed.
This script needs to be rerun whenever:
A .cpp file is added or removed from src/functions or src/types
Or src/ca/stdlib.ca is changed
Or src/names.txt is changed

Makefiles
The makefiles are generated using premake4. More info on this tool at:
http://industriousone.com/premake

The resulting generated makefiles are checked in to source control, so
that users can build straight straight from a clone.
The resulting generated makefiles are checked in to source control (also
so that users can build straight straight from a clone).

Makefiles need to be regenerated whenever a cpp file is added or removed. To
regenerate the makefiles, run "premake4 gmake".
Expand Down
2 changes: 1 addition & 1 deletion include/circa/circa.h
Expand Up @@ -236,7 +236,7 @@ caTerm* circa_caller_term(caStack* stack);
// Fetch the Block that holds the caller Term.
caBlock* circa_caller_block(caStack* stack);

caBlock* circa_top_block(caStack* stack);
caBlock* circa_stack_top_block(caStack* stack);

// -- Tagged Values --
//
Expand Down
44 changes: 44 additions & 0 deletions notes/state_with_memoizing
@@ -0,0 +1,44 @@

Notes on how to reimplement inlined state using saved-frames.

The basic outline:

There is a special function 'declared_state' whose results are always retained
as inlined state.
This function is actually a Circa function; there is some logic around using
the initializer. But I think it will continue to work.
Treating this as a memoized function should work pretty well.
Some differences with existing memoize() calls
Retention policy is different. If the initializer or type is changed, the existing
state should be migrated. (as opposed to memoize frames, which should be reevaluated).

State is not retained when the codepath becomes inactive (as in a failed if-block check,
or an unused for-loop iteration).
Considering also doing this for memoize blocks, but not yet implemented.
Existing memoize blocks only store 1 frame per for-loop, not N.

Need to support migration
Also a need for memoize blocks (but less important there)


Value boxing/unboxing
In the current language, there's a useful ability where you can call a function
with f(state = s), which captures the function's state as a first-class value.
So, you have more control over how the state is being used.

With the saved-frame approach, we have two choices:

1) User receives a copy of the frame
Pros
Less complexity?
Cons
There isn't much precedent for passing around frames as values.
(But, this doesn't sound like a bad thing)
Harder to manipulate frame values.
Somewhat surprising for newcomers (?)
2) We turn the frame into a different representation (maybe a dictionary) and
give them that.
Pros
Easier for newcomers
Cones
Information loss, such as loss of branch pointer, which will hurt migration.
5 changes: 5 additions & 0 deletions src/block.cpp
Expand Up @@ -592,6 +592,11 @@ void duplicate_block(Block* source, Block* dest)
dest->names.remapPointers(newTermMap);
}

Term* compile(Block* block, const char* str)
{
return parser::compile(block, parser::statement_list, str);
}

Symbol load_script(Block* block, const char* filename)
{
// Store the filename
Expand Down
6 changes: 6 additions & 0 deletions src/block.h
Expand Up @@ -178,9 +178,15 @@ void erase_term(Term* term);
// Delete the contents of 'block'.
void clear_block(Block* block);

// Deep copy of a block. Handles the migration of inner term references.
void duplicate_block(Block* source, Block* dest);

// Compile the string as a statement list. Appends new terms to the block and
// returns the last new term.
Term* compile(Block* block, const char* str);

Symbol load_script(Block* block, const char* filename);

void post_module_load(Block* block);

// Create an include() call that loads the given file. Returns the included
Expand Down
15 changes: 15 additions & 0 deletions src/building.cpp
Expand Up @@ -1002,6 +1002,19 @@ void update_extra_outputs(Term* term)

if (is_state_input(placeholder))
extra_output->setBoolProp("state", true);

#if 0
if (rebindsInput >= 0) {
Term* input = term->input(rebindsInput);

if (input != NULL) {

if (input->boolProp("explicitState", false))
extra_output->setBoolProp("explicitState", true);

}
}
#endif
}

if (needToUpdatePackState)
Expand Down Expand Up @@ -1082,8 +1095,10 @@ void block_finish_changes(Block* block)
block_update_state_type(block);

// Create an output_placeholder for state, if necessary.
#if 0
if (block_has_inline_state(block))
append_state_output(block);
#endif

// After we are finished creating outputs, update any nested control flow operators.
update_for_control_flow(block);
Expand Down

0 comments on commit bf3de4d

Please sign in to comment.