Full Code of wren-lang/wren for AI

main 99d2f0b8fc26 cached
1157 files
4.7 MB
1.3M tokens
972 symbols
1 requests
Download .txt
Showing preview only (5,122K chars total). Download the full file or copy to clipboard to get everything.
Repository: wren-lang/wren
Branch: main
Commit: 99d2f0b8fc26
Files: 1157
Total size: 4.7 MB

Directory structure:
gitextract_srwgaxf_/

├── .github/
│   └── workflows/
│       └── .githubCI.yml
├── .gitignore
├── .travis.sh
├── .travis.yml
├── AUTHORS
├── CHANGELOG.md
├── LICENSE
├── README.md
├── doc/
│   ├── error-handling.txt
│   ├── implicit fields.txt
│   ├── instruction counts.txt
│   ├── notes/
│   │   ├── import syntax.md
│   │   └── re-entrancy.md
│   ├── receiver-less calls 2.txt
│   ├── receiver-less calls.txt
│   ├── rfc/
│   │   └── 0001-smarter-imports.md
│   └── site/
│       ├── blog/
│       │   ├── 0-hello-wren.markdown
│       │   ├── 1-0.2.0-and-beyond.markdown
│       │   ├── 2-0.3.0-released.markdown
│       │   ├── 3-0.4.0-released.markdown
│       │   ├── index.markdown
│       │   ├── rss.xml
│       │   └── template.html
│       ├── classes.markdown
│       ├── cli/
│       │   ├── index.markdown
│       │   ├── modules/
│       │   │   ├── index.markdown
│       │   │   ├── io/
│       │   │   │   ├── directory.markdown
│       │   │   │   ├── file-flags.markdown
│       │   │   │   ├── file.markdown
│       │   │   │   ├── index.markdown
│       │   │   │   ├── stat.markdown
│       │   │   │   ├── stdin.markdown
│       │   │   │   ├── stdout.markdown
│       │   │   │   └── template.html
│       │   │   ├── os/
│       │   │   │   ├── index.markdown
│       │   │   │   ├── platform.markdown
│       │   │   │   ├── process.markdown
│       │   │   │   └── template.html
│       │   │   ├── scheduler/
│       │   │   │   ├── index.markdown
│       │   │   │   ├── scheduler.markdown
│       │   │   │   └── template.html
│       │   │   ├── template.html
│       │   │   └── timer/
│       │   │       ├── index.markdown
│       │   │       ├── template.html
│       │   │       └── timer.markdown
│       │   ├── template.html
│       │   └── usage.markdown
│       ├── concurrency.markdown
│       ├── contributing.markdown
│       ├── control-flow.markdown
│       ├── embedding/
│       │   ├── calling-c-from-wren.markdown
│       │   ├── calling-wren-from-c.markdown
│       │   ├── configuring-the-vm.markdown
│       │   ├── index.markdown
│       │   ├── slots-and-handles.markdown
│       │   ├── storing-c-data.markdown
│       │   └── template.html
│       ├── error-handling.markdown
│       ├── functions.markdown
│       ├── getting-started.markdown
│       ├── index.markdown
│       ├── lists.markdown
│       ├── maps.markdown
│       ├── method-calls.markdown
│       ├── modularity.markdown
│       ├── modules/
│       │   ├── core/
│       │   │   ├── bool.markdown
│       │   │   ├── class.markdown
│       │   │   ├── fiber.markdown
│       │   │   ├── fn.markdown
│       │   │   ├── index.markdown
│       │   │   ├── list.markdown
│       │   │   ├── map.markdown
│       │   │   ├── null.markdown
│       │   │   ├── num.markdown
│       │   │   ├── object.markdown
│       │   │   ├── range.markdown
│       │   │   ├── sequence.markdown
│       │   │   ├── string.markdown
│       │   │   ├── system.markdown
│       │   │   └── template.html
│       │   ├── index.markdown
│       │   ├── meta/
│       │   │   ├── index.markdown
│       │   │   ├── meta.markdown
│       │   │   └── template.html
│       │   ├── random/
│       │   │   ├── index.markdown
│       │   │   ├── random.markdown
│       │   │   └── template.html
│       │   └── template.html
│       ├── performance.markdown
│       ├── qa.markdown
│       ├── static/
│       │   ├── codejar-linenumbers.js
│       │   ├── codejar.js
│       │   ├── prism.css
│       │   ├── prism.js
│       │   ├── style.css
│       │   ├── wren.js
│       │   ├── wren_try.js
│       │   └── wren_try.wasm
│       ├── syntax.markdown
│       ├── template.html
│       ├── try/
│       │   ├── index.markdown
│       │   └── template.html
│       ├── values.markdown
│       └── variables.markdown
├── example/
│   ├── embedding/
│   │   └── main.c
│   ├── hello.wren
│   ├── import_module/
│   │   ├── cthulu.wren
│   │   └── lovecraft.wren
│   ├── mandelbrot.wren
│   ├── skynet.wren
│   └── syntax.wren
├── projects/
│   ├── make/
│   │   ├── Makefile
│   │   ├── wren.make
│   │   ├── wren_shared.make
│   │   └── wren_test.make
│   ├── make.bsd/
│   │   ├── Makefile
│   │   ├── wren.make
│   │   ├── wren_shared.make
│   │   └── wren_test.make
│   ├── make.mac/
│   │   ├── Makefile
│   │   ├── wren.make
│   │   ├── wren_shared.make
│   │   └── wren_test.make
│   ├── premake/
│   │   └── premake5.lua
│   ├── vs2017/
│   │   ├── wren.sln
│   │   ├── wren.vcxproj
│   │   ├── wren.vcxproj.filters
│   │   ├── wren_shared.vcxproj
│   │   ├── wren_shared.vcxproj.filters
│   │   ├── wren_test.vcxproj
│   │   └── wren_test.vcxproj.filters
│   ├── vs2019/
│   │   ├── wren.sln
│   │   ├── wren.vcxproj
│   │   ├── wren.vcxproj.filters
│   │   ├── wren_shared.vcxproj
│   │   ├── wren_shared.vcxproj.filters
│   │   ├── wren_test.vcxproj
│   │   └── wren_test.vcxproj.filters
│   └── xcode/
│       ├── wren.xcodeproj/
│       │   └── project.pbxproj
│       ├── wren.xcworkspace/
│       │   └── contents.xcworkspacedata
│       ├── wren_shared.xcodeproj/
│       │   └── project.pbxproj
│       └── wren_test.xcodeproj/
│           └── project.pbxproj
├── src/
│   ├── README.md
│   ├── include/
│   │   ├── wren.h
│   │   └── wren.hpp
│   ├── optional/
│   │   ├── wren_opt_meta.c
│   │   ├── wren_opt_meta.h
│   │   ├── wren_opt_meta.wren
│   │   ├── wren_opt_meta.wren.inc
│   │   ├── wren_opt_random.c
│   │   ├── wren_opt_random.h
│   │   ├── wren_opt_random.wren
│   │   └── wren_opt_random.wren.inc
│   └── vm/
│       ├── wren_common.h
│       ├── wren_compiler.c
│       ├── wren_compiler.h
│       ├── wren_core.c
│       ├── wren_core.h
│       ├── wren_core.wren
│       ├── wren_core.wren.inc
│       ├── wren_debug.c
│       ├── wren_debug.h
│       ├── wren_math.h
│       ├── wren_opcodes.h
│       ├── wren_primitive.c
│       ├── wren_primitive.h
│       ├── wren_utils.c
│       ├── wren_utils.h
│       ├── wren_value.c
│       ├── wren_value.h
│       ├── wren_vm.c
│       └── wren_vm.h
├── test/
│   ├── README.md
│   ├── api/
│   │   ├── api_tests.c
│   │   ├── api_tests.h
│   │   ├── benchmark.c
│   │   ├── benchmark.h
│   │   ├── call.c
│   │   ├── call.h
│   │   ├── call.wren
│   │   ├── call_calls_foreign.c
│   │   ├── call_calls_foreign.h
│   │   ├── call_calls_foreign.wren
│   │   ├── call_wren_call_root.c
│   │   ├── call_wren_call_root.h
│   │   ├── call_wren_call_root.wren
│   │   ├── error.c
│   │   ├── error.h
│   │   ├── error.wren
│   │   ├── foreign_class.c
│   │   ├── foreign_class.h
│   │   ├── foreign_class.wren
│   │   ├── get_variable.c
│   │   ├── get_variable.h
│   │   ├── get_variable.wren
│   │   ├── get_variable_module.wren
│   │   ├── handle.c
│   │   ├── handle.h
│   │   ├── handle.wren
│   │   ├── lists.c
│   │   ├── lists.h
│   │   ├── lists.wren
│   │   ├── maps.c
│   │   ├── maps.h
│   │   ├── maps.wren
│   │   ├── new_vm.c
│   │   ├── new_vm.h
│   │   ├── new_vm.wren
│   │   ├── reset_stack_after_call_abort.c
│   │   ├── reset_stack_after_call_abort.h
│   │   ├── reset_stack_after_call_abort.wren
│   │   ├── reset_stack_after_foreign_construct.c
│   │   ├── reset_stack_after_foreign_construct.h
│   │   ├── reset_stack_after_foreign_construct.wren
│   │   ├── resolution.c
│   │   ├── resolution.h
│   │   ├── resolution.wren
│   │   ├── slots.c
│   │   ├── slots.h
│   │   ├── slots.wren
│   │   ├── user_data.c
│   │   ├── user_data.h
│   │   └── user_data.wren
│   ├── benchmark/
│   │   ├── README.md
│   │   ├── api_call.wren
│   │   ├── api_foreign_method.wren
│   │   ├── binary_trees.dart
│   │   ├── binary_trees.lua
│   │   ├── binary_trees.py
│   │   ├── binary_trees.rb
│   │   ├── binary_trees.wren
│   │   ├── binary_trees_gc.wren
│   │   ├── delta_blue.dart
│   │   ├── delta_blue.lua.inprogress
│   │   ├── delta_blue.py
│   │   ├── delta_blue.wren
│   │   ├── fannkuch.lua
│   │   ├── fannkuch.py
│   │   ├── fannkuch.rb
│   │   ├── fib.dart
│   │   ├── fib.lua
│   │   ├── fib.py
│   │   ├── fib.rb
│   │   ├── fib.wren
│   │   ├── fibers.wren
│   │   ├── for.dart
│   │   ├── for.lua
│   │   ├── for.py
│   │   ├── for.rb
│   │   ├── for.wren
│   │   ├── map_numeric.dart.skip
│   │   ├── map_numeric.lua
│   │   ├── map_numeric.py
│   │   ├── map_numeric.rb
│   │   ├── map_numeric.wren
│   │   ├── map_string.lua
│   │   ├── map_string.py
│   │   ├── map_string.rb
│   │   ├── map_string.wren
│   │   ├── method_call.dart
│   │   ├── method_call.lua
│   │   ├── method_call.py
│   │   ├── method_call.rb
│   │   ├── method_call.wren
│   │   ├── string_equals.py
│   │   └── string_equals.wren
│   ├── core/
│   │   ├── bool/
│   │   │   ├── equality.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── not.wren
│   │   │   ├── to_string.wren
│   │   │   └── type.wren
│   │   ├── class/
│   │   │   ├── equality.wren
│   │   │   ├── name.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── supertype.wren
│   │   │   └── type.wren
│   │   ├── fiber/
│   │   │   ├── abort.wren
│   │   │   ├── abort_main_fiber.wren
│   │   │   ├── abort_not_string.wren
│   │   │   ├── abort_null.wren
│   │   │   ├── call.wren
│   │   │   ├── call_direct_reenter.wren
│   │   │   ├── call_done.wren
│   │   │   ├── call_error.wren
│   │   │   ├── call_indirect_reenter.wren
│   │   │   ├── call_return_implicit_null.wren
│   │   │   ├── call_return_value.wren
│   │   │   ├── call_root.wren
│   │   │   ├── call_to_parameter.wren
│   │   │   ├── call_transferred.wren
│   │   │   ├── call_with_value.wren
│   │   │   ├── call_with_value_direct_reenter.wren
│   │   │   ├── call_with_value_done.wren
│   │   │   ├── call_with_value_error.wren
│   │   │   ├── call_with_value_indirect_reenter.wren
│   │   │   ├── call_with_value_to_parameter.wren
│   │   │   ├── call_with_value_transferred.wren
│   │   │   ├── error.wren
│   │   │   ├── is_done.wren
│   │   │   ├── is_done_after_error.wren
│   │   │   ├── new_wrong_arg_type.wren
│   │   │   ├── new_wrong_arity.wren
│   │   │   ├── resume_caller.wren
│   │   │   ├── transfer.wren
│   │   │   ├── transfer_direct_reenter.wren
│   │   │   ├── transfer_error.wren
│   │   │   ├── transfer_error_not_string.wren
│   │   │   ├── transfer_indirect_reenter.wren
│   │   │   ├── transfer_return_call_value.wren
│   │   │   ├── transfer_return_transfer_value.wren
│   │   │   ├── transfer_to_done.wren
│   │   │   ├── transfer_to_error.wren
│   │   │   ├── transfer_to_parameter.wren
│   │   │   ├── transfer_to_yielded.wren
│   │   │   ├── transfer_with_value.wren
│   │   │   ├── transfer_with_value_direct_reenter.wren
│   │   │   ├── transfer_with_value_indirect_reenter.wren
│   │   │   ├── transfer_with_value_to_done.wren
│   │   │   ├── transfer_with_value_to_error.wren
│   │   │   ├── transfer_with_value_to_parameter.wren
│   │   │   ├── transfer_with_value_to_yielded.wren
│   │   │   ├── try.wren
│   │   │   ├── try_direct_reenter.wren
│   │   │   ├── try_done.wren
│   │   │   ├── try_error.wren
│   │   │   ├── try_indirect_reenter.wren
│   │   │   ├── try_through_call.wren
│   │   │   ├── try_value.wren
│   │   │   ├── try_value_yield.wren
│   │   │   ├── try_without_error.wren
│   │   │   ├── type.wren
│   │   │   ├── yield.wren
│   │   │   ├── yield_from_import.wren
│   │   │   ├── yield_from_import_module.wren
│   │   │   ├── yield_from_main.wren
│   │   │   ├── yield_return_call_value.wren
│   │   │   ├── yield_return_transfer_value.wren
│   │   │   ├── yield_with_no_caller.wren
│   │   │   ├── yield_with_value.wren
│   │   │   ├── yield_with_value_from_main.wren
│   │   │   └── yield_with_value_with_no_caller.wren
│   │   ├── function/
│   │   │   ├── arity.wren
│   │   │   ├── call_extra_arguments.wren
│   │   │   ├── call_missing_arguments.wren
│   │   │   ├── call_runtime_error.wren
│   │   │   ├── equality.wren
│   │   │   ├── new_wrong_arg_type.wren
│   │   │   ├── to_string.wren
│   │   │   └── type.wren
│   │   ├── list/
│   │   │   ├── add.wren
│   │   │   ├── add_all.wren
│   │   │   ├── clear.wren
│   │   │   ├── contains.wren
│   │   │   ├── count.wren
│   │   │   ├── count_predicate.wren
│   │   │   ├── count_predicate_non_bool_returning_fn.wren
│   │   │   ├── count_predicate_non_function_arg.wren
│   │   │   ├── each.wren
│   │   │   ├── each_no_items.wren
│   │   │   ├── each_non_function_arg.wren
│   │   │   ├── filled.wren
│   │   │   ├── filled_size_negative.wren
│   │   │   ├── filled_size_not_int.wren
│   │   │   ├── filled_size_not_num.wren
│   │   │   ├── index_of.wren
│   │   │   ├── insert.wren
│   │   │   ├── insert_index_not_int.wren
│   │   │   ├── insert_index_not_num.wren
│   │   │   ├── insert_index_too_large.wren
│   │   │   ├── insert_index_too_small.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_iterator_not_int.wren
│   │   │   ├── iterate_iterator_not_num.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── iterator_value_iterator_not_int.wren
│   │   │   ├── iterator_value_iterator_not_num.wren
│   │   │   ├── iterator_value_iterator_too_large.wren
│   │   │   ├── iterator_value_iterator_too_small.wren
│   │   │   ├── join.wren
│   │   │   ├── join_separator_not_string.wren
│   │   │   ├── map.wren
│   │   │   ├── multiply.wren
│   │   │   ├── multiply_negative.wren
│   │   │   ├── multiply_not_int.wren
│   │   │   ├── multiply_not_num.wren
│   │   │   ├── new.wren
│   │   │   ├── not.wren
│   │   │   ├── plus.wren
│   │   │   ├── plus_not_iterable.wren
│   │   │   ├── reduce.wren
│   │   │   ├── reduce_no_items.wren
│   │   │   ├── reduce_single_item.wren
│   │   │   ├── reduce_wrong_arity.wren
│   │   │   ├── remove.wren
│   │   │   ├── remove_at.wren
│   │   │   ├── remove_at_index_not_int.wren
│   │   │   ├── remove_at_index_not_num.wren
│   │   │   ├── remove_at_index_too_large.wren
│   │   │   ├── remove_at_index_too_small.wren
│   │   │   ├── sort.wren
│   │   │   ├── subscript.wren
│   │   │   ├── subscript_not_int.wren
│   │   │   ├── subscript_range.wren
│   │   │   ├── subscript_range_from_not_int.wren
│   │   │   ├── subscript_range_from_too_large.wren
│   │   │   ├── subscript_range_from_too_small.wren
│   │   │   ├── subscript_range_to_exclusive_too_large.wren
│   │   │   ├── subscript_range_to_exclusive_too_small.wren
│   │   │   ├── subscript_range_to_not_int.wren
│   │   │   ├── subscript_range_to_too_large.wren
│   │   │   ├── subscript_range_to_too_small.wren
│   │   │   ├── subscript_setter.wren
│   │   │   ├── subscript_setter_not_int.wren
│   │   │   ├── subscript_setter_not_num.wren
│   │   │   ├── subscript_setter_too_large.wren
│   │   │   ├── subscript_setter_too_small.wren
│   │   │   ├── subscript_too_large.wren
│   │   │   ├── subscript_too_small.wren
│   │   │   ├── subscript_wrong_type.wren
│   │   │   ├── swap.wren
│   │   │   ├── to_string.wren
│   │   │   ├── type.wren
│   │   │   └── where.wren
│   │   ├── map/
│   │   │   ├── churn.wren
│   │   │   ├── clear.wren
│   │   │   ├── contains_key.wren
│   │   │   ├── contains_key_not_value.wren
│   │   │   ├── count.wren
│   │   │   ├── empty_string_key.wren
│   │   │   ├── is_empty.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_iterator_not_int.wren
│   │   │   ├── iterate_iterator_not_num.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── iterator_value_iterator_not_int.wren
│   │   │   ├── iterator_value_iterator_not_num.wren
│   │   │   ├── iterator_value_iterator_too_large.wren
│   │   │   ├── iterator_value_iterator_too_small.wren
│   │   │   ├── key_iterate.wren
│   │   │   ├── key_iterate_iterator_not_int.wren
│   │   │   ├── key_iterate_iterator_not_num.wren
│   │   │   ├── key_types.wren
│   │   │   ├── new.wren
│   │   │   ├── remove.wren
│   │   │   ├── remove_key_not_value.wren
│   │   │   ├── reuse_tombstone.wren
│   │   │   ├── subscript_empty_map.wren
│   │   │   ├── subscript_key_not_value.wren
│   │   │   ├── subscript_setter_key_not_value.wren
│   │   │   ├── to_string.wren
│   │   │   ├── type.wren
│   │   │   ├── value_iterate.wren
│   │   │   ├── value_iterate_iterator_not_int.wren
│   │   │   └── value_iterate_iterator_not_num.wren
│   │   ├── map_entry/
│   │   │   └── new.wren
│   │   ├── null/
│   │   │   ├── no_constructor.wren
│   │   │   ├── not.wren
│   │   │   └── type.wren
│   │   ├── number/
│   │   │   ├── abs.wren
│   │   │   ├── acos.wren
│   │   │   ├── asin.wren
│   │   │   ├── atan.wren
│   │   │   ├── atan2.wren
│   │   │   ├── atan2_x_not_num.wren
│   │   │   ├── bitwise_and.wren
│   │   │   ├── bitwise_and_operand_not_num.wren
│   │   │   ├── bitwise_lsh.wren
│   │   │   ├── bitwise_lsh_operand_not_num.wren
│   │   │   ├── bitwise_not.wren
│   │   │   ├── bitwise_or.wren
│   │   │   ├── bitwise_or_operand_not_num.wren
│   │   │   ├── bitwise_rsh.wren
│   │   │   ├── bitwise_rsh_operand_not_num.wren
│   │   │   ├── bitwise_xor.wren
│   │   │   ├── bitwise_xor_operand_not_num.wren
│   │   │   ├── cbrt.wren
│   │   │   ├── ceil.wren
│   │   │   ├── clamp.wren
│   │   │   ├── clamp_max_not_num.wren
│   │   │   ├── clamp_min_not_num.wren
│   │   │   ├── comparison.wren
│   │   │   ├── cos.wren
│   │   │   ├── decimal_point_at_eof.wren
│   │   │   ├── divide.wren
│   │   │   ├── divide_operand_not_num.wren
│   │   │   ├── equality.wren
│   │   │   ├── exp.wren
│   │   │   ├── floor.wren
│   │   │   ├── fraction.wren
│   │   │   ├── from_string.wren
│   │   │   ├── from_string_not_string.wren
│   │   │   ├── from_string_too_large.wren
│   │   │   ├── greater_than_equal_operand_not_num.wren
│   │   │   ├── greater_than_operand_not_num.wren
│   │   │   ├── invalid_hex_literal.wren
│   │   │   ├── is_infinity.wren
│   │   │   ├── is_integer.wren
│   │   │   ├── is_nan.wren
│   │   │   ├── largest.wren
│   │   │   ├── less_than_equal_operand_not_num.wren
│   │   │   ├── less_than_operand_not_num.wren
│   │   │   ├── log.wren
│   │   │   ├── log2.wren
│   │   │   ├── maxSafeInteger.wren
│   │   │   ├── max_other_not_num.wren
│   │   │   ├── minSafeInteger.wren
│   │   │   ├── min_max.wren
│   │   │   ├── min_other_not_num.wren
│   │   │   ├── minus.wren
│   │   │   ├── minus_operand_not_num.wren
│   │   │   ├── mod.wren
│   │   │   ├── mod_operand_not_num.wren
│   │   │   ├── multiply.wren
│   │   │   ├── multiply_operand_not_num.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── not.wren
│   │   │   ├── plus.wren
│   │   │   ├── plus_operand_not_num.wren
│   │   │   ├── pow.wren
│   │   │   ├── pow_power_not_num.wren
│   │   │   ├── round.wren
│   │   │   ├── sign.wren
│   │   │   ├── sin.wren
│   │   │   ├── smallest.wren
│   │   │   ├── sqrt.wren
│   │   │   ├── tan.wren
│   │   │   ├── to_string.wren
│   │   │   ├── truncate.wren
│   │   │   └── type.wren
│   │   ├── object/
│   │   │   ├── is.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── nonclass_on_right.wren
│   │   │   ├── not.wren
│   │   │   ├── same.wren
│   │   │   ├── to_string.wren
│   │   │   └── type.wren
│   │   ├── range/
│   │   │   ├── contains.wren
│   │   │   ├── equality.wren
│   │   │   ├── exclusive_range_wrong_rhs_type.wren
│   │   │   ├── from.wren
│   │   │   ├── inclusive_range_wrong_rhs_type.wren
│   │   │   ├── is_inclusive.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_from_float.wren
│   │   │   ├── iterate_wrong_type.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── join.wren
│   │   │   ├── join_separator_not_string.wren
│   │   │   ├── map.wren
│   │   │   ├── max.wren
│   │   │   ├── min.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── reduce.wren
│   │   │   ├── to.wren
│   │   │   ├── to_string.wren
│   │   │   ├── type.wren
│   │   │   └── where.wren
│   │   ├── sequence/
│   │   │   ├── all.wren
│   │   │   ├── all_non_function_arg.wren
│   │   │   ├── any.wren
│   │   │   ├── any_non_function_arg.wren
│   │   │   ├── count.wren
│   │   │   ├── is_empty.wren
│   │   │   ├── map.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── skip.wren
│   │   │   ├── skip_negative.wren
│   │   │   ├── skip_not_int.wren
│   │   │   ├── skip_not_num.wren
│   │   │   ├── take.wren
│   │   │   ├── take_negative.wren
│   │   │   ├── take_not_int.wren
│   │   │   ├── take_not_num.wren
│   │   │   ├── to_list.wren
│   │   │   └── where.wren
│   │   ├── string/
│   │   │   ├── bytes.wren
│   │   │   ├── concatenation.wren
│   │   │   ├── concatenation_wrong_arg_type.wren
│   │   │   ├── contains.wren
│   │   │   ├── contains_argument_not_string.wren
│   │   │   ├── count.wren
│   │   │   ├── ends_with.wren
│   │   │   ├── ends_with_invalid_arg.wren
│   │   │   ├── equality.wren
│   │   │   ├── from_byte.wren
│   │   │   ├── from_byte_not_int.wren
│   │   │   ├── from_byte_not_num.wren
│   │   │   ├── from_byte_too_large.wren
│   │   │   ├── from_byte_too_small.wren
│   │   │   ├── from_code_point.wren
│   │   │   ├── from_code_point_not_int.wren
│   │   │   ├── from_code_point_not_num.wren
│   │   │   ├── from_code_point_too_large.wren
│   │   │   ├── from_code_point_too_small.wren
│   │   │   ├── index_of.wren
│   │   │   ├── index_of_invalid_arg.wren
│   │   │   ├── index_of_start.wren
│   │   │   ├── index_of_start_not_int.wren
│   │   │   ├── index_of_start_not_num.wren
│   │   │   ├── index_of_start_too_large.wren
│   │   │   ├── index_of_start_too_small.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_iterator_not_int.wren
│   │   │   ├── iterate_iterator_not_num.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── iterator_value_iterator_not_int.wren
│   │   │   ├── iterator_value_iterator_not_num.wren
│   │   │   ├── iterator_value_iterator_too_large.wren
│   │   │   ├── iterator_value_iterator_too_small.wren
│   │   │   ├── join.wren
│   │   │   ├── join_separator_not_string.wren
│   │   │   ├── multiply.wren
│   │   │   ├── multiply_negative.wren
│   │   │   ├── multiply_not_int.wren
│   │   │   ├── multiply_not_num.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── not.wren
│   │   │   ├── replace.wren
│   │   │   ├── replace_empty_old.wren
│   │   │   ├── replace_new_not_string.wren
│   │   │   ├── replace_old_not_string.wren
│   │   │   ├── split.wren
│   │   │   ├── split_argument_not_string.wren
│   │   │   ├── split_empty_seperator.wren
│   │   │   ├── starts_with.wren
│   │   │   ├── starts_with_invalid_arg.wren
│   │   │   ├── subscript.wren
│   │   │   ├── subscript_not_int.wren
│   │   │   ├── subscript_not_num.wren
│   │   │   ├── subscript_range.wren
│   │   │   ├── subscript_range_from_not_int.wren
│   │   │   ├── subscript_range_from_too_large.wren
│   │   │   ├── subscript_range_from_too_small.wren
│   │   │   ├── subscript_range_to_exclusive_too_large.wren
│   │   │   ├── subscript_range_to_exclusive_too_small.wren
│   │   │   ├── subscript_range_to_not_int.wren
│   │   │   ├── subscript_range_to_too_large.wren
│   │   │   ├── subscript_range_to_too_small.wren
│   │   │   ├── subscript_too_large.wren
│   │   │   ├── subscript_too_small.wren
│   │   │   ├── to_string.wren
│   │   │   ├── trim.wren
│   │   │   ├── trim_chars_not_string.wren
│   │   │   ├── trim_end.wren
│   │   │   ├── trim_end_chars_not_string.wren
│   │   │   ├── trim_start.wren
│   │   │   ├── trim_start_chars_not_string.wren
│   │   │   └── type.wren
│   │   ├── string_byte_sequence/
│   │   │   ├── count.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_not_int.wren
│   │   │   ├── iterate_wrong_type.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── iterator_value_not_int.wren
│   │   │   ├── iterator_value_not_num.wren
│   │   │   ├── iterator_value_too_large.wren
│   │   │   ├── iterator_value_too_small.wren
│   │   │   ├── subscript.wren
│   │   │   ├── subscript_not_int.wren
│   │   │   ├── subscript_not_num.wren
│   │   │   ├── subscript_too_large.wren
│   │   │   └── subscript_too_small.wren
│   │   ├── string_code_point_sequence/
│   │   │   ├── count.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_iterator_not_int.wren
│   │   │   ├── iterate_iterator_not_num.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── iterator_value_incomplete.wren
│   │   │   ├── iterator_value_not_int.wren
│   │   │   ├── iterator_value_not_num.wren
│   │   │   ├── iterator_value_too_large.wren
│   │   │   ├── iterator_value_too_small.wren
│   │   │   ├── subscript.wren
│   │   │   ├── subscript_incomplete.wren
│   │   │   ├── subscript_not_int.wren
│   │   │   ├── subscript_not_num.wren
│   │   │   ├── subscript_too_large.wren
│   │   │   └── subscript_too_small.wren
│   │   └── system/
│   │       ├── print.wren
│   │       ├── print_all.wren
│   │       ├── print_all_not_sequence.wren
│   │       ├── print_bad_to_string.wren
│   │       ├── write_all.wren
│   │       ├── write_all_not_sequence.wren
│   │       └── write_bad_to_string.wren
│   ├── language/
│   │   ├── assignment/
│   │   │   ├── associativity.wren
│   │   │   ├── global.wren
│   │   │   ├── grouping.wren
│   │   │   ├── infix_operator.wren
│   │   │   ├── is.wren
│   │   │   ├── local.wren
│   │   │   ├── prefix_operator.wren
│   │   │   ├── syntax.wren
│   │   │   └── undefined.wren
│   │   ├── bitwise_precedence.wren
│   │   ├── bom.wren
│   │   ├── break/
│   │   │   ├── closure_in_for.wren
│   │   │   ├── closure_in_while.wren
│   │   │   ├── exit_local_scopes.wren
│   │   │   ├── in_for_loop.wren
│   │   │   ├── in_function_in_loop.wren
│   │   │   ├── in_method_in_loop.wren
│   │   │   ├── in_while_loop.wren
│   │   │   ├── nested_for_loop.wren
│   │   │   ├── nested_while_loop.wren
│   │   │   └── outside_loop.wren
│   │   ├── chained_newline.wren
│   │   ├── class/
│   │   │   ├── attributes/
│   │   │   │   ├── attributes.wren
│   │   │   │   ├── compile_only.wren
│   │   │   │   ├── duplicate_keys.wren
│   │   │   │   ├── groups.wren
│   │   │   │   ├── invalid_expression.wren
│   │   │   │   ├── invalid_scope.wren
│   │   │   │   ├── invalid_toplevel.wren
│   │   │   │   ├── literals.wren
│   │   │   │   ├── methods.wren
│   │   │   │   └── without.wren
│   │   │   ├── field_in_foreign_class.wren
│   │   │   ├── foreign_class_inherit_fields.wren
│   │   │   ├── lowercase_name_inside_body.wren
│   │   │   ├── missing_class_after_foreign.wren
│   │   │   ├── name_inside_body.wren
│   │   │   ├── newline_after_class.wren
│   │   │   ├── newline_after_static.wren
│   │   │   └── syntax.wren
│   │   ├── closure/
│   │   │   ├── assign_to_closure.wren
│   │   │   ├── close_over_function_parameter.wren
│   │   │   ├── close_over_later_variable.wren
│   │   │   ├── close_over_method_parameter.wren
│   │   │   ├── closed_closure_in_function.wren
│   │   │   ├── nested_closure.wren
│   │   │   ├── open_closure_in_function.wren
│   │   │   ├── reference_closure_multiple_times.wren
│   │   │   ├── reuse_closure_slot.wren
│   │   │   ├── shadow_closure_with_local.wren
│   │   │   ├── unused_closure.wren
│   │   │   └── unused_later_closure.wren
│   │   ├── comments/
│   │   │   ├── block.wren
│   │   │   ├── block_at_eof.wren
│   │   │   ├── line_at_eof.wren
│   │   │   ├── only_line_comment.wren
│   │   │   ├── only_line_comment_and_line.wren
│   │   │   ├── unicode.wren
│   │   │   ├── unterminated_block.wren
│   │   │   └── unterminated_nested_block.wren
│   │   ├── conditional/
│   │   │   ├── conditional_in_then.wren
│   │   │   ├── missing_colon.wren
│   │   │   ├── missing_condition.wren
│   │   │   ├── missing_else.wren
│   │   │   ├── missing_question.wren
│   │   │   ├── missing_then.wren
│   │   │   ├── newlines.wren
│   │   │   ├── precedence.wren
│   │   │   └── short_circuit.wren
│   │   ├── constructor/
│   │   │   ├── cannot_be_infix.wren
│   │   │   ├── cannot_be_minus.wren
│   │   │   ├── cannot_be_setter.wren
│   │   │   ├── cannot_be_static.wren
│   │   │   ├── cannot_be_subscript.wren
│   │   │   ├── cannot_be_unary.wren
│   │   │   ├── cannot_call_initializer.wren
│   │   │   ├── cannot_return_value.wren
│   │   │   ├── named.wren
│   │   │   ├── no_default.wren
│   │   │   ├── no_parameter_list.wren
│   │   │   ├── not_inherited.wren
│   │   │   ├── return_without_value.wren
│   │   │   ├── super_must_have_args.wren
│   │   │   └── superclass.wren
│   │   ├── continue/
│   │   │   ├── closure_in_for.wren
│   │   │   ├── closure_in_while.wren
│   │   │   ├── exit_local_scopes.wren
│   │   │   ├── in_for_loop.wren
│   │   │   ├── in_function_in_loop.wren
│   │   │   ├── in_method_in_loop.wren
│   │   │   ├── in_while_loop.wren
│   │   │   ├── nested_for_loop.wren
│   │   │   ├── nested_while_loop.wren
│   │   │   └── outside_loop.wren
│   │   ├── deeply_nested_gc.wren
│   │   ├── empty_block.wren
│   │   ├── empty_file.wren
│   │   ├── fiber/
│   │   │   └── closure.wren
│   │   ├── field/
│   │   │   ├── closure.wren
│   │   │   ├── default_to_null.wren
│   │   │   ├── in_fn_in_static_method.wren
│   │   │   ├── in_static_method.wren
│   │   │   ├── in_static_method_in_nested_class.wren
│   │   │   ├── multiple.wren
│   │   │   ├── nested_class.wren
│   │   │   ├── object_reference.wren
│   │   │   ├── outside_class.wren
│   │   │   └── use_before_set.wren
│   │   ├── for/
│   │   │   ├── close_over_loop_variable.wren
│   │   │   ├── closure_in_body.wren
│   │   │   ├── newline_after_for.wren
│   │   │   ├── newline_before_in.wren
│   │   │   ├── only_evaluate_sequence_once.wren
│   │   │   ├── return_closure.wren
│   │   │   ├── return_inside.wren
│   │   │   ├── syntax.wren
│   │   │   └── truth.wren
│   │   ├── foreign/
│   │   │   ├── foreign_after_static.wren
│   │   │   ├── foreign_method_with_body.wren
│   │   │   └── unknown_method.wren
│   │   ├── function/
│   │   │   ├── empty_body.wren
│   │   │   ├── newline_body.wren
│   │   │   ├── newline_in_expression_block.wren
│   │   │   ├── no_newline_before_close.wren
│   │   │   ├── no_parameters.wren
│   │   │   ├── parameters.wren
│   │   │   └── syntax.wren
│   │   ├── if/
│   │   │   ├── dangling_else.wren
│   │   │   ├── else.wren
│   │   │   ├── if.wren
│   │   │   ├── newline_after_else.wren
│   │   │   ├── newline_after_if.wren
│   │   │   └── truth.wren
│   │   ├── ignore_carriage_returns.wren
│   │   ├── implicit_receiver/
│   │   │   ├── inherited_methods.wren
│   │   │   ├── instance_methods.wren
│   │   │   ├── locals_shadow_getter.wren
│   │   │   ├── locals_shadow_setter.wren
│   │   │   ├── nested_class.wren
│   │   │   └── static_methods.wren
│   │   ├── inheritance/
│   │   │   ├── do_not_inherit_static_methods.wren
│   │   │   ├── inherit_fields.wren
│   │   │   ├── inherit_from_bool.wren
│   │   │   ├── inherit_from_class.wren
│   │   │   ├── inherit_from_closure.wren
│   │   │   ├── inherit_from_fiber.wren
│   │   │   ├── inherit_from_fn.wren
│   │   │   ├── inherit_from_list.wren
│   │   │   ├── inherit_from_map.wren
│   │   │   ├── inherit_from_nonclass.wren
│   │   │   ├── inherit_from_null.wren
│   │   │   ├── inherit_from_null_class.wren
│   │   │   ├── inherit_from_num.wren
│   │   │   ├── inherit_from_range.wren
│   │   │   ├── inherit_from_string.wren
│   │   │   ├── inherit_methods.wren
│   │   │   ├── inherited_fields_in_closure.wren
│   │   │   └── is.wren
│   │   ├── interpolation/
│   │   │   ├── empty.wren
│   │   │   ├── interpolation.wren
│   │   │   ├── runtime_error_in_expression.wren
│   │   │   ├── switch_fiber.wren
│   │   │   ├── unterminated.wren
│   │   │   └── unterminated_expression.wren
│   │   ├── list/
│   │   │   ├── duplicate_comma.wren
│   │   │   ├── duplicate_trailing_comma.wren
│   │   │   ├── empty_list_with_comma.wren
│   │   │   ├── eof_after_comma.wren
│   │   │   ├── eof_after_element.wren
│   │   │   ├── grow_shrink.wren
│   │   │   ├── newline_before_comma.wren
│   │   │   ├── newlines.wren
│   │   │   └── trailing_comma.wren
│   │   ├── logical_operator/
│   │   │   ├── and.wren
│   │   │   ├── and_truth.wren
│   │   │   ├── or.wren
│   │   │   └── or_truth.wren
│   │   ├── many_reallocations.wren
│   │   ├── map/
│   │   │   ├── bad_key_precedence.wren
│   │   │   ├── duplicate_comma.wren
│   │   │   ├── duplicate_trailing_comma.wren
│   │   │   ├── empty_map_with_comma.wren
│   │   │   ├── eof_after_colon.wren
│   │   │   ├── eof_after_comma.wren
│   │   │   ├── eof_after_key.wren
│   │   │   ├── eof_after_value.wren
│   │   │   ├── grow_and_shrink.wren
│   │   │   ├── newlines.wren
│   │   │   ├── precedence.wren
│   │   │   └── trailing_comma.wren
│   │   ├── method/
│   │   │   ├── arity.wren
│   │   │   ├── call_name_too_long.wren
│   │   │   ├── duplicate_methods.wren
│   │   │   ├── empty_block.wren
│   │   │   ├── empty_subscript_call.wren
│   │   │   ├── empty_subscript_definition.wren
│   │   │   ├── long_name.wren
│   │   │   ├── many_methods.wren
│   │   │   ├── name_too_long.wren
│   │   │   ├── newlines.wren
│   │   │   ├── no_parameters_new_line.wren
│   │   │   ├── not_found.wren
│   │   │   ├── not_found_eleven_arguments.wren
│   │   │   ├── not_found_multiple_arguments.wren
│   │   │   ├── not_found_one_argument.wren
│   │   │   ├── operators.wren
│   │   │   ├── static.wren
│   │   │   ├── static_method_not_found.wren
│   │   │   ├── static_operators.wren
│   │   │   ├── subscript_operators.wren
│   │   │   ├── subscript_setter_too_many_arguments.wren
│   │   │   ├── subscript_too_many_arguments.wren
│   │   │   ├── too_many_arguments.wren
│   │   │   └── too_many_parameters.wren
│   │   ├── module/
│   │   │   ├── change_imported_value/
│   │   │   │   ├── change_imported_value.wren
│   │   │   │   └── module.wren
│   │   │   ├── compile_error/
│   │   │   │   ├── compile_error.wren
│   │   │   │   └── module.wren
│   │   │   ├── cyclic_import/
│   │   │   │   ├── a.wren
│   │   │   │   ├── b.wren
│   │   │   │   └── cyclic_import.wren
│   │   │   ├── implicitly_imports_core/
│   │   │   │   ├── implicitly_imports_core.wren
│   │   │   │   └── module.wren
│   │   │   ├── import_as/
│   │   │   │   ├── import_as.wren
│   │   │   │   └── module.wren
│   │   │   ├── inside_block/
│   │   │   │   ├── inside_block.wren
│   │   │   │   └── module.wren
│   │   │   ├── missing_for.wren
│   │   │   ├── missing_string_after_import.wren
│   │   │   ├── module_dir/
│   │   │   │   ├── module_dir.wren
│   │   │   │   └── something/
│   │   │   │       └── module.wren
│   │   │   ├── multiple_variables/
│   │   │   │   ├── module.wren
│   │   │   │   └── multiple_variables.wren
│   │   │   ├── name_collision.wren
│   │   │   ├── newlines/
│   │   │   │   ├── module.wren
│   │   │   │   └── newlines.wren
│   │   │   ├── no_variable/
│   │   │   │   ├── module.wren
│   │   │   │   └── no_variable.wren
│   │   │   ├── relative_import/
│   │   │   │   ├── module_3.wren
│   │   │   │   ├── relative_import.wren
│   │   │   │   └── sub/
│   │   │   │       ├── dir/
│   │   │   │       │   ├── module.wren
│   │   │   │       │   └── module_2.wren
│   │   │   │       ├── module.wren
│   │   │   │       ├── module_2.wren
│   │   │   │       └── module_3.wren
│   │   │   ├── returns/
│   │   │   │   ├── module_return.wren
│   │   │   │   ├── module_return_value.wren
│   │   │   │   ├── return.wren
│   │   │   │   ├── return_from_import.wren
│   │   │   │   ├── return_value.wren
│   │   │   │   └── return_value_from_import.wren
│   │   │   ├── shared_import/
│   │   │   │   ├── a.wren
│   │   │   │   ├── b.wren
│   │   │   │   ├── shared.wren
│   │   │   │   └── shared_import.wren
│   │   │   ├── simple_import/
│   │   │   │   ├── module.wren
│   │   │   │   └── simple_import.wren
│   │   │   ├── unknown_module.wren
│   │   │   └── unknown_variable/
│   │   │       ├── module.wren
│   │   │       └── unknown_variable.wren
│   │   ├── no_trailing_newline.wren
│   │   ├── nonlocal/
│   │   │   ├── assignment.wren
│   │   │   ├── duplicate_nonlocal.wren
│   │   │   ├── in_block_scope.wren
│   │   │   ├── localname_forward_declare.wren
│   │   │   ├── mutual_recursion.wren
│   │   │   ├── nonlocal_in_initializer.wren
│   │   │   ├── nonlocal_without_initializer.wren
│   │   │   ├── null_before_defined.wren
│   │   │   ├── undefined.wren
│   │   │   ├── use_in_function.wren
│   │   │   ├── use_in_function_before_definition.wren
│   │   │   ├── use_in_method.wren
│   │   │   └── use_in_method_before_definition.wren
│   │   ├── null/
│   │   │   └── literal.wren
│   │   ├── number/
│   │   │   ├── hex_literals.wren
│   │   │   ├── hex_too_large.wren
│   │   │   ├── literal_too_large.wren
│   │   │   ├── literals.wren
│   │   │   ├── scientific_float_missing_exponent.wren
│   │   │   ├── scientific_floating_exponent.wren
│   │   │   ├── scientific_literals.wren
│   │   │   ├── scientific_missing_exponent.wren
│   │   │   ├── scientific_missing_fractional_part.wren
│   │   │   ├── scientific_multiple_exponants.wren
│   │   │   └── scientific_multiple_exponent_signs.wren
│   │   ├── precedence.wren
│   │   ├── return/
│   │   │   ├── after_else.wren
│   │   │   ├── after_if.wren
│   │   │   ├── after_while.wren
│   │   │   ├── in_function.wren
│   │   │   ├── in_method.wren
│   │   │   └── return_null_if_newline.wren
│   │   ├── semicolon.wren
│   │   ├── setter/
│   │   │   ├── associativity.wren
│   │   │   ├── grouping.wren
│   │   │   ├── infix_operator.wren
│   │   │   ├── instance.wren
│   │   │   ├── is.wren
│   │   │   ├── prefix_operator.wren
│   │   │   ├── result.wren
│   │   │   ├── same_name_as_method.wren
│   │   │   └── static.wren
│   │   ├── shebang/
│   │   │   ├── shebang.wren
│   │   │   ├── shebang_at_eof.wren
│   │   │   ├── shebang_at_other_line.wren
│   │   │   └── shebang_invalid.wren
│   │   ├── static_field/
│   │   │   ├── closure.wren
│   │   │   ├── default_to_null.wren
│   │   │   ├── in_instance_method.wren
│   │   │   ├── multiple.wren
│   │   │   ├── nested_class.wren
│   │   │   ├── outside_class.wren
│   │   │   └── use_before_set.wren
│   │   ├── string/
│   │   │   ├── byte_escapes.wren
│   │   │   ├── escapes.wren
│   │   │   ├── incomplete_byte_escape.wren
│   │   │   ├── incomplete_byte_escape_at_eof.wren
│   │   │   ├── incomplete_long_unicode_escape.wren
│   │   │   ├── incomplete_unicode_escape.wren
│   │   │   ├── incomplete_unicode_escape_at_eof.wren
│   │   │   ├── invalid_byte_escape.wren
│   │   │   ├── invalid_escape.wren
│   │   │   ├── invalid_unicode_escape.wren
│   │   │   ├── literals.wren
│   │   │   ├── unicode_escapes.wren
│   │   │   ├── unicode_two_bytes_to_long_escape.wren
│   │   │   ├── unterminated.wren
│   │   │   └── unterminated_raw.wren
│   │   ├── super/
│   │   │   ├── call_different_arity.wren
│   │   │   ├── call_other_method.wren
│   │   │   ├── call_same_method.wren
│   │   │   ├── closure.wren
│   │   │   ├── implicit_name.wren
│   │   │   ├── indirectly_inherited.wren
│   │   │   ├── no_superclass_method.wren
│   │   │   ├── super_at_top_level.wren
│   │   │   ├── super_in_closure_in_inherited_method.wren
│   │   │   ├── super_in_inherited_method.wren
│   │   │   ├── super_in_static_method.wren
│   │   │   └── super_in_top_level_function.wren
│   │   ├── this/
│   │   │   ├── closure.wren
│   │   │   ├── nested_class.wren
│   │   │   ├── nested_closure.wren
│   │   │   ├── this_at_top_level.wren
│   │   │   ├── this_in_method.wren
│   │   │   ├── this_in_static_method.wren
│   │   │   └── this_in_top_level_function.wren
│   │   ├── unexpected_character.wren
│   │   ├── variable/
│   │   │   ├── duplicate_local.wren
│   │   │   ├── duplicate_parameter.wren
│   │   │   ├── global_in_initializer.wren
│   │   │   ├── global_without_initializer.wren
│   │   │   ├── local_collide_with_function_parameter.wren
│   │   │   ├── local_collide_with_method_parameter.wren
│   │   │   ├── local_in_initializer.wren
│   │   │   ├── local_in_middle_of_block.wren
│   │   │   ├── local_in_nested_block.wren
│   │   │   ├── local_outside_method.wren
│   │   │   ├── local_without_initializer.wren
│   │   │   ├── many_locals.wren
│   │   │   ├── many_nonsimultaneous_locals.wren
│   │   │   ├── newline_after_equals.wren
│   │   │   ├── newline_after_var.wren
│   │   │   ├── outside_method.wren
│   │   │   ├── scope_if.wren
│   │   │   ├── scope_reuse_in_different_blocks.wren
│   │   │   ├── scope_while.wren
│   │   │   ├── shadow_and_local.wren
│   │   │   ├── shadow_global.wren
│   │   │   ├── shadow_in_initializer.wren
│   │   │   ├── shadow_local.wren
│   │   │   ├── too_many_locals.wren
│   │   │   ├── too_many_locals_nested.wren
│   │   │   ├── undefined_global.wren
│   │   │   ├── undefined_local.wren
│   │   │   ├── use_false_as_var.wren
│   │   │   ├── use_field_as_var.wren
│   │   │   ├── use_null_as_var.wren
│   │   │   ├── use_this_as_var.wren
│   │   │   └── use_true_as_var.wren
│   │   ├── while/
│   │   │   ├── closure_in_body.wren
│   │   │   ├── newline_after_while.wren
│   │   │   ├── return_closure.wren
│   │   │   ├── return_inside.wren
│   │   │   ├── syntax.wren
│   │   │   └── truth.wren
│   │   └── whitespace.wren
│   ├── limit/
│   │   ├── interpolation_nesting.wren
│   │   ├── jump_too_far.wren
│   │   ├── long_function.wren
│   │   ├── long_string.wren
│   │   ├── long_variable_name.wren
│   │   ├── loop_too_far.wren
│   │   ├── many_constants.wren
│   │   ├── many_fields.wren
│   │   ├── many_globals.wren
│   │   ├── many_inherited_fields.wren
│   │   ├── reuse_constants.wren
│   │   ├── too_many_constants.wren
│   │   ├── too_many_fields.wren
│   │   ├── too_many_function_parameters.wren
│   │   ├── too_many_inherited_fields.wren
│   │   ├── too_much_interpolation_nesting.wren
│   │   └── variable_name_too_long.wren
│   ├── main.c
│   ├── meta/
│   │   ├── eval_compile_error.wren
│   │   ├── eval_existing_scoped_variable.wren
│   │   ├── eval_not_string.wren
│   │   ├── get_module_variables.wren
│   │   ├── get_module_variables_not_string.wren
│   │   └── get_module_variables_unknown_module.wren
│   ├── random/
│   │   ├── float.wren
│   │   ├── float_max.wren
│   │   ├── float_min_max.wren
│   │   ├── int.wren
│   │   ├── int_max.wren
│   │   ├── int_min_max.wren
│   │   ├── new.wren
│   │   ├── new_empty_sequence.wren
│   │   ├── new_number.wren
│   │   ├── new_sequence.wren
│   │   ├── new_wrong_arg_type.wren
│   │   ├── new_wrong_element_type.wren
│   │   ├── sample_count_multiple.wren
│   │   ├── sample_count_one.wren
│   │   ├── sample_count_too_many.wren
│   │   ├── sample_count_zero.wren
│   │   ├── sample_one.wren
│   │   ├── sample_one_empty.wren
│   │   └── shuffle.wren
│   ├── regression/
│   │   ├── 428.wren
│   │   ├── 429.wren
│   │   ├── 442-000005.wren
│   │   ├── 442-000007.wren
│   │   ├── 442-000086.wren
│   │   ├── 442-000088.wren
│   │   ├── 442-000089.wren
│   │   ├── 442-000100.wren
│   │   ├── 442-000115.wren
│   │   ├── 442-000166.wren
│   │   ├── 442-000181.wren
│   │   ├── 442-000182.wren
│   │   ├── 442-000238.wren
│   │   ├── 442-000295.wren
│   │   ├── 442-000321.wren
│   │   ├── 442-000348.wren
│   │   ├── 442-000357.wren
│   │   ├── 442-000440.wren
│   │   ├── 442-000665.wren
│   │   ├── 494.wren
│   │   └── 561.wren
│   ├── test.c
│   ├── test.h
│   └── unit/
│       ├── main.c
│       ├── path_test.c
│       ├── path_test.h
│       ├── test.c
│       └── test.h
├── try/
│   ├── main.try.c
│   ├── make.emscripten/
│   │   ├── Makefile
│   │   ├── wren.make
│   │   └── wren_try.make
│   └── readme.md
└── util/
    ├── benchmark.py
    ├── deploy_docs_from_travis.sh
    ├── generate_amalgamation.py
    ├── generate_docs.py
    ├── generate_projects.py
    ├── metrics.py
    ├── test.py
    └── wren_to_c_string.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/.githubCI.yml
================================================
name: WrenCI

on:
  workflow_dispatch:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  linux:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
      with:
        fetch-depth: 1
    - name: build
      run: ./.travis.sh
      shell: bash
      working-directory: ./
    - uses: actions/upload-artifact@v4
      with:
        name: wren-linux
        path: |
          bin/*
          lib/*
  mac:
    runs-on: macos-latest
    env:
      WREN_TARGET_MAC: 1
    steps:
    - uses: actions/checkout@v2
      with:
        fetch-depth: 1
    - name: build
      run: ./.travis.sh
      shell: bash
      working-directory: ./
    - uses: actions/upload-artifact@v4
      with:
        name: wren-mac
        path: |
          bin/*
          lib/*
  windows:
    runs-on: windows-latest
    steps:
    - uses: actions/checkout@v2
      with:
        fetch-depth: 1
    - name: msbuild
      uses: microsoft/setup-msbuild@v1.1
    - name: build
      working-directory: ./projects/vs2019/
      run: msbuild ./wren.sln /property:Configuration=Release /property:Platform=64bit
    - uses: actions/upload-artifact@v4
      with:
        name: wren-windows
        path: |
          bin/*
          lib/*


================================================
FILE: .gitignore
================================================
# Build outputs
/bin
/lib
# Intermediate files
*.obj
Debug/
Release/
/build
/.sass-cache
*.pyc

# I leave a temporary Wren script at the top
# level so that I can quickly test stuff.
/scratch.wren

# The baseline file is machine-specific
/test/benchmark/baseline.txt

# VSCode project files.
.vscode

# XCode user-specific stuff
xcuserdata/

# Visual Studio cache files
.vs/
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile

# Visual Studio User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# macOS
.DS_Store


================================================
FILE: .travis.sh
================================================
#!/bin/bash
set -e

# This build script only builds mac or linux right now, for CI.
WREN_WD="projects/make"
if [ -n "$WREN_TARGET_MAC" ]; then
  WREN_WD="projects/make.mac"
fi

WREN_PY=${WREN_PY_BINARY:-python3}

echo "using working directory '$WREN_WD' ..."
echo "using python binary '$WREN_PY' ..."

make -C $WREN_WD config=debug_64bit-no-nan-tagging
$WREN_PY ./util/test.py --suffix=_d

make -C $WREN_WD config=debug_64bit
$WREN_PY ./util/test.py --suffix=_d

make -C $WREN_WD config=release_64bit-no-nan-tagging
$WREN_PY ./util/test.py

make -C $WREN_WD config=release_64bit
$WREN_PY ./util/test.py


================================================
FILE: .travis.yml
================================================
language: c

# https://docs.travis-ci.com/user/languages/c/#gcc-on-macos
# On mac, gcc is aliased to clang, so we only have one row 
# in build the matrix, not two like on linux
compiler:
  - clang
  - gcc

# Automatically build and deploy docs.
jobs:
  include:
    - os: linux
    - os: osx
      env: WREN_TARGET_MAC=1

    - stage: deploy
      script: ./util/deploy_docs_from_travis.sh
      # Only deploy commits that land on main.
      if: branch = main and type = push

# Travis VMs are 64-bit but we compile both for 32 and 64 bit. To enable the
# 32-bit builds to work, we need gcc-multilib.
addons:
  apt:
    packages:
    - gcc-multilib
    - g++-multilib
    # These are needed for building and deploying the docs.
    - python3-markdown
    - python3-pygments
    - python3-setuptools
    - ruby-sass

# Can't do container-based builds for now because installing the custom
# Pygments lexer to generate the docs requires sudo. :( If that changes,
# uncomment the next line and delete the "sudo" and "dist" lines.
# sudo: false # Enable container-based builds.
sudo: required
dist: trusty

script: ./.travis.sh


================================================
FILE: AUTHORS
================================================
This is the (likely incomplete) list of people who have made Wren what it is.
If you submit a patch to Wren, please add your name and email address to the
end of this list.

Robert Nystrom <robert@stuffwithstuff.com>
Kyle Marek-Spartz <kyle.marek.spartz@gmail.com>
Paul Woolcock <paul@woolcock.us>
Evan Shaw <edsrzf@gmail.com>
Gavin Schulz <gavin.schulz@gmail.com>
Lukas Werling <lukas.werling@gmail.com>
Marco Lizza <marco.lizza@gmail.com>
Raymond Sohn <raymondsohn@gmail.com>
Thorbjørn Lindeijer <bjorn@lindeijer.nl>
Patricio Mac Adden <patriciomacadden@gmail.com>
Evan Hahn <me@evanhahn.com>
Starbeamrainbowlabs <contact@starbeamrainbowlabs.com>
Alexander Roper <minirop@gmail.com>
Will Speak <will@willspeak.me>
Damien Radtke <damienradtke@gmail.com>
Max Ferguson <maxxferguson@gmail.com>
Sven Bergström <sven@underscorediscovery.com>
Kyle Charters <kylewcharters@gmail.com>
Marshall Bowers <elliott.codes@gmail.com>
Michal Kozakiewicz <michalkozakiewicz3@gmail.com>
Charlotte Koch <cfkoch@edgebsd.org>
Michel Hermier <michel.hermier@gmail.com>
Taylor Hoff <primdevs@gmail.com>
ruby0x1 <ruby0x1@pm.me>
Kolja Kube <code@koljaku.be>
Alexander Klingenbeck <alexander.klingenbeck@gmx.de>
Aviv Beeri <avbeeri@gmail.com>
Mai Lapyst <floss@lapyst.dev>



================================================
FILE: CHANGELOG.md
================================================
## 0.4.0

### Language
- Add `continue` keyword
- Add `as`: `import "..." for Name as OtherName`
- Add Support positive sign in scientific notation
- Add Fiber.try(value) to complement Fiber.call(value)
- Allow `.` to be on a different line (for fluent/builder APIs)

### Modules
- Random: Random.sample optimizations
- List:
  - add `list.sort()` and `list.sort {|a, b| ... }` (quicksort)
  - add `list.swap(index0, index1)` for swapping elements within a list
  - add `list.indexOf(value)` for finding values in a list
- Num:
  - add `Num.tau`
  - add `Num.nan`
  - add `Num.infinity`
  - add `min(other)`
  - add `max(other)`
  - add `clamp(min, max)`
  - add `exp`
  - add `log2`

### Fixes
- Fix stack corruption related to `Fn` calls
- Fix a byte offset bug in CODE_IMPORT_VARIABLE
- Fix some stack corruptions related to multiple wrenInterpret calls
- Fixed crash when GC collects module during import
- Fix `Bool`, `Num` and `Null` allowing subclassing, which is invalid

### API
- BREAKING: Add `userData` to `wrenReallocateFn`
- BREAKING: Add `WrenLoadModuleResult` which has a `onComplete` callback, allowing freeing module strings
- Add `wrenHasVariable` and `wrenHasModule` queries, for use with `wrenGetVariable`
- Add `wrenSetListElement` to complement `wrenGetListElement`, and allow negative index for both
- Add Map functions to API
  - wrenSetSlotNewMap
  - wrenGetMapCount
  - wrenGetMapContainsKey
  - wrenGetMapValue
  - wrenSetMapValue
  - wrenRemoveMapValue

### Other
- build; add util/generate_docs.py for regenerating project files
- vm; Allow computed goto when using clang on Windows
- vm; WREN_MAX_TEMP_ROOTS default is 8 (instead of 5)
- vm; GC debug times are printed in milliseconds, not seconds

## 0.3.0

0.3.0 is a fairly specific release, aimed at fixing build issues across platforms,
streamlining the process for new users and making embedding easier.
This is a stepping stone for working on language features and improving the VM,
hacking on the docs and the VM is simpler than ever!

Builds now work out of the box on all primary platforms.
Previously there was issues on Windows and other platforms due to unix-ey workflows being the default.

All the python scripts have also been fixed and updated (to python 3), and work consistently
across all platforms out of the box too (including the tests, benchmarks, metrics etc).
Like before, there was some things that didn't hold up on Windows or Mac. Fixed!

A lot of work has been done to also clarify the distinction between the CLI project and the VM,
as well as [move the CLI to its own repo](https://github.com/wren-lang/wren-cli/)!
This removes a lot of code that wasn't being used, and also been clarified the project structure.

Docs have also had a clean up, and a new page to try Wren directly on the doc page was added.

### Language/VM

- CLI moved to own repo
- Use premake for project generation, see projects/
- Fix builds across platforms. "Just works" on all primary platforms.
- Fix amalgamated script generator and amalgamated build
- Fix unicode parsing and other issues in all python scripts
- All python scripts are python3 now, and run on all platforms correctly
- Test runner isolated and unified for VM tests
- Remove SASS and Pygments requirements from docs, just python now
- Updated docs to clarify VM/CLI split
- Added Try page for running wren code in the docs

## 0.2.0

0.2.0 spans a pretty wide time period with [around 290 commits](https://github.com/wren-lang/wren/compare/0.1.0...main).
This includes many bug fixes, improvements, clarity in the
code and documentation and so on. There's too many to explicitly list.
Below is the obvious user facing stuff that was easy to spot in the history.

Most noteworthy is that 'relative imports' are a slightly breaking change,
but help pave the way forward toward a consistency for modules.

### Language/VM

- `import` was made smarter, differentiating relative from logical
- `Fiber` can now accept a value from the first `call`/`transfer`
- Added `String.trim`, `String.trimEnd`, `String.trimStart` variants
- Added `String.split`, `String.replace`, `String.fromByte`
- Added `String.indexOf(needle, startIndex)`
- Added `Sequence.take` and `Sequence.skip`
- Added `List.filled(count, value)`
- Added `Num.pow`, `Num.log`, `Num.round`
- Added `Num.largest`, `Num.smallest`
- Added `Map` iteration (`MapEntry`)

#### C API

- Added `wren.hpp` for use in c++
- Added void* user data to `WrenVM`
- Allow hosts with no module loader to still load optional modules.
- Added `wrenAbortFiber`

### CLI
Please note that beyond 0.2.0 the CLI will have it's own changelog.
This list is not exhaustive. For a fuller history see the commit log above.

- Add path module
- Add `--version`
- Add REPL written in Wren
- Add Stdin.isTerminal
- Added Platform class
- Rename `process` module to `os`

## 0.1.0

First declared version. Everything is new!


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2013-2021 Robert Nystrom and Wren Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
## Wren is a small, fast, class-based concurrent scripting language

Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in
a familiar, modern [syntax][].

```dart
System.print("Hello, world!")

class Wren {
  flyTo(city) {
    System.print("Flying to %(city)")
  }
}

var adjectives = Fiber.new {
  ["small", "clean", "fast"].each {|word| Fiber.yield(word) }
}

while (!adjectives.isDone) System.print(adjectives.call())
```

 *  **Wren is small.** The VM implementation is under [4,000 semicolons][src].
    You can skim the whole thing in an afternoon. It's *small*, but not
    *dense*. It is readable and [lovingly-commented][nan].

 *  **Wren is fast.** A fast single-pass compiler to tight bytecode, and a
    compact object representation help Wren [compete with other dynamic
    languages][perf].

 *  **Wren is class-based.** There are lots of scripting languages out there,
    but many have unusual or non-existent object models. Wren places
    [classes][] front and center.

 *  **Wren is concurrent.** Lightweight [fibers][] are core to the execution
    model and let you organize your program into an army of communicating
    coroutines.

 *  **Wren is a scripting language.** Wren is intended for embedding in
    applications. It has no dependencies, a small standard library,
    and [an easy-to-use C API][embedding]. It compiles cleanly as C99, C++98
    or anything later.

If you like the sound of this, [let's get started][started]. You can even try
it [in your browser][browser]! Excited? Well, come on and [get
involved][contribute]!

[![Build Status](https://travis-ci.org/wren-lang/wren.svg?branch=main)](https://travis-ci.org/wren-lang/wren)

[syntax]: http://wren.io/syntax.html
[src]: https://github.com/wren-lang/wren/tree/main/src
[nan]: https://github.com/wren-lang/wren/blob/93dac9132773c5bc0bbe92df5ccbff14da9d25a6/src/vm/wren_value.h#L486-L541
[perf]: http://wren.io/performance.html
[classes]: http://wren.io/classes.html
[fibers]: http://wren.io/concurrency.html
[embedding]: http://wren.io/embedding/
[started]: http://wren.io/getting-started.html
[browser]: http://ppvk.github.io/wren-nest/
[contribute]: http://wren.io/contributing.html


================================================
FILE: doc/error-handling.txt
================================================
Q: Can we use fibers for error-handling?

The goal here is to avoid adding support for exception handling if we're already
going to support fibers. A potential bonus would be being able to have
restartable error-handling.

The general idea is that instead of putting code in a "try" block, you throw it
onto a new fiber. If an error occurs, that fiber is paused, and returns control
back to the spawning fiber. The parent fiber can then decipher the error and
either abandon the fiber, or try to fix the error and resume somehow.

The first question is what kinds of errors is this useful for. For things like
parsing strings where failure is common and error-handling needs to be
lightweight, I think using fibers is too heavy, both in performance and code.
A better answer there is to lean on dynamic typing and return null on parse
failure.

On the other hand, it might be nice to be able to resume here if the code that
provided the string is far away and you don't want to have to manually propagate
the error out.

Programmatic errors like invalid argument types should halt the fiber but the
programmer will not want to resume that at runtime. Using the mechanism here is
fine since it would then dump a stack trace, etc. But it won't take advantage
of resuming.

Resuming is probably useful for things like IO errors where the error can't be
easily predicted beforehand but where you may want to handle it gracefully. For
example, if a file can't be opened, the caller may want to wait a while and
try again.

--

After thinking about it, maybe resuming is a bridge too far. Erlang's model is
that a failure just kills the process. I'll note that Erlang does have try and
catch, though.

The goals for error-handling in a scripting language are:

0. Have simple semantics and implementation.

1. Make it easy for developers to track down programmatic errors so they can
   fix them. This means bugs like wrong argument types should fail immediately
   and loudly, and should provide context (a callstack) about where the error
   occurred.

2. For runtime errors like parsing an invalid string or opening a missing file,
   the program should be able to easily detect the error at handle it.

3. It *may* be useful for programmers to be able to trap all errors and try to
   keep the program alive, or at least log the error in a meaningful way. When
   you have user-defined scripts, or a lot of code, or code authored by
   non-technical people, it's nice if a failure in one part can be reported but
   not take down the entire system.

   Two close-at-hand examples:

   - The REPL. A bug in code in the REPL shouldn't kill the whole REPL session.

   - The test framework. In order to write tests in Wren that test programmatic
     runtime errors, we need to be able to detect them and output something.
     The test runner could just parse the error output when the entire process
     dies, but that means you can only have one error test per test file.

Given those, I'm thinking:

1. Programmatic errors take down the entire fiber and dump a callstack.
   Normally, they will also take down the parent fiber and so on until the
   entire program goes down.

2. Runtime errors return error codes (or null). Things like parsing a string to
   a number, etc. should just return an error that you are responsible for
   handling.

3. When handing off control to a fiber, there is a "guarded run" method that
   will run the fiber. If it fails with a programmatic error, the invoked fiber
   dies, but the parent does not. It gets the callstack and error as some sort
   of object it can poke at.


================================================
FILE: doc/implicit fields.txt
================================================
Q: Can fields be implicitly declared?

The idea is that just using a name starting with "_" somewhere in a class
automatically defines a field with that name. Implicit fields are particularly
nice because it means they don't have to be defined all before methods. (Since
we have a single-pass compiler, we would have to otherwise a method could
only refer to previously defined fields.)

One potential problem is with nested classes. This is more important if we
consider a module effectively a class. Consider:

  class Outer {
    foo {
      _blah = "value"
    }

    class Inner {
      IO.write(_blah) // Does this declare field in Inner, or access Outer?
    }
  }

Looking at this, though, I think there's already a question how referring to an
outer field would work. Having an instance of Inner doesn't imply you also have
an instance of Outer. We definitely don't want to recapitulate inner classes
in Java.

Q: What about static fields?

A: Different naming convention? __foo?


================================================
FILE: doc/instruction counts.txt
================================================
This is the number of times each instruction was executed when running the
delta_blue benchmark:

3753021 CODE_LOAD_LOCAL
2233991 CODE_RETURN
2151580 CODE_LOAD_FIELD_THIS
2121398 CODE_CALL_1
1827535 CODE_CALL_0
1328364 CODE_POP
1136064 CODE_JUMP_IF
715071 CODE_LOAD_GLOBAL
428374 CODE_STORE_FIELD_THIS
424999 CODE_NULL
355344 CODE_STORE_LOCAL
341762 CODE_LOOP
118855 CODE_CONSTANT
93048 CODE_CALL_2
75280 CODE_AND
59920 CODE_JUMP
16842 CODE_LIST
16660 CODE_TRUE
10040 CODE_OR
8200 CODE_LOAD_UPVALUE
8140 CODE_SUPER_1
6540 CODE_FALSE
6076 CODE_STORE_GLOBAL
4000 CODE_SUPER_3
2020 CODE_SUPER_2
2000 CODE_SUPER_0
2000 CODE_CALL_5
2000 CODE_CALL_3
160 CODE_CLOSURE
74 CODE_METHOD_INSTANCE
11 CODE_CLASS
4 CODE_METHOD_STATIC
0 CODE_SUPER_9
0 CODE_SUPER_8
0 CODE_SUPER_7
0 CODE_SUPER_6
0 CODE_SUPER_5
0 CODE_SUPER_4
0 CODE_SUPER_16
0 CODE_SUPER_15
0 CODE_SUPER_14
0 CODE_SUPER_13
0 CODE_SUPER_12
0 CODE_SUPER_11
0 CODE_SUPER_10
0 CODE_STORE_UPVALUE
0 CODE_STORE_FIELD
0 CODE_LOAD_FIELD
0 CODE_IS
0 CODE_CLOSE_UPVALUE
0 CODE_CALL_9
0 CODE_CALL_8
0 CODE_CALL_7
0 CODE_CALL_6
0 CODE_CALL_4
0 CODE_CALL_16
0 CODE_CALL_15
0 CODE_CALL_14
0 CODE_CALL_13
0 CODE_CALL_12
0 CODE_CALL_11
0 CODE_CALL_10

================================================
FILE: doc/notes/import syntax.md
================================================
So we need some syntax to distinguish between a relative import and a logical
import. I'm not sure which way to go, and I'd like some feedback (or possibly
other alternate ideas I haven't considered).

My two favorites are:

```
// Use
use "relative/path"
import "logical/path"

// Node-style
import "./relative/path"
import "logical/path"
```

If you folks are OK with "use", that's my preference. But otherwise, the Node
style will definitely work too. I'm open to other ideas as well, including a few
below, but I'd like to not bikeshed this forever.

## Background

There are four general approaches we can take:

### Use a modifier ("modifier")

Both kinds of imports start with `import`, but then we use a second keyword
afterwards to identify either a relative or logical import. We could use *two*
keywords -- one for each kind -- but that's unnecessarily verbose. Instead, we
use the presence or absence of the keyword to distinguish. In other words:

```
import foo "string"
import "string"
```

The specific questions we have to answer are:

1. Which kind of import gets the keyword? Ideally, the most common kind of
   import would be the one that doesn't need an extra keyword.

2. What keyword? This is surprisingly hard. Probably some kind of preposition.

### Use different keywords ("keyword")

Instead of using `import` for both logical and relative imports, we could have
two keywords, one for each kind. The specific questions to answer then are:

1. Which kind of import gets `import`?
2. What's the other keyword?

### Use different syntax for the path ("syntax")

Instead of always using a string literal to identify what's being imported, we
could use a different kind of token or tokens for the different kinds of import.
For example, a string literal for one kind, and an identifier token for the
other:

import identifier
import "string literal"

The specific questions are:

1. Which kind of import uses a string literal?
2. What's the syntax for the other kind?

### Use a signifier in the import string itself to distinguish ("string")

An import is always `import` followed by a string literal. Then we use some
specific markers inside the string literal itself to distinguish the two kinds.
For example, Node says that an import string starting with "./" or "../" is
relative and other import strings are logical.

The specific question to answer is what kind of signifier we'd use. I think
Node's convention is the only real contender here, though.

One feature this style has that none of the others do is that it means the
language syntax itself has no notion of logical and relative imports. This
means there is no overhead or complexity for host applications where that
distinction isn't meaningful.

## Contenders

These are options I'm open to, in roughly descending order of preference:

### Node-style (string)

If the string starts with "./" or "../", it's relative.

```
import "./relative/path"
import "logical/path"
```

This is how Node works, so there's prior art. It keeps the language completely
simple. It does feel sort of arbitrary and magical to me, but it's the simplest,
most expedient solution.

### Use (keyword)

The `use` keyword is for relative imports, `import` is for logical.

```
use "relative/path"
import "logical/path"
```

The `use` keyword comes from Pascal, but that's not very widely known. I kind
of like this. It's short, and `use` feels "nearer" to me than "import" so it
has the right connotation. (You can't "use" something unless you have it near
to hand.)

It adds a little complexity to the language and VM. We have to support both
keywords and pass that "use versus import" bit through the name resolution
process. But that's pretty minor.

### Slashes (syntax)

If the path is a string literal, it's relative. Otherwise, it is a
slash-separated series of unquoted identifiers.

```
import "relative/path"
import logical/path
```

This means you can't (easily) use reserved words as names of logical imports.
This was my initial pitch. I still like how it looks, but I seem to be in the
minority.

### Relative (modifier)

The `relative` modifier is for relative imports.

```
import relative "relative/path"
import "logical/path"
```

It's explicit, which is good. It is unfortunately verbose. I think `relative`
is too useful of a word to make into a reserved word, which means it would have
to be a contextual keyword (i.e. treated like a reserved word after `import`
but behaving like a regular identifier elsewhere). I'm not generally a fan of
contextual keywords—they tend to make things like syntax highlighters more
difficult to create—so I try to avoid them.

## Rejected

I considered these ideas, but don't think they are good enough approaches for
various reasons:

### Package identifier (syntax)

If an unquoted identifier appears before the import string, then it's a logical
import within that package. Otherwise, it's relative.

```
import "relative/path"
import logical "path"
```

This was one of my initial ideas. It has the same problem as other unquoted
imports in that it makes it harder to have odd package names. It means the VM
has to understand this syntax and figure out how to display package names in
stack traces and stuff, so there is some extra complexity involved.

The form where you have both a package name and a relative path within that
package is pretty unusual and likely unintuitive to users.

### Dotted (syntax)

If the path is a string literal, it's relative. Otherwise, it is a
dot-separated series of unquoted identifiers.

```
import "relative/path"
import logical.path
```

Similar to slashes, but using dots. This helps make logical imports look more
visually distinct from relative ones. But it also makes them look more similar
to getter calls, which they aren't related to at all.

### Include (keyword)

The `include` keyword is for relative imports, `import` is for logical.

```
include "relative/path"
import "logical/path"
```

Ruby uses `include` for applying mixins. "Include" reads to me more like some
kind of transclusion thing, so it feels a little weird.

### Require (keyword)

The `require` keyword is for relative imports, `import` is for logical.

```
require "relative/path"
import "logical/path"
```

Node uses "require" and ES6 uses "import" so this is kind of confusing. Ruby
uses `require` and `require_relative`, so using `require` for a relative import
is kind of confusing. Lua also uses `require`, but for both relative and
logical. Overall, this feels murky and unhelpful to me.

### Angle-brackets (syntax)

As in C/C++, an import string can be in angle brackets or quotes. Angle brackets
are for logical imports, quotes for relative.

```
import "relative/path"
import <logical/path>
```

Hard pass. It requires context-sensitive tokenization (!) in C and we definitely
don't want to go there.

### URI scheme (string)

An import string starting with "package:" and maybe "wren:" is treated as
logical, like they are URIs with an explicit scheme. Others are relative.

```
import "relative/path"
import "package:logical/path"
import "wren:random"
```

This is (roughly) how Dart works. I'm not a fan. I think it's too verbose for
logical imports.

### Package (modifier)

A `package` modifier indicates a logical import. Others are relative.

```
import "relative/path"
import package "logical/path"
```

Pretty long, and I'm not too crazy about baking "package" into the language and
VM.

### From (modifier)

A `from` modifier indicates, uh, one kind of import.

```
import "some/path"
import from "other/path"
```

It looks nice, but it's totally unclear to me whether logical imports should
get `from` or relative ones. Also kind of confusing in that Python and ES6 use
`from` in their notation for importing explicit variables from a module (where
Wren uses `for`).


================================================
FILE: doc/notes/re-entrancy.md
================================================
## wrenInterpret()

You can already call out to a foreign method or constructor from within an
execution that was started using `wrenInterpret()`, so I think that's fine.
`wrenInterpret()` doesn't use the API stack at all.

## wrenCall()

Normally, when using `wrenCall()` to start executing some code, the API slots
are at the very bottom of the fiber's stack and the fiber has no other
callframes until execution begins.

When a foreign method or constructor is called, there *are* callframes on the
fiber's stack. There must be, because that's where the arguments to the foreign
method are.

So, if you `wrenCall()`, which eventually calls a foreign method, the same fiber
will be used for the API twice. This is currently broken. The reason it's broken
is that `callForeign()` and `createForeign()` store the old apiStack pointer
(the one used for the initial `wrenCall()`) in a local variable and then restore
it when the foreign call completes. If a GC or stack grow occurs in the middle
of that, we end up restoring a bad pointer.

But I don't think we need to preserve apiStack for the `wrenCall()` anyway. As
soon as the user calls `wrenCall()` and it starts running, we no longer need to
track the number of slots allocated for the API. All that matters is that the
one return value is available at the end.

I think this means it *should* be fairly easy to support:

    wrenCall() -> wren code -> foreign method

## Foreign calls

The interesting one is whether you can call `wrenInterpret()` or `wrenCall()`
from within a foreign method. If we're going to allow re-entrancy at all, it
would be nice to completely support it. I do think there are practical uses
for this.

Calling `wrenInterpret()` should already work, though I don't think it's tested.

Calling `wrenCall()` is probably broken. It will try to re-use the slots that
are already set up for the foreign call and then who knows what happens if you
start to execute.

I think a key part of the problem is that we implicitly create or reuse the API
stack as soon as you start messing with slots. So if there already happens to
be an API stack -- because you're in the middle of a foreign method -- it will
incorrectly reuse it when you start preparing for the `wrenCall()`.

An obvious fix is to add a new function like `wrenPrepareCall()` that explicitly
creates a new API stack -- really a new fiber -- for you to use. We still have
to figure out how to keep track of the current API stack and fiber for the
foreign call so that we can return to it.

**TODO: more thinking here...**

If I can figure this out, it means we can do:

    foreign method -> C code -> wrenCall()

## Nested foreign calls

If we compose the above it leads to the question of whether you can have
multiple nested foreign calls in-progress at the same time. Can you have a C
stack like:

    wrenCall()
    runInterpreter()
    foreignCall()
    wrenCall()
    runInterpreter()
    foreignCall()
    ...

This does *not* mean there is a single Wren stack that contains multiple
foreign calls. Since each `wrenCall()` begins a new fiber, any given Wren stack
can only ever have a single foreign API call at the top of the stack. I think
that's a good invariant.

I believe we should support the above. This means that the core
`runInterpreter()` C function is itself re-entrant. So far, I've always assumed
it would not be, so it probably breaks some assumptions. I'll have to think
through. The main thing that could be problematic is the local variables inside
`runInterpreter()`, but I believe `STORE_FRAME()` and `LOAD_FRAME()` take care
of those. We just need to make sure they get called before any re-entrancy can
happen. That probably means calling them before we invoke a foreign method.

I'll have to write some tests and see what blows up for this.

## Calling re-entrant fibers

Where it gets really confusing is how re-entrant calls interact with fibers.
For example, say you:

    wrenCall()       -> creates Fiber #1
    runInterpreter() -> runs Fiber #1
                        some Wren code stores current fiber in a variable
    foreignCall()
    wrenCall()       -> creates Fiber #2
    runInterpreter() -> runs Fiber #2
                        some Wren code calls or transfers to Fiber #1

What happens in this scenario? We definitely want to prevent it. We already
detect and prevent the case where you call a fiber that's already called in the
current *Wren* stack, so we should be able to do something in the above case
too.

Now that I think about it, you can probably already get yourself in a weird
state if you grab the root fiber and call it. Yeah, I justed tested. This:

    var root = Fiber.current
    Fiber.new {
      root.call()
      System.print(1)
    }.call()
    System.print(2)

Segfaults the VM. :( It actually dies when the called child fiber *returns*. The
root call successfully continues executing the root fiber (which is super
weird). Then that completes and control returns to the spawned fiber. Then
*that* completes and tries to return control to the root fiber, but the root is
already done, and it blows up. So the above prints "2" then "1" then dies.

(If either of the `call()` calls are change to `transfer()`, the script runs
without any problems because then it never tries to unwind back through the
root fiber which already completed.)

To fix this, when `runInterpreter()` begins executing a root fiber (either from
`wrenCall()` or `wrenInterpret()`), we need to mark it in some way so that it
can't be called or transferred to.

## Suspending during re-entrancy

Maybe the weird conceptual case is when you suspend a fiber while there are
multiple re-entrant calls to `runInterpreter()` on the C stack. Ideall, they
would all magically return, but that's obviously not feasible.

I guess what will/should happen is that just the innermost one suspends. It's
up to the host to handle that fact. I need to think about this more, add some
tests, and work through it.

I think we'll probably want to add another WrenInterpretResult case for
suspension so that the host can tell that's what happened.


================================================
FILE: doc/receiver-less calls 2.txt
================================================
    var baz = "top level"

    class Foo {
      bar {
        baz
        _baz
      }

      baz { "getter" }
      _baz { "private getter" }

      this {
        _baz = "field"
      }
    }

Given `_foo`, how do we tell if it is:
1. A call to a private getter
2. Accessing a private field
3. Tearing off a reference to a private method

It's not 3 because of arity overloading. Wren doesn't really have method
tear-off because of this.)

This is hard because the getter may not be defined yet. One option is:
It's always a call to a private getter. After the class is defined, we see if
there are any private getters that were not implemented and define implicit
getters for them that return fields.

That's weird if you take into account setters, though. Consider:

    class Foo {
      a { IO.write(_prop) }
      _prop = value { ... }
    }

For first reference to `_prop`, compile it to getter call. Then see setter
defined for it, so we no longer implicitly make a field. But there's no getter,
so now the above call will fail.

Probably do want call to fail here, so that may be OK.

---

Given `_foo(arg)`, how do we tell if it is:

1. A call to a private method
2. A call to a private getter, which returns a field that's a fn, and invoking
   it.

Since arity is part of the name, the answer here is 1.

---

Given `foo(arg)` inside a class, how do we tell if it is:

1. A call to a method on this.
2. Accessing a field `foo` on this, which returns a fn, and invoking it.
3. Calling a getter `foo` on this, which returns a fn, and invoking it.
4. A call to a top-level fn.

Let's just dismiss 3. Since arity affects naming, `foo(arg)` and `(foo)(arg)`
are really different things in Wren. The parentheses and args are effectively
part of the name.

That covers 2 as well. If we ditch top level fns, we're left with 1. This is
good, I think. It means the common case of calling methods on yourself is nice
and terse.

---

Given `foo` inside a class, how do we tell if it is:

1. Accessing a field on this.
2. Calling a getter on this.
3. Accessing a global variable.
4. Accessing a top-level getter.
5. Accessing a local variable.

We can probably ditch 4. We can ditch 1 because Wren doesn't have public fields.

Because both getters and global variables can be used before they are defined,
we can't determine statically (in a single pass compiler) if there is a global
variable or getter named `foo` in order to disambiguate. Even if we could, we'd
still have to answer the ambiguous case where it's both.

If we assume it's a global and the user wants a getter, they can always do
`this.foo` to be explicit. If we assume it's getter, how would they indicate a
global?

One option is to have a different naming convention for globals, like a
capitalized initial variable. That lines up with class names at the top level
anyway. It just means if we have variables for imported modules, we'll want to
capitalize those.

We still have to distinguish locals, but since those are declared before use, we
can determine that statically. I.e. locals will shadow implicit getters.

---

OK, so here's one proposal:

    class MyClass {
      method {
        _foo      // access field
        _foo(arg) // not valid
        foo       // local var or getter on this
        foo(arg)  // method on this
        Foo       // global variable
      }
    }

This is simple, and straightforward to compile. Using capitalization for globals
is a bit weird, and not having private methods is a bummer, but maybe simplicity
is the right answer.

Here's another:

    class MyClass {
      method {
        _foo      // private getter on this
        _foo(arg) // private method on this
        foo       // local var or getter on this
        foo(arg)  // method on this
        Foo       // global variable
      }
    }

To get rid of the weird capitalization rule for globals, one option is to not
allow forward references to globals. That would break mutually recursive
references to classes, though:

    class A {
      foo { B.new }
    }

    class B {
      foo { A.new }
    }

So, not a fan of that.

Ignoring that, the main difference between the two proposals is the second has
private methods. Since the first proposal is practically a subset of the second,
let's start with that one first.



================================================
FILE: doc/receiver-less calls.txt
================================================
Q1: What does this resolve to:

    foo(arg)

   It could be:
   1. this.foo(arg)
   2. EnclosingClass.foo(arg) // i.e. a static method call
   3. a call to a top-level function foo()

If we adopt the idea that a module is just a class definition (with some
syntactic differences) and classes can be nested, then 3 really means "a call
to a static method on the class surrounding the enclosing class".

I *don't* think we want the answer to the question to vary based on the name
in question. We can't rely on name resolution to disambiguate because we don't
know the full set of surrounding names in a single pass compiler. Also, it's
semantically squishier.

I think the right answer is 1, it's an implicit call on this. That's what you
want most often, I think. For imported modules, we could import them with a
"prefix" (really import them as objects bound to named variables), so calling
a top-level function in another module would be something like:

  someModule.foo(arg)

This leaves the question of how *do* you call top level functions in your own
module? I.e., how do we call foo here:

  def foo(arg) { IO.write("called foo!") }

  class SomeClass {
    bar {
      // Want to call foo here...
    }
  }

This is analogous to:

  class SomeModule {
    static foo(arg) { IO.write("called foo!") }

    class SomeClass {
      bar {
        // Want to call foo here...
      }
    }
  }

The obvious solution is to use the class name:

  class SomeModule {
    static foo(arg) { IO.print("called foo!") }

    class SomeClass {
      bar {
        SomeModule.foo(arg)
      }
    }
  }

Which just leaves the question of what the class name of a top-level "module
class" is.

Idea: it's unnamed, so you just use a leading ".":

  def foo(arg) { IO.print("called foo!") }

  class SomeClass {
    bar {
      .foo(arg)
    }
  }

This mirrors C++'s unnamed scope thing:

  ::foo(arg);


================================================
FILE: doc/rfc/0001-smarter-imports.md
================================================
# Smarter Imports

**Note: This is now mostly implemented, though the implementation differs
somewhat from this original proposal.**

Here's a proposal for improving how imported modules are identified and found
to hopefully help us start growing an ecosystem of reusable Wren code. Please
do [let me know][list] what you think!

[list]: https://groups.google.com/forum/#!forum/wren-lang

## Motivation

As [others][210] [have][325] [noted][346], the way imports work in Wren,
particularly how the CLI resolves them, makes it much too hard to reuse code.
This proposal aims to improve that. It doesn't intend to fix *everything* about
imports and the module system, but should leave the door open for later
improvements.

[210]: https://github.com/wren-lang/wren/issues/210
[325]: https://github.com/wren-lang/wren/issues/325
[346]: https://github.com/wren-lang/wren/issues/346

### Relative imports

Today, it's hard to reuse your own code unless you literally dump everything in
a single directory. Say you have:

```text
script_a.wren
useful_stuff/
  script_b.wren
  thing_1.wren
  thing_2.wren
```

`script_a.wren` and `script_b.wren` are both scripts you can run directly from
the CLI. They would both like to use `thing_1.wren`, which in turn imports
`thing_2.wren`. What does `thing_1.wren` look like? If you do:

```scala
// thing_1.wren
import "thing_2"
```

Then it works fine if you run `script_b.wren` from the `useful_stuff/`
directory. But if you try to run `script_a.wren` from the top level directory,
then it looks for `thing_2.wren` *there* and fails to find it. If you change the
import to:

```scala
// thing_1.wren
import "useful_stuff/thing_2"
```

Then `script_a.wren` works, but now `script_b.wren` is broken. The problem is
that all imports are treated as relative to the directory containing the
*initial script* you run. That means you can't reuse modules from scripts that
live in different directories.

In this example, if feels like imports should be treated as relative to the
file that contains the import statement. Often you want to specify, "Here is
*where* this other module is, relative to where *I* am."

### Logical imports

If we make imports relative, is that enough? Should *all* imports be relative? I
don't think so. First of all, some modules are not even on the file system.
There is no relative path that will take you to "random" — it's built into the
VM itself. Likewise, "io" is baked into the CLI.

Today, when you write:

```scala
import "io"
```

You aren't saying *where* that module should be found, you're saying *what*
module you want. Assuming we get a package manager at some point, these kinds of
"logical" imports will be common. So I want these too.

If you look at other langauges' package managers, you'll find many times a
single package offers a number of separate libraries you can use. So I also
want to support logical imports that contain a path too — the import would say
both *what* package to look in and *where* in that package to look.

### Only logical imports?

Given some kind of package-y import syntax, could we get rid of relative imports
and use those for everything? You'd treat your own program like it was itself
some kind of package and anything you wanted to import in it you'd import
relative to your app's root directory.

The problem is that the "root directory" for your program's "package" isn't
well-defined. We could say it's always the same directory as the script you're
running, but that's probably too limiting. You may want to run scripts that live
in subdirectories.

We could walk up the parent directories looking for some kind of "manifest" file
that declares "the root of the package is here", but that seems like a lot of
hassle if you just want to create a couple of text files and start getting some
code running. So, for your own programs, I think it's nice to still support
"pure" relative imports.

### Ambiguity?

OK, so we want both relative imports and logical imports. Can we use the same
syntax for both? We could allow, say:

```scala
import "a/b"
```

And the semantics would be:

1.  Look for a module "a/b.wren" relative to the file containing the import. If
    found, use it.

2.  Otherwise, look inside some "package" directory for a package named "a" and
    a module named "b.wren" inside it. If found use that.

3.  Otherwise, look for a built in module named "a".

This is pretty much how things work now, but I don't think it's a good idea.
Relative imports will tend to be short — often single words like "utils".
Assuming we get a healthy package ecosystem at some point, the chances of one of
those colliding with a logical import name are high.

Also, when reading code, I think it's important to be able to easily tell "this
import is from my own program" without having to know the names of all of the
files and directories in the program.

## Proposal

OK, so here's my goals:

1.  A way to import a module relative to the one containing the import.
2.  A way to import a module from some named logical package, possibly at a
    specific path within that package.
3.  Distinct syntaxes for each of these.

I tried a few different ideas, and my favorite is:

### Relative imports

Relative imports use the existing syntax:

```scala
// Relative path.
import "ast/expr"
```

This looks for the file `ast/expr.wren` relative to the directory containing the
module that has this import statement in it.

You can also walk out of directories if you need to import a module in a parent
folder:

```scala
import "../../other/stuff"
```

### Logical imports

If you want to import a module from some named logical entity, you use an
*unquoted* identifier:

```scala
import random
```

Being unquoted means the names must be valid Wren identifiers and can't be
reserved words. I think that's OK. It would confuse the hell out of people if
you had a library named "if". I think the above *looks* nice, and the fact that
it's not quoted sends a signal (to me at least) that the name is a "what" more
than a "where".

If you want to import a specific module within a logical entity, you can have a
series of slash-separate identifiers after the name:

```scala
import wrenalyzer/ast/expr
```

This imports module "ast/expr" from "wrenalyzer".

## Implementation

That's the proposed syntax and basic semantics. The way we actually implement it
is tricky because Wren is both a standalone interpreter you can run on the
command line and an embedded scripting language. We have to figure out what goes
into the VM and what lives in the CLI, and the interface between the two.

### VM

As usual, I want to keep the VM minimal and free of policy. We do need to add
support for the new unquoted syntax. The more significant change is to the API
the VM uses to talk to the host app when a module is imported. The VM doesn't
know how to actually load modules. When it executes an import statement, it
calls:

```c
char* loadModuleFn(WrenVM* vm, const char* name);
```

The VM tells the host app the import string and the host app returns the code.
In order to distinguish relative imports (quoted) from an identical unquoted
name and path, we need to pass in an extra to bit to tell the host whether there
were quotes or not.

The more challenging change (and the reason I didn't support them when I first
added imports to Wren) is relative imports. There are two tricky parts:

First, the host app doesn't have enough context to resolve a relative import.
Right now, the VM only passes in the import string. It doesn't tell which module
*contains* that import string, so the host has no way of knowing what that
import should be relative *to*.

That's easy to fix. We have the VM pass in the name of the module that contains
the import.

The harder problem is **canonicalization**. When you import the same module
twice, the VM ensures it is only executed once and both places use the same
module data. This is important to ensure you don't get confusing things like
duplicate static state or other weird side effects.

To do that, the VM needs to be able to tell when two imports refer to the "same"
module. Right now, it uses the import string itself. If two imports use the same
string, they are the same module.

With relative imports, that is no longer valid. Consider:

```text
script_a.wren
useful_stuff/
  thing_1.wren
  thing_2.wren
```

Now imagine those files contain:

```scala
// script_a.wren
import "useful_stuff/thing_1"
import "useful_stuff/thing_2"

// useful_stuff/thing_1.wren
import "thing_2"

// useful_stuff/thing_2.wren
// Stuff...
```

Both `script_a.wren` and `thing_1` import `thing_2`, but the import *strings*
are different. The VM needs to be able to figure out that those two imports
refer to the same module. I don't want path manipulation logic in the VM, so it
will delegate to the host app for that as well.

Given the import string and the name of the module containing it, the host app
produces a "fully-qualified" or "canonical" name for the imported module. It is
*that* resulting string that the VM uses to tell if two imports resolve to the
same module. (It's also the string it uses in things like stack traces.)

This means importing becomes a three stage process:

1.  First the VM asks the host to resolve an import. It gives it the (previously
    resolved) name of the module containing the import, the imports string, and
    whether or not it was quoted. The host app returns a canonical string for
    that import.

2.  The VM checks to see if a module with that canonical name has already been
    imported. If so, it reuses that and its done.

3.  Otherwise, it circles back and asks the host for the source of the module
    with that given canonical name. It compiles and executes that and goes from
    there.

So we add a new callback to the embedding API. Something like:

```c
char* resolveModuleFn(WrenVM* vm,
    // Canonical name of the module containing the import.
    const char* importer,

    // The import string.
    const char* path,

    // Whether the path name was quoted.
    bool isQuoted);
```

The VM invokes this for step one above. The other two steps are the existing
loading logic but now using the canonicalized string.

### CLI

All of the policy lives over in the CLI (or in your app if you are embedding the
VM). You are free to use whatever canonicalization policy makes sense for you.
For the CLI, and for the policy described up in motivation, it's something like
this:

*   Imports are slash-separated paths. Resolving a relative path is normal path
    joining relative to the directory containing the import. So if you're
    importing "a/b" from "c/d" (which is a file named "d.wren" in a directory
    "c"), then the canonical name is "c/a/b" and the file is "c/a/b.wren".

    ".." and "." are allowed and are normalized. So these imports all resolve
    to the same module:

    ```scala
    import "a/b/c"
    import "a/./b/./c"
    import "a/d/../b/c"
    ```

*   If an import is quoted, the path is considered relative to the importing
    module's path, and is in the same package as the importing module.

    So, if the current file is "a/b/c.wren" in package "foo" then these are
    equivalent:

    ```scala
    import "d/e"
    import foo/a/b/d/e
    ```

*   If an import is unquoted, the first identifier is the logical "package"
    containing the module, and the remaining components are the path within that
    package. The canonicalized string is the logical name, a colon, then the
    resolved full path to the import (without the ".wren" file extension).
    So if you import:

    ```scala
    import wrenalyzer/ast/expr
    ```

    The canonical name is "wrenalyzer:ast/expr".

*   If an import is a single unquoted name, the CLI implicitly uses the name as
    the module to look for within that package. These are equivalent:

    ```scala
    import foo
    import foo/foo
    ```

    We could use some default name like "module" instead of the package name,
    similar to Python, but I think this is actually a little more usable in
    practice. If you're hacking on a bunch of packages at the same time, it's
    annoying if every tab in your text editor just says "module.wren".

*   The canonicalized string for the main script or a module imported using a
    relative path from the main script is just the normalized file path,
    probably relative to the working directory.

*   Since colon is used to separate the name from path, path components with
    colons are not allowed.

### Finding logical imports

The last remaining piece is how the CLI physically locates logical imports. If
you write:

```scala
import foo
```

Where does it look for "foo"? Of course, if "foo" is built into the VM like
"random", then that's easy. Likewise, if it's built into the CLI like "io",
that's easy too.

Otherwise, it will try to find it on the file system. We don't have a package
manager yet, so we need some kind of simple policy so you can "hand-author" the
layout a package manager would produce. Borrowing from Node, the basic idea is
pretty simple.

To find a logical import, the CLI starts in the directory that contains the main
script (not the directory containing the module doing the import), and looks for
a directory named "wren_modules". If not found there, it starts walking up
parent directories until it finds one. If it does, it looks for the logical
import inside there. So, if you import "foo", it will try to find
"wren_modules/foo/foo.wren".

Once it finds a "wren_modules" directory, it uses that one directory for all
logical imports. You can't scatter stuff across multiple "wren_modules" folders
at different levels of the hierarchy. If it can't find a "wren_modules"
directory, or it can't find the requested module inside the directory, the
import fails.

This means that to reuse someone else's Wren "package" (or your own for that
matter), you can just stick a "wren_modules" directory next to the main script
for your app or in some parent directory. Inside that "wren_modules" directory,
copy in the package you want to reuse. If that package in turn uses other
packages, copy those into the *same* "wren_modules" directory. In other words,
the transitive dependencies get flattened. This is important to handle shared
dependencies between packages without duplication.

You only need to worry about all of this if you actually have logical imports.
If you just have a couple of files that import each other, you can use straight
relative imports and everything just works.

## Migration

OK, that's the plan. How do we get there? I've start hacking on the
implementation a little and, so far, it seems straightforward. Honestly, it will
probably take less time than I spent writing this up.

The tricky part is that this is a breaking change. All of your existing quoted
import strings will mean something different. We definitely *can* and will make
breaking changes in Wren, so that's OK, but I'd like to minimize the pain. Right
now, Wren is currently at version 0.1.0. I'll probably consider the commit right
before I start landing this to be the "official" 0.1.0 release and then the
import changes will land in "0.2.0". I'll work in a branch off main until
everything looks solid and then merge it in.

If you have existing Wren code that you run on the CLI and that contains
imports, you'll probably need to tweak them.

If you are hosting Wren in your own app, the imports are fine since your app
has control over how they resolve. But you will have to fix your app a little
since the import embedding API is going to change to deal with canonicalization.
I think I can make it so that if you don't provide a canonicalization callback,
then the original import string is treated as the canonical string and you
fall back to the current behavior.

## Alternatives

Having both quoted and unquoted import strings is a little funny, but it's the
best I could come up with. For what it's worth, I [borrowed it from
Racket][racket].

[racket]: https://docs.racket-lang.org/guide/module-basics.html

I considered a couple of other ideas which are potentially on the table if
most of you don't dig the main proposal:

### Node-style

In Node, [all imports are quoted][node]. To distinguish between relative and
logical imports, relative imports always start with "./". In Wren, it would be:

[node]: https://nodejs.org/api/modules.html

```scala
import "./something/relative"
import "logical/thing"
```

This is simpler than the main proposal since there are no syntax changes and we
don't need to push the "was quoted?" bit through the embedding API. But I find
the "./" pretty unintuitive especially if you're not steeped in the UNIX
tradition. Even if you are, it's weird that you *need* to use "./" when it means
nothing to the filesystem.

### Unquoted identifiers

The other idea I had was to allow both an unquoted identifier and a quoted
path, like:

```scala
import wrenalyzer "ast/expr"
```

The unquoted name is the logical part — the package name. The quoted part is
the path within that logical package. If you omit the unquoted name, it's a
straight relative import. If you have a name but no path, it's desugars to use
the name as the path.

This is a little more complex because we have to pass around the name and path
separately between the VM and the host app during canonicalization. If we want
the canonicalized form to keep those separate as well, then the way we keep
track of previously-loaded modules needs to get more complex too. Likewise the
way we show stack traces, etc.

The main proposal gloms everything into a single string using ":" to separate
the logical name part from the path. That's a little arbitrary, but it keeps
the VM a good bit simpler and means the idea of there being a "package name" is
pure host app policy.


================================================
FILE: doc/site/blog/0-hello-wren.markdown
================================================
^title Hello Wren
4 Feb 2019

---

Welcome to the new Wren development blog!

Around November 2018 on the Wren mailing list, munificent announced that a new maintainer is taking over the development and maintainence of the Wren language. [The original post is here, with all the details.](https://groups.google.com/forum/#!topic/wren-lang/cMUwij-NIn0)

In short, [I'm (ruby0x1)](https://github.com/ruby0x1) taking over from [Bob (munificent)](https://github.com/munificent) as maintainer, but Bob is sticking around as a contributor!

### The Wren blog

One of the first things I felt Wren needed going forward is a consistent and centralized place to talk about the language. The existing design choices and goals, and especially the future and evolution of Wren are something a lot of people want to read about, in detail. Now we have a place to do exactly that!

The blog will be keeping in the spirit of Wren by remaining simple. Posts are just regular markdown files in the repository alongside the rest of the site, and are considered part of the documentation.

Since Wren as a project aims to help others learn, having the in depth thought processes, development details and technical intricacy be documented in the same place, over a timeline, is valuable.

### What's next for Wren?

First and foremost, I wanted to state explicitly that **Wren is going to be changing** but it is **not going to become something else**. 

Wren attracted me as a language because of what it _is_, not because it isn't {_other language_}. If I wanted to use {_other language_} I would have, but I chose Wren because I wanted what it was. 

So, Wren is going to be changing in ways that align with it's existing design intentions. Staying small, simple, learnable and hackable is all vital to what makes Wren valuable, and will remain. 

We're just as excited as you are to get to longer term changes and fun tweaks (we have lots of work done already in local projects like [the debugger](https://i.imgur.com/dazexnY.gifv)). There's plenty of ideas we've tried since we've been [using Wren full time](https://luxeengine.com) the last 2.5+ years, and can't wait to get started with bring those into the main branch (and optional modules). There's a lot to do!

In the next blog I want to try talk a bit more about the short to medium term goals and roadmap (rather than mixing it here with the meta/hello world post). Be sure to keep an eye out for that one, as it has more juicy details on what we're gonna get up to.

There are immediate term goals, though.

### First steps

I think it's important to reset the baseline before we shake things up too much. Think of it as a ramp up to gain momentum, rather than running into a china store with arms flailing. 

- We're gonna clear out a bit of backlog, tidying up issues and PRs
- Tidy up the website a bit, visually and structurally
- Make sure all documentation is up to date with the current development
- Tag 0.2.0 with a list of relevant changes since 0.1.0

Once we tag 0.2.0, we'll be in a good place to move forward. And, everything up until now will have a well defined checkpoint preserved, if people want to refer to it.

### Steps so far

Since the announcement and transition, I've been making my way through all the mailing list posts, issues and PRs in the backlog and reading all the way back to the early days. 

I've also been talking to community members one on one and getting personal experiences and thoughts on Wren. Forming a full picture will help us since we'll have an overview of what's most relevant (and what isn't) as time has passed, and gives us actionable things to do for the next milestone. I think it's an important step. 

We've also been investigating some of the PRs with the community to get those sorted out, since they're in the way.

Lastly, I've already done a bit of clean up on the website and documentation theme, added a new logo, and of course added the blog.

### Thanks!

Lastly, I wanted to say thanks to munificent, the community and all the contributors that have made Wren possible to this point. It's a wonderful thing and I look forward to seeing where we take it, together.

I hope you'll join us on the journey!

### More

- [The Wren Blog RSS](http://wren.io/blog/rss.xml)
- Join the [discord community](https://discord.gg/Kx6PxSX)
- Visit the [wren-lang organization](https://github.com/wren-lang) on GitHub.
- Follow [@munificentbob](https://twitter.com/munificentbob) or [@ruby0x1](https://twitter.com/ruby0x1) on twitter





================================================
FILE: doc/site/blog/1-0.2.0-and-beyond.markdown
================================================
^title 0.2.0 and beyond
30 Sep 2019

---

### 0.2.0 is here

It's time to tag a release!
Let's check our goals from [the last blog post](0-hello-wren.html):

- <s>We're gonna clear out a bit of backlog, tidying up issues and PRs</s>
- <s>Tidy up the website a bit, visually and structurally</s>
- <s>Make sure all documentation is up to date with the current development</s>
- <s>Tag 0.2.0 with a list of relevant changes since 0.1.0</s>

So far so good.

### Backlog

Clearing out the issues on a repo after some time has passed is always a bit tricky. 

Many issues are outdated (or unrelated), and some need a proper response. Some are related to future ideals, things that will take a while to get to. Some are related to the Wren CLI. It can be difficult to reason about the state of the tasks when they're all over the place, so we've been consolidating.

The good news is the issue list has been drastically reduced, 70+ issues being closed (or resolved). Around 21 of those are marked for future consideration, and 23 moved to the Wren CLI repository. More consolidation will still continue.

**The goal is that the active issues are as relevant as possible in the immediate term.**

A tricky but important aspect to mention here is the perception of closing an issue...
A closed issue doesn't necessarily mean anything final, it's just a categorization tool!

The other categorization tool which operates _within_ open/closed categories, is the _label_. Labels allow us to distinguish clearly the different types of issues, which makes open/closed less binary and more nuanced and rich. We rely on both to make sense of the list.

For example, discussions of future tasks, ideas or goals [are tagged `future`](https://github.com/wren-lang/wren/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3Afuture+). Now we can refer to them later, and re-open them when they become active and relevant again.

**We're in this together.**   
Please don't be discouraged if an issue is closed! Discussion is absolutely encouraged and ideas, proposals and input is very necessary. Feel free to keep a discussion going, even if the issue it's attached to has been marked as closed.

### 0.2.0

We've been hammering away on Wren since 0.1.0 for quite a while. The [change list on GitHub](https://github.com/wren-lang/wren/compare/0.1.0...5338275dcdd97fd8d9fc614f420a645500836a59) is too long to display!

Most importantly, before we start iterating on the language further, I wanted to make sure we had a checkpoint to look back to. That's largely what 0.2.0 is about.

There's quite a lot of good changes, with **290 commits from 41 contributors!**
Thanks to everyone getting involved, every little bit has helped Wren, no matter how small the contribution.

### 0.3.0

With 0.2.0 wrapped up, our next release won't be as far away this time.

**The primary goal for 0.3.0 is separating the VM from the CLI.**

This includes updated documentation, splitting the source repos, migrating all the tests, issues and more.
All the code and documentation will still be easy to access in one place, but clarity around Wren as a project will improve a lot.

The migration has already started, you can [find the wren-cli repository here](https://github.com/wren-lang/wren-cli).
I'm working on some of the refactoring on the [wren-cli-refactor branch.](https://github.com/wren-lang/wren/tree/wren-cli-refactor)

With that, we'll also have a cleaner build process for the CLI.
On some platforms (Windows especially), there have been several pain points, these will be addressed.
There's also gonna be an additional build target, namely emscripten, so we can easily run Wren examples on the Wren website and documentation.

And finally, we'll have some proper prebuilt releases with 0.3.0.
I know many people have just wanted to grab an executable and give the language a go, but that hasn't been an option.
We'll fix that with 0.3.0.

The 0.3.0 goals in simple form:
- VM / CLI split
- Build consistency/reliablity
- Web build for embedding in docs
- Prebuilt releases

### Beyond

I don't have any concrete plans for 0.4.0 right now, but once the dust settles from 0.3.0 we'll have a clearer view.

There's definitely things in the pipeline though, I've been playing with [adding compound assignments like `+=`](https://github.com/wren-lang/wren/pull/701).

More details about in development features and fixes can be found on the repo in the meantime.

Thanks for reading!

### More

- [The Wren Blog RSS](http://wren.io/blog/rss.xml)
- Join the [discord community](https://discord.gg/Kx6PxSX)
- Visit the [wren-lang organization](https://github.com/wren-lang) on GitHub to get involved.
- Follow the developers [@munificentbob](https://twitter.com/munificentbob) or [@ruby0x1](https://twitter.com/ruby0x1) on twitter





================================================
FILE: doc/site/blog/2-0.3.0-released.markdown
================================================
^title 0.3.0 released!
5 June 2020

---

In this post we'll cover 0.3.0 and the goals for 0.4.0 [#](#goals-for-0.4.0).

## About the 0.3.0 release

Let's revisit our goals from [the last blog post](1-0.2.0-and-beyond.html),   
and mark what we managed to get done:

- <s>VM / CLI split</s> [#](#vm--cli-split)
- <s>Build consistency/reliablity</s> [#](#build-consistencyreliability)
- <s>Web build for embedding in docs</s> [#](#web-build-for-embedding-in-docs)
- <s>Prebuilt releases</s> [#](#prebuilt-releases)

## The details

### VM / CLI split

With 0.3.0 we've separated the CLI from the Wren repo,
and updated the docs to make the distinction clearer.

The [CLI now has its own corner of the docs](../cli), so that the modules
and API docs aren't overlapped like before. This opens up space for the
CLI to get better, fuller documentation, and removes confusion about
built in modules vs ones that are in the CLI only.

The code structure is clearer, too, and all the tests and utils are now specific.

### Build consistency/reliability

Previously, builds on Windows could be a little fickle, and there was sometimes
issues with the dependencies on the CLI side.

To solve this, premake is now used to generate platform specific project files that
'just work', making it a one step process to build the VM or CLI. Both projects
now have a `projects/` folder which includes ready to go project files for primary platforms.

<small>The original `Makefile` and `util/wren.mk` no longer exist, so there might be some work needed
to reintegrate if you relied on those. You can find the updated makefile in `projects/make/`, or `projects/make.mac/`.</small>

The **amalgamated build** was fixed too, so that embedding in your own project is as simple as
including a single c file (and the `wren.h` header).

On the **CLI** side, the pre-build steps were removed and dependencies vendored in repo,
so that the project just builds with less potential points of error, especially across platforms.

And finally the **docs**! Previously [SASS](https://sass-lang.com/) was used, and code highlighting
was done at generation time using pygments, a python code highlighter. Both of these dependencies
have been removed, code highlighting is now done on the client side instead (see another reason why below).
The benefit here that it is now _easy_ to edit the docs, just a simple python command, no setup!

### Web build for embedding in docs
The goal was two part here, one is to have a page to just try out Wren.
Type in some code, run it. That's the first big step and we've now got that on the docs page.

<h4><a href="../try" target="_blank" class="dark-link">Try Wren directly in your browser!</a></h4>
This should work on desktop or mobile, and will continue to be improved over time.

The second part of that goal is having the VM available to make examples on each page interactive.
This is implemented, _but not activated on any pages yet_.

In the near future inline doc examples will have a small button that you can 
press to see the code result right there, live. Since there's a lot of examples,
and sometimes they're fragments of code that don't run in isolation,
it will take time to propagate it through the pages.

Mainly, I didn't want this to hold up 0.3.0, but expect to start seeing it soon.

### Prebuilt releases
In addition to the browser based build that removes a barrier to trying out Wren,
Wren CLI has prebuilt binaries for Mac, Windows and Linux now! This gives
an easy path to just tinkering with Wren before embedding it.

---

## Goals for 0.4.0

With 0.4.0 the goal is to address a couple of bigger todos, but also to push the language
itself, and the embedding experience forward.

You can see some of the [work in progress tasks](https://github.com/wren-lang/wren/pulls?q=is%3Apr+is%3Aopen+label%3A0.4.0) here, 
but there's a few things I'd like to resolve in 0.4.0.

**Compound operators**   
I've really missed having `+=` and friends,   
so I've been working on a (broken, wip) [PR here](https://github.com/wren-lang/wren/pull/701).
I've since had a better idea to implement it and will hope to address that in 0.4.0.

**Chained methods ('fluent interfaces')**   
Currently in Wren it's required that the period (`.`) be on the same line as the method.
<pre class="snippet">
  example.
    some().
    functions().
    here()
</pre>
This isn't as elegant as we'd want for this form of API,
so **in 0.4.0 the goal is** allowing a newline, as you'd expect:
<pre class="snippet">
  example
    .some()
    .functions()
    .here()
</pre>
This doesn't seem like a big deal but when your calls are wider,
longer and possibly accept block functions. It's hard to read,
and can be less fun to track down a missing `.` in a big chunk of code.
<pre class="snippet">
  example.
    some {|args, and, stuff|
      ...
    }.
    here()
</pre>

**C Side APIs**   
Some APIs for dealing with `Map` have been proposed several times,
it's time to bring that into the API. There's some additions for `List` as well,
like a helper to set an element in a list.

**Other goals**   
There's a few more things but I'm still exploring their viability.   
Keep an eye on the [PRs/issues](https://github.com/wren-lang/wren) or the [0.4.0 label](https://github.com/wren-lang/wren/pulls?q=is%3Apr+is%3Aopen+label%3A0.4.0) to see when they're discussed.

## Till next time

---

- [The Wren Blog RSS](http://wren.io/blog/rss.xml)
- Join the [discord community](https://discord.gg/Kx6PxSX)
- Visit the [wren-lang organization](https://github.com/wren-lang) on GitHub to get involved.
- Follow the developers [@munificentbob](https://twitter.com/munificentbob) or [@ruby0x1](https://twitter.com/ruby0x1) on twitter


================================================
FILE: doc/site/blog/3-0.4.0-released.markdown
================================================
^title 0.4.0 released!
8 April 2021

---

This post is all about the 0.4.0 release since it's a big one!   
<small>(A separate post for 0.5.0 goals would likely come later.)</small>

## 0.4.0 details

**0.4.0 contains 145 commits from 28 contributors.**

The [full release notes](https://github.com/wren-lang/wren/releases/tag/0.4.0)
link to each PR or commit, and contains a lot more details than this post.

**Goals**   
As usual, let's revisit the goals from the [0.3.0 post](2-0.3.0-released.html#goals-for-0.4.0).

Most importantly - compound operators didn't land in 0.4.0 for various reasons.
Still working on it, it's just a fun and nuanced problem and I don't want to
keep 0.4.0 back cos of it.

With that out the way, let's see what 0.4.0 contains! 

## 0.4.0 highlights

Below we'll highlight some key features, fixes and improvements from the release. 

**A lot of work came from the community, much thanks to everyone contributing!**

You can find all the details and the contributions in the [release notes](https://github.com/wren-lang/wren/releases/tag/0.4.0).

**Take note!** There are two minor breaking changes in the API on the release notes. 

--- 

### Bug fixes

Several important bugs have been fixed, sneaky stack corruptions and some user
experience fixes that clarify confusing states. 

### Documentation

A lot of work has gone into documentation this release, revising, fixing, adding
and closing gaps that were left. For example, Wren supports multi-line strings 
but this was never mentioned anywhere! 

### New **continue** keyword

Loops can now use continue, which is a welcome addition.

### New **as** keyword

You can now use `import "..." for Name as OtherName` to avoid name conflicts,
or to use aliases/shorthand for imported variables.

### Raw strings

Wren now supports triple quotes for a string `"""`.

This type of string is only unique in how it's parsed, the content of the 
string is ignored (no interpolation or escapes are processed), which allows 
complex strings to be expressed without needing to escape things. 

A common example is json or regex, where there's a lot of escaping that obscures
the string content and makes it hard to read and maintain. 

If they span multiple lines, the string ignores the open and closing newlines 
and whitespace and preserves anything in between.

<pre class="snippet">
var json = """
  {
    "hello": "wren",
    "from" : "json"
  }
"""
</pre>

### Attributes

Attributes are user-defined metadata associated with a class or method that
can be used at runtime, by external tools (and potentially by Wren itself).

<pre class="snippet">
#hidden = true
#doc = "A simple example class"
class Example {}
</pre>

They can be:

- a `#key` on it's own
- a `#key = value`
- a `#group(with, multiple = true, keys = "value")`

**Example**   

Below you can one obvious use case, a wip version where attributes for docs were 
parsed and sent over to [vscode](https://code.visualstudio.com/) to display.

<video preload="auto" controls="" loop="loop" style="max-width:100%; width:auto; margin:auto; display:block;">  
    <source src="https://i.imgur.com/W9DWysP.mp4" type="video/mp4">
</video>

**Runtime access**   
By default, attributes are compiled out and ignored.
For an attribute to be visible at runtime, mark it for runtime access using an 
exclamation:

<pre class="snippet">
#doc = "not runtime data"
#!runtimeAccess = true
#!maxIterations = 16
</pre>

Attributes at runtime are stored on the class itself. You can access them via 
`YourClass.attributes`. If any attributes are made available, they'll be found here:

- `YourClass.attributes.self` for the class attributes
- `YourClass.attributes.methods` for the method attributes

All the details for [Attributes can be found here](https://wren.io/classes.html#attributes).

### Chained methods fixes ('fluent interfaces')

Mentioned in the last post, you can now use this pattern in code as intended, 
the same-line requirement for the `.` has been removed.

<pre class="snippet">
  example
    .some()
    .functions()
    .here()
</pre>

### List additions

Lists are now sortable via `list.sort()` and `list.sort {|a, b| ... }`.
You can find an index of something via `list.indexOf(value)`, and remove a value
via `list.remove(value)`. There's also `list.swap(index0, index1)` for moving 
items around within a list.

For the API, `wrenSetListElement` now exists, and both set and
`wrenGetListElement` now accept negative indices same as the language side.

### Num additions

A few new constants:

- `Num.tau`
- `Num.nan` 
- `Num.infinity`
- `Num.minSafeInteger`/`Num.maxSafeInteger`

And some new methods on a number:

- `num.min(other)`
- `num.max(other)`
- `num.clamp(min, max)`
- `num.cbrt`
- `num.exp`
- `num.log2`

### Map access from the API 

You can now create and access maps from the API:

- `wrenSetSlotNewMap`
- `wrenGetMapCount`
- `wrenGetMapContainsKey`
- `wrenGetMapValue`
- `wrenSetMapValue`
- `wrenRemoveMapValue`

## Till next time

---

- [The Wren Blog RSS](http://wren.io/blog/rss.xml)
- Join the [discord community](https://discord.gg/Kx6PxSX)
- Visit the [wren-lang organization](https://github.com/wren-lang) on GitHub to get involved.
- Follow the developers [@munificentbob](https://twitter.com/munificentbob) or [@ruby0x1](https://twitter.com/ruby0x1) on twitter


================================================
FILE: doc/site/blog/index.markdown
================================================
^title Development blogs

[<h3>0.4.0 released!</h3>](3-0.4.0-released.html)
> <date>8 April 2021</date> • 0.4.0 is a big release, here's all the info! 

[<h3>0.3.0 released!</h3>](2-0.3.0-released.html)
> <date>5 June 2020</date> • 0.3.0 release info! Plus some notes and goals for the next release, 0.4.0.

[<h3>0.2.0 and beyond</h3>](1-0.2.0-and-beyond.html)
> <date>30 Sep 2019</date> • Checkpoints, and the plans for 0.3.0.

[<h3>System.print("hello wren")</h3>](0-hello-wren.html)
> <date>4 Feb 2019</date> • A short post introducing the blog, the new maintainer, and the immediate term plans for Wren.




================================================
FILE: doc/site/blog/rss.xml
================================================
<rss version="2.0">
  <channel><title>Wren - development blog</title>
    <link>https://wren.io/</link>
    <description>The development blog of the Wren programming language.</description>
    <language>en-us</language>
    <item>
      <title>0.4.0 released</title>
      <link>https://wren.io/blog/3-0.4.0-released.html</link>
      <description>0.4.0 is a big release, here's all the info!</description>
      <guid>https://wren.io/blog/3-0.4.0-released.html</guid>
      <pubDate>Thu, 08 Apr 2021 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>0.3.0 released</title>
      <link>https://wren.io/blog/2-0.3.0-released.html</link>
      <description>0.3.0 release info! Plus some notes and goals for the next release, 0.4.0.</description>
      <guid>https://wren.io/blog/2-0.3.0-released.html</guid>
      <pubDate>Mon, 05 Jun 2020 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>0.2.0 and beyond</title>
      <link>https://wren.io/blog/1-0.2.0-and-beyond.html</link>
      <description>Checkpoints, and the plans for 0.3.0.</description>
      <guid>https://wren.io/blog/1-0.2.0-and-beyond.html</guid>
      <pubDate>Mon, 30 Sep 2019 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>System.print("hello wren")</title>
      <link>https://wren.io/blog/0-hello-wren.html</link>
      <description>A short post introducing the blog, the new maintainer, and the immediate term plans for Wren.</description>
      <guid>https://wren.io/blog/0-hello-wren.html</guid>
      <pubDate>Mon, 04 Feb 2019 00:00:00 GMT</pubDate>
    </item>
  </channel>
</rss>

================================================
FILE: doc/site/blog/template.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>{title} &ndash; Wren</title>
<script type="application/javascript" src="../prism.js" data-manual></script>
<script type="application/javascript" src="../wren.js"></script>
<link rel="stylesheet" type="text/css" href="../prism.css" />
<link rel="stylesheet" type="text/css" href="../style.css" />
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
     the viewport. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
</head>
<body id="top">
<header>
  <div class="page">
    <div class="main-column">
      <h1><a href="../">wren</a></h1>
      <h2>a classy little scripting language</h2>      
    </div>
  </div>
</header>
<div class="page">
  <nav class="big">
    <a href="../"><img src="../wren.svg" class="logo"></a>
    <ul>
      <li><a href="../getting-started.html">Getting Started</a></li>
      <li><a href="../contributing.html">Contributing</a></li>
      <li><a href="../blog">Blog</a></li>
      <li><a href="../try">Try it!</a></li>
    </ul>
  </nav>
  <nav class="small">
    <table>
      <tr>
        <td>
        <ul>
          <li><a href="../getting-started.html">Getting Started</a></li>
          <li><a href="../contributing.html">Contributing</a></li>
          <li><a href="../blog">Blog</a></li>
          <li><a href="../try">Try it!</a></li>
        </ul>
        </td>
      </tr>
    </table>
  </nav>
  <main>
    <h2>{title}</h2>
    {html}
  </main>
</div>
<footer>
  <div class="page">
    <div class="main-column">
    <p>Wren lives
      <a href="https://github.com/wren-lang/wren">on GitHub</a>
      &mdash; Made with &#x2764; by
      <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
      <a href="https://github.com/wren-lang/wren/blob/main/AUTHORS">friends</a>.
    </p>
    <div class="main-column">
  </div>
</footer>
</body>
</html>


================================================
FILE: doc/site/classes.markdown
================================================
^title Classes

Every value in Wren is an object, and every object is an instance of a class.
Even `true` and `false` are full-featured objects&mdash;instances of the
[Bool][] class.

[bool]: modules/core/bool.html

Classes define an objects *behavior* and *state*. Behavior is defined by
[*methods*][method calls] which live in the class. Every object of the same
class supports the same methods. State is defined in *fields*, whose values are
stored in each instance.

[method calls]: method-calls.html

## Defining a class

Classes are created using the `class` keyword, unsurprisingly:

<pre class="snippet">
class Unicorn {}
</pre>

This creates a class named `Unicorn` with no methods or fields.

## Methods

To let our unicorn do stuff, we need to give it methods.

<pre class="snippet">
class Unicorn {
  prance() {
    System.print("The unicorn prances in a fancy manner!")
  }
}
</pre>

This defines a `prance()` method that takes no arguments. To add parameters, put
their names inside the parentheses:

<pre class="snippet">
class Unicorn {
  prance(where, when) {
    System.print("The unicorn prances in %(where) at %(when).")
  }
}
</pre>

Since the number of parameters is part of a method's [signature][] a class can
define multiple methods with the same name:

[signature]: method-calls.html#signature

<pre class="snippet">
class Unicorn {
  prance() {
    System.print("The unicorn prances in a fancy manner!")
  }

  prance(where) {
    System.print("The unicorn prances in %(where).")
  }

  prance(where, when) {
    System.print("The unicorn prances in %(where) at %(when).")
  }
}
</pre>

It's often natural to have the same conceptual operation work with different
sets of arguments. In other languages, you'd define a single method for the
operation and have to check for missing optional arguments. In Wren, they are
different methods that you implement separately.

In addition to named methods with parameter lists, Wren has a bunch of other
different syntaxes for methods. Your classes can define all of them.

### Getters

A getter leaves off the parameter list and the parentheses:

<pre class="snippet">
class Unicorn {
  // Unicorns are always fancy.
  isFancy { true }
}
</pre>

### Setters

A setter has `=` after the name, followed by a single parenthesized parameter:

<pre class="snippet">
class Unicorn {
  rider=(value) {
    System.print("I am being ridden by %(value).")
  }
}
</pre>

By convention, the parameter is usually named `value` but you can call it
whatever makes your heart flutter.

### Operators

Prefix operators, like getters, have no parameter list:

<pre class="snippet">
class Unicorn {
  - {
    System.print("Negating a unicorn is weird.")
  }
}
</pre>

Infix operators, like setters, have a single parenthesized parameter for the
right-hand operand:

<pre class="snippet">
class Unicorn {
  -(other) {
    System.print("Subtracting %(other) from a unicorn is weird.")
  }
}
</pre>

A subscript operator puts the parameters inside square brackets and can have
more than one:

<pre class="snippet">
class Unicorn {
  [index] {
    System.print("Unicorns are not lists!")
  }

  [x, y] {
    System.print("Unicorns are not matrices either!")
  }
}
</pre>

Unlike with named methods, you can't define a subscript operator with an empty
parameter list.

As the name implies, a subscript setter looks like a combination of a subscript
operator and a setter:

<pre class="snippet">
class Unicorn {
  [index]=(value) {
    System.print("You can't stuff %(value) into me at %(index)!")
  }
}
</pre>

## Method Scope

Up to this point, "[scope][]" has been used to talk exclusively about
[variables][]. In a procedural language like C, or a functional one like Scheme,
that's the only kind of scope there is. But object-oriented languages like Wren
introduce another kind of scope: *object scope*. It contains the methods that
are available on an object. When you write:

[scope]: variables.html#scope
[variables]: variables.html

<pre class="snippet">
unicorn.isFancy
</pre>

You're saying "look up the method `isFancy` in the scope of the object
`unicorn`&rdquo;. In this case, the fact that you want to look up a *method*
`isFancy` and not a *variable* `isFancy` is explicit. That's what `.` does and
the object to the left of the period is the object you want to look up the
method on.

### `this`

Things get more interesting when you're inside the body of a method. When the
method is called on some object and the body is being executed, you often need
to access that object itself. You can do that using `this`.

<pre class="snippet">
class Unicorn {
  name { "Francis" }

  printName() {
    System.print(this.name) //> Francis
  }
}
</pre>

The `this` keyword works sort of like a variable, but has special behavior. It
always refers to the instance whose method is currently being executed. This
lets you invoke methods on "yourself".

It's an error to refer to `this` outside of a method. However, it's perfectly
fine to use it inside a [function][] declared *inside* a method. When you do,
`this` still refers to the instance whose *method* is being called:

<pre class="snippet">
class Unicorn {
  name { "Francis" }

  printNameThrice() {
    (1..3).each {
      // Use "this" inside the function passed to each().
      System.print(this.name) //> Francis
    } //> Francis
  } //> Francis
}
</pre>

[function]: functions.html

This is unlike Lua and JavaScript which can "forget" `this` when you create a
callback inside a method. Wren does what you want here and retains the
reference to the original object.

(In technical terms, a function's closure includes `this`. Wren can do this
because it makes a distinction between methods and functions.)

### Implicit `this`

Using `this.` every time you want to call a method on yourself works, but it's
tedious and verbose, which is why some languages don't require it. You can do a
"self send" by calling a method (or getter or setter) without any explicit
receiver:

<pre class="snippet">
class Unicorn {
  name { "Francis" }

  printName() {
    System.print(name) //> Francis
  }
}
</pre>

Code like this gets tricky when there is also a variable outside of the class
with the same name. Consider:

<pre class="snippet">
var name = "variable"

class Unicorn {
  name { "Francis" }

  printName() {
    System.print(name) // ???
  }
}
</pre>

Should `printName()` print "variable" or "Francis"? A method body has a foot in
each of two worlds. It is surrounded by the lexical scope where it's defined in
the program, but it also has the object scope of the methods on `this`.

Which scope wins? Every language has to decide how to handle this and there
is a surprising plethora of approaches. Wren's approach to resolving a name
inside a method works like this:

1.  If there is a local variable inside the method with that name, that wins.
2.  Else, if the name starts with a lowercase letter, treat it like a method on
    `this`.
3.  Otherwise, look for a variable with that name in the surrounding scope.

So, in the above example, we hit case #2 and it prints "Francis". Distinguishing
self sends from outer variables based on the *case* of the first letter in the
name probably seems weird but it works surprisingly well. Method names are
lowercase in Wren. Class names are capitalized.

Most of the time, when you're in a method and want to access a name from outside
of the class, it's usually the name of some other class. This rule makes that
work.

Here's an example that shows all three cases:

<pre class="snippet">
var shadowed = "surrounding"
var lowercase = "surrounding"
var Capitalized = "surrounding"

class Scope {
  shadowed { "object" }
  lowercase { "object" }
  Capitalized { "object" }

  test() {
    var shadowed = "local"

    System.print(shadowed) //> local
    System.print(lowercase) //> object
    System.print(Capitalized) //> surrounding
  }
}
</pre>

It's a bit of a strange rule, but Ruby works more or less the same way.

## Constructors

We've seen how to define kinds of objects and how to declare methods on them.
Our unicorns can prance around, but we don't actually *have* any unicorns to do
it. To create *instances* of a class, we need a *constructor*. You define one
like so:

<pre class="snippet">
class Unicorn {
  construct new(name, color) {
    System.print("My name is " + name + " and I am " + color + ".")
  }
}
</pre>

The `construct` keyword says we're defining a constructor, and `new` is its
name. In Wren, all constructors have names. The word "new" isn't special to
Wren, it's just a common constructor name.

To make a unicorn now, we call the constructor method on the class itself:

<pre class="snippet">
var fred = Unicorn.new("Fred", "palomino")
</pre>

Giving constructors names is handy because it means you can have more than one,
and each can clarify how it creates the instance:

<pre class="snippet">
class Unicorn {
  construct brown(name) {
    System.print("My name is " + name + " and I am brown.")
  }
}

var dave = Unicorn.brown("Dave")
</pre>

Note that we have to declare a constructor because, unlike some other
languages, Wren doesn't give you a default one. This is useful because some
classes aren't designed to be constructed. If you have an abstract base class
that just contains methods to be inherited by other classes, it doesn't need
and won't have a constructor.

Like other methods, constructors can obviously have arguments, and can be
overloaded by [arity](#signature). A constructor *must* be a named method with
a (possibly empty) argument list. Operators, getters, and setters cannot be
constructors.

A constructor returns the instance of the class being created, even if you 
don't explicitly use `return`. It is valid to use `return` inside of a 
constructor, but it is an error to have an expression after the return.
That rule applies to `return this` as well, return handles that implicitly inside
a constructor, so just `return` is enough.

<pre class="snippet">
return          //> valid, returns 'this'

return variable //> invalid
return null     //> invalid
return this     //> also invalid
</pre>

A constructor is actually a pair of methods. You get a method on the class:

<pre class="snippet">
Unicorn.brown("Dave")
</pre>

That creates the new instance, then it invokes the *initializer* on that
instance. This is where the constructor body you defined gets run.

This distinction is important because it means inside the body of the
constructor, you can access `this`, assign [fields](#fields), call superclass
constructors, etc.

## Fields

All state stored in instances is stored in *fields*. Each field has a name
that starts with an underscore.

<pre class="snippet">
class Rectangle {
  area { _width * _height }

  // Other stuff...
}
</pre>

Here, `_width` and `_height` in the `area` [getter](classes.html#methods) refer
to fields on the rectangle instance. You can think of them like `this.width`
and `this.height` in other languages.

When a field name appears, Wren looks for the nearest enclosing class and looks
up the field on the instance of that class. Field names cannot be used outside
of an instance method. They *can* be used inside a [function](functions.html)
in a method. Wren will look outside any nested functions until it finds an
enclosing method.

Unlike [variables](variables.html), fields are implicitly declared by simply
assigning to them. If you access a field before it has been initialized, its
value is `null`.

### Encapsulation

All fields are *private* in Wren&mdash;an object's fields can only be directly
accessed from within methods defined on the object's class. 

In short, if you want to make a property of an object visible,
**you need to define a getter to expose it**:

<pre class="snippet">
class Rectangle {
  width { _width }
  height { _height }

  // ...
}
</pre>

To allow outside code to modify the field,
**you need to provide setters to provide access**:

<pre class="snippet">
class Rectangle {
  width=(value) { _width = value }
  height=(value) { _height = value }
}
</pre>

This might be different from what you're used to, so here are two important facts:

- You can't access fields from a base class.
- You can't access fields on another instance of your own class.

Here is an example in code:

<pre class="snippet">
class Shape {
  construct new() {
    _shape = "none"
  }
}

class Rectangle is Shape {
  construct new() {
    //This will print null!
    //_shape from the parent class is private,
    //we are reading `_shape` from `this`,
    //which has not been set, so returns null.
    System.print("I am a %(_shape)")

    //a local variable, all variables are private
    _width = 10
    var other = Rectangle.new()

    //other._width is not accessible from here,
    //even though we are also a rectangle. The field
    //is private, and other._width is invalid syntax!
  }
}
...
</pre>

One thing we've learned in the past forty years of software engineering is that
encapsulating state tends to make code easier to maintain, so Wren defaults to
keeping your object's state pretty tightly bundled up. Don't feel that you have
to or even should define getters or setters for most of your object's fields.

## Metaclasses and static members

**TODO**

### Static fields

A name that starts with *two* underscores is a *static* field. They work
similar to [fields](#fields) except the data is stored on the class itself, and
not the instance. They can be used in *both* instance and static methods.

<pre class="snippet">
class Foo {
  construct new() {}

  static setFromStatic(a) { __a = a }
  setFromInstance(a) { __a = a }

  static printFromStatic() {
    System.print(__a)
  }

  printFromInstance() {
    System.print(__a)
  }
}
</pre>

Just like instance fields, static fields are initially `null`:

<pre class="snippet">
Foo.printFromStatic() //> null
</pre>

They can be used from static methods:

<pre class="snippet">
Foo.setFromStatic("first")
Foo.printFromStatic() //> first
</pre>

And also instance methods. When you do so, there is still only one static field
shared among all instances of the class:

<pre class="snippet">
var foo1 = Foo.new()
var foo2 = Foo.new()

foo1.setFromInstance("second")
foo2.printFromInstance() //> second
</pre>

## Inheritance

A class can inherit from a "parent" or *superclass*. When you invoke a method
on an object of some class, if it can't be found, it walks up the chain of
superclasses looking for it there.

By default, any new class inherits from Object, which is the superclass from
which all other classes ultimately descend. You can specify a different parent
class using `is` when you declare the class:

<pre class="snippet">
class Pegasus is Unicorn {}
</pre>

This declares a new class Pegasus that inherits from Unicorn.

Note that you should not create classes that inherit from the built-in types
(Bool, Num, String, Range, List). The built-in types expect their internal bit
representation to be very specific and get horribly confused when you invoke one
of the inherited built-in methods on the derived type.

The metaclass hierarchy does *not* parallel the regular class hierarchy. So, if
Pegasus inherits from Unicorn, Pegasus's metaclass does not inherit from
Unicorn's metaclass. In more prosaic terms, this means that static methods are
not inherited.

<pre class="snippet">
class Unicorn {
  // Unicorns cannot fly. :(
  static canFly { false }
}

class Pegasus is Unicorn {}

Pegasus.canFly //! Static methods are not inherited.
</pre>

This also means constructors are not inherited:

<pre class="snippet">
class Unicorn {
  construct new(name) {
    System.print("My name is " + name + ".")
  }
}

class Pegasus is Unicorn {}

Pegasus.new("Fred") //! Pegasus does not define new().
</pre>

Each class gets to control how it may be constructed independently of its base
classes. However, constructor *initializers* are inherited since those are
instance methods on the new object.

This means you can do `super` calls inside a constructor:

<pre class="snippet">
class Unicorn {
  construct new(name) {
    System.print("My name is " + name + ".")
  }
}

class Pegasus is Unicorn {
  construct new(name) {
    super(name)
  }
}

Pegasus.new("Fred") //> My name is Fred
</pre>

## Super

**TODO: Integrate better into page. Should explain this before mentioning
super above.**

Sometimes you want to invoke a method on yourself, but using methods defined in
one of your [superclasses](classes.html#inheritance). You typically do this in
an overridden method when you want to access the original method being
overridden.

To do that, you can use the special `super` keyword as the receiver in a method
call:

<pre class="snippet">
class Base {
  method() {
    System.print("base method")
  }
}

class Derived is Base {
  method() {
    super.method() //> base method
  }
}
</pre>

You can also use `super` without a method name inside a constructor to invoke a
base class constructor:

<pre class="snippet">
class Base {
  construct new(arg) {
    System.print("base got " + arg)
  }
}

class Derived is Base {
  construct new() {
    super("value") //> base got value
  }
}
</pre>


## Attributes

<small>**experimental stage**: subject to minor changes</small>

A class and methods within a class can be tagged with 'meta attributes'.

Like this:

<pre class="snippet">
#hidden = true
class Example {}
</pre>

These attributes are metadata, they give you a way to annotate and store
any additional information about a class, which you can optionally access at runtime.
This information can also be used by external tools, to provide additional
hints and information from code to the tool.

<small>
Since this feature has just been introduced, **take note**.

**Currently** there are no attributes with a built-in meaning. 
Attributes are user-defined metadata. This may not remain 
true as some may become well defined through convention or potentially
through use by Wren itself. 
</small>

Attributes are placed before a class or method definition,
and use the `#` hash/pound symbol. 

They can be 

- a `#key` on it's own
- a `#key = value`
- a `#group(with, multiple = true, keys = "value")`

An attribute _key_ can only be a `Name`. This is the same type of name 
as a method name, a class name or variable name, an identifier that matches
the Wren identifier rules. A name results in a String value at runtime.

An attribute _value_ can be any of these literal values: `Name, String, Bool, Num`.
Values cannot contain expressions, just a value, there is no compile time 
evaluation.

Groups can span multiple lines, methods have their own attributes, and duplicate
keys are valid.

<pre class="snippet">
#key
#key = value
#group(
  multiple,
  lines = true,
  lines = 0
)
class Example {
  #test(skip = true, iterations = 32)
  doStuff() {}
}
</pre>

### Accessing attributes at runtime

By default, attributes are compiled out and ignored.

For an attribute to be visible at runtime, mark it for runtime
access using an exclamation:

<pre class="snippet">
#doc = "not runtime data"
#!runtimeAccess = true
#!maxIterations = 16
</pre>

Attributes at runtime are stored on the class. You can access them via 
`YourClass.attributes`. The `attributes` field on a class will 
be null if a class has no attributes or if it's attributes aren't marked.

If the class contains class or method attributes, it will be an object with
two getters:

- `YourClass.attributes.self` for the class attributes
- `YourClass.attributes.methods` for the method attributes

Attributes are stored by group in a regular Wren Map. 
Keys that are not grouped, use `null` as the group key.

Values are stored in a list, since duplicate keys are allowed, multiple
values need to be stored. They're stored in order of definition.

Method attributes are stored in a map by method signature, and each method
has it's own attributes that match the above structure. The method signature
is prefixed by `static` or `foreign static` as needed.

Let's see what that looks like:

<pre class="snippet">
// Example.attributes.self = 
// { 
//   null: { "key":[null] }, 
//   group: { "key":[value, 32, false] }
// }

#!key
#ignored //compiled out
#!group(key=value, key=32, key=false)
class Example {
  #!getter
  getter {}

  // { regular(_,_): { null: { regular:[null] } } }
  #!regular
  regular(arg0, arg1) {}

  // { static other(): { null: { isStatic:[true] } } }
  #!isStatic = true
  static other() {}
  
  // { foreign static example(): { null: { isForeignStatic:[32] } } }
  #!isForeignStatic=32
  foreign static example()
}
</pre>

<br><hr>
<a class="right" href="concurrency.html">Concurrency &rarr;</a>
<a href="functions.html">&larr; Functions</a>


================================================
FILE: doc/site/cli/index.markdown
================================================
^title Wren CLI

---

## What is it?

**The Wren Command-Line Interface** is a tool you can run which gives you a way to run Wren code, and
    also includes modules for talking to the operating system&mdash;file IO,
    networking, stuff like that. It depends on [libuv][] for that
    functionality.

Wren as a language is intentionally designed to be minimal.   
That includes the built in language features, the standard library and the VM itself.

In order to access files, networks and other IO, you'd need to make a tool _using_ the language VM. 
That's what the CLI project is! It is not bundled as part of the wren project,
instead it is its own project as a standalone tool you can run.
It exposes its own standard library and modules that may be of interest
if looking for a general purpose single binary scriptable tool.

Wren CLI is a work in progress, and contributions are welcome to make it more useful over time.

## Why does it exist?

- It's fun to make things.
- It's always a good idea to test the language you're making!
- Interest was expressed in a scriptable tool using the Wren language.
- It's helpful for others to learn from, since it is a real world usage example showing several concepts.

[libuv]: http://libuv.org/


================================================
FILE: doc/site/cli/modules/index.markdown
================================================
^title CLI Modules

The Wren CLI executable extends the built in language modules with its own,
which offer access to IO and other facilities for scripting.

The CLI modules are deeply tied to [libuv][], each other, and other internals
of the command-line app, so can't easily be separated out and pulled into host
applications that want to embed Wren. Scripts written for the CLI then,
are specific to the CLI unless another host implements the same API.

[libuv]: http://libuv.org

* [io](io)
* [os](os)
* [scheduler](scheduler)
* [timer](timer)


================================================
FILE: doc/site/cli/modules/io/directory.markdown
================================================
^title Directory Class

A directory on the file system.

## Static Methods

### Directory.**exists**(path)

Whether a directory exists at `path`. This returns `false` for files or other
special file system entities.

### Directory.**list**(path)

Lists the contents of the directory at `path`. Returns a sorted list of path
strings for all of the contents of the directory.


================================================
FILE: doc/site/cli/modules/io/file-flags.markdown
================================================
^title FileFlags Class

Contains constants for the various file flags used to open or create a file.
These correspond directly to the flags that can be passed to the POSIX
[`open()`][open] syscall.

[open]: http://linux.die.net/man/2/open

They are integers and can be bitwise or'ed together to produce a composite
flag.

## Static Methods

### FileFlags.**readOnly**

The file can be read from but not written. Equivalent to `O_RDONLY`.

### FileFlags.**writeOnly**

The file can be written but not read from. Equivalent to `O_WRONLY`.

### FileFlags.**readWrite**

The file can be both read from and written to. Equivalent to `O_RDWR`.

### FileFlags.**sync**

Writes will block until the data has been physically written to the underling
hardware. This does *not* affect whether or the file API is synchronous. File
operations are always asynchronous in Wren and may allow other scheduled fibers
to run.

This is a lower-level flag that ensures that when a write completes, it has
been flushed all the way to disc.

### FileFlags.**create**

Creates a new file if a file at the given path does not already exist.

### FileFlags.**truncate**

If the file already exists and can be written to, its previous contents are
discarded.

### FileFlags.**exclusive**

Ensures that a new file must be created. If a file already exists at the given
path, this flag will cause the operation to fail.


================================================
FILE: doc/site/cli/modules/io/file.markdown
================================================
^title File Class

Lets you work with files on the file system. An instance of this class
represents an open file with a file descriptor.

When you are done with a file object, it's a good idea to explicitly close it.
If you don't, the GC will close it when the file is no longer used and gets
finalized, but that may take a while. In the meantime, leaving it open wastes
a file descriptor.

## Static Methods

### File.**create**(path, fn)

Opens the file at `path` for writing and passes it to `fn`. If there is already
a file at that path, it is truncated. After the function returns, the file is
automatically closed.

<pre class="snippet">
File.create("numbers.txt") {|file|
  file.writeBytes("one two three")
}
</pre>

### File.**delete**(path)

Deletes the file at `path`.

### File.**exists**(path)

Whether a regular file exists at `path`. This returns `false` for directories
or other special file system entities.

### File.**open**(path, fn)

Opens the file at `path` for reading and passes it to `fn`. After the function
returns, the file is automatically closed.

<pre class="snippet">
File.open("words.txt") {|file|
  file.readBytes(5)
}
</pre>

### File.**read**(path)

Reads the entire contents of the file at `path` and returns it as a string.

<pre class="snippet">
File.read("words.txt")
</pre>

No encoding or decoding is done. If the file is UTF-8, then the resulting
string will be a UTF-8 string. Otherwise, it will be a string of bytes in
whatever encoding the file uses.

### File.**realPath**(path)

Resolves `path`, traversing symlinks and removining any unneeded `./` and `../`
components. Returns the canonical absolute path to the file.

<pre class="snippet">
var path = "/some/./symlink/a/../b/file.txt"
System.print(File.realPath(path)) //> /real/path/a/file.txt
</pre>

### File.**size**(path)

Returns the size in bytes of the contents of the file at `path`.

## Constructors

### File.**create**(path)

Opens the file at `path` for writing. If there is already a file at that path,
it is truncated.

<pre class="snippet">
var file = File.create("colors.txt")
file.writeBytes("chartreuse lime teal")
file.close()
</pre>

### File.**open**(path)

Opens the file at `path` for reading. You are responsible for closing it when
done with it.

## Methods

### **descriptor**

The numeric file descriptor used to access the file.

### **isOpen**

Whether the file is still open or has been closed.

### **size**

The size of the contents of the file in bytes.

### **close**()

Closes the file. After calling this, you can't read or write from it.

### **readBytes**(count)

Reads up to `count` bytes starting from the beginning of the file.

<pre class="snippet">
// Assume this file contains "I am a file!".
File.open("example.txt") {|file|
  System.print(file.readBytes(6)) //> I am a
}
</pre>

### **readBytes**(count, offset)

Reads up to `count` bytes starting at `offset` bytes from the beginning of
the file.

<pre class="snippet">
// Assume this file contains "I am a file!".
File.open("example.txt") {|file|
  System.print(file.readBytes(6, 2)) //> am a f
}
</pre>

### **writeBytes**(bytes)

Writes the raw bytes of the string `bytes` to the end of the file.

### **writeBytes**(bytes, offset)

Writes the raw bytes of the string `bytes` to the to the file, starting at
`offset`. Any overlapping bytes already in the file at the offset are
overwritten.


================================================
FILE: doc/site/cli/modules/io/index.markdown
================================================
^title Module "io"

Provides access to operating system streams and the file system.

* [Directory](directory.html)
* [File](file.html)
* [Stat](stat.html)
* [Stdin](stdin.html)
* [Stdout](stdout.html)


================================================
FILE: doc/site/cli/modules/io/stat.markdown
================================================
^title Stat Class

A data structure describing the low-level details of a file system entry.

## Static Methods

### Stat.**path**(path)

"Stats" the file or directory at `path`.

## Methods

### **blockCount**

The number of system blocks allocated on disk for the file.

### **blockSize**

The preferred block size in bytes for interacting with the file. It may vary
from file to file.

### **device**

The ID of the device containing the entry.

### **group**

Numeric group ID of the file's owner.

### **inode**

The [inode][] number of the entry.

[inode]: https://en.wikipedia.org/wiki/Inode

### **isDirectory**

Whether the file system entity is a directory.

### **isFile**

Whether the file system entity is a regular file, as opposed to a directory or
other special entity.

### **linkCount**

The number of hard links to the entry.

### **mode**

A bit field describing the entry's type and protection flags.

### **size**

The size of the entry in bytes.

### **specialDevice**

The device ID for the entry, if it's a special file.

### **user**

Numeric user ID of the file's owner.


================================================
FILE: doc/site/cli/modules/io/stdin.markdown
================================================
^title Stdin Class

The standard input stream.

## Static Methods

### **isRaw**

Returns `true` if stdin is in raw mode. When in raw mode, input is not echoed
or buffered, and all characters, even non-printing and control characters go
into stdin.

Defaults to `false`.

### **isRaw**=(value)

Sets raw mode on or off.

### **isTerminal**

Returns `true` if Stdin is connected to a "TTY". This is true when the user is
running Wren in an interactive terminal, and false if it its input is coming
from a pipe.

### **readByte**()

Reads one byte of input from stdin. Blocks the current fiber until a byte has
been received.

Returns the byte value as a number or `null` if stdin is closed.

Note that output is not automatically flushed when calling this. If you want to
display a prompt before reading input, you'll want to call `Stdout.flush()`
after printing the prompt.

### **readLine**()

Reads one line of input from stdin. Blocks the current fiber until a full line
of input has been received.

Returns the string of input or `null` if stdin is closed.

Note that output is not automatically flushed when calling this. If you want to
display a prompt before reading input, you'll want to call `Stdout.flush()`
after printing the prompt.


================================================
FILE: doc/site/cli/modules/io/stdout.markdown
================================================
^title Stdout Class

The standard output stream.

## Static Methods

### **flush()**

Flushes all buffered data to the stream. Ensures any data written to stdout
that is in the buffer gets written to the file or terminal that stdout is
connected to.


================================================
FILE: doc/site/cli/modules/io/template.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>{title} &ndash; Wren</title>
<script type="application/javascript" src="../../../prism.js" data-manual></script>
<script type="application/javascript" src="../../../wren.js"></script>
<link rel="stylesheet" type="text/css" href="../../../prism.css" />
<link rel="stylesheet" type="text/css" href="../../../style.css" />
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
     the viewport. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
</head>
<body id="top" class="module">
<header>
  <div class="page">
    <div class="main-column">
      <h1><a href="../../../">wren</a></h1>
      <h2>a classy little scripting language</h2>
    </div>
  </div>
</header>
<div class="page">
  <nav class="big">
    <a href="../../../"><img src="../../../wren.svg" class="logo"></a>
    <ul>
      <li><a href="../../">Back to Wren CLI</a></li>
      <li><a href="../">Back to CLI Modules</a></li>
      <li><a href="./">io module</a></li>
    </ul>
    <section>
      <h2>io classes</h2>
      <ul>
        <li><a href="directory.html">Directory</a></li>
        <li><a href="file.html">File</a></li>
        <li><a href="file-flags.html">FileFlags</a></li>
        <li><a href="stat.html">Stat</a></li>
        <li><a href="stdin.html">Stdin</a></li>
        <li><a href="stdout.html">Stdout</a></li>
      </ul>
    </section>
  </nav>
  <nav class="small">
    <table>
      <tr>
        <td><a href="../">Back to CLI Modules</a></td>
        <td><a href="./">io module</a></td>
      </tr>
      <tr>
        <td colspan="2"><h2>io classes</h2></td>
      </tr>
      <tr>
        <td>
          <ul>
            <li><a href="directory.html">Directory</a></li>
            <li><a href="file.html">File</a></li>
            <li><a href="file-flags.html">FileFlags</a></li>
          </ul>
        </td>
        <td>
          <ul>
            <li><a href="stat.html">Stat</a></li>
            <li><a href="stdin.html">Stdin</a></li>
            <li><a href="stdout.html">Stdout</a></li>
          </ul>
        </td>
      </tr>
    </table>
  </nav>
  <main>
    <h1>{title}</h1>
    {html}
  </main>
</div>
<footer>
  <div class="page">
    <div class="main-column">
    <p>Wren lives
      <a href="https://github.com/wren-lang/wren">on GitHub</a>
      &mdash; Made with &#x2764; by
      <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
      <a href="https://github.com/wren-lang/wren/blob/main/AUTHORS">friends</a>.
    </p>
    <div class="main-column">
  </div>
</footer>
</body>
</html>


================================================
FILE: doc/site/cli/modules/os/index.markdown
================================================
^title Module "os"

The os module exposes classes for accessing capabilities provided by the
underlying operating system.

* [Platform](platform.html)
* [Process](process.html)


================================================
FILE: doc/site/cli/modules/os/platform.markdown
================================================
^title Platform Class

The Platform class exposes basic information about the operating system Wren is
running on top of.

## Static Methods

### **name**

The name of the platform. This roughly describes the operating system, and is
usually one of:

* "iOS"
* "Linux"
* "OS X"
* "POSIX"
* "Unix"
* "Windows"

If Wren was compiled for an unknown operating system, returns "Unknown".

### **isPosix**

Returns `true` if the host operating system is known to support the POSIX
standard. This is true for Linux and other Unices, as well as the various Apple
operating systems.

### **isWindows**

Returns `true` if the host operating system is some flavor of Windows.


================================================
FILE: doc/site/cli/modules/os/process.markdown
================================================
^title Process Class

The Process class lets you work with operating system processes, including the
currently running one.

## Static Methods

### **allArguments**

The list of command-line arguments that were passed when the Wren process was
spawned. This includes the Wren executable itself, the path to the file being
run (if any), and any other options passed to Wren itself.

If you run:

    $ wren file.wren arg

This returns:

<pre class="snippet">
System.print(Process.allArguments) //> ["wren", "file.wren", "arg"]
</pre>

### **arguments**

The list of command-line arguments that were passed to your program when the
Wren process was spawned. This does not include arguments handled by Wren
itself.

If you run:

    $ wren file.wren arg

This returns:

<pre class="snippet">
System.print(Process.arguments) //> ["arg"]
</pre>

================================================
FILE: doc/site/cli/modules/os/template.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>{title} &ndash; Wren</title>
<script type="application/javascript" src="../../../prism.js" data-manual></script>
<script type="application/javascript" src="../../../wren.js"></script>
<link rel="stylesheet" type="text/css" href="../../../prism.css" />
<link rel="stylesheet" type="text/css" href="../../../style.css" />
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
     the viewport. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
</head>
<body id="top" class="module">
<header>
  <div class="page">
    <div class="main-column">
      <h1><a href="../../../">wren</a></h1>
      <h2>a classy little scripting language</h2>
    </div>
  </div>
</header>
<div class="page">
  <nav class="big">
    <a href="../../../"><img src="../../../wren.svg" class="logo"></a>
    <ul>
      <li><a href="../../">Back to Wren CLI</a></li>
      <li><a href="../">Back to CLI Modules</a></li>
      <li><a href="./">os module</a></li>
    </ul>
    <section>
      <h2>os classes</h2>
      <ul>
        <li><a href="platform.html">Platform</a></li>
        <li><a href="process.html">Process</a></li>
      </ul>
    </section>
  </nav>
  <nav class="small">
    <table>
      <tr>
        <td><a href="../">Back to CLI Modules</a></td>
        <td><a href="./">os module</a></td>
      </tr>
      <tr>
        <td colspan="2"><h2>os classes</h2></td>
      </tr>
      <tr>
        <td>
          <ul>
            <li><a href="platform.html">Platform</a></li>
            <li><a href="process.html">Process</a></li>
          </ul>
        </td>
        <td>
          <ul>
          </ul>
        </td>
      </tr>
    </table>
  </nav>
  <main>
    <h1>{title}</h1>
    {html}
  </main>
</div>
<footer>
  <div class="page">
    <div class="main-column">
    <p>Wren lives
      <a href="https://github.com/wren-lang/wren">on GitHub</a>
      &mdash; Made with &#x2764; by
      <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
      <a href="https://github.com/wren-lang/wren/blob/main/AUTHORS">friends</a>.
    </p>
    <div class="main-column">
  </div>
</footer>
</body>
</html>


================================================
FILE: doc/site/cli/modules/scheduler/index.markdown
================================================
^title Module "scheduler"

This module provides a vehicle to allow other operations to be performed asynchronously whilst waiting for the main operation to be completed.

It contains a single class:

* [Scheduler](scheduler.html)


================================================
FILE: doc/site/cli/modules/scheduler/scheduler.markdown
================================================
^title Scheduler Class

The Scheduler class maintains a list of fibers, to be started one after the other, when a signal to do so is received. The signal (a private method call) is typically transmitted by _long running_ methods in the File or Timer classes which suspend the current fiber so that Wren can carry out other tasks in the meantime.

## Static Method

### Scheduler.**add**(callable)

Adds a new fiber to the scheduler's fibers list. This fiber calls `callable` and then transfers to the next fiber in the list, if there is one.

`callable` is a function or other object which has a call() method.

<pre class="snippet">
var a = 3

Scheduler.add {
  a = a * a
}

Scheduler.add {
  a = a + 1
}

System.print(a)        // still 3
Timer.sleep(3000)      // wait 3 seconds
System.print(a)        // now 3 * 3 + 1 = 10
</pre>


================================================
FILE: doc/site/cli/modules/scheduler/template.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>{title} &ndash; Wren</title>
<script type="application/javascript" src="../../../prism.js" data-manual></script>
<script type="application/javascript" src="../../../wren.js"></script>
<link rel="stylesheet" type="text/css" href="../../../prism.css" />
<link rel="stylesheet" type="text/css" href="../../../style.css" />
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
     the viewport. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
</head>
<body id="top" class="module">
<header>
  <div class="page">
    <div class="main-column">
      <h1><a href="../../../">wren</a></h1>
      <h2>a classy little scripting language</h2>
    </div>
  </div>
</header>
<div class="page">
  <nav class="big">
    <a href="../../../"><img src="../../../wren.svg" class="logo"></a>
    <ul>
      <li><a href="../../">Back to Wren CLI</a></li>
      <li><a href="../">Back to CLI Modules</a></li>
      <li><a href="./">scheduler module</a></li>
    </ul>
    <section>
      <h2>scheduler classes</h2>
      <ul>
        <li><a href="scheduler.html">Scheduler</a></li>
      </ul>
    </section>
  </nav>
  <nav class="small">
    <table>
      <tr>
        <td><a href="../">Back to CLI Modules</a></td>
        <td><a href="./">scheduler module</a></td>
      </tr>
      <tr>
        <td colspan="2"><h2>scheduler classes</h2></td>
      </tr>
      <tr>
        <td>
          <ul>
            <li><a href="scheduler.html">Scheduler</a></li>
          </ul>
        </td>
        <td>
          <ul>
          </ul>
        </td>
      </tr>
    </table>
  </nav>
  <main>
    <h1>{title}</h1>
    {html}
  </main>
</div>
<footer>
  <div class="page">
    <div class="main-column">
    <p>Wren lives
      <a href="https://github.com/wren-lang/wren">on GitHub</a>
      &mdash; Made with &#x2764; by
      <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
      <a href="https://github.com/wren-lang/wren/blob/main/AUTHORS">friends</a>.
    </p>
    <div class="main-column">
  </div>
</footer>
</body>
</html>


================================================
FILE: doc/site/cli/modules/template.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>{title} &ndash; Wren</title>
<script type="application/javascript" src="../../prism.js" data-manual></script>
<script type="application/javascript" src="../../wren.js"></script>
<link rel="stylesheet" type="text/css" href="../../prism.css" />
<link rel="stylesheet" type="text/css" href="../../style.css" />
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
     the viewport. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
</head>
<body id="top" class="module">
<header>
  <div class="page">
    <div class="main-column">
      <h1><a href="../../">wren</a></h1>
      <h2>a classy little scripting language</h2>
    </div>
  </div>
</header>
<div class="page">
  <nav class="big">
    <a href="../../"><img src="../../wren.svg" class="logo"></a>
    <ul>
      <li><a href="../">Back to Wren CLI</a></li>
    </ul>
    <section>
      <h2>Built In</h2>
      <ul>
        <li><a href="../../modules">Wren modules</a></li>
      </ul>
    </section>
    <section>
      <h2>CLI modules</h2>
      <ul>
        <li><a href="io">io</a></li>
        <li><a href="os">os</a></li>
        <li><a href="scheduler">scheduler</a></li>
        <li><a href="timer">timer</a></li>
      </ul>
    </section>
  </nav>
  <nav class="small">
    <table>
      <tr>
        <td><h2>core</h2></td>
        <td><h2>optional</h2></td>
        <td><h2>cli</h2></td>
      </tr>
      <tr>
        <td>
          <ul>
            <li><a href="core">core</a></li>
          </ul>
        </td>
        <td>
          <ul>
            <li><a href="meta">meta</a></li>
            <li><a href="random">random</a></li>
          </ul>
        </td>
        <td>
          <ul>
            <li><a href="io">io</a></li>
            <li><a href="os">os</a></li>
            <li><a href="scheduler">scheduler</a></li>
            <li><a href="timer">timer</a></li>
          </ul>
        </td>
      </tr>
    </table>
  </nav>
  <main>
    <h1>{title}</h1>
    {html}
  </main>
</div>
<footer>
  <div class="page">
    <div class="main-column">
    <p>Wren lives
      <a href="https://github.com/wren-lang/wren">on GitHub</a>
      &mdash; Made with &#x2764; by
      <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
      <a href="https://github.com/wren-lang/wren/blob/main/AUTHORS">friends</a>.
    </p>
    <div class="main-column">
  </div>
</footer>
</body>
</html>


================================================
FILE: doc/site/cli/modules/timer/index.markdown
================================================
^title Module "timer"

This module provides a mechanism to suspend the current fiber for a given period of time either as a simple delay or to allow other operations to be performed asynchronously in the meantime.

It contains a single class:

* [Timer](timer.html)


================================================
FILE: doc/site/cli/modules/timer/template.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>{title} &ndash; Wren</title>
<script type="application/javascript" src="../../../prism.js" data-manual></script>
<script type="application/javascript" src="../../../wren.js"></script>
<link rel="stylesheet" type="text/css" href="../../../prism.css" />
<link rel="stylesheet" type="text/css" href="../../../style.css" />
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
     the viewport. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
</head>
<body id="top" class="module">
<header>
  <div class="page">
    <div class="main-column">
      <h1><a href="../../../">wren</a></h1>
      <h2>a classy little scripting language</h2>
    </div>
  </div>
</header>
<div class="page">
  <nav class="big">
    <a href="../../../"><img src="../../../wren.svg" class="logo"></a>
    <ul>
      <li><a href="../../">Back to Wren CLI</a></li>
      <li><a href="../">Back to CLI Modules</a></li>
      <li><a href="./">timer module</a></li>
    </ul>
    <section>
      <h2>timer classes</h2>
      <ul>
        <li><a href="timer.html">Timer</a></li>
      </ul>
    </section>
  </nav>
  <nav class="small">
    <table>
      <tr>
        <td><a href="../">Back to CLI Modules</a></td>
        <td><a href="./">timer module</a></td>
      </tr>
      <tr>
        <td colspan="2"><h2>timer classes</h2></td>
      </tr>
      <tr>
        <td>
          <ul>
            <li><a href="timer.html">Timer</a></li>
          </ul>
        </td>
        <td>
          <ul>
          </ul>
        </td>
      </tr>
    </table>
  </nav>
  <main>
    <h1>{title}</h1>
    {html}
  </main>
</div>
<footer>
  <div class="page">
    <div class="main-column">
    <p>Wren lives
      <a href="https://github.com/wren-lang/wren">on GitHub</a>
      &mdash; Made with &#x2764; by
      <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
      <a href="https://github.com/wren-lang/wren/blob/main/AUTHORS">friends</a>.
    </p>
    <div class="main-column">
  </div>
</footer>
</body>
</html>


================================================
FILE: doc/site/cli/modules/timer/timer.markdown
================================================
^title Timer Class

## Static Method

### Timer.**sleep**(milliseconds)

Suspends the current fiber for the given number of milliseconds. It is a runtime error if this is not a non-negative number.

This method is often used in conjunction with the Scheduler class which runs any scheduled tasks in separate fibers whilst the current fiber is sleeping.

Note that this method also suspends the System.clock method which will not give the correct running time for a program as a result.



================================================
FILE: doc/site/cli/template.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>{title} &ndash; Wren</title>
<script type="application/javascript" src="../prism.js" data-manual></script>
<script type="application/javascript" src="../wren.js"></script>
<link rel="stylesheet" type="text/css" href="../prism.css" />
<link rel="stylesheet" type="text/css" href="../style.css" />
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
     the viewport. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
</head>
<body id="top">
<header>
  <div class="page">
    <div class="main-column">
      <h1><a href="../">wren</a></h1>
      <h2>a classy little scripting language</h2>
    </div>
  </div>
</header>
<div class="page">
  <nav class="big">
    <a href="../"><img src="../wren.svg" class="logo"></a>
    <ul>
      <li><a href="../">Back to Wren</a></li>
    </ul>
    <section>
      <h2>Wren CLI</h2>
      <ul>
        <li><a href="./">About</a></li>
        <li><a target="_blank" href="https://github.com/wren-lang/wren-cli/releases">Downloads</a></li>
        <li><a href="usage.html">Usage</a></li>
      </ul>
    </section>
    <section>
      <h2>API docs</h2>
      <ul>
        <li><a href="modules">CLI Modules</a></li>
      </ul>
    </section>
  </nav>
  <nav class="small">
    <table>
      <tr>
        <div><a href="../">Back to Wren</a></div>
      </tr>
      <tr>
        <td><h2>CLI</h2></td>
        <td><h2>API</h2></td>
      </tr>
      <tr>
        <td>
          <ul>
            <li><a href="./">About</a></li>
            <li><a target="_blank" href="https://github.com/wren-lang/wren-cli/releases">Downloads</a></li>
            <li><a href="usage.html">Usage</a></li>
          </ul>
        </td>
        <td>
          <ul>
            <li><a href="modules">CLI Modules</a></li>
          </ul>
        </td>
      </tr>
    </table>
  </nav>
  <main>
    <h2>{title}</h2>
    {html}
  </main>
</div>
<footer>
  <div class="page">
    <div class="main-column">
    <p>Wren lives
      <a href="https://github.com/wren-lang/wren">on GitHub</a>
      &mdash; Made with &#x2764; by
      <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
      <a href="https://github.com/wren-lang/wren/blob/main/AUTHORS">friends</a>.
    </p>
    <div class="main-column">
  </div>
</footer>
</body>
</html>


================================================
FILE: doc/site/cli/usage.markdown
================================================
^title Wren CLI Usage

---


You can [download a build for your OS from the releases page](https://github.com/wren-lang/wren-cli/releases).

### Interactive mode

If you just run `wren_cli` without any arguments, it starts the interpreter in
interactive mode, where you can type in a line of code, and it immediately executes
it. You can exit the interpreter using good old Ctrl-C or Ctrl-D.

Here's something to try:

<pre class="snippet">
System.print("Hello, world!")
</pre>

Or a little more exciting:

<pre class="snippet">
for (i in 1..10) System.print("Counting up %(i)")
</pre>

### Running scripts

The standalone interpreter can also load scripts from files and run them. Just
pass the name of the script to `wren_cli`. Create a file named "my_script.wren" in
your favorite text editor and paste this into it:

<pre class="snippet">
for (yPixel in 0...24) {
  var y = yPixel / 12 - 1
  for (xPixel in 0...80) {
    var x = xPixel / 30 - 2
    var x0 = x
    var y0 = y
    var iter = 0
    while (iter < 11 && x0 * x0 + y0 * y0 <= 4) {
      var x1 = (x0 * x0) - (y0 * y0) + x
      var y1 = 2 * x0 * y0 + y
      x0 = x1
      y0 = y1
      iter = iter + 1
    }
    System.write(" .-:;+=xX$& "[iter])
  }
  System.print("")
}
</pre>

Now run:

    $ ./wren_cli my_script.wren


================================================
FILE: doc/site/concurrency.markdown
================================================
^title Concurrency

Lightweight concurrency is a key feature of Wren and it is expressed using
*fibers*. They control how all code is executed, and take the place of
exceptions in [error handling](error-handling.html).

Fibers are a bit like threads except they are *cooperatively* scheduled. That
means Wren doesn't pause one fiber and switch to another until you tell it to.
You don't have to worry about context switches at random times and all of the
headaches those cause.

Wren takes care of all of the fibers in the VM, so they don't use OS thread
resources, or require heavyweight context switches. Each just needs a bit of
memory for its stack. A fiber will get garbage collected like any other object
when not referenced any more, so you can create them freely.

They are lightweight enough that you can, for example, have a separate fiber for
each entity in a game. Wren can handle thousands of them without breaking a
sweat. For example, when you run Wren in interactive mode, it creates a new
fiber for every line of code you type in.

## Creating fibers

All Wren code runs within the context of a fiber. When you first start a Wren
script, a main fiber is created for you automatically. You can spawn new fibers
using the Fiber class's constructor:

<pre class="snippet">
var fiber = Fiber.new {
  System.print("This runs in a separate fiber.")
}
</pre>

It takes a [function][] containing the code the fiber should execute. The
function can take zero or one parameter, but no more than that. Creating the
fiber does not immediately run it. It just wraps the function and sits there,
waiting to be activated.

[function]: functions.html

## Invoking fibers

Once you've created a fiber, you run it by calling its `call()` method:

<pre class="snippet">
fiber.call()
</pre>

This suspends the current fiber and executes the called one until it reaches the
end of its body or until it passes control to yet another fiber. If it reaches
the end of its body, it is considered *done*:

<pre class="snippet">
var fiber = Fiber.new {
  System.print("It's alive!")
}

System.print(fiber.isDone) //> false
fiber.call() //> It's alive!
System.print(fiber.isDone) //> true
</pre>

When a called fiber finishes, it automatically passes control *back* to the
fiber that called it. It's a runtime error to try to call a fiber that is
already done.

## Yielding

The main difference between fibers and functions is that a fiber can be
suspended in the middle of its operation and then resumed later. Calling
another fiber is one way to suspend a fiber, but that's more or less the same
as one function calling another.

Things get interesting when a fiber *yields*. A yielded fiber passes control
*back* to the fiber that ran it, but *remembers where it is*. The next time the
fiber is called, it picks up right where it left off and keeps going.

You make a fiber yield by calling the static `yield()` method on Fiber:

<pre class="snippet">
var fiber = Fiber.new {
  System.print("Before yield")
  Fiber.yield()
  System.print("Resumed")
}

System.print("Before call") //> Before call
fiber.call() //> Before yield
System.print("Calling again") //> Calling again
fiber.call() //> Resumed
System.print("All done") //> All done
</pre>

Note that even though this program uses *concurrency*, it is still
*deterministic*. You can reason precisely about what it's doing and aren't at
the mercy of a thread scheduler playing Russian roulette with your code.

## Passing values

Calling and yielding fibers is used for passing control, but it can also pass
*data*. When you call a fiber, you can optionally pass a value to it.

If you create a fiber using a function that takes a parameter, you can pass a
value to it through `call()`:

<pre class="snippet">
var fiber = Fiber.new {|param|
  System.print(param)
}

fiber.call("Here you go") //> Here you go
</pre>

If the fiber has yielded and is waiting to resume, the value you pass to call
becomes the return value of the `yield()` call when it resumes:

<pre class="snippet">
var fiber = Fiber.new {|param|
  System.print(param)
  var result = Fiber.yield()
  System.print(result)
}

fiber.call("First") //> First
fiber.call("Second") //> Second
</pre>

Fibers can also pass values *back* when they yield. If you pass an argument to
`yield()`, that will become the return value of the `call()` that was used to
invoke the fiber:

<pre class="snippet">
var fiber = Fiber.new {
  Fiber.yield("Reply")
}

System.print(fiber.call()) //> Reply
</pre>

This is sort of like how a function call may return a value, except that a fiber
may return a whole sequence of values, one every time it yields.

## Full coroutines

What we've seen so far is very similar to what you can do with languages like
Python and C# that have *generators*. Those let you define a function call that
you can suspend and resume. When using the function, it appears like a sequence
you can iterate over.

Wren's fibers can do that, but they can do much more. Like Lua, they are full
*coroutines*&mdash;they can suspend from anywhere in the callstack. The function
you use to create a fiber can call a method that calls another method that calls
some third method which finally calls yield. When that happens, *all* of those
method calls &mdash; the entire callstack &mdash; gets suspended. For example:

<pre class="snippet">
var fiber = Fiber.new {
  (1..10).each {|i|
    Fiber.yield(i)
  }
}
</pre>

Here, we're calling `yield()` from within a [function](functions.html) being
passed to the `each()` method. This works fine in Wren because that inner
`yield()` call will suspend the call to `each()` and the function passed to it
as a callback.

## Transferring control

Fibers have one more trick up their sleeves. When you execute a fiber using
`call()`, the fiber tracks which fiber it will return to when it yields. This
lets you build up a chain of fiber calls that will eventually unwind back to
the main fiber when all of the called ones yield or finish.

This is usually what you want. But if you're doing something low level, like
writing your own scheduler to manage a pool of fibers, you may not want to treat
them explicitly like a stack.

For rare cases like that, fibers also have a `transfer()` method. This switches
execution to the transferred fiber and "forgets" the fiber that was transferred
*from*. The previous one is suspended, leaving it in whatever state it was in.
You can resume the previous fiber by explicitly transferring back to it, or even
calling it. If you don't, execution stops when the last transferred fiber
returns.

Where `call()` and `yield()` are analogous to calling and returning from
functions, `transfer()` works more like an unstructured goto. It lets you freely
switch control between a number of fibers, all of which act as peers to one
another.

<br><hr>
<a class="right" href="error-handling.html">Error Handling &rarr;</a>
<a href="classes.html">&larr; Classes</a>


================================================
FILE: doc/site/contributing.markdown
================================================
^title Contributing

Like the bird, Wren's ecosystem is small but full of life. Almost everything is
under active development and there's lots to do. We'd be delighted to have you
help.

The first thing to do is to join [the discord community][discord] (or [the mailing list][list]) and say,
"Hi". There are no strangers to Wren, just friends we haven't met yet.

## Growing the ecosystem

The simplest and often most helpful way to join the Wren party is to be a Wren
*user*. Create an application that embeds Wren. Write a library or a handy
utility in Wren. Add syntax highlighting support for Wren to your favorite text
editor. Share that stuff and it will help the next Wren user to come along.

If you do any of the above, let us know by adding it to [the wiki][wiki].   
We like to keep track of:

[wiki]: https://github.com/wren-lang/wren/wiki

* [Applications][] that host Wren as a scripting language.
* [Modules][] written in Wren that others can use.
* [Language bindings][] that let you interact with Wren from other
  languages.
* [Tools and utilities][] that make it easier to be a Wren programmer.

[applications]: https://github.com/wren-lang/wren/wiki/Applications
[modules]: https://github.com/wren-lang/wren/wiki/Modules
[language bindings]: https://github.com/wren-lang/wren/wiki/Language-Bindings
[tools and utilities]: https://github.com/wren-lang/wren/wiki/Tools

## Contributing to Wren

You're also more than welcome to contribute to Wren itself, both the core VM and
the command-line interpreter. The source is developed [on GitHub][github]. Our
hope is that the codebase, tests, and [documentation][docs] are easy to
understand and contribute to. If they aren't, that's a bug.

You can learn how to build wren on the [getting started page](getting-started.html#building-wren).

### Finding something to hack on

Between the [issue tracker][issue] and searching for `TODO` comments in the
code, it's pretty easy to find something that needs doing, though we don't
always do a good job of writing everything down.

If nothing there suits your fancy, new ideas are welcome as well! If you have an
idea for a significant change or addition, please file a [proposal][] to discuss
it before writing lots of code. Wren tries very *very* hard to be minimal which
means often having to say "no" to language additions, even really cool ones.

### Hacking on docs

The [documentation][] is one of the easiest&mdash;and most
important!&mdash;parts of Wren to contribute to. The source for the site is
written in [Markdown][] and lives under `doc/site`. A
simple Python 3 script, `util/generate_docs.py`, converts that to HTML and CSS.

[documentation]: /
[markdown]: http://daringfireball.net/projects/markdown/

    $ python util/generate_docs.py

This generates the site in `build/docs/`. You can run any simple static web
server from there. Python includes one:

    $ cd build/docs
    $ python -m http.server

Running that script every time you change a line of Markdown can be slow,
so there is also a file watching version that will automatically regenerate the
docs when you edit a file:

    $ python util/generate_docs.py --watch

### Hacking on the VM

The basic process is simple:

1. **Make sure you can build and run the tests locally.** It's good to ensure
   you're starting from a happy place before you poke at the code. Running the
   tests is as simple as [building the vm project](getting-started.html#building-wren),
   which generates `bin/wren_test` and then running the following python 3 script:

        $ python util/test.py

    If there are no failures, you're good to go.

2. **[Fork the repo][fork] so you can change it locally.** Please make your
   changes in separate [feature branches][] to make things a little easier.

3. **Change the code.** Please follow the style of the surrounding code. That
   basically means `camelCase` names, `{` on the next line, keep within 80
   columns, and two spaces of indentation. If you see places where the existing
   code is inconsistent, let us know.

4. **Write some tests for your new functionality.** They live under `test/`.
   Take a look at some existing tests to get an idea of how to define
   expectations.

5. **Make sure the tests all pass, both the old ones and your new ones.**

6. **Add your name and email to the [AUTHORS][] file if you haven't already.**

7. **Send a [pull request][].** Pat yourself on the back for contributing to a
   fun open source project! 

## Getting help

If at any point you have questions, feel free to [file an issue][issue] or ask
on the [discord community][discord] (or the [mailing list][list]). If you're a Redditor, try the
[/r/wren_lang][subreddit] subreddit. You can also email me directly (`robert` at
`stuffwithstuff.com`) if you want something less public.

[mit]: http://opensource.org/licenses/MIT
[github]: https://github.com/wren-lang/
[fork]: https://help.github.com/articles/fork-a-repo/
[docs]: https://github.com/wren-lang/wren/tree/main/doc/site
[issue]: https://github.com/wren-lang/wren/issues
[proposal]: https://github.com/wren-lang/wren/labels/proposal
[feature branches]: https://www.atlassian.com/git/tutorials/comparing-workflows/centralized-workflow
[authors]: https://github.com/wren-lang/wren/tree/main/AUTHORS
[pull request]: https://github.com/wren-lang/wren/pulls
[list]: https://groups.google.com/forum/#!forum/wren-lang
[subreddit]: https://www.reddit.com/r/wren_lang/
[discord]: https://discord.gg/Kx6PxSX


================================================
FILE: doc/site/control-flow.markdown
================================================
^title Control Flow

Control flow is used to determine which chunks of code are executed and how many
times. *Branching* statements and expressions decide whether or not to execute
some code and *looping* ones execute something more than once.

## Truth

All control flow is based on *deciding* whether or not to do something. This
decision depends on some expression's value. We take the entire universe of
possible objects and divide them into two buckets: some we consider "true" and
the rest are "false". If the expression results in a value in the true bucket,
we do one thing. Otherwise, we do something else.

Obviously, the boolean `true` is in the "true" bucket and `false` is in
"false", but what about values of other types? The choice is ultimately
arbitrary, and different languages have different rules. Wren's rules follow
Ruby:

  * The boolean value `false` is false.
  * The null value `null` is false.
  * Everything else is true.

This means `0`, empty strings, and empty collections are all considered "true"
values.

## If statements

The simplest branching statement, `if` lets you conditionally skip a chunk of
code. It looks like this:

<pre class="snippet">
if (ready) System.print("go!")
</pre>

That evaluates the parenthesized expression after `if`. If it's true, then the
statement after the condition is evaluated. Otherwise it is skipped. Instead of
a statement, you can have a [block](syntax.html#blocks):

<pre class="snippet">
if (ready) {
  System.print("getSet")
  System.print("go!")
}
</pre>

You may also provide an `else` branch. It will be executed if the condition is
false:

<pre class="snippet">
if (ready) System.print("go!") else System.print("not ready!")
</pre>

And, of course, it can take a block too:

<pre class="snippet">
if (ready) {
  System.print("go!")
} else {
  System.print("not ready!")
}
</pre>

You can also use `else if` branches to handle multiple possibilities. For example, what if `ready` was not a boolean value?
<pre class="snippet">
if (ready == true) {
  System.print("go!")
} else if (ready == false) {
  System.print("not ready!")
} else { // If ready isn't a boolean
  System.print("not sure if I'm ready or not!")
}
</pre>

## Logical operators

Unlike most other [operators][] in Wren which are just a special syntax for
[method calls][], the `&&` and `||` operators are special. This is because they
only conditionally evaluate the right operand&mdash;they short-circuit.

[operators]: method-calls.html#operators
[method calls]: method-calls.html

A `&&` ("logical and") expression evaluates the left-hand argument. If it's
false, it returns that value. Otherwise it evaluates and returns the right-hand
argument.

<pre class="snippet">
System.print(false && 1)  //> false
System.print(1 && 2)      //> 2
</pre>

A `||` ("logical or") expression is reversed. If the left-hand argument is
*true*, it's returned, otherwise the right-hand argument is evaluated and
returned:

<pre class="snippet">
System.print(false || 1)  //> 1
System.print(1 || 2)      //> 1
</pre>

## The conditional operator `?:`

Also known as the "ternary" operator since it takes three arguments, Wren has
the little "if statement in the form of an expression" you know and love from C
and similar languages.

<pre class="snippet">
System.print(1 != 2 ? "math is sane" : "math is not sane!")
</pre>

It takes a condition expression, followed by `?`, followed by a then
expression, a `:`, then an else expression. Just like `if`, it evaluates the
condition. If true, it evaluates and returns the then expression. Otherwise
it does the else expression.

## While statements

It's hard to write a useful program without executing some chunk of code
repeatedly. To do that, you use looping statements. There are two in Wren, and
they should be familiar if you've used other imperative languages.

The simplest, a `while` statement executes a chunk of code as long as a
condition continues to hold. For example:

<pre class="snippet">
// Hailstone sequence.
var n = 27
while (n != 1) {
  if (n % 2 == 0) {
    n = n / 2
  } else {
    n = 3 * n + 1
  }
}
</pre>

This evaluates the expression `n != 1`. If it is true, then it executes the
following body. After that, it loops back to the top, and evaluates the
condition again. It keeps doing this as long as the condition evaluates to
something true.

The condition for a while loop can be any expression, and must be surrounded by
parentheses. The body of the loop is usually a curly block but can also be a
single statement:

<pre class="snippet">
var n = 27
while (n != 1) if (n % 2 == 0) n = n / 2 else n = 3 * n + 1
</pre>

## For statements

While statements are useful when you want to loop indefinitely or according to
some complex condition. But in most cases, you're looping through
a [list](lists.html), a series of numbers, or some other "sequence" object.
That's what `for` is, uh, for. It looks like this:

<pre class="snippet">
for (beatle in ["george", "john", "paul", "ringo"]) {
  System.print(beatle)
}
</pre>

A `for` loop has three components:

1. A *variable name* to bind. In the example, that's `beatle`. Wren will create
   a new variable with that name whose scope is the body of the loop.

2. A *sequence expression*. This determines what you're looping over. It gets
   evaluated *once* before the body of the loop. In this case, it's a list
   literal, but it can be any expression.

3. A *body*. This is a curly block or a single statement. It gets executed once
   for each iteration of the loop.

## Break statements

Sometimes, right in the middle of a loop body, you decide you want to bail out
and stop. To do that, you can use a `break` statement. It's just the `break`
keyword all by itself. That immediately exits out of the nearest enclosing
`while` or `for` loop.

<pre class="snippet">
for (i in [1, 2, 3, 4]) {
  System.print(i)           //> 1
  if (i == 3) break         //> 2
}                           //> 3
</pre>

## Continue statements

During the execution of a loop body, you might decide that you want to skip the 
rest of this iteration and move on to the next one. You can use a `continue` 
statement to do that. It's just the `continue` keyword all by itself. Execution
will immediately jump to the beginning of the next loop iteration (and check the
loop conditions).

<pre class="snippet">
for (i in [1, 2, 3, 4]) {
  if (i == 2) continue      //> 1
  System.print(i)           //> 3
}                           //> 4
</pre>

## Numeric ranges

Lists are one common use for `for` loops, but sometimes you want to walk over a
sequence of numbers, or loop a number of times. For that, you can create a
[range](values.html#ranges), like so:

<pre class="snippet">
for (i in 1..100) {
  System.print(i)
}
</pre>

This loops over the numbers from 1 to 100, including 100 itself. If you want to
leave off the last value, use three dots instead of two:

<pre class="snippet">
for (i in 1...100) {
  System.print(i)
}
</pre>

This looks like some special "range" syntax in the `for` loop, but it's actually
just a pair of operators. The `..` and `...` syntax are infix "range" operators.
Like [other operators][operators], they are special syntax for a regular method
call. The number type implements them and returns a [range object][] that knows
how to iterate over a series of numbers.

[range object]: values.html#ranges

## The iterator protocol

Lists and ranges cover the two most common kinds of loops, but you should also
be able to define your own sequences. To enable that, the semantics of `for`
are defined in terms of an "iterator protocol". The loop itself doesn't know
anything about lists or ranges, it just knows how to call two particular
methods on the object that resulted from evaluating the sequence expression.

When you write a loop like this:

<pre class="snippet">
for (i in 1..100) {
  System.print(i)
}
</pre>

Wren sees it something like this:

<pre class="snippet">
var iter_ = null
var seq_ = 1..100
while (iter_ = seq_.iterate(iter_)) {
  var i = seq_.iteratorValue(iter_)
  System.print(i)
}
</pre>

First, Wren evaluates the sequence expression and stores it in a hidden
variable (written `seq_` in the example but in reality it doesn't have a name
you can use). It also creates a hidden "iterator" variable and initializes it
to `null`.

Each iteration, it calls `iterate()` on the sequence, passing in the current
iterator value. (In the first iteration, it passes in `null`.) The sequence's
job is to take that iterator and advance it to the next element in the
sequence. (Or, in the case where the iterator is `null`, to advance it to the
*first* element). It then returns either the new iterator, or `false` to
indicate that there are no more elements.

If `false` is returned, Wren exits out of the loop and we're done. If anything
else is returned, that means that we have advanced to a new valid element. To
get that, Wren then calls `iteratorValue()` on the sequence and passes in the
iterator value that it just got from calling `iterate()`. The sequence uses
that to look up and return the appropriate element.

The built-in [List](lists.html) and [Range](values.html#ranges) types implement
`iterate()` and `iteratorValue()` to walk over their respective sequences. You
can implement the same methods in your classes to make your own types iterable.

<br><hr>
<a class="right" href="variables.html">Variables &rarr;</a>
<a href="method-calls.html">&larr; Method Calls</a>


================================================
FILE: doc/site/embedding/calling-c-from-wren.markdown
================================================
^title Calling C from Wren

When we are ensconced within the world of Wren, the external C world is
"foreign" to us. There are two reasons we might want to bring some foreign
flavor into our VM:

* We want to execute code written in C.
* We want to store raw C data.

Since Wren is object-oriented, behavior lives in methods, so for the former we
have **foreign methods**. Likewise, data lives in objects, so for the latter, we
define **foreign classes**. This page is about the first, foreign methods. The
[next page][] covers foreign classes.

[next page]: /embedding/storing-c-data.html

A foreign method looks to Wren like a regular method. It is defined on a Wren
class, it has a name and signature, and calls to it are dynamically dispatched.
The only difference is that the *body* of the method is written in C.

A foreign method is declared in Wren like so:

<pre class="snippet">
class Math {
  foreign static add(a, b)
}
</pre>

The `foreign` keyword tells Wren that the method `add()` is declared on `Math`,
but implemented in C. Both static and instance methods can be foreign.

## Binding Foreign Methods

When you call a foreign method, Wren needs to figure out which C function to
execute. This process is called *binding*. Binding is performed on-demand by the
VM. When a class that declares a foreign method is executed -- when the `class`
statement itself is evaluated -- the VM asks the host application for the C
function that should be used for the foreign method.

It does this through the `bindForeignMethodFn` callback you give it when you
first [configure the VM][config]. This callback isn't the foreign method itself.
It's the binding function your app uses to *look up* foreign methods.

[config]: configuring-the-vm.html

Its signature is:

<pre class="snippet" data-lang="c">
WrenForeignMethodFn bindForeignMethodFn(
    WrenVM* vm,
    const char* module,
    const char* className,
    bool isStatic,
    const char* signature);
</pre>

Every time a foreign method is first declared, the VM invokes this callback. It
passes in the module containing the class declaration, the name of the class
containing the method, the method's signature, and whether or not it's a static
method. In the above example, it would pass something like:

<pre class="snippet" data-lang="c">
bindForeignMethodFn(vm, "main", "Math", true, "add(_,_)");
</pre>

When you configure the VM, you give it a C callback that looks up the
appropriate function for the given foreign method and returns a pointer to it.
Something like:

<pre class="snippet" data-lang="c">
WrenForeignMethodFn bindForeignMethod(
    WrenVM* vm,
    const char* module,
    const char* className,
    bool isStatic,
    const char* signature)
{
  if (strcmp(module, "main") == 0)
  {
    if (strcmp(className, "Math") == 0)
    {
      if (isStatic && strcmp(signature, "add(_,_)") == 0)
      {
        return mathAdd; // C function for Math.add(_,_).
      }
      // Other foreign methods on Math...
    }
    // Other classes in main...
  }
  // Other modules...
}
</pre>

This implementation is pretty tedious, but you get the idea. Feel free to do
something more clever here in your host application.

The important part is that it returns a pointer to a C function to use for that
foreign method. Wren does this binding step *once* when the class definition is
first executed. It then keeps the function pointer you return and associates it
with that method. This way, *calls* to the foreign method are fast.

## Implementing a Foreign Method

All C functions for foreign methods have the same signature:

<pre class="snippet" data-lang="c">
void foreignMethod(WrenVM* vm);
</pre>

Arguments passed from Wren are not passed as C arguments, and the method's
return value is not a C return value. Instead -- you guessed it -- we go through
the [slot array][].

[slot array]: /embedding/slots-and-handles.html

When a foreign method is called from Wren, the VM sets up the slot array with
the receiver and arguments to the call. As in calling Wren from C, the receiver
object is in slot zero, and arguments are in consecutive slots after that.

You use the slot API to read those arguments, and then perform whatever work you
want to in C. If you want the foreign method to return a value, place it in slot
zero. Like so:

<pre class="snippet" data-lang="c">
void mathAdd(WrenVM* vm)
{
  double a = wrenGetSlotDouble(vm, 1);
  double b = wrenGetSlotDouble(vm, 2);
  wrenSetSlotDouble(vm, 0, a + b);
}
</pre>

While your foreign method is executing, the VM is completely suspended. No other
fibers run until your foreign method returns. You should *not* try to resume the
VM from within a foreign method by calling `wrenCall()` or `wrenInterpret()`.
The VM is not re-entrant.

This covers foreign behavior, but what about foreign *state*? For that, we need
a foreign *class*...

<a class="right" href="storing-c-data.html">Storing C Data &rarr;</a>
<a href="calling-wren-from-c.html">&larr; Calling Wren from C</a>


================================================
FILE: doc/site/embedding/calling-wren-from-c.markdown
================================================
^title Calling Wren from C

From C, we can tell Wren to do stuff by calling `wrenInterpret()`, but that's
not always the ideal way to drive the VM. First of all, it's slow. It has to
parse and compile the string of source code you give it. Wren has a pretty fast
compiler, but that's still a good bit of work.

It's also not an effective way to communicate. You can't pass arguments to
Wren&mdash;at least, not without doing something nasty like converting them to
literals in a string of source code&mdash;and you can't get a result value back.

`wrenInterpret()` is great for loading code into the VM, but it's not the best
way to execute code that's already been loaded. What we want to do is invoke
some already compiled chunk of code. Since Wren is an object-oriented language,
"chunk of code" means a [method][], not a [function][].

[method]: ../method-calls.html
[function]: ../functions.html

The C API for doing this is `wrenCall()`. In order to invoke a Wren method from
C, we need a few things:

* **The method to call.** Wren is dynamically typed, so this means we'll look it
  up by name. Further, since Wren supports overloading by arity, we actually
  need its entire [signature][].

[signature]: ../method-calls.html#signature

* **The receiver object to invoke the method on.** The receiver's class
  determines which method is actually called.

* **The arguments to pass to the method.**

We'll tackle these one at a time.

### Getting a Method Handle

When you run a chunk of Wren code like this:

<pre class="snippet">
object.someMethod(1, 2, 3)
</pre>

At runtime, the VM has to look up the class of `object` and find a method there
whose signature is `someMethod(_,_,_)`. This sounds like it's doing some string
manipulation&mdash;at the very least hashing the signature&mdash;every time a
method is called. That's how many dynamic languages work.

But, as you can imagine, that's pretty slow. So, instead, Wren does as much of
that work at compile time as it can. When it's compiling the above code to
bytecode, it takes that method signature and converts it to a *method symbol*,
a number that uniquely identifes that method. That's the only part of the
process that requires treating a signature as a string.

At runtime, the VM just looks for the method *symbol* in the receiver's class's
method table. In fact, the way it's implemented today, the symbol is simply the
array index into the table. That's [why method calls are so fast][perf] in Wren.

[perf]: ../performance.html

It would be a shame if calling a method from C didn't have that same speed
benefit. To achieve that, we split the process of calling a method into two
steps. First, we create a handle that represents a "compiled" method signature:

<pre class="snippet" data-lang="c">
WrenHandle* wrenMakeCallHandle(WrenVM* vm, const char* signature);
</pre>

That takes a method signature as a string and gives you back an opaque handle
that represents the compiled method symbol. Now you have a *reusable* handle
that can be used to very quickly call a certain method given a receiver and some
arguments.

This is just a regular WrenHandle, which means you can hold onto it as long as
you like. Typically, you'd call this once outside of your application's
performance critical loops and reuse it as long as you need. It is us up to you
to release it when you no longer need it by calling `wrenReleaseHandle()`.

## Setting Up a Receiver

OK, we have a method, but who are we calling it on? We need a receiver, and as
you can probably guess after reading the [last section][], we give that to Wren
by storing it in a slot. In particular, **the receiver for a method call goes in
slot zero.**

Any object you store in that slot can be used as a receiver. You could even call
`+` on a number by storing a number in there if you felt like it.

[last section]: slots-and-handles.html

Needing a receiver to call some Wren code from C might feel strange. C is
procedural, so it's natural to want to just invoke a bare *function* from Wren,
but Wren isn't procedural. Instead, if you want to define some executable
operation that isn't logically tied to a specific object, the natural way is to
define a static method on an appropriate class.

For example, say we're making a game engine. From C, we want to tell the game
engine to update all of the entities each frame. We'll keep track of the list of
entities within Wren, so from C, there's no obvious object to call `update(_)`
on. Instead, we'll just make it a static method:

<pre class="snippet">
class GameEngine {
  static update(elapsedTime) {
    // ...
  }
}
</pre>

Often, when you call a Wren method from C, you'll be calling a static method.
But, even then, you need a receiver. Now, though, the receiver is the *class
itself*. Classes are first class objects in Wren, and when you define a named
class, you're really declaring a variable with the class's name and storing a
reference to the class object in it.

Assuming you declared that class at the top level, the C API [gives you a way to
look it up][variable]. We can get a handle to the above class like so:

[variable]: slots-and-handles.html#looking-up-variables

<pre class="snippet" data-lang="c">
// Load the class into slot 0.
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", "GameEngine", 0);
</pre>

We could do this every time we call `update()`, but, again, that's kind of slow
because we're looking up "GameEngine" by name each time. A faster solution is to
create a handle to the class once and use it each time:

<pre class="snippet" data-lang="c">
// Load the class into slot 0.
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", "GameEngine", 0);
WrenHandle* gameEngineClass = wrenGetSlotHandle(vm, 0);
</pre>

Now, each time we want to call a method on GameEngine, we store that value back
in slot zero:

<pre class="snippet" data-lang="c">
wrenSetSlotHandle(vm, 0, gameEngineClass);
</pre>

Just like we hoisted `wrenMakeCallHandle()` out of our performance critical
loop, we can hoist the call to `wrenGetVariable()` out. Of course, if your code
isn't performance critical, you don't have to do this.

## Passing Arguments

We've got a receiver in slot zero now, next we need to pass in any other
arguments. In our GameEngine example, that's just the elapsed time. Method
arguments go in consecutive slots after the receiver. So the elapsed time goes
into slot one. You can use any of the slot functions to set this up. For the
example, it's just:

<pre class="snippet" data-lang="c">
wrenSetSlotDouble(vm, 1, elapsedTime);
</pre>

## Calling the Method

We have all of the data in place, so all that's left is to pull the trigger and
tell the VM to start running some code:

<pre class="snippet" data-lang="c">
WrenInterpretResult wrenCall(WrenVM* vm, WrenHandle* method);
</pre>

It takes the method handle we created using `wrenMakeCallHandle()`. Now Wren
starts running code. It looks up the method on the receiver, executes it and
keeps running until either the method returns or a fiber [suspends][].

[suspends]: ../modules/core/fiber.html#fiber.suspend()

`wrenCall()` returns the same WrenInterpretResult enum as `wrenInterpret()` to
tell you if the method completed successfully or a runtime error occurred.
(`wrenCall()` never returns `WREN_ERROR_COMPILE` since it doesn't compile
anything.)

## Getting the Return Value

When `wrenCall()` returns, it leaves the slot array in place. In slot zero, you
can find the method's return value, which you can access using any of the slot
reading functions. If you don't need the return value, you can ignore it.

This is how you drive Wren from C, but how do you put control in Wren's hands?
For that, you'll need the next section...

<a class="right" href="calling-c-from-wren.html">Calling C From Wren &rarr;</a>
<a href="slots-and-handles.html">&larr; Slots and Handles</a>


================================================
FILE: doc/site/embedding/configuring-the-vm.markdown
================================================
^title Configuring the VM

When you create a Wren VM, you tweak it by passing in a pointer to a
WrenConfiguration structure. Since Wren has no global state, you can configure
each VM differently if your application happens to run multiple.

The struct looks like:

<pre class="snippet" data-lang="c">
typedef struct
{
  WrenReallocateFn reallocateFn;
  WrenLoadModuleFn loadModuleFn;
  WrenBindForeignMethodFn bindForeignMethodFn;
  WrenBindForeignClassFn bindForeignClassFn;
  WrenWriteFn writeFn;
  WrenErrorFn errorFn;
  size_t initialHeapSize;
  size_t minHeapSize;
  int heapGrowthPercent;
} WrenConfiguration;
</pre>

Most fields have useful defaults, which you can (and should) initialize by
calling:

<pre class="snippet" data-lang="c">
wrenInitConfiguration(&configuration);
</pre>

Calling this ensures that your VM doesn't get uninitialized configuration when
new fields are added to WrenConfiguration. Here is what each field does, roughly
categorized:

## Binding

The VM is isolated from the outside world. These callbacks let the VM request
access to imported code and foreign functionality.

### **`loadModuleFn`**

This is the callback Wren uses to load an imported module. The VM itself does
not know how to talk to the file system, so when an `import` statement is
executed, it relies on the host application to locate and read the source code
for a module.

The signature of this function is:

<pre class="snippet" data-lang="c">
WrenLoadModuleResult loadModule(WrenVM* vm, const char* name)
</pre>

When a module is imported, Wren calls this and passes in the module's name. The
host should return the source code for that module in a `WrenLoadModuleResult` struct.

<pre class="snippet" data-lang="c">
WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) {
  WrenLoadModuleResult result = {0};
    result.source = getSourceForModule(name);
  return result;
}
</pre>

The module loader is only be called once for any given module name. Wren caches
the result internally so subsequent imports of the same module use the
previously loaded code.

If your host application isn't able to load a module with some name, it should
make sure the `source` value is `NULL` when returned. Wren will then report that as a runtime error.

If you don't use any `import` statements, you can leave the `loadModuleFn` field in
the configuration set to `NULL` (the default).

Additionally, the `WrenLoadModuleResult` allows us to add a callback for when Wren is 
done with the `source`, so we can free the memory if needed.

<pre class="snippet" data-lang="c">

static void loadModuleComplete(WrenVM* vm, 
                               const char* module,
                               WrenLoadModuleResult result) 
{
  if(result.source) {
    //for example, if we used malloc to allocate
    //our source string, we use free to release it.
    free((void*)result.source);
  }
}

WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) {
  WrenLoadModuleResult result = {0};
    result.onComplete = loadModuleComplete;
    result.source = getSourceForModule(name);
  return result;
}
</pre>

### **`bindForeignMethodFn`**

The callback Wren uses to find a foreign method and bind it to a class. See
[this page][foreign method] for details. If your application defines no foreign
methods, you can leave this `NULL`.

[foreign method]: /embedding/calling-c-from-wren.html

### **`bindForeignClassFn`**

The callback Wren uses to find a foreign class and get its foreign methods. See
[this page][foreign class] for details. If your application defines no foreign
classes, you can leave this `NULL`.

[foreign class]: /embedding/storing-c-data.html

## Diagnostics

These let you wire up some minimal output so you can tell if your code is doing
what you expect.

### **`writeFn`**

This is the callback Wren uses to output text when `System.print()` or the other
related functions are called. This is the minimal connection the VM has with the
outside world and lets you do rudimentary "printf debugging". Its signature is:

<pre class="snippet" data-lang="c">
void write(WrenVM* vm, const char* text)
</pre>

Wren does *not* have a default implementation for this. It's up to you to wire
it up to `printf()` or some other way to show the text. If you leave it `NULL`,
calls to `System.print()` and others silently do nothing.

### **`errorFn`**

Wren uses this callback to report compile time and runtime errors. Its signature
is:

<pre class="snippet" data-lang="c">
void error(
      WrenVM* vm, 
      WrenErrorType type,
      const char* module,
      int line,
      const char* message)
</pre>

The `type` parameter is one of:

<pre class="snippet" data-lang="c">
typedef enum
{
  // A syntax or resolution error detected at compile time.
  WREN_ERROR_COMPILE,

  // The error message for a runtime error.
  WREN_ERROR_RUNTIME,

  // One entry of a runtime error's stack trace.
  WREN_ERROR_STACK_TRACE
} WrenErrorType;
</pre>

When a compile error occurs, `errorFn` is called once with type
`WREN_ERROR_COMPILE`, the name of the module and line where the error occurs,
and the error message.

Runtime errors include stack traces. To handle this, Wren first calls `errorFn`
with `WREN_ERROR_RUNTIME`, no module or line, and the runtime error's message.
After that, it calls `errorFn` again using type `WREN_ERROR_STACK_TRACE`, once
for each line in the stack trace. Each of those calls has the module and line
where the method or function is defined and `message` is the name of the method
or function.

If you leave this `NULL`, Wren does not report any errors.

## Memory Management

These fields control how the VM allocates and manages memory.

### **`reallocateFn`**

This lets you provide a custom memory allocation function. Its signature is:

<pre class="snippet" data-lang="c">
void* reallocate(void* memory, size_t newSize, void* userData)
</pre>

Wren uses this one function to allocate, grow, shrink, and deallocate memory.
When called, `memory` is the existing pointer to the block of memory if an
allocation is being changed or freed. If Wren is requesting new memory, then
`memory` is `NULL`.

`newSize` is the number of bytes of memory being requested. If memory is being
freed, this is zero. Your callback should allocate the proper amount of memory
and return it.

If you don't provide a custom allocator, the VM uses a default one that relies
on `realloc` and `free`.

### **`initialHeapSize`**

This defines the total number of bytes of memory the VM will allocate before
triggering the first garbage collection. Setting this to a smaller number
reduces the amount of memory Wren will have allocated at one time, but causes it
to collect garbage more frequently.

If you set this to zero, Wren uses a default size of 10MB.

### **`minHeapSize`**

After a garbage collection occurs, the threshold for the *next* collection is
determined based on the number of bytes remaining in use. This allows Wren to
grow or shrink its memory usage automatically based on how much memory is
actually needed.

This can be used to ensure that the heap does not get *too* small, which can
in turn lead to a large number of collections afterwards as the heap grows
back to a usable size.

If zero, this defaults to 1MB.

### **`heapGrowthPercent`**

Wren tunes the rate of garbage collection based on how much memory is still in
use after a collection. This number controls that. It determines the amount of
additional memory Wren will use after a collection, as a percentage of the
current heap size.

For example, say that this is 50. After a garbage collection, there are 400
bytes of memory still in use. That means the next collection will be triggered
after a total of 600 bytes are allocated (including the 400 already in use.)

Setting this to a smaller number wastes less memory, but triggers more
frequent garbage collections.

If set to zero, the VM uses a default of 50.

<a href="storing-c-data.html">&larr; Storing C Data</a>


================================================
FILE: doc/site/embedding/index.markdown
================================================
^title Embedding

Wren is designed to be a scripting language that lives inside a host
application, so the embedding API is as important as any of its language
features. Designing this API well requires satisfying several constraints:

1. **Wren is dynamically typed, but C is not.** A variable can hold a value of
   any type in Wren, but that's definitely not the case in C unless you define
   some sort of variant type, which ultimately just kicks the problem down the
   road. Eventually, we have to move data across the boundary between statically and dynamically typed code.

2. **Wren uses garbage collection, but C manages memory manually.** GC adds a
   few constraints on the API. The VM must be able to find every Wren object
   that is still usable, even if that object is being referenced from native C
   code. Otherwise, Wren could free an object that's still in use.

    Also, we ideally don't want to let native C code see a bare pointer to a
    chunk of memory managed by Wren. Many garbage collection strategies involve
    [moving objects][] in memory. If we allow C code to point directly to an
    object, that pointer will be left dangling when the object moves. Wren's GC
    doesn't move objects today, but we would like to keep that option for the
    future.

3. **The embedding API needs to be fast.** Users may add layers of abstraction
   on top of the API to make it more pleasant to work with, but the base API
   defines the *maximum* performance you can get out of the system. It's the
   bottom of the stack, so there's no way for a user to optimize around it if
   it's too slow. There is no lower level alternative.

4. **We want the API to be pleasant to use.** This is the last constraint
   because it's the softest. Of course, we want a beautiful, usable API. But we
   really *need* to handle the above, so we're willing to make things a bit more
   of a chore to reach the first three goals.

[moving objects]: https://en.wikipedia.org/wiki/Tracing_garbage_collection#Copying_vs._mark-and-sweep_vs._mark-and-don.27t-sweep

Fortunately, we aren't the first people to tackle this. If you're familiar with
[Lua's C API][lua], you'll find Wren's similar.

[lua]: https://www.lua.org/pil/24.html

### Performance and safety

When code is safely snuggled within the confines of the VM, it's pretty safe.
Method calls are dynamically checked and generate runtime errors which can be
caught and handled. The stack grows if it gets close to overflowing. In general,
when you're within Wren code, it tries very hard to avoid crashing and burning.

This is why you use a high level language after all&mdash;it's safer and more
productive than C. C, meanwhile, really assumes you know what you're doing. You
can cast pointers in invalid ways, misinterpret bits, use memory after freeing
it, etc. What you get in return is blazing performance. Many of the reasons C is
fast are because it takes all the governors and guardrails off.

Wren's embedding API defines the border between those worlds, and takes on some
of the characteristics of C. When you call any of the embedding API functions,
it assumes you are calling them correctly. If you invoke a Wren method from C
that expects three arguments, it trusts that you gave it three arguments.

In debug builds, Wren has assertions to check as many things as it can, but in
release builds, Wren expects you to do the right thing. This means you need to
take care when using the embedding API, just like you do in all C code you
write. In return, you get an API that is quite fast.

## Including Wren

There are two (well, three) ways to get the Wren VM into your program:

1.  **Link to the static or dynamic library.** When you [build Wren][build], it
    generates both shared and static libraries in `lib` that you can link to.

2.  **Include the source directly in your application.** If you want to include
    the source directly in your program, you don't need to run any build steps.
    Just add the source files in `src/vm` to your project. They should compile
    cleanly as C99 or C++98 or anything later.

[build]: ../getting-started.html

In either case, you also want to add `src/include` to your include path so you
can find the [public header for Wren][wren.h]:

[wren.h]: https://github.com/wren-lang/wren/blob/main/src/include/wren.h

<pre class="snippet" data-lang="c">
#include "wren.h"
</pre>

Wren depends only on the C standard library, so you don't usually need to link
to anything else. On some platforms (at least BSD and Linux) some of the math
functions in `math.h` are implemented in a separate library, [libm][], that you
have to explicitly link to.

[libm]: https://en.wikipedia.org/wiki/C_mathematical_functions#libm

If your program is in C++ but you are linking to the Wren library compiled as C,
this header handles the differences in calling conventions between C and C++:

<pre class="snippet" data-lang="c">
#include "wren.hpp"
</pre>

## Creating a Wren VM

Once you've integrated the code into your executable, you need to create a
virtual machine. To do that, you create a `WrenConfiguration` object and
initialize it.

<pre class="snippet" data-lang="c">
    WrenConfiguration config;
    wrenInitConfiguration(&config);
</pre>

This gives you a basic configuration that has reasonable defaults for
everything. We'll [learn more][configuration] about what you can configure later,
but for now we'll just add the `writeFn`, so that we can print text.

First we need a function that will do something with the output
that Wren sends us from `System.print` (or `System.write`). *Note that it doesn't
include a newline in the output.*

<pre class="snippet" data-lang="c">
void writeFn(WrenVM* vm, const char* text) {
  printf("%s", text);
}
</pre>

And then, we update the configuration to point to it.

<pre class="snippet" data-lang="c">
  WrenConfiguration config;
  wrenInitConfiguration(&config);
    config.writeFn = &writeFn;
</pre>

[configuration]: configuring-the-vm.html

With this ready, you can create the VM:

<pre class="snippet" data-lang="c">
WrenVM* vm = wrenNewVM(&config);
</pre>

This allocates memory for a new VM and initializes it. The Wren C implementation
has no global state, so every single bit of data Wren uses is bundled up inside
a WrenVM. You can have multiple Wren VMs running independently of each other
without any problems, even concurrently on different threads.

`wrenNewVM()` stores its own copy of the configuration, so after calling it, you
can discard the WrenConfiguration struct you filled in. Now you have a live
VM, waiting to run some code!

## Executing Wren code

You execute a string of Wren source code like so:

<pre class="snippet" data-lang="c">
WrenInterpretResult result = wrenInterpret(
    vm,
    "my_module",
    "System.print(\"I am running in a VM!\")");
</pre>

The string is a series of one or more statements separated by newlines. Wren
copies the string, so you can free it after calling this. When you call
`wrenInterpret()`, Wren first compiles your source to bytecode. If an error
occurs, it returns immediately with `WREN_RESULT_COMPILE_ERROR`.

Otherwise, Wren spins up a new [fiber][] and executes the code in that. Your
code can in turn spawn whatever other fibers it wants. It keeps running fibers
until they all complete or one [suspends].

[fiber]: ../concurrency.html
[suspends]: ../modules/core/fiber.html#fiber.suspend()

If a [runtime error][] occurs (and another fiber doesn't handle it), Wren aborts
fibers all the way back to the main one and returns `WREN_RESULT_RUNTIME_ERROR`.
Otherwise, when the last fiber successfully returns, it returns
`WREN_RESULT_SUCCESS`.

[runtime error]: ../error-handling.html

All code passed to `wrenInterpret()` runs in a special "main" module. That way,
top-level names defined in one call can be accessed in later ones. It's similar
to a REPL session.

## Shutting down a VM

Once the party is over and you're ready to end your relationship with a VM, you
need to free any memory it allocated. You do that like so:

<pre class="snippet" data-lang="c">
wrenFreeVM(vm);
</pre>

After calling that, you obviously cannot use the `WrenVM*` you passed to it
again. It's dead.

Note that Wren will yell at you if you still have any live [WrenHandle][handle]
objects when you call this. This makes sure you haven't lost track of any of
them (which leaks memory) and you don't try to use any of them after the VM has
been freed.

## A complete example

Below is a complete example of the above.
You can find this file in the [example](https://github.com/wren-lang/wren/blob/main/example/embedding/main.c) folder.

<pre class="snippet" data-lang="c">
//For more details, visit https://wren.io/embedding/

#include &lt;stdio.h>
#include "wren.h"

static void writeFn(WrenVM* vm, const char* text)
{
  printf("%s", text);
}

void errorFn(WrenVM* vm, WrenErrorType errorType,
             const char* module, const int line,
             const char* msg)
{
  switch (errorType)
  {
    case WREN_ERROR_COMPILE:
    {
      printf("[%s line %d] [Error] %s\n", module, line, msg);
    } break;
    case WREN_ERROR_STACK_TRACE:
    {
      printf("[%s line %d] in %s\n", module, line, msg);
    } break;
    case WREN_ERROR_RUNTIME:
    {
      printf("[Runtime Error] %s\n", msg);
    } break;
  }
}

int main()
{

  WrenConfiguration config;
  wrenInitConfiguration(&config);
    config.writeFn = &writeFn;
    config.errorFn = &errorFn;
  WrenVM* vm = wrenNewVM(&config);

  const char* module = "main";
  const char* script = "System.print(\"I am running in a VM!\")";

  WrenInterpretResult result = wrenInterpret(vm, module, script);

  switch (result) {
    case WREN_RESULT_COMPILE_ERROR:
      { printf("Compile Error!\n"); } break;
    case WREN_RESULT_RUNTIME_ERROR:
      { printf("Runtime Error!\n"); } break;
    case WREN_RESULT_SUCCESS:
      { printf("Success!\n"); } break;
  }

  wrenFreeVM(vm);

}
</pre>

[handle]: slots-and-handles.html#handles

Next, we'll learn to make that VM do useful stuff...

<a class="right" href="slots-and-handles.html">Slots and Handles &rarr;</a>


================================================
FILE: doc/site/embedding/slots-and-handles.markdown
================================================
^title Slots and Handles

With `wrenInterpret()`, we can execute code, but that code can't do anything
particularly interesting. By default, the VM is isolated from the rest of the
world, so pretty much all it can do is turn your laptop into a lap warmer.

To make our Wren code *useful*, the VM needs to communicate with the outside
world. Wren uses a single unified set of functions for passing data into and out
of the VM. These functions are based on two fundamental concepts: **slots** and
**handles**.

## The Slot Array

When you want to send data to Wren, read data from it, or generally monkey
around with Wren objects from C, you do so by going through an array of slots.
Think of it as a shared message board that both the VM and your C code leave
notes on for the other side to process.

The array is zero-based, and each slot can hold a value of any type. It is
dynamically sized, but it's your responsibility to ensure there are enough slots
*before* you use them. You do this by calling:

<pre class="snippet" data-lang="c">
wrenEnsureSlots(WrenVM* vm, int slotCount);
</pre>

This grows the slot array if needed to ensure that many slots are available. If
it's already big enough, this does nothing. You'll typically call this once
before populating the slots with data that you want to send to Wren.

<pre class="snippet" data-lang="c">
wrenEnsureSlots(vm, 4);
// Can now use slots 0 through 3, inclusive.
</pre>

After you ensure an array of slots, you can only rely on them being there until
you pass control back to Wren. That includes calling `wrenCall()` or
`wrenInterpret()`, or returning from a [foreign method][].

[foreign method]: calling-c-from-wren.html

If you read or write from a slot that you haven't ensured is valid, Wren makes
no guarantees about what will happen. I've heard rumors of smoke and feathers
flying out of a user's computer.

If you want to see how big the slot array is, use:

<pre class="snippet" data-lang="c">
int wrenGetSlotCount(WrenVM* vm);
</pre>

It returns the number of slots in the array. Note that this may be higher than
the size you've ensured. Wren reuses the memory for this array when possible,
so you may get one bigger than you need if it happened to be laying around.

When Wren [calls your C code][] and passes data to you, it ensures there are
enough slots for the objects it is sending you.

[calls your c code]: calling-c-from-wren.html

### Writing slots

Once you have some slots, you store data in them using a number of functions all
named `wrenSetSlot<type>()` where `<type>` is the kind of data. We'll start with
the simple ones:

<pre class="snippet" data-lang="c">
void wrenSetSlotBool(WrenVM* vm, int slot, bool value);
void wrenSetSlotDouble(WrenVM* vm, int slot, double value);
void wrenSetSlotNull(WrenVM* vm, int slot);
</pre>

Each of these takes a primitive C value and converts it to the corresponding
[Wren value][]. (Since Wren's [native number type][] *is* a double, there's not
really much *conversion* going on, but you get the idea.)

[wren value]: ../values.html
[native number type]: ../values.html#numbers

You can also pass string data to Wren:

<pre class="snippet" data-lang="c">
void wrenSetSlotBytes(WrenVM* vm, int slot,
                      const char* bytes, size_t length);

void wrenSetSlotString(WrenVM* vm, int slot,
                       const char* text);
</pre>

Both of these copy the bytes into a new [String][] object managed by Wren's
garbage collector, so you can free your copy of it after you call this. The
difference between the two is that `wrenSetSlotBytes()` takes an explicit
length. Since Wren strings may contain arbitrary byte values, including the null
byte, this lets you pass those in. It's also a little faster to use this for
regular strings if you happen to know the length. The latter calculates the
length of the string using `strlen()`.

[string]: ../values.html#strings

### Reading slots

You can, of course, also pull data out of slots. Here are the simple ones:

<pre class="snippet" data-lang="c">
bool wrenGetSlotBool(WrenVM* vm, int slot);
double wrenGetSlotDouble(WrenVM* vm, int slot);
</pre>

These take a Wren value of the corresponding type and convert it to its raw C
representation. For strings, we have:

<pre class="snippet" data-lang="c">
const char* wrenGetSlotString(WrenVM* vm, int slot);
const char* wrenGetSlotBytes(WrenVM* vm, int slot,
                             int* length);
</pre>

These return a pointer to the first byte of the string. If you want to know the
length, the latter stores it in the variable pointed to by `length`. Both of
these return a direct pointer to the bytes managed by Wren. You should not hold
on to this pointer for long. Wren does not promise that it won't move or free
the data.

With these functions, you are going from dynamically typed Wren data to
statically typed C. It's up to *you* to ensure that you read a value as the
correct type. If you read a number from a slot that currently holds a string,
you're gonna have a bad time.

Fortunately, you usually know what type of data you have in a slot. If not, you
can ask:

<pre class="snippet" data-lang="c">
WrenType wrenGetSlotType(WrenVM* vm, int slot);
</pre>

This returns an enum defining what type of value is in the slot. It only covers
the primitive values that are supported by the C API. Things like ranges and
instances of classes come back as `WREN_TYPE_UNKNOWN`. If you want to move that
kind of data between Wren and C, you'll have to pull the object apart into
simple primitive values first or use a [foreign class][].

[foreign class]: storing-c-data.html

### Looking up variables

There are a few other utility functions that move data into and out of slots.
Here's the first:

<pre class="snippet" data-lang="c">
void wrenGetVariable(WrenVM* vm, const char* module,
                     const char* name, int slot);
</pre>

This looks up a top level variable with the given name in the module with the
given name and stores its value in the given slot. Note that classes are just
objects stored in variables too, so you can use this to look up a class by its
name. Handy for calling static methods on it.

Like any method that works with strings, this one is a bit slow. It has to hash
the name and look it up in the module's string table. You might want to avoid
calling this in the middle of a hot loop where performance is critical. Instead,
it's faster to look up the variable once outside the loop and store a reference
to the object using a [handle](#handles).

### Working with lists

The slot array is fine for moving a fixed number of objects between Wren and
C, but sometimes you need to shuttle a larger or dynamically-sized ball of
stuff. [List objects][lists] work well for that, so the C API lets you work
with them directly.

[lists]: ../lists.html

You can create a new empty list from C using:

<pre class="snippet" data-lang="c">
void wrenSetSlotNewList(WrenVM* vm, int slot);
</pre>

It stores the resulting list in the given slot. If you have a list in a
slot&mdash;either one you created from C or from Wren&mdash;you can add elements
to it using:

<pre class="snippet" data-lang="c">
void wrenInsertInList(WrenVM* vm, int listSlot, int index,
                      int elementSlot);
</pre>

That's a lot of int parameters:

* `listSlot` is the slot where the list object is stored. That's the list you'll
  be modifying. If you crea
Download .txt
gitextract_srwgaxf_/

├── .github/
│   └── workflows/
│       └── .githubCI.yml
├── .gitignore
├── .travis.sh
├── .travis.yml
├── AUTHORS
├── CHANGELOG.md
├── LICENSE
├── README.md
├── doc/
│   ├── error-handling.txt
│   ├── implicit fields.txt
│   ├── instruction counts.txt
│   ├── notes/
│   │   ├── import syntax.md
│   │   └── re-entrancy.md
│   ├── receiver-less calls 2.txt
│   ├── receiver-less calls.txt
│   ├── rfc/
│   │   └── 0001-smarter-imports.md
│   └── site/
│       ├── blog/
│       │   ├── 0-hello-wren.markdown
│       │   ├── 1-0.2.0-and-beyond.markdown
│       │   ├── 2-0.3.0-released.markdown
│       │   ├── 3-0.4.0-released.markdown
│       │   ├── index.markdown
│       │   ├── rss.xml
│       │   └── template.html
│       ├── classes.markdown
│       ├── cli/
│       │   ├── index.markdown
│       │   ├── modules/
│       │   │   ├── index.markdown
│       │   │   ├── io/
│       │   │   │   ├── directory.markdown
│       │   │   │   ├── file-flags.markdown
│       │   │   │   ├── file.markdown
│       │   │   │   ├── index.markdown
│       │   │   │   ├── stat.markdown
│       │   │   │   ├── stdin.markdown
│       │   │   │   ├── stdout.markdown
│       │   │   │   └── template.html
│       │   │   ├── os/
│       │   │   │   ├── index.markdown
│       │   │   │   ├── platform.markdown
│       │   │   │   ├── process.markdown
│       │   │   │   └── template.html
│       │   │   ├── scheduler/
│       │   │   │   ├── index.markdown
│       │   │   │   ├── scheduler.markdown
│       │   │   │   └── template.html
│       │   │   ├── template.html
│       │   │   └── timer/
│       │   │       ├── index.markdown
│       │   │       ├── template.html
│       │   │       └── timer.markdown
│       │   ├── template.html
│       │   └── usage.markdown
│       ├── concurrency.markdown
│       ├── contributing.markdown
│       ├── control-flow.markdown
│       ├── embedding/
│       │   ├── calling-c-from-wren.markdown
│       │   ├── calling-wren-from-c.markdown
│       │   ├── configuring-the-vm.markdown
│       │   ├── index.markdown
│       │   ├── slots-and-handles.markdown
│       │   ├── storing-c-data.markdown
│       │   └── template.html
│       ├── error-handling.markdown
│       ├── functions.markdown
│       ├── getting-started.markdown
│       ├── index.markdown
│       ├── lists.markdown
│       ├── maps.markdown
│       ├── method-calls.markdown
│       ├── modularity.markdown
│       ├── modules/
│       │   ├── core/
│       │   │   ├── bool.markdown
│       │   │   ├── class.markdown
│       │   │   ├── fiber.markdown
│       │   │   ├── fn.markdown
│       │   │   ├── index.markdown
│       │   │   ├── list.markdown
│       │   │   ├── map.markdown
│       │   │   ├── null.markdown
│       │   │   ├── num.markdown
│       │   │   ├── object.markdown
│       │   │   ├── range.markdown
│       │   │   ├── sequence.markdown
│       │   │   ├── string.markdown
│       │   │   ├── system.markdown
│       │   │   └── template.html
│       │   ├── index.markdown
│       │   ├── meta/
│       │   │   ├── index.markdown
│       │   │   ├── meta.markdown
│       │   │   └── template.html
│       │   ├── random/
│       │   │   ├── index.markdown
│       │   │   ├── random.markdown
│       │   │   └── template.html
│       │   └── template.html
│       ├── performance.markdown
│       ├── qa.markdown
│       ├── static/
│       │   ├── codejar-linenumbers.js
│       │   ├── codejar.js
│       │   ├── prism.css
│       │   ├── prism.js
│       │   ├── style.css
│       │   ├── wren.js
│       │   ├── wren_try.js
│       │   └── wren_try.wasm
│       ├── syntax.markdown
│       ├── template.html
│       ├── try/
│       │   ├── index.markdown
│       │   └── template.html
│       ├── values.markdown
│       └── variables.markdown
├── example/
│   ├── embedding/
│   │   └── main.c
│   ├── hello.wren
│   ├── import_module/
│   │   ├── cthulu.wren
│   │   └── lovecraft.wren
│   ├── mandelbrot.wren
│   ├── skynet.wren
│   └── syntax.wren
├── projects/
│   ├── make/
│   │   ├── Makefile
│   │   ├── wren.make
│   │   ├── wren_shared.make
│   │   └── wren_test.make
│   ├── make.bsd/
│   │   ├── Makefile
│   │   ├── wren.make
│   │   ├── wren_shared.make
│   │   └── wren_test.make
│   ├── make.mac/
│   │   ├── Makefile
│   │   ├── wren.make
│   │   ├── wren_shared.make
│   │   └── wren_test.make
│   ├── premake/
│   │   └── premake5.lua
│   ├── vs2017/
│   │   ├── wren.sln
│   │   ├── wren.vcxproj
│   │   ├── wren.vcxproj.filters
│   │   ├── wren_shared.vcxproj
│   │   ├── wren_shared.vcxproj.filters
│   │   ├── wren_test.vcxproj
│   │   └── wren_test.vcxproj.filters
│   ├── vs2019/
│   │   ├── wren.sln
│   │   ├── wren.vcxproj
│   │   ├── wren.vcxproj.filters
│   │   ├── wren_shared.vcxproj
│   │   ├── wren_shared.vcxproj.filters
│   │   ├── wren_test.vcxproj
│   │   └── wren_test.vcxproj.filters
│   └── xcode/
│       ├── wren.xcodeproj/
│       │   └── project.pbxproj
│       ├── wren.xcworkspace/
│       │   └── contents.xcworkspacedata
│       ├── wren_shared.xcodeproj/
│       │   └── project.pbxproj
│       └── wren_test.xcodeproj/
│           └── project.pbxproj
├── src/
│   ├── README.md
│   ├── include/
│   │   ├── wren.h
│   │   └── wren.hpp
│   ├── optional/
│   │   ├── wren_opt_meta.c
│   │   ├── wren_opt_meta.h
│   │   ├── wren_opt_meta.wren
│   │   ├── wren_opt_meta.wren.inc
│   │   ├── wren_opt_random.c
│   │   ├── wren_opt_random.h
│   │   ├── wren_opt_random.wren
│   │   └── wren_opt_random.wren.inc
│   └── vm/
│       ├── wren_common.h
│       ├── wren_compiler.c
│       ├── wren_compiler.h
│       ├── wren_core.c
│       ├── wren_core.h
│       ├── wren_core.wren
│       ├── wren_core.wren.inc
│       ├── wren_debug.c
│       ├── wren_debug.h
│       ├── wren_math.h
│       ├── wren_opcodes.h
│       ├── wren_primitive.c
│       ├── wren_primitive.h
│       ├── wren_utils.c
│       ├── wren_utils.h
│       ├── wren_value.c
│       ├── wren_value.h
│       ├── wren_vm.c
│       └── wren_vm.h
├── test/
│   ├── README.md
│   ├── api/
│   │   ├── api_tests.c
│   │   ├── api_tests.h
│   │   ├── benchmark.c
│   │   ├── benchmark.h
│   │   ├── call.c
│   │   ├── call.h
│   │   ├── call.wren
│   │   ├── call_calls_foreign.c
│   │   ├── call_calls_foreign.h
│   │   ├── call_calls_foreign.wren
│   │   ├── call_wren_call_root.c
│   │   ├── call_wren_call_root.h
│   │   ├── call_wren_call_root.wren
│   │   ├── error.c
│   │   ├── error.h
│   │   ├── error.wren
│   │   ├── foreign_class.c
│   │   ├── foreign_class.h
│   │   ├── foreign_class.wren
│   │   ├── get_variable.c
│   │   ├── get_variable.h
│   │   ├── get_variable.wren
│   │   ├── get_variable_module.wren
│   │   ├── handle.c
│   │   ├── handle.h
│   │   ├── handle.wren
│   │   ├── lists.c
│   │   ├── lists.h
│   │   ├── lists.wren
│   │   ├── maps.c
│   │   ├── maps.h
│   │   ├── maps.wren
│   │   ├── new_vm.c
│   │   ├── new_vm.h
│   │   ├── new_vm.wren
│   │   ├── reset_stack_after_call_abort.c
│   │   ├── reset_stack_after_call_abort.h
│   │   ├── reset_stack_after_call_abort.wren
│   │   ├── reset_stack_after_foreign_construct.c
│   │   ├── reset_stack_after_foreign_construct.h
│   │   ├── reset_stack_after_foreign_construct.wren
│   │   ├── resolution.c
│   │   ├── resolution.h
│   │   ├── resolution.wren
│   │   ├── slots.c
│   │   ├── slots.h
│   │   ├── slots.wren
│   │   ├── user_data.c
│   │   ├── user_data.h
│   │   └── user_data.wren
│   ├── benchmark/
│   │   ├── README.md
│   │   ├── api_call.wren
│   │   ├── api_foreign_method.wren
│   │   ├── binary_trees.dart
│   │   ├── binary_trees.lua
│   │   ├── binary_trees.py
│   │   ├── binary_trees.rb
│   │   ├── binary_trees.wren
│   │   ├── binary_trees_gc.wren
│   │   ├── delta_blue.dart
│   │   ├── delta_blue.lua.inprogress
│   │   ├── delta_blue.py
│   │   ├── delta_blue.wren
│   │   ├── fannkuch.lua
│   │   ├── fannkuch.py
│   │   ├── fannkuch.rb
│   │   ├── fib.dart
│   │   ├── fib.lua
│   │   ├── fib.py
│   │   ├── fib.rb
│   │   ├── fib.wren
│   │   ├── fibers.wren
│   │   ├── for.dart
│   │   ├── for.lua
│   │   ├── for.py
│   │   ├── for.rb
│   │   ├── for.wren
│   │   ├── map_numeric.dart.skip
│   │   ├── map_numeric.lua
│   │   ├── map_numeric.py
│   │   ├── map_numeric.rb
│   │   ├── map_numeric.wren
│   │   ├── map_string.lua
│   │   ├── map_string.py
│   │   ├── map_string.rb
│   │   ├── map_string.wren
│   │   ├── method_call.dart
│   │   ├── method_call.lua
│   │   ├── method_call.py
│   │   ├── method_call.rb
│   │   ├── method_call.wren
│   │   ├── string_equals.py
│   │   └── string_equals.wren
│   ├── core/
│   │   ├── bool/
│   │   │   ├── equality.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── not.wren
│   │   │   ├── to_string.wren
│   │   │   └── type.wren
│   │   ├── class/
│   │   │   ├── equality.wren
│   │   │   ├── name.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── supertype.wren
│   │   │   └── type.wren
│   │   ├── fiber/
│   │   │   ├── abort.wren
│   │   │   ├── abort_main_fiber.wren
│   │   │   ├── abort_not_string.wren
│   │   │   ├── abort_null.wren
│   │   │   ├── call.wren
│   │   │   ├── call_direct_reenter.wren
│   │   │   ├── call_done.wren
│   │   │   ├── call_error.wren
│   │   │   ├── call_indirect_reenter.wren
│   │   │   ├── call_return_implicit_null.wren
│   │   │   ├── call_return_value.wren
│   │   │   ├── call_root.wren
│   │   │   ├── call_to_parameter.wren
│   │   │   ├── call_transferred.wren
│   │   │   ├── call_with_value.wren
│   │   │   ├── call_with_value_direct_reenter.wren
│   │   │   ├── call_with_value_done.wren
│   │   │   ├── call_with_value_error.wren
│   │   │   ├── call_with_value_indirect_reenter.wren
│   │   │   ├── call_with_value_to_parameter.wren
│   │   │   ├── call_with_value_transferred.wren
│   │   │   ├── error.wren
│   │   │   ├── is_done.wren
│   │   │   ├── is_done_after_error.wren
│   │   │   ├── new_wrong_arg_type.wren
│   │   │   ├── new_wrong_arity.wren
│   │   │   ├── resume_caller.wren
│   │   │   ├── transfer.wren
│   │   │   ├── transfer_direct_reenter.wren
│   │   │   ├── transfer_error.wren
│   │   │   ├── transfer_error_not_string.wren
│   │   │   ├── transfer_indirect_reenter.wren
│   │   │   ├── transfer_return_call_value.wren
│   │   │   ├── transfer_return_transfer_value.wren
│   │   │   ├── transfer_to_done.wren
│   │   │   ├── transfer_to_error.wren
│   │   │   ├── transfer_to_parameter.wren
│   │   │   ├── transfer_to_yielded.wren
│   │   │   ├── transfer_with_value.wren
│   │   │   ├── transfer_with_value_direct_reenter.wren
│   │   │   ├── transfer_with_value_indirect_reenter.wren
│   │   │   ├── transfer_with_value_to_done.wren
│   │   │   ├── transfer_with_value_to_error.wren
│   │   │   ├── transfer_with_value_to_parameter.wren
│   │   │   ├── transfer_with_value_to_yielded.wren
│   │   │   ├── try.wren
│   │   │   ├── try_direct_reenter.wren
│   │   │   ├── try_done.wren
│   │   │   ├── try_error.wren
│   │   │   ├── try_indirect_reenter.wren
│   │   │   ├── try_through_call.wren
│   │   │   ├── try_value.wren
│   │   │   ├── try_value_yield.wren
│   │   │   ├── try_without_error.wren
│   │   │   ├── type.wren
│   │   │   ├── yield.wren
│   │   │   ├── yield_from_import.wren
│   │   │   ├── yield_from_import_module.wren
│   │   │   ├── yield_from_main.wren
│   │   │   ├── yield_return_call_value.wren
│   │   │   ├── yield_return_transfer_value.wren
│   │   │   ├── yield_with_no_caller.wren
│   │   │   ├── yield_with_value.wren
│   │   │   ├── yield_with_value_from_main.wren
│   │   │   └── yield_with_value_with_no_caller.wren
│   │   ├── function/
│   │   │   ├── arity.wren
│   │   │   ├── call_extra_arguments.wren
│   │   │   ├── call_missing_arguments.wren
│   │   │   ├── call_runtime_error.wren
│   │   │   ├── equality.wren
│   │   │   ├── new_wrong_arg_type.wren
│   │   │   ├── to_string.wren
│   │   │   └── type.wren
│   │   ├── list/
│   │   │   ├── add.wren
│   │   │   ├── add_all.wren
│   │   │   ├── clear.wren
│   │   │   ├── contains.wren
│   │   │   ├── count.wren
│   │   │   ├── count_predicate.wren
│   │   │   ├── count_predicate_non_bool_returning_fn.wren
│   │   │   ├── count_predicate_non_function_arg.wren
│   │   │   ├── each.wren
│   │   │   ├── each_no_items.wren
│   │   │   ├── each_non_function_arg.wren
│   │   │   ├── filled.wren
│   │   │   ├── filled_size_negative.wren
│   │   │   ├── filled_size_not_int.wren
│   │   │   ├── filled_size_not_num.wren
│   │   │   ├── index_of.wren
│   │   │   ├── insert.wren
│   │   │   ├── insert_index_not_int.wren
│   │   │   ├── insert_index_not_num.wren
│   │   │   ├── insert_index_too_large.wren
│   │   │   ├── insert_index_too_small.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_iterator_not_int.wren
│   │   │   ├── iterate_iterator_not_num.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── iterator_value_iterator_not_int.wren
│   │   │   ├── iterator_value_iterator_not_num.wren
│   │   │   ├── iterator_value_iterator_too_large.wren
│   │   │   ├── iterator_value_iterator_too_small.wren
│   │   │   ├── join.wren
│   │   │   ├── join_separator_not_string.wren
│   │   │   ├── map.wren
│   │   │   ├── multiply.wren
│   │   │   ├── multiply_negative.wren
│   │   │   ├── multiply_not_int.wren
│   │   │   ├── multiply_not_num.wren
│   │   │   ├── new.wren
│   │   │   ├── not.wren
│   │   │   ├── plus.wren
│   │   │   ├── plus_not_iterable.wren
│   │   │   ├── reduce.wren
│   │   │   ├── reduce_no_items.wren
│   │   │   ├── reduce_single_item.wren
│   │   │   ├── reduce_wrong_arity.wren
│   │   │   ├── remove.wren
│   │   │   ├── remove_at.wren
│   │   │   ├── remove_at_index_not_int.wren
│   │   │   ├── remove_at_index_not_num.wren
│   │   │   ├── remove_at_index_too_large.wren
│   │   │   ├── remove_at_index_too_small.wren
│   │   │   ├── sort.wren
│   │   │   ├── subscript.wren
│   │   │   ├── subscript_not_int.wren
│   │   │   ├── subscript_range.wren
│   │   │   ├── subscript_range_from_not_int.wren
│   │   │   ├── subscript_range_from_too_large.wren
│   │   │   ├── subscript_range_from_too_small.wren
│   │   │   ├── subscript_range_to_exclusive_too_large.wren
│   │   │   ├── subscript_range_to_exclusive_too_small.wren
│   │   │   ├── subscript_range_to_not_int.wren
│   │   │   ├── subscript_range_to_too_large.wren
│   │   │   ├── subscript_range_to_too_small.wren
│   │   │   ├── subscript_setter.wren
│   │   │   ├── subscript_setter_not_int.wren
│   │   │   ├── subscript_setter_not_num.wren
│   │   │   ├── subscript_setter_too_large.wren
│   │   │   ├── subscript_setter_too_small.wren
│   │   │   ├── subscript_too_large.wren
│   │   │   ├── subscript_too_small.wren
│   │   │   ├── subscript_wrong_type.wren
│   │   │   ├── swap.wren
│   │   │   ├── to_string.wren
│   │   │   ├── type.wren
│   │   │   └── where.wren
│   │   ├── map/
│   │   │   ├── churn.wren
│   │   │   ├── clear.wren
│   │   │   ├── contains_key.wren
│   │   │   ├── contains_key_not_value.wren
│   │   │   ├── count.wren
│   │   │   ├── empty_string_key.wren
│   │   │   ├── is_empty.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_iterator_not_int.wren
│   │   │   ├── iterate_iterator_not_num.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── iterator_value_iterator_not_int.wren
│   │   │   ├── iterator_value_iterator_not_num.wren
│   │   │   ├── iterator_value_iterator_too_large.wren
│   │   │   ├── iterator_value_iterator_too_small.wren
│   │   │   ├── key_iterate.wren
│   │   │   ├── key_iterate_iterator_not_int.wren
│   │   │   ├── key_iterate_iterator_not_num.wren
│   │   │   ├── key_types.wren
│   │   │   ├── new.wren
│   │   │   ├── remove.wren
│   │   │   ├── remove_key_not_value.wren
│   │   │   ├── reuse_tombstone.wren
│   │   │   ├── subscript_empty_map.wren
│   │   │   ├── subscript_key_not_value.wren
│   │   │   ├── subscript_setter_key_not_value.wren
│   │   │   ├── to_string.wren
│   │   │   ├── type.wren
│   │   │   ├── value_iterate.wren
│   │   │   ├── value_iterate_iterator_not_int.wren
│   │   │   └── value_iterate_iterator_not_num.wren
│   │   ├── map_entry/
│   │   │   └── new.wren
│   │   ├── null/
│   │   │   ├── no_constructor.wren
│   │   │   ├── not.wren
│   │   │   └── type.wren
│   │   ├── number/
│   │   │   ├── abs.wren
│   │   │   ├── acos.wren
│   │   │   ├── asin.wren
│   │   │   ├── atan.wren
│   │   │   ├── atan2.wren
│   │   │   ├── atan2_x_not_num.wren
│   │   │   ├── bitwise_and.wren
│   │   │   ├── bitwise_and_operand_not_num.wren
│   │   │   ├── bitwise_lsh.wren
│   │   │   ├── bitwise_lsh_operand_not_num.wren
│   │   │   ├── bitwise_not.wren
│   │   │   ├── bitwise_or.wren
│   │   │   ├── bitwise_or_operand_not_num.wren
│   │   │   ├── bitwise_rsh.wren
│   │   │   ├── bitwise_rsh_operand_not_num.wren
│   │   │   ├── bitwise_xor.wren
│   │   │   ├── bitwise_xor_operand_not_num.wren
│   │   │   ├── cbrt.wren
│   │   │   ├── ceil.wren
│   │   │   ├── clamp.wren
│   │   │   ├── clamp_max_not_num.wren
│   │   │   ├── clamp_min_not_num.wren
│   │   │   ├── comparison.wren
│   │   │   ├── cos.wren
│   │   │   ├── decimal_point_at_eof.wren
│   │   │   ├── divide.wren
│   │   │   ├── divide_operand_not_num.wren
│   │   │   ├── equality.wren
│   │   │   ├── exp.wren
│   │   │   ├── floor.wren
│   │   │   ├── fraction.wren
│   │   │   ├── from_string.wren
│   │   │   ├── from_string_not_string.wren
│   │   │   ├── from_string_too_large.wren
│   │   │   ├── greater_than_equal_operand_not_num.wren
│   │   │   ├── greater_than_operand_not_num.wren
│   │   │   ├── invalid_hex_literal.wren
│   │   │   ├── is_infinity.wren
│   │   │   ├── is_integer.wren
│   │   │   ├── is_nan.wren
│   │   │   ├── largest.wren
│   │   │   ├── less_than_equal_operand_not_num.wren
│   │   │   ├── less_than_operand_not_num.wren
│   │   │   ├── log.wren
│   │   │   ├── log2.wren
│   │   │   ├── maxSafeInteger.wren
│   │   │   ├── max_other_not_num.wren
│   │   │   ├── minSafeInteger.wren
│   │   │   ├── min_max.wren
│   │   │   ├── min_other_not_num.wren
│   │   │   ├── minus.wren
│   │   │   ├── minus_operand_not_num.wren
│   │   │   ├── mod.wren
│   │   │   ├── mod_operand_not_num.wren
│   │   │   ├── multiply.wren
│   │   │   ├── multiply_operand_not_num.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── not.wren
│   │   │   ├── plus.wren
│   │   │   ├── plus_operand_not_num.wren
│   │   │   ├── pow.wren
│   │   │   ├── pow_power_not_num.wren
│   │   │   ├── round.wren
│   │   │   ├── sign.wren
│   │   │   ├── sin.wren
│   │   │   ├── smallest.wren
│   │   │   ├── sqrt.wren
│   │   │   ├── tan.wren
│   │   │   ├── to_string.wren
│   │   │   ├── truncate.wren
│   │   │   └── type.wren
│   │   ├── object/
│   │   │   ├── is.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── nonclass_on_right.wren
│   │   │   ├── not.wren
│   │   │   ├── same.wren
│   │   │   ├── to_string.wren
│   │   │   └── type.wren
│   │   ├── range/
│   │   │   ├── contains.wren
│   │   │   ├── equality.wren
│   │   │   ├── exclusive_range_wrong_rhs_type.wren
│   │   │   ├── from.wren
│   │   │   ├── inclusive_range_wrong_rhs_type.wren
│   │   │   ├── is_inclusive.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_from_float.wren
│   │   │   ├── iterate_wrong_type.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── join.wren
│   │   │   ├── join_separator_not_string.wren
│   │   │   ├── map.wren
│   │   │   ├── max.wren
│   │   │   ├── min.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── reduce.wren
│   │   │   ├── to.wren
│   │   │   ├── to_string.wren
│   │   │   ├── type.wren
│   │   │   └── where.wren
│   │   ├── sequence/
│   │   │   ├── all.wren
│   │   │   ├── all_non_function_arg.wren
│   │   │   ├── any.wren
│   │   │   ├── any_non_function_arg.wren
│   │   │   ├── count.wren
│   │   │   ├── is_empty.wren
│   │   │   ├── map.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── skip.wren
│   │   │   ├── skip_negative.wren
│   │   │   ├── skip_not_int.wren
│   │   │   ├── skip_not_num.wren
│   │   │   ├── take.wren
│   │   │   ├── take_negative.wren
│   │   │   ├── take_not_int.wren
│   │   │   ├── take_not_num.wren
│   │   │   ├── to_list.wren
│   │   │   └── where.wren
│   │   ├── string/
│   │   │   ├── bytes.wren
│   │   │   ├── concatenation.wren
│   │   │   ├── concatenation_wrong_arg_type.wren
│   │   │   ├── contains.wren
│   │   │   ├── contains_argument_not_string.wren
│   │   │   ├── count.wren
│   │   │   ├── ends_with.wren
│   │   │   ├── ends_with_invalid_arg.wren
│   │   │   ├── equality.wren
│   │   │   ├── from_byte.wren
│   │   │   ├── from_byte_not_int.wren
│   │   │   ├── from_byte_not_num.wren
│   │   │   ├── from_byte_too_large.wren
│   │   │   ├── from_byte_too_small.wren
│   │   │   ├── from_code_point.wren
│   │   │   ├── from_code_point_not_int.wren
│   │   │   ├── from_code_point_not_num.wren
│   │   │   ├── from_code_point_too_large.wren
│   │   │   ├── from_code_point_too_small.wren
│   │   │   ├── index_of.wren
│   │   │   ├── index_of_invalid_arg.wren
│   │   │   ├── index_of_start.wren
│   │   │   ├── index_of_start_not_int.wren
│   │   │   ├── index_of_start_not_num.wren
│   │   │   ├── index_of_start_too_large.wren
│   │   │   ├── index_of_start_too_small.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_iterator_not_int.wren
│   │   │   ├── iterate_iterator_not_num.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── iterator_value_iterator_not_int.wren
│   │   │   ├── iterator_value_iterator_not_num.wren
│   │   │   ├── iterator_value_iterator_too_large.wren
│   │   │   ├── iterator_value_iterator_too_small.wren
│   │   │   ├── join.wren
│   │   │   ├── join_separator_not_string.wren
│   │   │   ├── multiply.wren
│   │   │   ├── multiply_negative.wren
│   │   │   ├── multiply_not_int.wren
│   │   │   ├── multiply_not_num.wren
│   │   │   ├── no_constructor.wren
│   │   │   ├── not.wren
│   │   │   ├── replace.wren
│   │   │   ├── replace_empty_old.wren
│   │   │   ├── replace_new_not_string.wren
│   │   │   ├── replace_old_not_string.wren
│   │   │   ├── split.wren
│   │   │   ├── split_argument_not_string.wren
│   │   │   ├── split_empty_seperator.wren
│   │   │   ├── starts_with.wren
│   │   │   ├── starts_with_invalid_arg.wren
│   │   │   ├── subscript.wren
│   │   │   ├── subscript_not_int.wren
│   │   │   ├── subscript_not_num.wren
│   │   │   ├── subscript_range.wren
│   │   │   ├── subscript_range_from_not_int.wren
│   │   │   ├── subscript_range_from_too_large.wren
│   │   │   ├── subscript_range_from_too_small.wren
│   │   │   ├── subscript_range_to_exclusive_too_large.wren
│   │   │   ├── subscript_range_to_exclusive_too_small.wren
│   │   │   ├── subscript_range_to_not_int.wren
│   │   │   ├── subscript_range_to_too_large.wren
│   │   │   ├── subscript_range_to_too_small.wren
│   │   │   ├── subscript_too_large.wren
│   │   │   ├── subscript_too_small.wren
│   │   │   ├── to_string.wren
│   │   │   ├── trim.wren
│   │   │   ├── trim_chars_not_string.wren
│   │   │   ├── trim_end.wren
│   │   │   ├── trim_end_chars_not_string.wren
│   │   │   ├── trim_start.wren
│   │   │   ├── trim_start_chars_not_string.wren
│   │   │   └── type.wren
│   │   ├── string_byte_sequence/
│   │   │   ├── count.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_not_int.wren
│   │   │   ├── iterate_wrong_type.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── iterator_value_not_int.wren
│   │   │   ├── iterator_value_not_num.wren
│   │   │   ├── iterator_value_too_large.wren
│   │   │   ├── iterator_value_too_small.wren
│   │   │   ├── subscript.wren
│   │   │   ├── subscript_not_int.wren
│   │   │   ├── subscript_not_num.wren
│   │   │   ├── subscript_too_large.wren
│   │   │   └── subscript_too_small.wren
│   │   ├── string_code_point_sequence/
│   │   │   ├── count.wren
│   │   │   ├── iterate.wren
│   │   │   ├── iterate_iterator_not_int.wren
│   │   │   ├── iterate_iterator_not_num.wren
│   │   │   ├── iterator_value.wren
│   │   │   ├── iterator_value_incomplete.wren
│   │   │   ├── iterator_value_not_int.wren
│   │   │   ├── iterator_value_not_num.wren
│   │   │   ├── iterator_value_too_large.wren
│   │   │   ├── iterator_value_too_small.wren
│   │   │   ├── subscript.wren
│   │   │   ├── subscript_incomplete.wren
│   │   │   ├── subscript_not_int.wren
│   │   │   ├── subscript_not_num.wren
│   │   │   ├── subscript_too_large.wren
│   │   │   └── subscript_too_small.wren
│   │   └── system/
│   │       ├── print.wren
│   │       ├── print_all.wren
│   │       ├── print_all_not_sequence.wren
│   │       ├── print_bad_to_string.wren
│   │       ├── write_all.wren
│   │       ├── write_all_not_sequence.wren
│   │       └── write_bad_to_string.wren
│   ├── language/
│   │   ├── assignment/
│   │   │   ├── associativity.wren
│   │   │   ├── global.wren
│   │   │   ├── grouping.wren
│   │   │   ├── infix_operator.wren
│   │   │   ├── is.wren
│   │   │   ├── local.wren
│   │   │   ├── prefix_operator.wren
│   │   │   ├── syntax.wren
│   │   │   └── undefined.wren
│   │   ├── bitwise_precedence.wren
│   │   ├── bom.wren
│   │   ├── break/
│   │   │   ├── closure_in_for.wren
│   │   │   ├── closure_in_while.wren
│   │   │   ├── exit_local_scopes.wren
│   │   │   ├── in_for_loop.wren
│   │   │   ├── in_function_in_loop.wren
│   │   │   ├── in_method_in_loop.wren
│   │   │   ├── in_while_loop.wren
│   │   │   ├── nested_for_loop.wren
│   │   │   ├── nested_while_loop.wren
│   │   │   └── outside_loop.wren
│   │   ├── chained_newline.wren
│   │   ├── class/
│   │   │   ├── attributes/
│   │   │   │   ├── attributes.wren
│   │   │   │   ├── compile_only.wren
│   │   │   │   ├── duplicate_keys.wren
│   │   │   │   ├── groups.wren
│   │   │   │   ├── invalid_expression.wren
│   │   │   │   ├── invalid_scope.wren
│   │   │   │   ├── invalid_toplevel.wren
│   │   │   │   ├── literals.wren
│   │   │   │   ├── methods.wren
│   │   │   │   └── without.wren
│   │   │   ├── field_in_foreign_class.wren
│   │   │   ├── foreign_class_inherit_fields.wren
│   │   │   ├── lowercase_name_inside_body.wren
│   │   │   ├── missing_class_after_foreign.wren
│   │   │   ├── name_inside_body.wren
│   │   │   ├── newline_after_class.wren
│   │   │   ├── newline_after_static.wren
│   │   │   └── syntax.wren
│   │   ├── closure/
│   │   │   ├── assign_to_closure.wren
│   │   │   ├── close_over_function_parameter.wren
│   │   │   ├── close_over_later_variable.wren
│   │   │   ├── close_over_method_parameter.wren
│   │   │   ├── closed_closure_in_function.wren
│   │   │   ├── nested_closure.wren
│   │   │   ├── open_closure_in_function.wren
│   │   │   ├── reference_closure_multiple_times.wren
│   │   │   ├── reuse_closure_slot.wren
│   │   │   ├── shadow_closure_with_local.wren
│   │   │   ├── unused_closure.wren
│   │   │   └── unused_later_closure.wren
│   │   ├── comments/
│   │   │   ├── block.wren
│   │   │   ├── block_at_eof.wren
│   │   │   ├── line_at_eof.wren
│   │   │   ├── only_line_comment.wren
│   │   │   ├── only_line_comment_and_line.wren
│   │   │   ├── unicode.wren
│   │   │   ├── unterminated_block.wren
│   │   │   └── unterminated_nested_block.wren
│   │   ├── conditional/
│   │   │   ├── conditional_in_then.wren
│   │   │   ├── missing_colon.wren
│   │   │   ├── missing_condition.wren
│   │   │   ├── missing_else.wren
│   │   │   ├── missing_question.wren
│   │   │   ├── missing_then.wren
│   │   │   ├── newlines.wren
│   │   │   ├── precedence.wren
│   │   │   └── short_circuit.wren
│   │   ├── constructor/
│   │   │   ├── cannot_be_infix.wren
│   │   │   ├── cannot_be_minus.wren
│   │   │   ├── cannot_be_setter.wren
│   │   │   ├── cannot_be_static.wren
│   │   │   ├── cannot_be_subscript.wren
│   │   │   ├── cannot_be_unary.wren
│   │   │   ├── cannot_call_initializer.wren
│   │   │   ├── cannot_return_value.wren
│   │   │   ├── named.wren
│   │   │   ├── no_default.wren
│   │   │   ├── no_parameter_list.wren
│   │   │   ├── not_inherited.wren
│   │   │   ├── return_without_value.wren
│   │   │   ├── super_must_have_args.wren
│   │   │   └── superclass.wren
│   │   ├── continue/
│   │   │   ├── closure_in_for.wren
│   │   │   ├── closure_in_while.wren
│   │   │   ├── exit_local_scopes.wren
│   │   │   ├── in_for_loop.wren
│   │   │   ├── in_function_in_loop.wren
│   │   │   ├── in_method_in_loop.wren
│   │   │   ├── in_while_loop.wren
│   │   │   ├── nested_for_loop.wren
│   │   │   ├── nested_while_loop.wren
│   │   │   └── outside_loop.wren
│   │   ├── deeply_nested_gc.wren
│   │   ├── empty_block.wren
│   │   ├── empty_file.wren
│   │   ├── fiber/
│   │   │   └── closure.wren
│   │   ├── field/
│   │   │   ├── closure.wren
│   │   │   ├── default_to_null.wren
│   │   │   ├── in_fn_in_static_method.wren
│   │   │   ├── in_static_method.wren
│   │   │   ├── in_static_method_in_nested_class.wren
│   │   │   ├── multiple.wren
│   │   │   ├── nested_class.wren
│   │   │   ├── object_reference.wren
│   │   │   ├── outside_class.wren
│   │   │   └── use_before_set.wren
│   │   ├── for/
│   │   │   ├── close_over_loop_variable.wren
│   │   │   ├── closure_in_body.wren
│   │   │   ├── newline_after_for.wren
│   │   │   ├── newline_before_in.wren
│   │   │   ├── only_evaluate_sequence_once.wren
│   │   │   ├── return_closure.wren
│   │   │   ├── return_inside.wren
│   │   │   ├── syntax.wren
│   │   │   └── truth.wren
│   │   ├── foreign/
│   │   │   ├── foreign_after_static.wren
│   │   │   ├── foreign_method_with_body.wren
│   │   │   └── unknown_method.wren
│   │   ├── function/
│   │   │   ├── empty_body.wren
│   │   │   ├── newline_body.wren
│   │   │   ├── newline_in_expression_block.wren
│   │   │   ├── no_newline_before_close.wren
│   │   │   ├── no_parameters.wren
│   │   │   ├── parameters.wren
│   │   │   └── syntax.wren
│   │   ├── if/
│   │   │   ├── dangling_else.wren
│   │   │   ├── else.wren
│   │   │   ├── if.wren
│   │   │   ├── newline_after_else.wren
│   │   │   ├── newline_after_if.wren
│   │   │   └── truth.wren
│   │   ├── ignore_carriage_returns.wren
│   │   ├── implicit_receiver/
│   │   │   ├── inherited_methods.wren
│   │   │   ├── instance_methods.wren
│   │   │   ├── locals_shadow_getter.wren
│   │   │   ├── locals_shadow_setter.wren
│   │   │   ├── nested_class.wren
│   │   │   └── static_methods.wren
│   │   ├── inheritance/
│   │   │   ├── do_not_inherit_static_methods.wren
│   │   │   ├── inherit_fields.wren
│   │   │   ├── inherit_from_bool.wren
│   │   │   ├── inherit_from_class.wren
│   │   │   ├── inherit_from_closure.wren
│   │   │   ├── inherit_from_fiber.wren
│   │   │   ├── inherit_from_fn.wren
│   │   │   ├── inherit_from_list.wren
│   │   │   ├── inherit_from_map.wren
│   │   │   ├── inherit_from_nonclass.wren
│   │   │   ├── inherit_from_null.wren
│   │   │   ├── inherit_from_null_class.wren
│   │   │   ├── inherit_from_num.wren
│   │   │   ├── inherit_from_range.wren
│   │   │   ├── inherit_from_string.wren
│   │   │   ├── inherit_methods.wren
│   │   │   ├── inherited_fields_in_closure.wren
│   │   │   └── is.wren
│   │   ├── interpolation/
│   │   │   ├── empty.wren
│   │   │   ├── interpolation.wren
│   │   │   ├── runtime_error_in_expression.wren
│   │   │   ├── switch_fiber.wren
│   │   │   ├── unterminated.wren
│   │   │   └── unterminated_expression.wren
│   │   ├── list/
│   │   │   ├── duplicate_comma.wren
│   │   │   ├── duplicate_trailing_comma.wren
│   │   │   ├── empty_list_with_comma.wren
│   │   │   ├── eof_after_comma.wren
│   │   │   ├── eof_after_element.wren
│   │   │   ├── grow_shrink.wren
│   │   │   ├── newline_before_comma.wren
│   │   │   ├── newlines.wren
│   │   │   └── trailing_comma.wren
│   │   ├── logical_operator/
│   │   │   ├── and.wren
│   │   │   ├── and_truth.wren
│   │   │   ├── or.wren
│   │   │   └── or_truth.wren
│   │   ├── many_reallocations.wren
│   │   ├── map/
│   │   │   ├── bad_key_precedence.wren
│   │   │   ├── duplicate_comma.wren
│   │   │   ├── duplicate_trailing_comma.wren
│   │   │   ├── empty_map_with_comma.wren
│   │   │   ├── eof_after_colon.wren
│   │   │   ├── eof_after_comma.wren
│   │   │   ├── eof_after_key.wren
│   │   │   ├── eof_after_value.wren
│   │   │   ├── grow_and_shrink.wren
│   │   │   ├── newlines.wren
│   │   │   ├── precedence.wren
│   │   │   └── trailing_comma.wren
│   │   ├── method/
│   │   │   ├── arity.wren
│   │   │   ├── call_name_too_long.wren
│   │   │   ├── duplicate_methods.wren
│   │   │   ├── empty_block.wren
│   │   │   ├── empty_subscript_call.wren
│   │   │   ├── empty_subscript_definition.wren
│   │   │   ├── long_name.wren
│   │   │   ├── many_methods.wren
│   │   │   ├── name_too_long.wren
│   │   │   ├── newlines.wren
│   │   │   ├── no_parameters_new_line.wren
│   │   │   ├── not_found.wren
│   │   │   ├── not_found_eleven_arguments.wren
│   │   │   ├── not_found_multiple_arguments.wren
│   │   │   ├── not_found_one_argument.wren
│   │   │   ├── operators.wren
│   │   │   ├── static.wren
│   │   │   ├── static_method_not_found.wren
│   │   │   ├── static_operators.wren
│   │   │   ├── subscript_operators.wren
│   │   │   ├── subscript_setter_too_many_arguments.wren
│   │   │   ├── subscript_too_many_arguments.wren
│   │   │   ├── too_many_arguments.wren
│   │   │   └── too_many_parameters.wren
│   │   ├── module/
│   │   │   ├── change_imported_value/
│   │   │   │   ├── change_imported_value.wren
│   │   │   │   └── module.wren
│   │   │   ├── compile_error/
│   │   │   │   ├── compile_error.wren
│   │   │   │   └── module.wren
│   │   │   ├── cyclic_import/
│   │   │   │   ├── a.wren
│   │   │   │   ├── b.wren
│   │   │   │   └── cyclic_import.wren
│   │   │   ├── implicitly_imports_core/
│   │   │   │   ├── implicitly_imports_core.wren
│   │   │   │   └── module.wren
│   │   │   ├── import_as/
│   │   │   │   ├── import_as.wren
│   │   │   │   └── module.wren
│   │   │   ├── inside_block/
│   │   │   │   ├── inside_block.wren
│   │   │   │   └── module.wren
│   │   │   ├── missing_for.wren
│   │   │   ├── missing_string_after_import.wren
│   │   │   ├── module_dir/
│   │   │   │   ├── module_dir.wren
│   │   │   │   └── something/
│   │   │   │       └── module.wren
│   │   │   ├── multiple_variables/
│   │   │   │   ├── module.wren
│   │   │   │   └── multiple_variables.wren
│   │   │   ├── name_collision.wren
│   │   │   ├── newlines/
│   │   │   │   ├── module.wren
│   │   │   │   └── newlines.wren
│   │   │   ├── no_variable/
│   │   │   │   ├── module.wren
│   │   │   │   └── no_variable.wren
│   │   │   ├── relative_import/
│   │   │   │   ├── module_3.wren
│   │   │   │   ├── relative_import.wren
│   │   │   │   └── sub/
│   │   │   │       ├── dir/
│   │   │   │       │   ├── module.wren
│   │   │   │       │   └── module_2.wren
│   │   │   │       ├── module.wren
│   │   │   │       ├── module_2.wren
│   │   │   │       └── module_3.wren
│   │   │   ├── returns/
│   │   │   │   ├── module_return.wren
│   │   │   │   ├── module_return_value.wren
│   │   │   │   ├── return.wren
│   │   │   │   ├── return_from_import.wren
│   │   │   │   ├── return_value.wren
│   │   │   │   └── return_value_from_import.wren
│   │   │   ├── shared_import/
│   │   │   │   ├── a.wren
│   │   │   │   ├── b.wren
│   │   │   │   ├── shared.wren
│   │   │   │   └── shared_import.wren
│   │   │   ├── simple_import/
│   │   │   │   ├── module.wren
│   │   │   │   └── simple_import.wren
│   │   │   ├── unknown_module.wren
│   │   │   └── unknown_variable/
│   │   │       ├── module.wren
│   │   │       └── unknown_variable.wren
│   │   ├── no_trailing_newline.wren
│   │   ├── nonlocal/
│   │   │   ├── assignment.wren
│   │   │   ├── duplicate_nonlocal.wren
│   │   │   ├── in_block_scope.wren
│   │   │   ├── localname_forward_declare.wren
│   │   │   ├── mutual_recursion.wren
│   │   │   ├── nonlocal_in_initializer.wren
│   │   │   ├── nonlocal_without_initializer.wren
│   │   │   ├── null_before_defined.wren
│   │   │   ├── undefined.wren
│   │   │   ├── use_in_function.wren
│   │   │   ├── use_in_function_before_definition.wren
│   │   │   ├── use_in_method.wren
│   │   │   └── use_in_method_before_definition.wren
│   │   ├── null/
│   │   │   └── literal.wren
│   │   ├── number/
│   │   │   ├── hex_literals.wren
│   │   │   ├── hex_too_large.wren
│   │   │   ├── literal_too_large.wren
│   │   │   ├── literals.wren
│   │   │   ├── scientific_float_missing_exponent.wren
│   │   │   ├── scientific_floating_exponent.wren
│   │   │   ├── scientific_literals.wren
│   │   │   ├── scientific_missing_exponent.wren
│   │   │   ├── scientific_missing_fractional_part.wren
│   │   │   ├── scientific_multiple_exponants.wren
│   │   │   └── scientific_multiple_exponent_signs.wren
│   │   ├── precedence.wren
│   │   ├── return/
│   │   │   ├── after_else.wren
│   │   │   ├── after_if.wren
│   │   │   ├── after_while.wren
│   │   │   ├── in_function.wren
│   │   │   ├── in_method.wren
│   │   │   └── return_null_if_newline.wren
│   │   ├── semicolon.wren
│   │   ├── setter/
│   │   │   ├── associativity.wren
│   │   │   ├── grouping.wren
│   │   │   ├── infix_operator.wren
│   │   │   ├── instance.wren
│   │   │   ├── is.wren
│   │   │   ├── prefix_operator.wren
│   │   │   ├── result.wren
│   │   │   ├── same_name_as_method.wren
│   │   │   └── static.wren
│   │   ├── shebang/
│   │   │   ├── shebang.wren
│   │   │   ├── shebang_at_eof.wren
│   │   │   ├── shebang_at_other_line.wren
│   │   │   └── shebang_invalid.wren
│   │   ├── static_field/
│   │   │   ├── closure.wren
│   │   │   ├── default_to_null.wren
│   │   │   ├── in_instance_method.wren
│   │   │   ├── multiple.wren
│   │   │   ├── nested_class.wren
│   │   │   ├── outside_class.wren
│   │   │   └── use_before_set.wren
│   │   ├── string/
│   │   │   ├── byte_escapes.wren
│   │   │   ├── escapes.wren
│   │   │   ├── incomplete_byte_escape.wren
│   │   │   ├── incomplete_byte_escape_at_eof.wren
│   │   │   ├── incomplete_long_unicode_escape.wren
│   │   │   ├── incomplete_unicode_escape.wren
│   │   │   ├── incomplete_unicode_escape_at_eof.wren
│   │   │   ├── invalid_byte_escape.wren
│   │   │   ├── invalid_escape.wren
│   │   │   ├── invalid_unicode_escape.wren
│   │   │   ├── literals.wren
│   │   │   ├── unicode_escapes.wren
│   │   │   ├── unicode_two_bytes_to_long_escape.wren
│   │   │   ├── unterminated.wren
│   │   │   └── unterminated_raw.wren
│   │   ├── super/
│   │   │   ├── call_different_arity.wren
│   │   │   ├── call_other_method.wren
│   │   │   ├── call_same_method.wren
│   │   │   ├── closure.wren
│   │   │   ├── implicit_name.wren
│   │   │   ├── indirectly_inherited.wren
│   │   │   ├── no_superclass_method.wren
│   │   │   ├── super_at_top_level.wren
│   │   │   ├── super_in_closure_in_inherited_method.wren
│   │   │   ├── super_in_inherited_method.wren
│   │   │   ├── super_in_static_method.wren
│   │   │   └── super_in_top_level_function.wren
│   │   ├── this/
│   │   │   ├── closure.wren
│   │   │   ├── nested_class.wren
│   │   │   ├── nested_closure.wren
│   │   │   ├── this_at_top_level.wren
│   │   │   ├── this_in_method.wren
│   │   │   ├── this_in_static_method.wren
│   │   │   └── this_in_top_level_function.wren
│   │   ├── unexpected_character.wren
│   │   ├── variable/
│   │   │   ├── duplicate_local.wren
│   │   │   ├── duplicate_parameter.wren
│   │   │   ├── global_in_initializer.wren
│   │   │   ├── global_without_initializer.wren
│   │   │   ├── local_collide_with_function_parameter.wren
│   │   │   ├── local_collide_with_method_parameter.wren
│   │   │   ├── local_in_initializer.wren
│   │   │   ├── local_in_middle_of_block.wren
│   │   │   ├── local_in_nested_block.wren
│   │   │   ├── local_outside_method.wren
│   │   │   ├── local_without_initializer.wren
│   │   │   ├── many_locals.wren
│   │   │   ├── many_nonsimultaneous_locals.wren
│   │   │   ├── newline_after_equals.wren
│   │   │   ├── newline_after_var.wren
│   │   │   ├── outside_method.wren
│   │   │   ├── scope_if.wren
│   │   │   ├── scope_reuse_in_different_blocks.wren
│   │   │   ├── scope_while.wren
│   │   │   ├── shadow_and_local.wren
│   │   │   ├── shadow_global.wren
│   │   │   ├── shadow_in_initializer.wren
│   │   │   ├── shadow_local.wren
│   │   │   ├── too_many_locals.wren
│   │   │   ├── too_many_locals_nested.wren
│   │   │   ├── undefined_global.wren
│   │   │   ├── undefined_local.wren
│   │   │   ├── use_false_as_var.wren
│   │   │   ├── use_field_as_var.wren
│   │   │   ├── use_null_as_var.wren
│   │   │   ├── use_this_as_var.wren
│   │   │   └── use_true_as_var.wren
│   │   ├── while/
│   │   │   ├── closure_in_body.wren
│   │   │   ├── newline_after_while.wren
│   │   │   ├── return_closure.wren
│   │   │   ├── return_inside.wren
│   │   │   ├── syntax.wren
│   │   │   └── truth.wren
│   │   └── whitespace.wren
│   ├── limit/
│   │   ├── interpolation_nesting.wren
│   │   ├── jump_too_far.wren
│   │   ├── long_function.wren
│   │   ├── long_string.wren
│   │   ├── long_variable_name.wren
│   │   ├── loop_too_far.wren
│   │   ├── many_constants.wren
│   │   ├── many_fields.wren
│   │   ├── many_globals.wren
│   │   ├── many_inherited_fields.wren
│   │   ├── reuse_constants.wren
│   │   ├── too_many_constants.wren
│   │   ├── too_many_fields.wren
│   │   ├── too_many_function_parameters.wren
│   │   ├── too_many_inherited_fields.wren
│   │   ├── too_much_interpolation_nesting.wren
│   │   └── variable_name_too_long.wren
│   ├── main.c
│   ├── meta/
│   │   ├── eval_compile_error.wren
│   │   ├── eval_existing_scoped_variable.wren
│   │   ├── eval_not_string.wren
│   │   ├── get_module_variables.wren
│   │   ├── get_module_variables_not_string.wren
│   │   └── get_module_variables_unknown_module.wren
│   ├── random/
│   │   ├── float.wren
│   │   ├── float_max.wren
│   │   ├── float_min_max.wren
│   │   ├── int.wren
│   │   ├── int_max.wren
│   │   ├── int_min_max.wren
│   │   ├── new.wren
│   │   ├── new_empty_sequence.wren
│   │   ├── new_number.wren
│   │   ├── new_sequence.wren
│   │   ├── new_wrong_arg_type.wren
│   │   ├── new_wrong_element_type.wren
│   │   ├── sample_count_multiple.wren
│   │   ├── sample_count_one.wren
│   │   ├── sample_count_too_many.wren
│   │   ├── sample_count_zero.wren
│   │   ├── sample_one.wren
│   │   ├── sample_one_empty.wren
│   │   └── shuffle.wren
│   ├── regression/
│   │   ├── 428.wren
│   │   ├── 429.wren
│   │   ├── 442-000005.wren
│   │   ├── 442-000007.wren
│   │   ├── 442-000086.wren
│   │   ├── 442-000088.wren
│   │   ├── 442-000089.wren
│   │   ├── 442-000100.wren
│   │   ├── 442-000115.wren
│   │   ├── 442-000166.wren
│   │   ├── 442-000181.wren
│   │   ├── 442-000182.wren
│   │   ├── 442-000238.wren
│   │   ├── 442-000295.wren
│   │   ├── 442-000321.wren
│   │   ├── 442-000348.wren
│   │   ├── 442-000357.wren
│   │   ├── 442-000440.wren
│   │   ├── 442-000665.wren
│   │   ├── 494.wren
│   │   └── 561.wren
│   ├── test.c
│   ├── test.h
│   └── unit/
│       ├── main.c
│       ├── path_test.c
│       ├── path_test.h
│       ├── test.c
│       └── test.h
├── try/
│   ├── main.try.c
│   ├── make.emscripten/
│   │   ├── Makefile
│   │   ├── wren.make
│   │   └── wren_try.make
│   └── readme.md
└── util/
    ├── benchmark.py
    ├── deploy_docs_from_travis.sh
    ├── generate_amalgamation.py
    ├── generate_docs.py
    ├── generate_projects.py
    ├── metrics.py
    ├── test.py
    └── wren_to_c_string.py
Download .txt
SYMBOL INDEX (972 symbols across 65 files)

FILE: doc/site/static/codejar-linenumbers.js
  function withLineNumbers (line 1) | function withLineNumbers(highlight, options = {}) {
  function init (line 18) | function init(editor, opts) {

FILE: doc/site/static/codejar.js
  function CodeJar (line 1) | function CodeJar(editor, highlight, opt = {}) {

FILE: doc/site/static/prism.js
  function o (line 3) | function o(e){i.highlightedCode=e,C.hooks.run("before-insert",i),i.eleme...
  function _ (line 3) | function _(e,n,t,r,a){this.type=e,this.content=n,this.alias=t,this.lengt...
  function l (line 3) | function l(){var e={value:null,prev:null,next:null},n={value:null,prev:e...
  function M (line 3) | function M(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a...
  function W (line 3) | function W(e,n,t){for(var r=n.next,a=0;a<t&&r!==e.tail;a++)r=r.next;(n.n...
  function t (line 3) | function t(){C.manual||C.highlightAll()}

FILE: doc/site/static/wren_try.js
  function locateFile (line 61) | function locateFile(path) {
  function staticAlloc (line 223) | function staticAlloc(size) {
  function dynamicAlloc (line 227) | function dynamicAlloc(size) {
  function alignMemory (line 236) | function alignMemory(size, factor) {
  function getNativeTypeSize (line 241) | function getNativeTypeSize(type) {
  function warnOnce (line 263) | function warnOnce(text) {
  function convertJsFunctionToWasm (line 283) | function convertJsFunctionToWasm(func, sig) {
  function addFunctionWasm (line 372) | function addFunctionWasm(func, sig) {
  function removeFunctionWasm (line 427) | function removeFunctionWasm(index) {
  function addFunction (line 434) | function addFunction(func, sig) {
  function removeFunction (line 440) | function removeFunction(index) {
  function getFuncWrapper (line 448) | function getFuncWrapper(func, sig) {
  function makeBigInt (line 485) | function makeBigInt(low, high, unsigned) {
  function dynCall (line 490) | function dynCall(sig, ptr, args) {
  function getCompilerSetting (line 513) | function getCompilerSetting(name) {
  function setValue (line 564) | function setValue(ptr, value, type, noSafe) {
  function getValue (line 582) | function getValue(ptr, type, noSafe) {
  function assert (line 630) | function assert(condition, text) {
  function getCFunc (line 637) | function getCFunc(ident) {
  function ccall (line 648) | function ccall(ident, returnType, argTypes, args, opts) {
  function cwrap (line 699) | function cwrap(ident, returnType, argTypes, opts) {
  function allocate (line 724) | function allocate(slab, types, allocator, ptr) {
  function getMemory (line 796) | function getMemory(size) {
  function UTF8ArrayToString (line 820) | function UTF8ArrayToString(heap, idx, maxBytesToRead) {
  function UTF8ToString (line 876) | function UTF8ToString(ptr, maxBytesToRead) {
  function stringToUTF8Array (line 893) | function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
  function stringToUTF8 (line 939) | function stringToUTF8(str, outPtr, maxBytesToWrite) {
  function lengthBytesUTF8 (line 945) | function lengthBytesUTF8(str) {
  function AsciiToString (line 973) | function AsciiToString(ptr) {
  function stringToAscii (line 985) | function stringToAscii(str, outPtr) {
  function UTF16ToString (line 994) | function UTF16ToString(ptr) {
  function stringToUTF16 (line 1030) | function stringToUTF16(str, outPtr, maxBytesToWrite) {
  function lengthBytesUTF16 (line 1054) | function lengthBytesUTF16(str) {
  function UTF32ToString (line 1058) | function UTF32ToString(ptr) {
  function stringToUTF32 (line 1089) | function stringToUTF32(str, outPtr, maxBytesToWrite) {
  function lengthBytesUTF32 (line 1118) | function lengthBytesUTF32(str) {
  function allocateUTF8 (line 1133) | function allocateUTF8(str) {
  function allocateUTF8OnStack (line 1141) | function allocateUTF8OnStack(str) {
  function writeStringToMemory (line 1154) | function writeStringToMemory(string, buffer, dontAddNull) {
  function writeArrayToMemory (line 1169) | function writeArrayToMemory(array, buffer) {
  function writeAsciiToMemory (line 1175) | function writeAsciiToMemory(str, buffer, dontAddNull) {
  function alignUp (line 1192) | function alignUp(x, multiple) {
  function updateGlobalBufferAndViews (line 1219) | function updateGlobalBufferAndViews(buf) {
  function writeStackCookie (line 1311) | function writeStackCookie() {
  function checkStackCookie (line 1321) | function checkStackCookie() {
  function abortStackOverflow (line 1332) | function abortStackOverflow(allocSize) {
  function abortFnPtrError (line 1353) | function abortFnPtrError(ptr, sig) {
  function callRuntimeCallbacks (line 1359) | function callRuntimeCallbacks(callbacks) {
  function preRun (line 1389) | function preRun() {
  function initRuntime (line 1401) | function initRuntime() {
  function preMain (line 1409) | function preMain() {
  function exitRuntime (line 1415) | function exitRuntime() {
  function postRun (line 1420) | function postRun() {
  function addOnPreRun (line 1433) | function addOnPreRun(cb) {
  function addOnInit (line 1437) | function addOnInit(cb) {
  function addOnPreMain (line 1441) | function addOnPreMain(cb) {
  function addOnExit (line 1445) | function addOnExit(cb) {
  function addOnPostRun (line 1448) | function addOnPostRun(cb) {
  function unSign (line 1453) | function unSign(value, bits, ignore) {
  function reSign (line 1461) | function reSign(value, bits, ignore) {
  function getUniqueRunDependency (line 1531) | function getUniqueRunDependency(id) {
  function addRunDependency (line 1539) | function addRunDependency(id) {
  function removeRunDependency (line 1575) | function removeRunDependency(id) {
  function abort (line 1606) | function abort(what) {
  function isDataURI (line 1672) | function isDataURI(filename) {
  function getBinary (line 1686) | function getBinary() {
  function getBinaryPromise (line 1703) | function getBinaryPromise() {
  function createWasm (line 1726) | function createWasm() {
  function demangle (line 1830) | function demangle(func) {
  function demangleAll (line 1835) | function demangleAll(text) {
  function jsStackTrace (line 1845) | function jsStackTrace() {
  function stackTrace (line 1862) | function stackTrace() {
  function ___handle_stack_overflow (line 1868) | function ___handle_stack_overflow() {
  function _clock (line 1872) | function _clock() {
  function _emscripten_get_sbrk_ptr (line 1877) | function _emscripten_get_sbrk_ptr() {
  function _emscripten_memcpy_big (line 1881) | function _emscripten_memcpy_big(dest, src, num) {
  function _emscripten_get_heap_size (line 1886) | function _emscripten_get_heap_size() {
  function abortOnCannotGrowMemory (line 1890) | function abortOnCannotGrowMemory(requestedSize) {
  function _emscripten_resize_heap (line 1892) | function _emscripten_resize_heap(requestedSize) {
  function _exit (line 1896) | function _exit(status) {
  function _fd_close (line 1990) | function _fd_close(fd) {
  function _fd_seek (line 1995) | function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {
  function flush_NO_FILESYSTEM (line 1999) | function flush_NO_FILESYSTEM() {
  function _fd_write (line 2005) | function _fd_write(fd, iov, iovcnt, pnum) {
  function _round (line 2021) | function _round(d) {
  function _setTempRet0 (line 2026) | function _setTempRet0($i) {
  function _time (line 2030) | function _time(ptr) {
  function intArrayFromString (line 2046) | function intArrayFromString(stringy, dontAddNull, length) {
  function intArrayToString (line 2054) | function intArrayToString(array) {
  function ExitStatus (line 2358) | function ExitStatus(status) {
  function callMain (line 2373) | function callMain(args) {
  function run (line 2429) | function run(args) {
  function checkUnflushedContent (line 2478) | function checkUnflushedContent() {
  function exit (line 2509) | function exit(status, implicit) {

FILE: example/embedding/main.c
  function writeFn (line 6) | static void writeFn(WrenVM* vm, const char* text)
  function errorFn (line 11) | void errorFn(WrenVM* vm, WrenErrorType errorType,
  function main (line 32) | int main()

FILE: src/include/wren.h
  type WrenVM (line 34) | typedef struct WrenVM WrenVM;
  type WrenHandle (line 41) | typedef struct WrenHandle WrenHandle;
  type WrenLoadModuleResult (line 77) | struct WrenLoadModuleResult
  type WrenLoadModuleResult (line 81) | struct WrenLoadModuleResult
  type WrenLoadModuleResult (line 86) | typedef struct WrenLoadModuleResult
  type WrenLoadModuleResult (line 94) | typedef WrenLoadModuleResult (*WrenLoadModuleFn)(WrenVM* vm, const char*...
  type WrenForeignMethodFn (line 98) | typedef WrenForeignMethodFn (*WrenBindForeignMethodFn)(WrenVM* vm,
  type WrenErrorType (line 105) | typedef enum
  type WrenForeignClassMethods (line 133) | typedef struct
  type WrenForeignClassMethods (line 150) | typedef WrenForeignClassMethods (*WrenBindForeignClassFn)(
  type WrenConfiguration (line 153) | typedef struct
  type WrenInterpretResult (line 274) | typedef enum
  type WrenType (line 285) | typedef enum

FILE: src/optional/wren_opt_meta.c
  function metaCompile (line 10) | void metaCompile(WrenVM* vm)
  function metaGetModuleVariables (line 40) | void metaGetModuleVariables(WrenVM* vm)
  function WrenForeignMethodFn (line 73) | WrenForeignMethodFn wrenMetaBindForeignMethod(WrenVM* vm,

FILE: src/optional/wren_opt_random.c
  type Well512 (line 16) | typedef struct
  function advanceState (line 23) | static uint32_t advanceState(Well512* well)
  function randomAllocate (line 40) | static void randomAllocate(WrenVM* vm)
  function randomSeed0 (line 46) | static void randomSeed0(WrenVM* vm)
  function randomSeed1 (line 57) | static void randomSeed1(WrenVM* vm)
  function randomSeed16 (line 68) | static void randomSeed16(WrenVM* vm)
  function randomFloat (line 78) | static void randomFloat(WrenVM* vm)
  function randomInt0 (line 98) | static void randomInt0(WrenVM* vm)
  function WrenForeignClassMethods (line 110) | WrenForeignClassMethods wrenRandomBindForeignClass(WrenVM* vm,
  function WrenForeignMethodFn (line 121) | WrenForeignMethodFn wrenRandomBindForeignMethod(WrenVM* vm,

FILE: src/vm/wren_compiler.c
  type TokenType (line 53) | typedef enum
  type Token (line 141) | typedef struct
  type Parser (line 158) | typedef struct
  type Local (line 209) | typedef struct
  type CompilerUpvalue (line 227) | typedef struct
  type Loop (line 238) | typedef struct sLoop
  type SignatureType (line 259) | typedef enum
  type Signature (line 283) | typedef struct
  type ClassInfo (line 292) | typedef struct
  type sCompiler (line 320) | struct sCompiler
  type Scope (line 381) | typedef enum
  type Variable (line 395) | typedef struct
  function printError (line 420) | static void printError(Parser* parser, int line, const char* label,
  function lexError (line 443) | static void lexError(Parser* parser, const char* format, ...)
  function error (line 459) | static void error(Compiler* compiler, const char* format, ...)
  function addConstant (line 496) | static int addConstant(Compiler* compiler, Value constant)
  function initCompiler (line 532) | static void initCompiler(Compiler* compiler, Parser* parser, Compiler* p...
  type Keyword (line 592) | typedef struct
  function isName (line 627) | static bool isName(char c)
  function isDigit (line 633) | static bool isDigit(char c)
  function peekChar (line 639) | static char peekChar(Parser* parser)
  function peekNextChar (line 645) | static char peekNextChar(Parser* parser)
  function nextChar (line 653) | static char nextChar(Parser* parser)
  function matchChar (line 662) | static bool matchChar(Parser* parser, char c)
  function makeToken (line 671) | static void makeToken(Parser* parser, TokenType type)
  function twoCharToken (line 684) | static void twoCharToken(Parser* parser, char c, TokenType two, TokenTyp...
  function skipLineComment (line 690) | static void skipLineComment(Parser* parser)
  function skipBlockComment (line 699) | static void skipBlockComment(Parser* parser)
  function readHexDigit (line 733) | static int readHexDigit(Parser* parser)
  function makeNumber (line 747) | static void makeNumber(Parser* parser, bool isHex)
  function readHexNumber (line 773) | static void readHexNumber(Parser* parser)
  function readNumber (line 785) | static void readNumber(Parser* parser)
  function readName (line 818) | static void readName(Parser* parser, TokenType type, char firstChar)
  function readHexEscape (line 850) | static int readHexEscape(Parser* parser, int digits, const char* descrip...
  function readUnicodeEscape (line 879) | static void readUnicodeEscape(Parser* parser, ByteBuffer* string, int le...
  function readRawString (line 892) | static void readRawString(Parser* parser)
  function readString (line 970) | static void readString(Parser* parser)
  function nextToken (line 1051) | static void nextToken(Parser* parser)
  function TokenType (line 1244) | static TokenType peek(Compiler* compiler)
  function TokenType (line 1250) | static TokenType peekNext(Compiler* compiler)
  function match (line 1257) | static bool match(Compiler* compiler, TokenType expected)
  function consume (line 1266) | static void consume(Compiler* compiler, TokenType expected,
  function matchLine (line 1281) | static bool matchLine(Compiler* compiler)
  function ignoreNewlines (line 1290) | static void ignoreNewlines(Compiler* compiler)
  function consumeLine (line 1297) | static void consumeLine(Compiler* compiler, const char* errorMessage)
  function allowLineBeforeDot (line 1303) | static void allowLineBeforeDot(Compiler* compiler) {
  function emitByte (line 1312) | static int emitByte(Compiler* compiler, int byte)
  function emitOp (line 1324) | static void emitOp(Compiler* compiler, Code instruction)
  function emitShort (line 1337) | static void emitShort(Compiler* compiler, int arg)
  function emitByteArg (line 1345) | static int emitByteArg(Compiler* compiler, Code instruction, int arg)
  function emitShortArg (line 1353) | static void emitShortArg(Compiler* compiler, Code instruction, int arg)
  function emitJump (line 1362) | static int emitJump(Compiler* compiler, Code instruction)
  function emitConstant (line 1371) | static void emitConstant(Compiler* compiler, Value value)
  function addLocal (line 1381) | static int addLocal(Compiler* compiler, const char* name, int length)
  function declareVariable (line 1394) | static int declareVariable(Compiler* compiler, Token* token)
  function declareNamedVariable (line 1460) | static int declareNamedVariable(Compiler* compiler)
  function defineVariable (line 1467) | static void defineVariable(Compiler* compiler, int symbol)
  function pushScope (line 1480) | static void pushScope(Compiler* compiler)
  function discardLocals (line 1492) | static int discardLocals(Compiler* compiler, int depth)
  function popScope (line 1522) | static void popScope(Compiler* compiler)
  function resolveLocal (line 1532) | static int resolveLocal(Compiler* compiler, const char* name, int length)
  function addUpvalue (line 1551) | static int addUpvalue(Compiler* compiler, bool isLocal, int index)
  function findUpvalue (line 1577) | static int findUpvalue(Compiler* compiler, const char* name, int length)
  function Variable (line 1618) | static Variable resolveNonmodule(Compiler* compiler,
  function Variable (line 1636) | static Variable resolveName(Compiler* compiler, const char* name, int le...
  function loadLocal (line 1647) | static void loadLocal(Compiler* compiler, int slot)
  function ObjFn (line 1661) | static ObjFn* endCompiler(Compiler* compiler,
  type Precedence (line 1711) | typedef enum
  type GrammarRule (line 1738) | typedef struct
  function patchJump (line 1756) | static void patchJump(Compiler* compiler, int offset)
  function finishBlock (line 1771) | static bool finishBlock(Compiler* compiler)
  function finishBody (line 1803) | static void finishBody(Compiler* compiler)
  function validateNumParameters (line 1826) | static void validateNumParameters(Compiler* compiler, int numArgs)
  function finishParameterList (line 1839) | static void finishParameterList(Compiler* compiler, Signature* signature)
  function methodSymbol (line 1853) | static int methodSymbol(Compiler* compiler, const char* name, int length)
  function signatureParameterList (line 1867) | static void signatureParameterList(char name[MAX_METHOD_SIGNATURE], int*...
  function signatureToString (line 1885) | static void signatureToString(Signature* signature,
  function signatureSymbol (line 1931) | static int signatureSymbol(Compiler* compiler, Signature* signature)
  function Signature (line 1942) | static Signature signatureFromToken(Compiler* compiler, SignatureType type)
  function finishArgumentList (line 1965) | static void finishArgumentList(Compiler* compiler, Signature* signature)
  function callSignature (line 1980) | static void callSignature(Compiler* compiler, Code instruction,
  function callMethod (line 2001) | static void callMethod(Compiler* compiler, int numArgs, const char* name,
  function methodCall (line 2010) | static void methodCall(Compiler* compiler, Code instruction,
  function namedCall (line 2085) | static void namedCall(Compiler* compiler, bool canAssign, Code instruction)
  function loadVariable (line 2110) | static void loadVariable(Compiler* compiler, Variable variable)
  function loadThis (line 2130) | static void loadThis(Compiler* compiler)
  function loadCoreVariable (line 2136) | static void loadCoreVariable(Compiler* compiler, const char* name)
  function grouping (line 2145) | static void grouping(Compiler* compiler, bool canAssign)
  function list (line 2152) | static void list(Compiler* compiler, bool canAssign)
  function map (line 2177) | static void map(Compiler* compiler, bool canAssign)
  function unaryOp (line 2208) | static void unaryOp(Compiler* compiler, bool canAssign)
  function boolean (line 2221) | static void boolean(Compiler* compiler, bool canAssign)
  function Compiler (line 2229) | static Compiler* getEnclosingClassCompiler(Compiler* compiler)
  function ClassInfo (line 2242) | static ClassInfo* getEnclosingClass(Compiler* compiler)
  function field (line 2248) | static void field(Compiler* compiler, bool canAssign)
  function bareName (line 2307) | static void bareName(Compiler* compiler, bool canAssign, Variable variable)
  function staticField (line 2339) | static void staticField(Compiler* compiler, bool canAssign)
  function name (line 2370) | static void name(Compiler* compiler, bool canAssign)
  function null (line 2421) | static void null(Compiler* compiler, bool canAssign)
  function literal (line 2427) | static void literal(Compiler* compiler, bool canAssign)
  function stringInterpolation (line 2442) | static void stringInterpolation(Compiler* compiler, bool canAssign)
  function super_ (line 2471) | static void super_(Compiler* compiler, bool canAssign)
  function this_ (line 2501) | static void this_(Compiler* compiler, bool canAssign)
  function subscript (line 2513) | static void subscript(Compiler* compiler, bool canAssign)
  function call (line 2535) | static void call(Compiler* compiler, bool canAssign)
  function and_ (line 2542) | static void and_(Compiler* compiler, bool canAssign)
  function or_ (line 2552) | static void or_(Compiler* compiler, bool canAssign)
  function conditional (line 2562) | static void conditional(Compiler* compiler, bool canAssign)
  function infixOp (line 2589) | void infixOp(Compiler* compiler, bool canAssign)
  function infixSignature (line 2605) | void infixSignature(Compiler* compiler, Signature* signature)
  function unarySignature (line 2618) | void unarySignature(Compiler* compiler, Signature* signature)
  function mixedSignature (line 2626) | void mixedSignature(Compiler* compiler, Signature* signature)
  function maybeSetter (line 2646) | static bool maybeSetter(Compiler* compiler, Signature* signature)
  function subscriptSignature (line 2672) | void subscriptSignature(Compiler* compiler, Signature* signature)
  function parameterList (line 2689) | static void parameterList(Compiler* compiler, Signature* signature)
  function namedSignature (line 2707) | void namedSignature(Compiler* compiler, Signature* signature)
  function constructorSignature (line 2719) | void constructorSignature(Compiler* compiler, Signature* signature)
  function GrammarRule (line 2824) | static GrammarRule* getRule(TokenType type)
  function parsePrecedence (line 2830) | void parsePrecedence(Compiler* compiler, Precedence precedence)
  function expression (line 2861) | void expression(Compiler* compiler)
  function getByteCountForArguments (line 2868) | static int getByteCountForArguments(const uint8_t* bytecode,
  function startLoop (line 2974) | static void startLoop(Compiler* compiler, Loop* loop)
  function testExitLoop (line 2985) | static void testExitLoop(Compiler* compiler)
  function loopBody (line 2992) | static void loopBody(Compiler* compiler)
  function endLoop (line 3000) | static void endLoop(Compiler* compiler)
  function forStatement (line 3031) | static void forStatement(Compiler* compiler)
  function ifStatement (line 3129) | static void ifStatement(Compiler* compiler)
  function whileStatement (line 3160) | static void whileStatement(Compiler* compiler)
  function statement (line 3181) | void statement(Compiler* compiler)
  function createConstructor (line 3285) | static void createConstructor(Compiler* compiler, Signature* signature,
  function defineMethod (line 3307) | static void defineMethod(Compiler* compiler, Variable classVariable,
  function declareMethod (line 3326) | static int declareMethod(Compiler* compiler, Signature* signature,
  function Value (line 3350) | static Value consumeLiteral(Compiler* compiler, const char* message)
  function matchAttribute (line 3363) | static bool matchAttribute(Compiler* compiler) {
  function method (line 3433) | static bool method(Compiler* compiler, Variable classVariable)
  function classDefinition (line 3520) | static void classDefinition(Compiler* compiler, bool isForeign)
  function import (line 3649) | static void import(Compiler* compiler)
  function variableDefinition (line 3706) | static void variableDefinition(Compiler* compiler)
  function definition (line 3733) | void definition(Compiler* compiler)
  function ObjFn (line 3768) | ObjFn* wrenCompile(WrenVM* vm, ObjModule* module, const char* source,
  function wrenBindMethodCode (line 3849) | void wrenBindMethodCode(ObjClass* classObj, ObjFn* fn)
  function wrenMarkCompiler (line 3910) | void wrenMarkCompiler(WrenVM* vm, Compiler* compiler)
  function disallowAttributes (line 3947) | static void disallowAttributes(Compiler* compiler)
  function addToAttributeGroup (line 3958) | static void addToAttributeGroup(Compiler* compiler,
  function emitAttributes (line 3998) | static void emitAttributes(Compiler* compiler, ObjMap* attributes)
  function emitAttributeMethods (line 4046) | static void emitAttributeMethods(Compiler* compiler, ObjMap* attributes)
  function emitClassAttributes (line 4065) | static void emitClassAttributes(Compiler* compiler, ClassInfo* classInfo)
  function copyAttributes (line 4082) | static void copyAttributes(Compiler* compiler, ObjMap* into)
  function copyMethodAttributes (line 4106) | static void copyMethodAttributes(Compiler* compiler, bool isForeign,

FILE: src/vm/wren_compiler.h
  type Compiler (line 7) | typedef struct sCompiler Compiler;

FILE: src/vm/wren_core.c
  function DEF_PRIMITIVE (line 16) | DEF_PRIMITIVE(bool_not)
  function DEF_PRIMITIVE (line 21) | DEF_PRIMITIVE(bool_toString)
  function DEF_PRIMITIVE (line 33) | DEF_PRIMITIVE(class_name)
  function DEF_PRIMITIVE (line 38) | DEF_PRIMITIVE(class_supertype)
  function DEF_PRIMITIVE (line 48) | DEF_PRIMITIVE(class_toString)
  function DEF_PRIMITIVE (line 53) | DEF_PRIMITIVE(class_attributes)
  function DEF_PRIMITIVE (line 58) | DEF_PRIMITIVE(fiber_new)
  function DEF_PRIMITIVE (line 71) | DEF_PRIMITIVE(fiber_abort)
  function runFiber (line 86) | static bool runFiber(WrenVM* vm, ObjFiber* fiber, Value* args, bool isCall,
  function DEF_PRIMITIVE (line 140) | DEF_PRIMITIVE(fiber_call)
  function DEF_PRIMITIVE (line 145) | DEF_PRIMITIVE(fiber_call1)
  function DEF_PRIMITIVE (line 150) | DEF_PRIMITIVE(fiber_current)
  function DEF_PRIMITIVE (line 155) | DEF_PRIMITIVE(fiber_error)
  function DEF_PRIMITIVE (line 160) | DEF_PRIMITIVE(fiber_isDone)
  function DEF_PRIMITIVE (line 166) | DEF_PRIMITIVE(fiber_suspend)
  function DEF_PRIMITIVE (line 174) | DEF_PRIMITIVE(fiber_transfer)
  function DEF_PRIMITIVE (line 179) | DEF_PRIMITIVE(fiber_transfer1)
  function DEF_PRIMITIVE (line 184) | DEF_PRIMITIVE(fiber_transferError)
  function DEF_PRIMITIVE (line 191) | DEF_PRIMITIVE(fiber_try)
  function DEF_PRIMITIVE (line 200) | DEF_PRIMITIVE(fiber_try1)
  function DEF_PRIMITIVE (line 209) | DEF_PRIMITIVE(fiber_yield)
  function DEF_PRIMITIVE (line 227) | DEF_PRIMITIVE(fiber_yield1)
  function DEF_PRIMITIVE (line 251) | DEF_PRIMITIVE(fn_new)
  function DEF_PRIMITIVE (line 259) | DEF_PRIMITIVE(fn_arity)
  function call_fn (line 264) | static void call_fn(WrenVM* vm, Value* args, int numArgs)
  function DEF_PRIMITIVE (line 295) | DEF_PRIMITIVE(fn_toString)
  function DEF_PRIMITIVE (line 301) | DEF_PRIMITIVE(list_filled)
  function DEF_PRIMITIVE (line 317) | DEF_PRIMITIVE(list_new)
  function DEF_PRIMITIVE (line 322) | DEF_PRIMITIVE(list_add)
  function DEF_PRIMITIVE (line 331) | DEF_PRIMITIVE(list_addCore)
  function DEF_PRIMITIVE (line 339) | DEF_PRIMITIVE(list_clear)
  function DEF_PRIMITIVE (line 345) | DEF_PRIMITIVE(list_count)
  function DEF_PRIMITIVE (line 350) | DEF_PRIMITIVE(list_insert)
  function DEF_PRIMITIVE (line 363) | DEF_PRIMITIVE(list_iterate)
  function DEF_PRIMITIVE (line 384) | DEF_PRIMITIVE(list_iteratorValue)
  function DEF_PRIMITIVE (line 393) | DEF_PRIMITIVE(list_removeAt)
  function DEF_PRIMITIVE (line 402) | DEF_PRIMITIVE(list_removeValue) {
  function DEF_PRIMITIVE (line 409) | DEF_PRIMITIVE(list_indexOf)
  function DEF_PRIMITIVE (line 415) | DEF_PRIMITIVE(list_swap)
  function DEF_PRIMITIVE (line 430) | DEF_PRIMITIVE(list_subscript)
  function DEF_PRIMITIVE (line 462) | DEF_PRIMITIVE(list_subscriptSetter)
  function DEF_PRIMITIVE (line 473) | DEF_PRIMITIVE(map_new)
  function DEF_PRIMITIVE (line 478) | DEF_PRIMITIVE(map_subscript)
  function DEF_PRIMITIVE (line 489) | DEF_PRIMITIVE(map_subscriptSetter)
  function DEF_PRIMITIVE (line 500) | DEF_PRIMITIVE(map_addCore)
  function DEF_PRIMITIVE (line 510) | DEF_PRIMITIVE(map_clear)
  function DEF_PRIMITIVE (line 516) | DEF_PRIMITIVE(map_containsKey)
  function DEF_PRIMITIVE (line 523) | DEF_PRIMITIVE(map_count)
  function DEF_PRIMITIVE (line 528) | DEF_PRIMITIVE(map_iterate)
  function DEF_PRIMITIVE (line 561) | DEF_PRIMITIVE(map_remove)
  function DEF_PRIMITIVE (line 568) | DEF_PRIMITIVE(map_keyIteratorValue)
  function DEF_PRIMITIVE (line 583) | DEF_PRIMITIVE(map_valueIteratorValue)
  function DEF_PRIMITIVE (line 598) | DEF_PRIMITIVE(null_not)
  function DEF_PRIMITIVE (line 603) | DEF_PRIMITIVE(null_toString)
  function DEF_PRIMITIVE (line 608) | DEF_PRIMITIVE(num_fromString)
  function DEF_PRIMITIVE (line 714) | DEF_PRIMITIVE(num_eqeq)
  function DEF_PRIMITIVE (line 720) | DEF_PRIMITIVE(num_bangeq)
  function DEF_PRIMITIVE (line 726) | DEF_PRIMITIVE(num_bitwiseNot)
  function DEF_PRIMITIVE (line 732) | DEF_PRIMITIVE(num_dotDot)
  function DEF_PRIMITIVE (line 741) | DEF_PRIMITIVE(num_dotDotDot)
  function DEF_PRIMITIVE (line 750) | DEF_PRIMITIVE(num_atan2)
  function DEF_PRIMITIVE (line 757) | DEF_PRIMITIVE(num_min)
  function DEF_PRIMITIVE (line 766) | DEF_PRIMITIVE(num_max)
  function DEF_PRIMITIVE (line 775) | DEF_PRIMITIVE(num_clamp)
  function DEF_PRIMITIVE (line 787) | DEF_PRIMITIVE(num_pow)
  function DEF_PRIMITIVE (line 794) | DEF_PRIMITIVE(num_fraction)
  function DEF_PRIMITIVE (line 800) | DEF_PRIMITIVE(num_isInfinity)
  function DEF_PRIMITIVE (line 805) | DEF_PRIMITIVE(num_isInteger)
  function DEF_PRIMITIVE (line 812) | DEF_PRIMITIVE(num_isNan)
  function DEF_PRIMITIVE (line 817) | DEF_PRIMITIVE(num_sign)
  function DEF_PRIMITIVE (line 834) | DEF_PRIMITIVE(num_toString)
  function DEF_PRIMITIVE (line 839) | DEF_PRIMITIVE(num_truncate)
  function DEF_PRIMITIVE (line 846) | DEF_PRIMITIVE(object_same)
  function DEF_PRIMITIVE (line 851) | DEF_PRIMITIVE(object_not)
  function DEF_PRIMITIVE (line 856) | DEF_PRIMITIVE(object_eqeq)
  function DEF_PRIMITIVE (line 861) | DEF_PRIMITIVE(object_bangeq)
  function DEF_PRIMITIVE (line 866) | DEF_PRIMITIVE(object_is)
  function DEF_PRIMITIVE (line 888) | DEF_PRIMITIVE(object_toString)
  function DEF_PRIMITIVE (line 895) | DEF_PRIMITIVE(object_type)
  function DEF_PRIMITIVE (line 900) | DEF_PRIMITIVE(range_from)
  function DEF_PRIMITIVE (line 905) | DEF_PRIMITIVE(range_to)
  function DEF_PRIMITIVE (line 910) | DEF_PRIMITIVE(range_min)
  function DEF_PRIMITIVE (line 916) | DEF_PRIMITIVE(range_max)
  function DEF_PRIMITIVE (line 922) | DEF_PRIMITIVE(range_isInclusive)
  function DEF_PRIMITIVE (line 927) | DEF_PRIMITIVE(range_iterate)
  function DEF_PRIMITIVE (line 958) | DEF_PRIMITIVE(range_iteratorValue)
  function DEF_PRIMITIVE (line 964) | DEF_PRIMITIVE(range_toString)
  function DEF_PRIMITIVE (line 982) | DEF_PRIMITIVE(string_fromCodePoint)
  function DEF_PRIMITIVE (line 999) | DEF_PRIMITIVE(string_fromByte)
  function DEF_PRIMITIVE (line 1014) | DEF_PRIMITIVE(string_byteAt)
  function DEF_PRIMITIVE (line 1024) | DEF_PRIMITIVE(string_byteCount)
  function DEF_PRIMITIVE (line 1029) | DEF_PRIMITIVE(string_codePointAt)
  function DEF_PRIMITIVE (line 1045) | DEF_PRIMITIVE(string_contains)
  function DEF_PRIMITIVE (line 1055) | DEF_PRIMITIVE(string_endsWith)
  function DEF_PRIMITIVE (line 1069) | DEF_PRIMITIVE(string_indexOf1)
  function DEF_PRIMITIVE (line 1080) | DEF_PRIMITIVE(string_indexOf2)
  function DEF_PRIMITIVE (line 1093) | DEF_PRIMITIVE(string_iterate)
  function DEF_PRIMITIVE (line 1119) | DEF_PRIMITIVE(string_iterateByte)
  function DEF_PRIMITIVE (line 1142) | DEF_PRIMITIVE(string_iteratorValue)
  function DEF_PRIMITIVE (line 1151) | DEF_PRIMITIVE(string_startsWith)
  function DEF_PRIMITIVE (line 1164) | DEF_PRIMITIVE(string_plus)
  function DEF_PRIMITIVE (line 1170) | DEF_PRIMITIVE(string_subscript)
  function DEF_PRIMITIVE (line 1195) | DEF_PRIMITIVE(string_toString)
  function DEF_PRIMITIVE (line 1200) | DEF_PRIMITIVE(system_clock)
  function DEF_PRIMITIVE (line 1205) | DEF_PRIMITIVE(system_gc)
  function DEF_PRIMITIVE (line 1211) | DEF_PRIMITIVE(system_writeString)
  function ObjClass (line 1222) | static ObjClass* defineClass(WrenVM* vm, ObjModule* module, const char* ...
  function wrenInitializeCore (line 1235) | void wrenInitializeCore(WrenVM* vm)

FILE: src/vm/wren_debug.c
  function wrenDebugPrintStackTrace (line 5) | void wrenDebugPrintStackTrace(WrenVM* vm)
  function dumpObject (line 45) | static void dumpObject(Obj* obj)
  function wrenDumpValue (line 67) | void wrenDumpValue(Value value)
  function dumpInstruction (line 102) | static int dumpInstruction(WrenVM* vm, ObjFn* fn, int i, int* lastLine)
  function wrenDumpInstruction (line 356) | int wrenDumpInstruction(WrenVM* vm, ObjFn* fn, int i)
  function wrenDumpCode (line 361) | void wrenDumpCode(WrenVM* vm, ObjFn* fn)
  function wrenDumpStack (line 379) | void wrenDumpStack(ObjFiber* fiber)

FILE: src/vm/wren_math.h
  type WrenDoubleBits (line 8) | typedef union
  function wrenDoubleFromBits (line 20) | static inline double wrenDoubleFromBits(uint64_t bits)
  function wrenDoubleToBits (line 27) | static inline uint64_t wrenDoubleToBits(double num)

FILE: src/vm/wren_primitive.c
  function validateIndexValue (line 8) | static uint32_t validateIndexValue(WrenVM* vm, uint32_t count, double va...
  function validateFn (line 23) | bool validateFn(WrenVM* vm, Value arg, const char* argName)
  function validateNum (line 29) | bool validateNum(WrenVM* vm, Value arg, const char* argName)
  function validateIntValue (line 35) | bool validateIntValue(WrenVM* vm, double value, const char* argName)
  function validateInt (line 41) | bool validateInt(WrenVM* vm, Value arg, const char* argName)
  function validateKey (line 48) | bool validateKey(WrenVM* vm, Value arg)
  function validateIndex (line 55) | uint32_t validateIndex(WrenVM* vm, Value arg, uint32_t count,
  function validateString (line 62) | bool validateString(WrenVM* vm, Value arg, const char* argName)
  function calculateRange (line 68) | uint32_t calculateRange(WrenVM* vm, ObjRange* range, uint32_t* length,

FILE: src/vm/wren_utils.c
  function wrenSymbolTableInit (line 10) | void wrenSymbolTableInit(SymbolTable* symbols)
  function wrenSymbolTableClear (line 15) | void wrenSymbolTableClear(WrenVM* vm, SymbolTable* symbols)
  function wrenSymbolTableAdd (line 20) | int wrenSymbolTableAdd(WrenVM* vm, SymbolTable* symbols,
  function wrenSymbolTableEnsure (line 32) | int wrenSymbolTableEnsure(WrenVM* vm, SymbolTable* symbols,
  function wrenSymbolTableFind (line 43) | int wrenSymbolTableFind(const SymbolTable* symbols,
  function wrenBlackenSymbolTable (line 56) | void wrenBlackenSymbolTable(WrenVM* vm, SymbolTable* symbolTable)
  function wrenUtf8EncodeNumBytes (line 67) | int wrenUtf8EncodeNumBytes(int value)
  function wrenUtf8Encode (line 78) | int wrenUtf8Encode(int value, uint8_t* bytes)
  function wrenUtf8Decode (line 122) | int wrenUtf8Decode(const uint8_t* bytes, uint32_t length)
  function wrenUtf8DecodeNumBytes (line 170) | int wrenUtf8DecodeNumBytes(uint8_t byte)
  function wrenPowerOf2Ceil (line 185) | int wrenPowerOf2Ceil(int n)
  function wrenValidateIndex (line 198) | uint32_t wrenValidateIndex(uint32_t count, int64_t value)

FILE: src/vm/wren_utils.h
  type ObjString (line 11) | typedef struct sObjString ObjString;
  type StringBuffer (line 71) | typedef StringBuffer SymbolTable;

FILE: src/vm/wren_value.c
  function initObj (line 37) | static void initObj(WrenVM* vm, Obj* obj, ObjType type, ObjClass* classObj)
  function ObjClass (line 46) | ObjClass* wrenNewSingleClass(WrenVM* vm, int numFields, ObjString* name)
  function wrenBindSuperclass (line 62) | void wrenBindSuperclass(WrenVM* vm, ObjClass* subclass, ObjClass* superc...
  function ObjClass (line 86) | ObjClass* wrenNewClass(WrenVM* vm, ObjClass* superclass, int numFields,
  function wrenBindMethod (line 120) | void wrenBindMethod(WrenVM* vm, ObjClass* classObj, int symbol, Method m...
  function ObjClosure (line 134) | ObjClosure* wrenNewClosure(WrenVM* vm, ObjFn* fn)
  function ObjFiber (line 149) | ObjFiber* wrenNewFiber(WrenVM* vm, ObjClosure* closure)
  function wrenEnsureStack (line 190) | void wrenEnsureStack(WrenVM* vm, ObjFiber* fiber, int needed)
  function ObjForeign (line 234) | ObjForeign* wrenNewForeign(WrenVM* vm, ObjClass* classObj, size_t size)
  function ObjFn (line 244) | ObjFn* wrenNewFunction(WrenVM* vm, ObjModule* module, int maxSlots)
  function wrenFunctionBindName (line 264) | void wrenFunctionBindName(WrenVM* vm, ObjFn* fn, const char* name, int l...
  function Value (line 271) | Value wrenNewInstance(WrenVM* vm, ObjClass* classObj)
  function ObjList (line 286) | ObjList* wrenNewList(WrenVM* vm, uint32_t numElements)
  function wrenListInsert (line 304) | void wrenListInsert(WrenVM* vm, ObjList* list, Value value, uint32_t index)
  function wrenListIndexOf (line 323) | int wrenListIndexOf(WrenVM* vm, ObjList* list, Value value)
  function Value (line 336) | Value wrenListRemoveAt(WrenVM* vm, ObjList* list, uint32_t index)
  function ObjMap (line 363) | ObjMap* wrenNewMap(WrenVM* vm)
  function hashBits (line 373) | static inline uint32_t hashBits(uint64_t hash)
  function hashNumber (line 388) | static inline uint32_t hashNumber(double num)
  function hashObject (line 395) | static uint32_t hashObject(Obj* object)
  function hashValue (line 430) | static uint32_t hashValue(Value value)
  function findEntry (line 459) | static bool findEntry(MapEntry* entries, uint32_t capacity, Value key,
  function insertEntry (line 523) | static bool insertEntry(MapEntry* entries, uint32_t capacity,
  function resizeMap (line 544) | static void resizeMap(WrenVM* vm, ObjMap* map, uint32_t capacity)
  function Value (line 574) | Value wrenMapGet(ObjMap* map, Value key)
  function wrenMapSet (line 582) | void wrenMapSet(WrenVM* vm, ObjMap* map, Value key, Value value)
  function wrenMapClear (line 601) | void wrenMapClear(WrenVM* vm, ObjMap* map)
  function Value (line 609) | Value wrenMapRemoveKey(WrenVM* vm, ObjMap* map, Value key)
  function ObjModule (line 645) | ObjModule* wrenNewModule(WrenVM* vm, ObjString* name)
  function Value (line 663) | Value wrenNewRange(WrenVM* vm, double from, double to, bool isInclusive)
  function ObjString (line 679) | static ObjString* allocateString(WrenVM* vm, size_t length)
  function hashString (line 690) | static void hashString(ObjString* string)
  function Value (line 707) | Value wrenNewString(WrenVM* vm, const char* text)
  function Value (line 712) | Value wrenNewStringLength(WrenVM* vm, const char* text, size_t length)
  function Value (line 728) | Value wrenNewStringFromRange(WrenVM* vm, ObjString* source, int start,
  function Value (line 757) | Value wrenNumToString(WrenVM* vm, double value)
  function Value (line 796) | Value wrenStringFromCodePoint(WrenVM* vm, int value)
  function Value (line 809) | Value wrenStringFromByte(WrenVM *vm, uint8_t value)
  function Value (line 818) | Value wrenStringFormat(WrenVM* vm, const char* format, ...)
  function Value (line 883) | Value wrenStringCodePointAt(WrenVM* vm, ObjString* string, uint32_t index)
  function wrenStringFind (line 902) | uint32_t wrenStringFind(ObjString* haystack, ObjString* needle, uint32_t...
  function ObjUpvalue (line 963) | ObjUpvalue* wrenNewUpvalue(WrenVM* vm, Value* value)
  function wrenGrayObj (line 976) | void wrenGrayObj(WrenVM* vm, Obj* obj)
  function wrenGrayValue (line 999) | void wrenGrayValue(WrenVM* vm, Value value)
  function wrenGrayBuffer (line 1005) | void wrenGrayBuffer(WrenVM* vm, ValueBuffer* buffer)
  function blackenClass (line 1013) | static void blackenClass(WrenVM* vm, ObjClass* classObj)
  function blackenClosure (line 1039) | static void blackenClosure(WrenVM* vm, ObjClosure* closure)
  function blackenFiber (line 1055) | static void blackenFiber(WrenVM* vm, ObjFiber* fiber)
  function blackenFn (line 1087) | static void blackenFn(WrenVM* vm, ObjFn* fn)
  function blackenForeign (line 1105) | static void blackenForeign(WrenVM* vm, ObjForeign* foreign)
  function blackenInstance (line 1114) | static void blackenInstance(WrenVM* vm, ObjInstance* instance)
  function blackenList (line 1129) | static void blackenList(WrenVM* vm, ObjList* list)
  function blackenMap (line 1139) | static void blackenMap(WrenVM* vm, ObjMap* map)
  function blackenModule (line 1156) | static void blackenModule(WrenVM* vm, ObjModule* module)
  function blackenRange (line 1172) | static void blackenRange(WrenVM* vm, ObjRange* range)
  function blackenString (line 1178) | static void blackenString(WrenVM* vm, ObjString* string)
  function blackenUpvalue (line 1184) | static void blackenUpvalue(WrenVM* vm, ObjUpvalue* upvalue)
  function blackenObject (line 1193) | static void blackenObject(WrenVM* vm, Obj* obj)
  function wrenBlackenObjects (line 1219) | void wrenBlackenObjects(WrenVM* vm)
  function wrenFreeObj (line 1229) | void wrenFreeObj(WrenVM* vm, Obj* obj)
  function ObjClass (line 1290) | ObjClass* wrenGetClass(WrenVM* vm, Value value)
  function wrenValuesEqual (line 1295) | bool wrenValuesEqual(Value a, Value b)

FILE: src/vm/wren_value.h
  type ObjType (line 90) | typedef enum {
  type ObjClass (line 105) | typedef struct sObjClass ObjClass;
  type Obj (line 108) | typedef struct sObj Obj;
  type sObj (line 109) | struct sObj
  type Value (line 123) | typedef uint64_t Value;
  type ValueType (line 127) | typedef enum
  type Value (line 137) | typedef struct
  type sObjString (line 152) | struct sObjString
  type ObjUpvalue (line 178) | typedef struct sObjUpvalue
  type FnDebug (line 209) | typedef struct
  type ObjModule (line 224) | typedef struct
  type ObjFn (line 247) | typedef struct
  type ObjClosure (line 272) | typedef struct
  type CallFrame (line 283) | typedef struct
  type FiberState (line 300) | typedef enum
  type ObjFiber (line 316) | typedef struct sObjFiber
  type MethodType (line 357) | typedef enum
  type Method (line 376) | typedef struct
  type sObjClass (line 392) | struct sObjClass
  type ObjForeign (line 418) | typedef struct
  type ObjInstance (line 424) | typedef struct
  type ObjList (line 430) | typedef struct
  type MapEntry (line 438) | typedef struct
  type ObjMap (line 466) | typedef struct
  type ObjRange (line 480) | typedef struct
  function wrenAppendCallFrame (line 645) | static inline void wrenAppendCallFrame(WrenVM* vm, ObjFiber* fiber,
  function wrenHasError (line 660) | static inline bool wrenHasError(const ObjFiber* fiber)
  function wrenStringEqualsCString (line 764) | static inline bool wrenStringEqualsCString(const ObjString* a,
  function wrenValuesSame (line 803) | static inline bool wrenValuesSame(Value a, Value b)
  function wrenIsBool (line 823) | static inline bool wrenIsBool(Value value)
  function wrenIsObjType (line 834) | static inline bool wrenIsObjType(Value value, ObjType type)
  function Value (line 840) | static inline Value wrenObjectToValue(Obj* obj)
  function wrenValueToNum (line 858) | static inline double wrenValueToNum(Value value)
  function Value (line 868) | static inline Value wrenNumToValue(double num)
  function wrenMapIsValidKey (line 880) | static inline bool wrenMapIsValidKey(Value arg)

FILE: src/vm/wren_vm.c
  function wrenGetVersionNumber (line 39) | int wrenGetVersionNumber()
  function wrenInitConfiguration (line 44) | void wrenInitConfiguration(WrenConfiguration* config)
  function WrenVM (line 59) | WrenVM* wrenNewVM(WrenConfiguration* config)
  function wrenFreeVM (line 99) | void wrenFreeVM(WrenVM* vm)
  function wrenCollectGarbage (line 125) | void wrenCollectGarbage(WrenVM* vm)
  function ObjUpvalue (line 244) | static ObjUpvalue* captureUpvalue(WrenVM* vm, ObjFiber* fiber, Value* lo...
  function closeUpvalues (line 287) | static void closeUpvalues(ObjFiber* fiber, Value* last)
  function WrenForeignMethodFn (line 307) | static WrenForeignMethodFn findForeignMethod(WrenVM* vm,
  function bindMethod (line 348) | static void bindMethod(WrenVM* vm, int methodType, int symbol,
  function callForeign (line 384) | static void callForeign(WrenVM* vm, ObjFiber* fiber,
  function runtimeError (line 403) | static void runtimeError(WrenVM* vm)
  function methodNotFound (line 438) | static void methodNotFound(WrenVM* vm, ObjClass* classObj, int symbol)
  function ObjModule (line 447) | static ObjModule* getModule(WrenVM* vm, Value name)
  function ObjClosure (line 453) | static ObjClosure* compileInModule(WrenVM* vm, Value name, const char* s...
  function Value (line 507) | static Value validateSuperclass(WrenVM* vm, Value name, Value superclass...
  function bindForeignClass (line 562) | static void bindForeignClass(WrenVM* vm, ObjClass* classObj, ObjModule* ...
  function endClass (line 618) | static void endClass(WrenVM* vm)
  function createClass (line 638) | static void createClass(WrenVM* vm, int numFields, ObjModule* module)
  function createForeign (line 658) | static void createForeign(WrenVM* vm, ObjFiber* fiber, Value* stack)
  function wrenFinalizeForeign (line 680) | void wrenFinalizeForeign(WrenVM* vm, ObjForeign* foreign)
  function Value (line 703) | static Value resolveModule(WrenVM* vm, Value name)
  function Value (line 731) | static Value importModule(WrenVM* vm, Value name)
  function Value (line 789) | static Value getModuleVariable(WrenVM* vm, ObjModule* module,
  function checkArity (line 809) | inline static bool checkArity(WrenVM* vm, Value value, int numArgs)
  function WrenInterpretResult (line 826) | static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber*...
  function CASE_CODE (line 1094) | CASE_CODE(LOAD_UPVALUE):
  function CASE_CODE (line 1101) | CASE_CODE(STORE_UPVALUE):
  function CASE_CODE (line 1116) | CASE_CODE(STORE_FIELD_THIS):
  function CASE_CODE (line 1127) | CASE_CODE(LOAD_FIELD):
  function CASE_CODE (line 1138) | CASE_CODE(STORE_FIELD):
  function CASE_CODE (line 1149) | CASE_CODE(JUMP):
  function CASE_CODE (line 1156) | CASE_CODE(LOOP):
  function CASE_CODE (line 1164) | CASE_CODE(JUMP_IF):
  function CASE_CODE (line 1173) | CASE_CODE(AND):
  function CASE_CODE (line 1191) | CASE_CODE(OR):
  function CASE_CODE (line 1215) | CASE_CODE(RETURN):
  function CASE_CODE (line 1270) | CASE_CODE(CLOSURE):
  function CASE_CODE (line 1298) | CASE_CODE(END_CLASS):
  function CASE_CODE (line 1305) | CASE_CODE(CLASS):
  function CASE_CODE (line 1312) | CASE_CODE(FOREIGN_CLASS):
  function CASE_CODE (line 1319) | CASE_CODE(METHOD_INSTANCE):
  function CASE_CODE (line 1366) | CASE_CODE(IMPORT_VARIABLE):
  function WrenHandle (line 1392) | WrenHandle* wrenMakeCallHandle(WrenVM* vm, const char* signature)
  function WrenInterpretResult (line 1443) | WrenInterpretResult wrenCall(WrenVM* vm, WrenHandle* method)
  function WrenHandle (line 1476) | WrenHandle* wrenMakeHandle(WrenVM* vm, Value value)
  function wrenReleaseHandle (line 1495) | void wrenReleaseHandle(WrenVM* vm, WrenHandle* handle)
  function WrenInterpretResult (line 1514) | WrenInterpretResult wrenInterpret(WrenVM* vm, const char* module,
  function ObjClosure (line 1528) | ObjClosure* wrenCompileSource(WrenVM* vm, const char* module, const char...
  function Value (line 1545) | Value wrenGetModuleVariable(WrenVM* vm, Value moduleName, Value variable...
  function Value (line 1558) | Value wrenFindVariable(WrenVM* vm, ObjModule* module, const char* name)
  function wrenDeclareVariable (line 1564) | int wrenDeclareVariable(WrenVM* vm, ObjModule* module, const char* name,
  function wrenDefineVariable (line 1576) | int wrenDefineVariable(WrenVM* vm, ObjModule* module, const char* name,
  function wrenPushRoot (line 1615) | void wrenPushRoot(WrenVM* vm, Obj* obj)
  function wrenPopRoot (line 1623) | void wrenPopRoot(WrenVM* vm)
  function wrenGetSlotCount (line 1629) | int wrenGetSlotCount(WrenVM* vm)
  function wrenEnsureSlots (line 1636) | void wrenEnsureSlots(WrenVM* vm, int numSlots)
  function validateApiSlot (line 1656) | static void validateApiSlot(WrenVM* vm, int slot)
  function WrenType (line 1663) | WrenType wrenGetSlotType(WrenVM* vm, int slot)
  function wrenGetSlotBool (line 1677) | bool wrenGetSlotBool(WrenVM* vm, int slot)
  function wrenGetSlotDouble (line 1695) | double wrenGetSlotDouble(WrenVM* vm, int slot)
  function WrenHandle (line 1720) | WrenHandle* wrenGetSlotHandle(WrenVM* vm, int slot)
  function setSlot (line 1727) | static void setSlot(WrenVM* vm, int slot, Value value)
  function wrenSetSlotBool (line 1733) | void wrenSetSlotBool(WrenVM* vm, int slot, bool value)
  function wrenSetSlotBytes (line 1738) | void wrenSetSlotBytes(WrenVM* vm, int slot, const char* bytes, size_t le...
  function wrenSetSlotDouble (line 1744) | void wrenSetSlotDouble(WrenVM* vm, int slot, double value)
  function wrenSetSlotNewList (line 1764) | void wrenSetSlotNewList(WrenVM* vm, int slot)
  function wrenSetSlotNewMap (line 1769) | void wrenSetSlotNewMap(WrenVM* vm, int slot)
  function wrenSetSlotNull (line 1774) | void wrenSetSlotNull(WrenVM* vm, int slot)
  function wrenSetSlotString (line 1779) | void wrenSetSlotString(WrenVM* vm, int slot, const char* text)
  function wrenSetSlotHandle (line 1786) | void wrenSetSlotHandle(WrenVM* vm, int slot, WrenHandle* handle)
  function wrenGetListCount (line 1793) | int wrenGetListCount(WrenVM* vm, int slot)
  function wrenGetListElement (line 1802) | void wrenGetListElement(WrenVM* vm, int listSlot, int index, int element...
  function wrenSetListElement (line 1816) | void wrenSetListElement(WrenVM* vm, int listSlot, int index, int element...
  function wrenInsertInList (line 1830) | void wrenInsertInList(WrenVM* vm, int listSlot, int index, int elementSlot)
  function wrenGetMapCount (line 1847) | int wrenGetMapCount(WrenVM* vm, int slot)
  function wrenGetMapContainsKey (line 1856) | bool wrenGetMapContainsKey(WrenVM* vm, int mapSlot, int keySlot)
  function wrenGetMapValue (line 1872) | void wrenGetMapValue(WrenVM* vm, int mapSlot, int keySlot, int valueSlot)
  function wrenSetMapValue (line 1888) | void wrenSetMapValue(WrenVM* vm, int mapSlot, int keySlot, int valueSlot)
  function wrenRemoveMapValue (line 1908) | void wrenRemoveMapValue(WrenVM* vm, int mapSlot, int keySlot,
  function wrenGetVariable (line 1925) | void wrenGetVariable(WrenVM* vm, const char* module, const char* name,
  function wrenHasVariable (line 1946) | bool wrenHasVariable(WrenVM* vm, const char* module, const char* name)
  function wrenHasModule (line 1966) | bool wrenHasModule(WrenVM* vm, const char* module)
  function wrenAbortFiber (line 1980) | void wrenAbortFiber(WrenVM* vm, int slot)
  function wrenSetUserData (line 1991) | void wrenSetUserData(WrenVM* vm, void* userData)

FILE: src/vm/wren_vm.h
  type WrenHandle (line 23) | struct WrenHandle
  type WrenVM (line 31) | struct WrenVM
  function wrenCallFunction (line 178) | static inline void wrenCallFunction(WrenVM* vm, ObjFiber* fiber,
  function ObjClass (line 209) | static inline ObjClass* wrenGetClassInline(WrenVM* vm, Value value)
  function wrenIsLocalName (line 241) | static inline bool wrenIsLocalName(const char* name)
  function wrenIsFalsyValue (line 246) | static inline bool wrenIsFalsyValue(Value value)

FILE: test/api/api_tests.c
  function WrenForeignMethodFn (line 5) | WrenForeignMethodFn APITest_bindForeignMethod(
  function WrenForeignClassMethods (line 64) | WrenForeignClassMethods APITest_bindForeignClass(
  function APITest_Run (line 85) | int APITest_Run(WrenVM* vm, const char* inTestName)

FILE: test/api/benchmark.c
  function arguments (line 6) | static void arguments(WrenVM* vm)
  function call (line 23) | static void call(WrenVM* vm)
  function WrenForeignMethodFn (line 75) | WrenForeignMethodFn benchmarkBindMethod(const char* signature)

FILE: test/api/call.c
  function callRunTests (line 6) | int callRunTests(WrenVM* vm)

FILE: test/api/call_calls_foreign.c
  function api (line 6) | static void api(WrenVM *vm) {
  function WrenForeignMethodFn (line 18) | WrenForeignMethodFn callCallsForeignBindMethod(const char* signature)
  function callCallsForeignRunTests (line 25) | int callCallsForeignRunTests(WrenVM* vm)

FILE: test/api/call_wren_call_root.c
  function callWrenCallRootRunTests (line 7) | int callWrenCallRootRunTests(WrenVM* vm)

FILE: test/api/error.c
  function runtimeError (line 6) | static void runtimeError(WrenVM* vm)
  function WrenForeignMethodFn (line 13) | WrenForeignMethodFn errorBindMethod(const char* signature)

FILE: test/api/foreign_class.c
  function apiFinalized (line 8) | static void apiFinalized(WrenVM* vm)
  function counterAllocate (line 13) | static void counterAllocate(WrenVM* vm)
  function counterIncrement (line 19) | static void counterIncrement(WrenVM* vm)
  function counterValue (line 27) | static void counterValue(WrenVM* vm)
  function pointAllocate (line 33) | static void pointAllocate(WrenVM* vm)
  function pointTranslate (line 53) | static void pointTranslate(WrenVM* vm)
  function pointToString (line 61) | static void pointToString(WrenVM* vm)
  function resourceAllocate (line 70) | static void resourceAllocate(WrenVM* vm)
  function resourceFinalize (line 76) | static void resourceFinalize(void* data)
  function badClassAllocate (line 85) | static void badClassAllocate(WrenVM* vm)
  function WrenForeignMethodFn (line 92) | WrenForeignMethodFn foreignClassBindMethod(const char* signature)
  function foreignClassBindClass (line 103) | void foreignClassBindClass(

FILE: test/api/get_variable.c
  function beforeDefined (line 5) | static void beforeDefined(WrenVM* vm)
  function afterDefined (line 10) | static void afterDefined(WrenVM* vm)
  function afterAssigned (line 15) | static void afterAssigned(WrenVM* vm)
  function otherSlot (line 20) | static void otherSlot(WrenVM* vm)
  function otherModule (line 30) | static void otherModule(WrenVM* vm)
  function hasVariable (line 35) | static void hasVariable(WrenVM* vm)
  function hasModule (line 45) | static void hasModule(WrenVM* vm)
  function WrenForeignMethodFn (line 54) | WrenForeignMethodFn getVariableBindMethod(const char* signature)

FILE: test/api/handle.c
  function setValue (line 7) | static void setValue(WrenVM* vm)
  function getValue (line 12) | static void getValue(WrenVM* vm)
  function WrenForeignMethodFn (line 18) | WrenForeignMethodFn handleBindMethod(const char* signature)

FILE: test/api/lists.c
  function newList (line 5) | static void newList(WrenVM* vm)
  function insertNumber (line 12) | static void insertNumber(WrenVM* vm, int index, double value)
  function appendNumber (line 20) | static void appendNumber(WrenVM* vm, double value)
  function insert (line 26) | static void insert(WrenVM* vm)
  function get (line 48) | static void get(WrenVM* vm)
  function set (line 56) | static void set(WrenVM* vm)
  function WrenForeignMethodFn (line 76) | WrenForeignMethodFn listsBindMethod(const char* signature)

FILE: test/api/maps.c
  function newMap (line 5) | static void newMap(WrenVM* vm)
  function invalidInsert (line 10) | static void invalidInsert(WrenVM* vm)
  function insert (line 20) | static void insert(WrenVM* vm)
  function removeKey (line 52) | static void removeKey(WrenVM* vm)
  function countWren (line 60) | static void countWren(WrenVM* vm)
  function countAPI (line 66) | static void countAPI(WrenVM* vm)
  function containsWren (line 73) | static void containsWren(WrenVM* vm)
  function containsAPI (line 80) | static void containsAPI(WrenVM* vm)
  function containsAPIFalse (line 91) | static void containsAPIFalse(WrenVM* vm)
  function WrenForeignMethodFn (line 103) | WrenForeignMethodFn mapsBindMethod(const char* signature)
  function foreignAllocate (line 118) | void foreignAllocate(WrenVM* vm) {
  function mapBindClass (line 122) | void mapBindClass(

FILE: test/api/new_vm.c
  function nullConfig (line 5) | static void nullConfig(WrenVM* vm)
  function multipleInterpretCalls (line 16) | static void multipleInterpretCalls(WrenVM* vm)
  function WrenForeignMethodFn (line 53) | WrenForeignMethodFn newVMBindMethod(const char* signature)

FILE: test/api/reset_stack_after_call_abort.c
  function resetStackAfterCallAbortRunTests (line 6) | int resetStackAfterCallAbortRunTests(WrenVM* vm)

FILE: test/api/reset_stack_after_foreign_construct.c
  function counterAllocate (line 6) | static void counterAllocate(WrenVM* vm)
  function resetStackAfterForeignConstructBindClass (line 12) | void resetStackAfterForeignConstructBindClass(
  function resetStackAfterForeignConstructRunTests (line 22) | int resetStackAfterForeignConstructRunTests(WrenVM* vm)

FILE: test/api/resolution.c
  function writeFn (line 6) | static void writeFn(WrenVM* vm, const char* text)
  function reportError (line 11) | static void reportError(WrenVM* vm, WrenErrorType type,
  function loadModuleComplete (line 17) | static void loadModuleComplete(WrenVM* vm, const char* module, WrenLoadM...
  function WrenLoadModuleResult (line 22) | static WrenLoadModuleResult loadModule(WrenVM* vm, const char* module)
  function runTestVM (line 45) | static void runTestVM(WrenVM* vm, WrenConfiguration* configuration,
  function noResolver (line 68) | static void noResolver(WrenVM* vm)
  function returnsNull (line 89) | static void returnsNull(WrenVM* vm)
  function changesString (line 117) | static void changesString(WrenVM* vm)
  function shared (line 126) | static void shared(WrenVM* vm)
  function importer (line 135) | static void importer(WrenVM* vm)
  function WrenForeignMethodFn (line 144) | WrenForeignMethodFn resolutionBindMethod(const char* signature)
  function resolutionBindClass (line 155) | void resolutionBindClass(const char* className, WrenForeignClassMethods*...

FILE: test/api/slots.c
  function noSet (line 6) | static void noSet(WrenVM* vm)
  function getSlots (line 11) | static void getSlots(WrenVM* vm)
  function setSlots (line 40) | static void setSlots(WrenVM* vm)
  function slotTypes (line 79) | static void slotTypes(WrenVM* vm)
  function ensure (line 94) | static void ensure(WrenVM* vm)
  function ensureOutsideForeign (line 120) | static void ensureOutsideForeign(WrenVM* vm)
  function foreignClassAllocate (line 154) | static void foreignClassAllocate(WrenVM* vm)
  function getListCount (line 159) | static void getListCount(WrenVM* vm)
  function getListElement (line 164) | static void getListElement(WrenVM* vm)
  function getMapValue (line 170) | static void getMapValue(WrenVM* vm)
  function WrenForeignMethodFn (line 175) | WrenForeignMethodFn slotsBindMethod(const char* signature)
  function slotsBindClass (line 190) | void slotsBindClass(const char* className, WrenForeignClassMethods* meth...

FILE: test/api/user_data.c
  function test (line 20) | static void test(WrenVM* vm)
  function WrenForeignMethodFn (line 59) | WrenForeignMethodFn userDataBindMethod(const char* signature)

FILE: test/benchmark/binary_trees.dart
  class Tree (line 3) | class Tree {
  function main (line 27) | main()

FILE: test/benchmark/binary_trees.py
  function make_tree (line 17) | def make_tree(item, depth):
  function check_tree (line 23) | def check_tree(node):

FILE: test/benchmark/binary_trees.rb
  function item_check (line 8) | def item_check(left, item, right)
  function bottom_up_tree (line 13) | def bottom_up_tree(item, depth)

FILE: test/benchmark/delta_blue.dart
  function main (line 40) | main()
  class Strength (line 61) | class Strength {
    method nextWeaker (line 68) | Strength nextWeaker()
    method stronger (line 72) | bool stronger(Strength s1, Strength s2)
    method weaker (line 76) | bool weaker(Strength s1, Strength s2)
    method weakest (line 80) | Strength weakest(Strength s1, Strength s2)
    method strongest (line 84) | Strength strongest(Strength s1, Strength s2)
  class Constraint (line 100) | abstract class Constraint {
    method isSatisfied (line 106) | bool isSatisfied()
    method markUnsatisfied (line 107) | void markUnsatisfied()
    method addToGraph (line 108) | void addToGraph()
    method removeFromGraph (line 109) | void removeFromGraph()
    method chooseMethod (line 110) | void chooseMethod(int mark)
    method markInputs (line 111) | void markInputs(int mark)
    method inputsKnown (line 112) | bool inputsKnown(int mark)
    method output (line 113) | Variable output()
    method execute (line 114) | void execute()
    method recalculate (line 115) | void recalculate()
    method addConstraint (line 118) | void addConstraint()
    method satisfy (line 130) | Constraint satisfy(mark)
    method destroyConstraint (line 148) | void destroyConstraint()
    method isInput (line 158) | bool isInput()
  class UnaryConstraint (line 164) | abstract class UnaryConstraint extends Constraint {
    method addToGraph (line 174) | void addToGraph()
    method chooseMethod (line 180) | void chooseMethod(int mark)
    method isSatisfied (line 186) | bool isSatisfied()
    method markInputs (line 188) | void markInputs(int mark)
    method output (line 193) | Variable output()
    method recalculate (line 200) | void recalculate()
    method markUnsatisfied (line 207) | void markUnsatisfied()
    method inputsKnown (line 211) | bool inputsKnown(int mark)
    method removeFromGraph (line 213) | void removeFromGraph()
  class StayConstraint (line 226) | class StayConstraint extends UnaryConstraint {
    method execute (line 230) | void execute()
  class EditConstraint (line 240) | class EditConstraint extends UnaryConstraint {
    method isInput (line 245) | bool isInput()
    method execute (line 247) | void execute()
  class BinaryConstraint (line 263) | abstract class BinaryConstraint extends Constraint {
    method chooseMethod (line 278) | void chooseMethod(int mark)
    method addToGraph (line 299) | void addToGraph()
    method isSatisfied (line 306) | bool isSatisfied()
    method markInputs (line 309) | void markInputs(int mark)
    method input (line 314) | Variable input()
    method output (line 317) | Variable output()
    method recalculate (line 324) | void recalculate()
    method markUnsatisfied (line 332) | void markUnsatisfied()
    method inputsKnown (line 336) | bool inputsKnown(int mark)
    method removeFromGraph (line 341) | void removeFromGraph()
  class ScaleConstraint (line 356) | class ScaleConstraint extends BinaryConstraint {
    method addToGraph (line 366) | void addToGraph()
    method removeFromGraph (line 372) | void removeFromGraph()
    method markInputs (line 378) | void markInputs(int mark)
    method execute (line 384) | void execute()
    method recalculate (line 397) | void recalculate()
  class EqualityConstraint (line 410) | class EqualityConstraint extends BinaryConstraint {
    method execute (line 416) | void execute()
  class Variable (line 428) | class Variable {
    method addConstraint (line 444) | void addConstraint(Constraint c)
    method removeConstraint (line 449) | void removeConstraint(Constraint c)
  class Planner (line 456) | class Planner {
    method incrementalAdd (line 474) | void incrementalAdd(Constraint c)
    method incrementalRemove (line 492) | void incrementalRemove(Constraint c)
    method newMark (line 508) | int newMark()
    method makePlan (line 529) | Plan makePlan(List<Constraint> sources)
    method extractPlanFromConstraints (line 548) | Plan extractPlanFromConstraints(List<Constraint> constraints)
    method addPropagate (line 571) | bool addPropagate(Constraint c, int mark)
    method removePropagateFrom (line 590) | List<Constraint> removePropagateFrom(Variable out)
    method addConstraintsConsumingTo (line 614) | void addConstraintsConsumingTo(Variable v, List<Constraint> coll)
  class Plan (line 629) | class Plan {
    method addConstraint (line 632) | void addConstraint(Constraint c)
    method size (line 636) | int size()
    method execute (line 638) | void execute()
  function chainTest (line 659) | void chainTest(int n)
  function projectionTest (line 686) | void projectionTest(int n)
  function change (line 718) | void change(Variable v, int newValue)

FILE: test/benchmark/delta_blue.py
  class Strength (line 33) | class Strength(object):
    method __init__ (line 42) | def __init__(self, strength, name):
    method stronger (line 48) | def stronger(cls, s1, s2):
    method weaker (line 52) | def weaker(cls, s1, s2):
    method weakest_of (line 56) | def weakest_of(cls, s1, s2):
    method strongest (line 63) | def strongest(cls, s1, s2):
    method next_weaker (line 69) | def next_weaker(self):
  class Constraint (line 93) | class Constraint(object):
    method __init__ (line 94) | def __init__(self, strength):
    method add_constraint (line 98) | def add_constraint(self):
    method satisfy (line 103) | def satisfy(self, mark):
    method destroy_constraint (line 128) | def destroy_constraint(self):
    method is_input (line 135) | def is_input(self):
  class UrnaryConstraint (line 139) | class UrnaryConstraint(Constraint):
    method __init__ (line 140) | def __init__(self, v, strength):
    method add_to_graph (line 146) | def add_to_graph(self):
    method choose_method (line 150) | def choose_method(self, mark):
    method is_satisfied (line 157) | def is_satisfied(self):
    method mark_inputs (line 160) | def mark_inputs(self, mark):
    method output (line 164) | def output(self):
    method recalculate (line 169) | def recalculate(self):
    method mark_unsatisfied (line 176) | def mark_unsatisfied(self):
    method inputs_known (line 179) | def inputs_known(self, mark):
    method remove_from_graph (line 182) | def remove_from_graph(self):
  class StayConstraint (line 188) | class StayConstraint(UrnaryConstraint):
    method __init__ (line 189) | def __init__(self, v, string):
    method execute (line 192) | def execute(self):
  class EditConstraint (line 197) | class EditConstraint(UrnaryConstraint):
    method __init__ (line 198) | def __init__(self, v, string):
    method is_input (line 201) | def is_input(self):
    method execute (line 204) | def execute(self):
  class Direction (line 209) | class Direction(object):
  class BinaryConstraint (line 216) | class BinaryConstraint(Constraint):
    method __init__ (line 217) | def __init__(self, v1, v2, strength):
    method choose_method (line 224) | def choose_method(self, mark):
    method add_to_graph (line 248) | def add_to_graph(self):
    method is_satisfied (line 253) | def is_satisfied(self):
    method mark_inputs (line 256) | def mark_inputs(self, mark):
    method input (line 259) | def input(self):
    method output (line 265) | def output(self):
    method recalculate (line 271) | def recalculate(self):
    method mark_unsatisfied (line 280) | def mark_unsatisfied(self):
    method inputs_known (line 283) | def inputs_known(self, mark):
    method remove_from_graph (line 287) | def remove_from_graph(self):
  class ScaleConstraint (line 297) | class ScaleConstraint(BinaryConstraint):
    method __init__ (line 298) | def __init__(self, src, scale, offset, dest, strength):
    method add_to_graph (line 304) | def add_to_graph(self):
    method remove_from_graph (line 309) | def remove_from_graph(self):
    method mark_inputs (line 318) | def mark_inputs(self, mark):
    method execute (line 323) | def execute(self):
    method recalculate (line 329) | def recalculate(self):
  class EqualityConstraint (line 339) | class EqualityConstraint(BinaryConstraint):
    method execute (line 340) | def execute(self):
  class Variable (line 344) | class Variable(object):
    method __init__ (line 345) | def __init__(self, name, initial_value=0):
    method __repr__ (line 355) | def __repr__(self):
    method add_constraint (line 362) | def add_constraint(self, constraint):
    method remove_constraint (line 365) | def remove_constraint(self, constraint):
  class Planner (line 372) | class Planner(object):
    method __init__ (line 373) | def __init__(self):
    method incremental_add (line 377) | def incremental_add(self, constraint):
    method incremental_remove (line 384) | def incremental_remove(self, constraint):
    method new_mark (line 402) | def new_mark(self):
    method make_plan (line 406) | def make_plan(self, sources):
    method extract_plan_from_constraints (line 421) | def extract_plan_from_constraints(self, constraints):
    method add_propagate (line 430) | def add_propagate(self, c, mark):
    method remove_propagate_from (line 446) | def remove_propagate_from(self, out):
    method add_constraints_consuming_to (line 470) | def add_constraints_consuming_to(self, v, coll):
  class Plan (line 482) | class Plan(object):
    method __init__ (line 483) | def __init__(self):
    method add_constraint (line 487) | def add_constraint(self, c):
    method __len__ (line 490) | def __len__(self):
    method __getitem__ (line 493) | def __getitem__(self, index):
    method execute (line 496) | def execute(self):
  function chain_test (line 504) | def chain_test(n):
  function projection_test (line 555) | def projection_test(n):
  function change (line 606) | def change(v, new_value):
  function delta_blue (line 626) | def delta_blue():

FILE: test/benchmark/fannkuch.py
  function fannkuch (line 9) | def fannkuch(n):

FILE: test/benchmark/fannkuch.rb
  function fannkuch (line 1) | def fannkuch(n)

FILE: test/benchmark/fib.dart
  function fib (line 1) | fib(n)
  function main (line 6) | main()

FILE: test/benchmark/fib.py
  function fib (line 5) | def fib(n):

FILE: test/benchmark/fib.rb
  function fib (line 1) | def fib(n)

FILE: test/benchmark/for.dart
  function main (line 1) | main()

FILE: test/benchmark/method_call.dart
  class Toggle (line 1) | class Toggle {
  class NthToggle (line 16) | class NthToggle extends Toggle {
  function main (line 37) | main()

FILE: test/benchmark/method_call.py
  class Toggle (line 14) | class Toggle(object):
    method __init__ (line 15) | def __init__(self, start_state):
    method value (line 17) | def value(self):
    method activate (line 19) | def activate(self):
  class NthToggle (line 23) | class NthToggle(Toggle):
    method __init__ (line 24) | def __init__(self, start_state, max_counter):
    method activate (line 28) | def activate(self):
  function main (line 36) | def main():

FILE: test/benchmark/method_call.rb
  class Toggle (line 7) | class Toggle
    method initialize (line 8) | def initialize(start_state)
    method value (line 12) | def value
    method activate (line 16) | def activate
  class NthToggle (line 22) | class NthToggle < Toggle
    method initialize (line 23) | def initialize(start_state, max_counter)
    method activate (line 29) | def activate
  function main (line 39) | def main()

FILE: test/main.c
  function WrenVM (line 14) | static WrenVM* initVM(bool isAPITest)
  function main (line 34) | int main(int argc, const char* argv[]) {

FILE: test/test.c
  function ensureCapacity (line 5) | void ensureCapacity(Path* path, size_t capacity)
  function appendSlice (line 23) | void appendSlice(Path* path, Slice slice)
  function pathAppendString (line 32) | void pathAppendString(Path* path, const char* string)
  function isSeparator (line 40) | inline static bool isSeparator(char c)
  function isDriveLetter (line 54) | inline static bool isDriveLetter(char c)
  function absolutePrefixLength (line 66) | inline static size_t absolutePrefixLength(const char* path)
  function PathType (line 94) | PathType pathType(const char* path)
  function Path (line 110) | Path* pathNew(const char* string)
  function pathFree (line 123) | void pathFree(Path* path)
  function pathDirName (line 129) | void pathDirName(Path* path)
  function pathRemoveExtension (line 147) | void pathRemoveExtension(Path* path)
  function pathAppendChar (line 163) | void pathAppendChar(Path* path, char c)
  function pathJoin (line 170) | void pathJoin(Path* path, const char* string)
  function pathNormalize (line 180) | void pathNormalize(Path* path)
  function vm_write (line 343) | void vm_write(WrenVM* vm, const char* text)
  function reportError (line 348) | void reportError(WrenVM* vm, WrenErrorType type,
  function readModuleComplete (line 367) | void readModuleComplete(WrenVM* vm, const char* module, WrenLoadModuleRe...
  function WrenLoadModuleResult (line 375) | WrenLoadModuleResult readModule(WrenVM* vm, const char* module)
  function isModuleAnAPITest (line 426) | bool isModuleAnAPITest(const char* module)
  function WrenInterpretResult (line 433) | WrenInterpretResult runFile(WrenVM* vm, const char* path)
  function handle_args (line 464) | int handle_args(int argc, const char* argv[])

FILE: test/test.h
  type Slice (line 32) | typedef struct {
  type PathType (line 38) | typedef enum
  type Path (line 52) | typedef struct

FILE: test/unit/main.c
  function main (line 4) | int main()

FILE: test/unit/path_test.c
  function expectNormalize (line 9) | static void expectNormalize(const char* input, const char* expected)
  function testNormalize (line 31) | static void testNormalize()
  function testPath (line 99) | void testPath()

FILE: test/unit/test.c
  function pass (line 8) | void pass()
  function fail (line 13) | void fail()
  function showTestResults (line 18) | int showTestResults()

FILE: try/main.try.c
  function WrenVM (line 11) | static WrenVM* initVM()
  function wren_compile (line 28) | int wren_compile(const char* input) {
  function main (line 36) | int main(int argc, const char* argv[]) {

FILE: util/benchmark.py
  function BENCHMARK (line 52) | def BENCHMARK(name, pattern):
  function green (line 116) | def green(text):
  function red (line 119) | def red(text):
  function yellow (line 122) | def yellow(text):
  function get_score (line 126) | def get_score(time):
  function standard_deviation (line 135) | def standard_deviation(times):
  function run_trial (line 149) | def run_trial(benchmark, language):
  function run_benchmark_language (line 174) | def run_benchmark_language(benchmark, language, benchmark_result):
  function run_benchmark (line 237) | def run_benchmark(benchmark, languages, graph):
  function graph_results (line 253) | def graph_results(benchmark_result):
  function read_baseline (line 279) | def read_baseline():
  function generate_baseline (line 293) | def generate_baseline():
  function print_html (line 306) | def print_html():
  function main (line 341) | def main():

FILE: util/generate_amalgamation.py
  function find_file (line 16) | def find_file(filename):
  function add_comment_file (line 28) | def add_comment_file(filename):
  function add_file (line 35) | def add_file(filename):

FILE: util/generate_docs.py
  class RootedHTTPServer (line 28) | class RootedHTTPServer(HTTPServer):
    method __init__ (line 33) | def __init__(self, base_path, *args, **kwargs):
  class RootedHTTPRequestHandler (line 38) | class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
    method translate_path (line 43) | def translate_path(self, path):
  function ensure_dir (line 60) | def ensure_dir(path):
  function is_up_to_date (line 65) | def is_up_to_date(path, out_path):
  function format_file (line 75) | def format_file(path, skip_up_to_date):
  function copy_static (line 147) | def copy_static():
  function format_files (line 165) | def format_files(skip_up_to_date):
  function run_server (line 174) | def run_server():

FILE: util/generate_projects.py
  function run_premake (line 29) | def run_premake(action, os):

FILE: util/metrics.py
  function c_metrics (line 34) | def c_metrics(label, directories):
  function wren_metrics (line 76) | def wren_metrics(label, directories):

FILE: util/test.py
  class Test (line 56) | class Test:
    method __init__ (line 57) | def __init__(self, path):
    method parse (line 68) | def parse(self):
    method run (line 148) | def run(self, app, type):
    method validate (line 176) | def validate(self, is_example, exit_code, out, err):
    method validate_runtime_error (line 203) | def validate_runtime_error(self, error_lines):
    method validate_compile_errors (line 239) | def validate_compile_errors(self, error_lines):
    method validate_exit_code (line 260) | def validate_exit_code(self, exit_code, error_lines):
    method validate_output (line 268) | def validate_output(self, out):
    method fail (line 292) | def fail(self, message, *args):
  function color_text (line 298) | def color_text(text, color):
  function green (line 309) | def green(text):  return color_text(text, '\033[32m')
  function pink (line 310) | def pink(text):   return color_text(text, '\033[91m')
  function red (line 311) | def red(text):    return color_text(text, '\033[31m')
  function yellow (line 312) | def yellow(text): return color_text(text, '\033[33m')
  function walk (line 315) | def walk(dir, callback, ignored=None):
  function print_line (line 333) | def print_line(line=None):
  function run_script (line 343) | def run_script(app, path, type):
  function run_test (line 388) | def run_test(path, example=False):
  function run_api_test (line 392) | def run_api_test(path):
  function run_example (line 396) | def run_example(path):

FILE: util/wren_to_c_string.py
  function wren_to_c_string (line 22) | def wren_to_c_string(input_path, wren_source_lines, module):
  function main (line 34) | def main():
Condensed preview — 1157 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,340K chars).
[
  {
    "path": ".github/workflows/.githubCI.yml",
    "chars": 1250,
    "preview": "name: WrenCI\n\non:\n  workflow_dispatch:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\njobs:\n  li"
  },
  {
    "path": ".gitignore",
    "chars": 521,
    "preview": "# Build outputs\n/bin\n/lib\n# Intermediate files\n*.obj\nDebug/\nRelease/\n/build\n/.sass-cache\n*.pyc\n\n# I leave a temporary Wr"
  },
  {
    "path": ".travis.sh",
    "chars": 603,
    "preview": "#!/bin/bash\nset -e\n\n# This build script only builds mac or linux right now, for CI.\nWREN_WD=\"projects/make\"\nif [ -n \"$WR"
  },
  {
    "path": ".travis.yml",
    "chars": 1168,
    "preview": "language: c\r\n\r\n# https://docs.travis-ci.com/user/languages/c/#gcc-on-macos\r\n# On mac, gcc is aliased to clang, so we onl"
  },
  {
    "path": "AUTHORS",
    "chars": 1250,
    "preview": "This is the (likely incomplete) list of people who have made Wren what it is.\nIf you submit a patch to Wren, please add "
  },
  {
    "path": "CHANGELOG.md",
    "chars": 4909,
    "preview": "## 0.4.0\n\n### Language\n- Add `continue` keyword\n- Add `as`: `import \"...\" for Name as OtherName`\n- Add Support positive "
  },
  {
    "path": "LICENSE",
    "chars": 1098,
    "preview": "MIT License\n\nCopyright (c) 2013-2021 Robert Nystrom and Wren Contributors\n\nPermission is hereby granted, free of charge,"
  },
  {
    "path": "README.md",
    "chars": 2206,
    "preview": "## Wren is a small, fast, class-based concurrent scripting language\n\nThink Smalltalk in a Lua-sized package with a dash "
  },
  {
    "path": "doc/error-handling.txt",
    "chars": 3611,
    "preview": "Q: Can we use fibers for error-handling?\n\nThe goal here is to avoid adding support for exception handling if we're alrea"
  },
  {
    "path": "doc/implicit fields.txt",
    "chars": 989,
    "preview": "Q: Can fields be implicitly declared?\n\nThe idea is that just using a name starting with \"_\" somewhere in a class\nautomat"
  },
  {
    "path": "doc/instruction counts.txt",
    "chars": 1185,
    "preview": "This is the number of times each instruction was executed when running the\ndelta_blue benchmark:\n\n3753021 CODE_LOAD_LOCA"
  },
  {
    "path": "doc/notes/import syntax.md",
    "chars": 7832,
    "preview": "So we need some syntax to distinguish between a relative import and a logical\nimport. I'm not sure which way to go, and "
  },
  {
    "path": "doc/notes/re-entrancy.md",
    "chars": 6110,
    "preview": "## wrenInterpret()\n\nYou can already call out to a foreign method or constructor from within an\nexecution that was starte"
  },
  {
    "path": "doc/receiver-less calls 2.txt",
    "chars": 4306,
    "preview": "    var baz = \"top level\"\n\n    class Foo {\n      bar {\n        baz\n        _baz\n      }\n\n      baz { \"getter\" }\n      _b"
  },
  {
    "path": "doc/receiver-less calls.txt",
    "chars": 1896,
    "preview": "Q1: What does this resolve to:\n\n    foo(arg)\n\n   It could be:\n   1. this.foo(arg)\n   2. EnclosingClass.foo(arg) // i.e. "
  },
  {
    "path": "doc/rfc/0001-smarter-imports.md",
    "chars": 17836,
    "preview": "# Smarter Imports\n\n**Note: This is now mostly implemented, though the implementation differs\nsomewhat from this original"
  },
  {
    "path": "doc/site/blog/0-hello-wren.markdown",
    "chars": 4531,
    "preview": "^title Hello Wren\n4 Feb 2019\n\n---\n\nWelcome to the new Wren development blog!\n\nAround November 2018 on the Wren mailing l"
  },
  {
    "path": "doc/site/blog/1-0.2.0-and-beyond.markdown",
    "chars": 4797,
    "preview": "^title 0.2.0 and beyond\n30 Sep 2019\n\n---\n\n### 0.2.0 is here\n\nIt's time to tag a release!\nLet's check our goals from [the"
  },
  {
    "path": "doc/site/blog/2-0.3.0-released.markdown",
    "chars": 5722,
    "preview": "^title 0.3.0 released!\n5 June 2020\n\n---\n\nIn this post we'll cover 0.3.0 and the goals for 0.4.0 [#](#goals-for-0.4.0).\n\n"
  },
  {
    "path": "doc/site/blog/3-0.4.0-released.markdown",
    "chars": 5342,
    "preview": "^title 0.4.0 released!\n8 April 2021\n\n---\n\nThis post is all about the 0.4.0 release since it's a big one!   \n<small>(A se"
  },
  {
    "path": "doc/site/blog/index.markdown",
    "chars": 610,
    "preview": "^title Development blogs\n\n[<h3>0.4.0 released!</h3>](3-0.4.0-released.html)\n> <date>8 April 2021</date> • 0.4.0 is a big"
  },
  {
    "path": "doc/site/blog/rss.xml",
    "chars": 1586,
    "preview": "<rss version=\"2.0\">\n  <channel><title>Wren - development blog</title>\n    <link>https://wren.io/</link>\n    <description"
  },
  {
    "path": "doc/site/blog/template.html",
    "chars": 2148,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/classes.markdown",
    "chars": 20716,
    "preview": "^title Classes\n\nEvery value in Wren is an object, and every object is an instance of a class.\nEven `true` and `false` ar"
  },
  {
    "path": "doc/site/cli/index.markdown",
    "chars": 1248,
    "preview": "^title Wren CLI\n\n---\n\n## What is it?\n\n**The Wren Command-Line Interface** is a tool you can run which gives you a way to"
  },
  {
    "path": "doc/site/cli/modules/index.markdown",
    "chars": 548,
    "preview": "^title CLI Modules\n\nThe Wren CLI executable extends the built in language modules with its own,\nwhich offer access to IO"
  },
  {
    "path": "doc/site/cli/modules/io/directory.markdown",
    "chars": 374,
    "preview": "^title Directory Class\n\nA directory on the file system.\n\n## Static Methods\n\n### Directory.**exists**(path)\n\nWhether a di"
  },
  {
    "path": "doc/site/cli/modules/io/file-flags.markdown",
    "chars": 1391,
    "preview": "^title FileFlags Class\n\nContains constants for the various file flags used to open or create a file.\nThese correspond di"
  },
  {
    "path": "doc/site/cli/modules/io/file.markdown",
    "chars": 3393,
    "preview": "^title File Class\n\nLets you work with files on the file system. An instance of this class\nrepresents an open file with a"
  },
  {
    "path": "doc/site/cli/modules/io/index.markdown",
    "chars": 202,
    "preview": "^title Module \"io\"\n\nProvides access to operating system streams and the file system.\n\n* [Directory](directory.html)\n* [F"
  },
  {
    "path": "doc/site/cli/modules/io/stat.markdown",
    "chars": 1098,
    "preview": "^title Stat Class\n\nA data structure describing the low-level details of a file system entry.\n\n## Static Methods\n\n### Sta"
  },
  {
    "path": "doc/site/cli/modules/io/stdin.markdown",
    "chars": 1245,
    "preview": "^title Stdin Class\n\nThe standard input stream.\n\n## Static Methods\n\n### **isRaw**\n\nReturns `true` if stdin is in raw mode"
  },
  {
    "path": "doc/site/cli/modules/io/stdout.markdown",
    "chars": 250,
    "preview": "^title Stdout Class\n\nThe standard output stream.\n\n## Static Methods\n\n### **flush()**\n\nFlushes all buffered data to the s"
  },
  {
    "path": "doc/site/cli/modules/io/template.html",
    "chars": 2859,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/cli/modules/os/index.markdown",
    "chars": 177,
    "preview": "^title Module \"os\"\n\nThe os module exposes classes for accessing capabilities provided by the\nunderlying operating system"
  },
  {
    "path": "doc/site/cli/modules/os/platform.markdown",
    "chars": 665,
    "preview": "^title Platform Class\n\nThe Platform class exposes basic information about the operating system Wren is\nrunning on top of"
  },
  {
    "path": "doc/site/cli/modules/os/process.markdown",
    "chars": 839,
    "preview": "^title Process Class\n\nThe Process class lets you work with operating system processes, including the\ncurrently running o"
  },
  {
    "path": "doc/site/cli/modules/os/template.html",
    "chars": 2449,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/cli/modules/scheduler/index.markdown",
    "chars": 230,
    "preview": "^title Module \"scheduler\"\n\nThis module provides a vehicle to allow other operations to be performed asynchronously whils"
  },
  {
    "path": "doc/site/cli/modules/scheduler/scheduler.markdown",
    "chars": 834,
    "preview": "^title Scheduler Class\n\nThe Scheduler class maintains a list of fibers, to be started one after the other, when a signal"
  },
  {
    "path": "doc/site/cli/modules/scheduler/template.html",
    "chars": 2373,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/cli/modules/template.html",
    "chars": 2719,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/cli/modules/timer/index.markdown",
    "chars": 266,
    "preview": "^title Module \"timer\"\n\nThis module provides a mechanism to suspend the current fiber for a given period of time either a"
  },
  {
    "path": "doc/site/cli/modules/timer/template.html",
    "chars": 2341,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/cli/modules/timer/timer.markdown",
    "chars": 487,
    "preview": "^title Timer Class\n\n## Static Method\n\n### Timer.**sleep**(milliseconds)\n\nSuspends the current fiber for the given number"
  },
  {
    "path": "doc/site/cli/template.html",
    "chars": 2608,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/cli/usage.markdown",
    "chars": 1288,
    "preview": "^title Wren CLI Usage\n\n---\n\n\nYou can [download a build for your OS from the releases page](https://github.com/wren-lang/"
  },
  {
    "path": "doc/site/concurrency.markdown",
    "chars": 6939,
    "preview": "^title Concurrency\n\nLightweight concurrency is a key feature of Wren and it is expressed using\n*fibers*. They control ho"
  },
  {
    "path": "doc/site/contributing.markdown",
    "chars": 5480,
    "preview": "^title Contributing\n\nLike the bird, Wren's ecosystem is small but full of life. Almost everything is\nunder active develo"
  },
  {
    "path": "doc/site/control-flow.markdown",
    "chars": 9468,
    "preview": "^title Control Flow\n\nControl flow is used to determine which chunks of code are executed and how many\ntimes. *Branching*"
  },
  {
    "path": "doc/site/embedding/calling-c-from-wren.markdown",
    "chars": 4999,
    "preview": "^title Calling C from Wren\n\nWhen we are ensconced within the world of Wren, the external C world is\n\"foreign\" to us. The"
  },
  {
    "path": "doc/site/embedding/calling-wren-from-c.markdown",
    "chars": 7861,
    "preview": "^title Calling Wren from C\n\nFrom C, we can tell Wren to do stuff by calling `wrenInterpret()`, but that's\nnot always the"
  },
  {
    "path": "doc/site/embedding/configuring-the-vm.markdown",
    "chars": 7970,
    "preview": "^title Configuring the VM\n\nWhen you create a Wren VM, you tweak it by passing in a pointer to a\nWrenConfiguration struct"
  },
  {
    "path": "doc/site/embedding/index.markdown",
    "chars": 10125,
    "preview": "^title Embedding\n\nWren is designed to be a scripting language that lives inside a host\napplication, so the embedding API"
  },
  {
    "path": "doc/site/embedding/slots-and-handles.markdown",
    "chars": 11025,
    "preview": "^title Slots and Handles\n\nWith `wrenInterpret()`, we can execute code, but that code can't do anything\nparticularly inte"
  },
  {
    "path": "doc/site/embedding/storing-c-data.markdown",
    "chars": 13277,
    "preview": "^title Storing C Data\n\nAn embedded language often needs to work with native data. You may want a\npointer to some memory "
  },
  {
    "path": "doc/site/embedding/template.html",
    "chars": 2912,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/error-handling.markdown",
    "chars": 5893,
    "preview": "^title Error Handling\n\nErrors come in a few fun flavors.\n\n## Syntax errors\n\nThe first errors you're likely to run into a"
  },
  {
    "path": "doc/site/functions.markdown",
    "chars": 6431,
    "preview": "^title Functions\n\nLike many languages today, functions in Wren are little bundles of code \nyou can store in a variable, "
  },
  {
    "path": "doc/site/getting-started.markdown",
    "chars": 3701,
    "preview": "^title Getting Started\n\n## Trying out the language\n\nIf you'd like to try Wren, you have a few options.\n\n *  **In your br"
  },
  {
    "path": "doc/site/index.markdown",
    "chars": 1999,
    "preview": "^title\n\n## Wren is a small, fast, class-based concurrent scripting language\n\n---\n\nThink Smalltalk in a Lua-sized package"
  },
  {
    "path": "doc/site/lists.markdown",
    "chars": 4222,
    "preview": "^title Lists\n\nA list is a compound object that holds a collection of elements identified by\ninteger index. You can creat"
  },
  {
    "path": "doc/site/maps.markdown",
    "chars": 5278,
    "preview": "^title Maps\n\nA map is an *associative* collection. It holds a set of entries, each of which\nmaps a *key* to a *value*. T"
  },
  {
    "path": "doc/site/method-calls.markdown",
    "chars": 6521,
    "preview": "^title Method Calls\n\nWren is deeply object oriented, so most code consists of invoking methods on\nobjects, usually somet"
  },
  {
    "path": "doc/site/modularity.markdown",
    "chars": 10852,
    "preview": "^title Modularity\n\nOnce you start writing programs that are more than little toys, you quickly run\ninto two problems:\n\n1"
  },
  {
    "path": "doc/site/modules/core/bool.markdown",
    "chars": 366,
    "preview": "^title Bool Class\n\nBoolean [values][]. There are two instances, `true` and `false`.\n\n[values]: ../../values.html\n\n## Met"
  },
  {
    "path": "doc/site/modules/core/class.markdown",
    "chars": 530,
    "preview": "^title Class Class\n\n**TODO**\n\n## Methods\n\n### **name**\n\nThe name of the class.\n\n### **supertype**\n\nThe superclass of thi"
  },
  {
    "path": "doc/site/modules/core/fiber.markdown",
    "chars": 6801,
    "preview": "^title Fiber Class\n\nA lightweight coroutine. [Here][fibers] is a gentle introduction.\n\n[fibers]: ../../concurrency.html\n"
  },
  {
    "path": "doc/site/modules/core/fn.markdown",
    "chars": 1221,
    "preview": "^title Fn Class\n\nA first class function&mdash;an object that wraps an executable chunk of code.\n[Here][functions] is a f"
  },
  {
    "path": "doc/site/modules/core/index.markdown",
    "chars": 66,
    "preview": "\n<script type=\"text/javascript\">\nwindow.location = '../'\n</script>"
  },
  {
    "path": "doc/site/modules/core/list.markdown",
    "chars": 6222,
    "preview": "^title List Class\n\nExtends [Sequence](sequence.html).\n\nAn indexable contiguous collection of elements. More details [her"
  },
  {
    "path": "doc/site/modules/core/map.markdown",
    "chars": 2650,
    "preview": "^title Map Class\n\nExtends [Sequence](sequence.html).\n\nAn associative collection that maps keys to values. More details ["
  },
  {
    "path": "doc/site/modules/core/null.markdown",
    "chars": 193,
    "preview": "^title Null Class\n\n## Methods\n\n### **!** operator\n\nReturns `true`, since `null` is considered [false](../../control-flow"
  },
  {
    "path": "doc/site/modules/core/num.markdown",
    "chars": 7797,
    "preview": "^title Num Class\n\n## Static Methods\n\n### Num.**fromString**(value)\n\nAttempts to parse `value` as a decimal literal and r"
  },
  {
    "path": "doc/site/modules/core/object.markdown",
    "chars": 1493,
    "preview": "^title Object Class\n\n## Static Methods\n\n### **same**(obj1, obj2)\n\nReturns `true` if *obj1* and *obj2* are the same. For "
  },
  {
    "path": "doc/site/modules/core/range.markdown",
    "chars": 1388,
    "preview": "^title Range Class\n\nA range defines a bounded range of values from a starting point to a possibly\nexclusive endpoint. [H"
  },
  {
    "path": "doc/site/modules/core/sequence.markdown",
    "chars": 5859,
    "preview": "^title Sequence Class\n\nAn abstract base class for any iterable object. Any class that implements the\ncore [iterator prot"
  },
  {
    "path": "doc/site/modules/core/string.markdown",
    "chars": 8401,
    "preview": "^title String Class\n\nA string is an immutable array of bytes. Strings usually store text, in which\ncase the bytes are th"
  },
  {
    "path": "doc/site/modules/core/system.markdown",
    "chars": 1602,
    "preview": "^title System Class\n\nThe System class is a grab-bag of functionality exposed by the VM, mostly for\nuse during developmen"
  },
  {
    "path": "doc/site/modules/core/template.html",
    "chars": 3380,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/modules/index.markdown",
    "chars": 1225,
    "preview": "^title Modules\r\n\r\nWren comes with two kinds of modules, the core module (built-in),\r\nand a few optional modules that the"
  },
  {
    "path": "doc/site/modules/meta/index.markdown",
    "chars": 264,
    "preview": "^title Module \"meta\"\n\nThis module enables Wren to do certain kinds of meta-programming.\n\nIt is an optional module. You c"
  },
  {
    "path": "doc/site/modules/meta/meta.markdown",
    "chars": 4289,
    "preview": "^title Meta Class\n\nThis class contains static methods to list a module's top-level variables and to compile Wren express"
  },
  {
    "path": "doc/site/modules/meta/template.html",
    "chars": 2236,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/modules/random/index.markdown",
    "chars": 274,
    "preview": "^title Module \"random\"\n\nThis module provides a simple, fast pseudo-random number generator.\n\nIt is an optional module. Y"
  },
  {
    "path": "doc/site/modules/random/random.markdown",
    "chars": 3773,
    "preview": "^title Random Class\n\nA simple, fast pseudo-random number generator. Internally, it uses the [well\nequidistributed long-p"
  },
  {
    "path": "doc/site/modules/random/template.html",
    "chars": 2252,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/modules/template.html",
    "chars": 3660,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/performance.markdown",
    "chars": 10936,
    "preview": "^title Performance\n\nEven though most benchmarks aren't worth the pixels they're printed on, people\nseem to like them, so"
  },
  {
    "path": "doc/site/qa.markdown",
    "chars": 7491,
    "preview": "^title Q & A\n\n## Why did you create Wren?\n\nOther creative endeavors aren't immediately met with existential crises, but\n"
  },
  {
    "path": "doc/site/static/codejar-linenumbers.js",
    "chars": 2087,
    "preview": "function withLineNumbers(highlight, options = {}) {\n    const opts = Object.assign({ class: \"codejar-linenumbers\", wrapC"
  },
  {
    "path": "doc/site/static/codejar.js",
    "chars": 12978,
    "preview": "function CodeJar(editor, highlight, opt = {}) {\n    const options = Object.assign({ tab: \"\\t\" }, opt);\n    let listeners"
  },
  {
    "path": "doc/site/static/prism.css",
    "chars": 2355,
    "preview": "/* PrismJS 1.20.0\nhttps://prismjs.com/download.html#themes=prism&languages=clike+c+lua */\n/**\n * prism.js default theme "
  },
  {
    "path": "doc/site/static/prism.js",
    "chars": 9756,
    "preview": "/* PrismJS 1.20.0\nhttps://prismjs.com/download.html#themes=prism&languages=clike+c+lua */\nvar _self=\"undefined\"!=typeof "
  },
  {
    "path": "doc/site/static/style.css",
    "chars": 10349,
    "preview": "\n:root {\n  --header-h: 8em;\n  --header: \"Sanchez\", helvetica, arial, sans-serif;\n  --subheader: \"Lato\", helvetica, arial"
  },
  {
    "path": "doc/site/static/wren.js",
    "chars": 3414,
    "preview": "window.onload = function() {\n  var blocks = document.querySelectorAll('pre.snippet')\n  blocks.forEach((element) => {\n   "
  },
  {
    "path": "doc/site/static/wren_try.js",
    "chars": 112552,
    "preview": "/**\n * @license\n * Copyright 2010 The Emscripten Authors\n * SPDX-License-Identifier: MIT\n */\n\n// The Module object: Our "
  },
  {
    "path": "doc/site/syntax.markdown",
    "chars": 8219,
    "preview": "^title Syntax\n\nWren's syntax is designed to be familiar to people coming from C-like languages\nwhile being a bit simpler"
  },
  {
    "path": "doc/site/template.html",
    "chars": 4548,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/try/index.markdown",
    "chars": 612,
    "preview": "^title Try Wren\n\n---\n\n<div id=\"examples\">\nexamples: &nbsp;\n<a class=\"button\" id=\"try-hello\">hello</a>\n<a class=\"button\" "
  },
  {
    "path": "doc/site/try/template.html",
    "chars": 5617,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n<title>{title} &ndash"
  },
  {
    "path": "doc/site/values.markdown",
    "chars": 6091,
    "preview": "^title Values\n\nValues are the built-in atomic object types that all other objects are composed\nof. They can be created t"
  },
  {
    "path": "doc/site/variables.markdown",
    "chars": 2255,
    "preview": "^title Variables\n\nVariables are named slots for storing values. You define a new variable in Wren\nusing a `var` statemen"
  },
  {
    "path": "example/embedding/main.c",
    "chars": 1259,
    "preview": "//For more details, visit https://wren.io/embedding/\n\n#include <stdio.h>\n#include \"wren.h\"\n\nstatic void writeFn(WrenVM* "
  },
  {
    "path": "example/hello.wren",
    "chars": 30,
    "preview": "System.print(\"Hello, world!\")\n"
  },
  {
    "path": "example/import_module/cthulu.wren",
    "chars": 105,
    "preview": "class Cthulu {\n  construct new() {}\n  message { \"Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn\" }\n}\n"
  },
  {
    "path": "example/import_module/lovecraft.wren",
    "chars": 141,
    "preview": "import \"./cthulu\" for Cthulu\n\nclass Lovecraft {\n  construct new() {}\n  say() { Cthulu.new().message }\n}\n\nSystem.print(Lo"
  },
  {
    "path": "example/mandelbrot.wren",
    "chars": 658,
    "preview": "var yMin = -0.2\nvar yMax = 0.1\nvar xMin = -1.5\nvar xMax = -1.1\n\nfor (yPixel in 0...24) {\n  var y = (yPixel / 24) * (yMax"
  },
  {
    "path": "example/skynet.wren",
    "chars": 681,
    "preview": "// A million fiber microbenchmark based on: https://github.com/atemerev/skynet.\nclass Skynet {\n  static makeFiber(num, s"
  },
  {
    "path": "example/syntax.wren",
    "chars": 3542,
    "preview": "// This file provides examples of syntactic constructs in wren, which is mainly\n// interesting for testing syntax highli"
  },
  {
    "path": "projects/make/Makefile",
    "chars": 2443,
    "preview": "# Alternative GNU Make workspace makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef v"
  },
  {
    "path": "projects/make/wren.make",
    "chars": 5742,
    "preview": "# Alternative GNU Make project makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef ver"
  },
  {
    "path": "projects/make/wren_shared.make",
    "chars": 6102,
    "preview": "# Alternative GNU Make project makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef ver"
  },
  {
    "path": "projects/make/wren_test.make",
    "chars": 8042,
    "preview": "# Alternative GNU Make project makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef ver"
  },
  {
    "path": "projects/make.bsd/Makefile",
    "chars": 2443,
    "preview": "# Alternative GNU Make workspace makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef v"
  },
  {
    "path": "projects/make.bsd/wren.make",
    "chars": 5742,
    "preview": "# Alternative GNU Make project makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef ver"
  },
  {
    "path": "projects/make.bsd/wren_shared.make",
    "chars": 5958,
    "preview": "# Alternative GNU Make project makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef ver"
  },
  {
    "path": "projects/make.bsd/wren_test.make",
    "chars": 8042,
    "preview": "# Alternative GNU Make project makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef ver"
  },
  {
    "path": "projects/make.mac/Makefile",
    "chars": 2443,
    "preview": "# Alternative GNU Make workspace makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef v"
  },
  {
    "path": "projects/make.mac/wren.make",
    "chars": 5804,
    "preview": "# Alternative GNU Make project makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef ver"
  },
  {
    "path": "projects/make.mac/wren_shared.make",
    "chars": 6302,
    "preview": "# Alternative GNU Make project makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef ver"
  },
  {
    "path": "projects/make.mac/wren_test.make",
    "chars": 8084,
    "preview": "# Alternative GNU Make project makefile autogenerated by Premake\n\nifndef config\n  config=release_64bit\nendif\n\nifndef ver"
  },
  {
    "path": "projects/premake/premake5.lua",
    "chars": 2010,
    "preview": "workspace \"wren\"\r\n  configurations { \"Release\", \"Debug\" }\r\n  platforms { \"64bit\", \"32bit\", \"64bit-no-nan-tagging\" }\r\n  d"
  },
  {
    "path": "projects/vs2017/wren.sln",
    "chars": 4654,
    "preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 15\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00"
  },
  {
    "path": "projects/vs2017/wren.vcxproj",
    "chars": 14838,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro"
  },
  {
    "path": "projects/vs2017/wren.vcxproj.filters",
    "chars": 2754,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "projects/vs2017/wren_shared.vcxproj",
    "chars": 15514,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro"
  },
  {
    "path": "projects/vs2017/wren_shared.vcxproj.filters",
    "chars": 2754,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "projects/vs2017/wren_test.vcxproj",
    "chars": 16070,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro"
  },
  {
    "path": "projects/vs2017/wren_test.vcxproj.filters",
    "chars": 3988,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "projects/vs2019/wren.sln",
    "chars": 4654,
    "preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 16\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00"
  },
  {
    "path": "projects/vs2019/wren.vcxproj",
    "chars": 14810,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/m"
  },
  {
    "path": "projects/vs2019/wren.vcxproj.filters",
    "chars": 2754,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "projects/vs2019/wren_shared.vcxproj",
    "chars": 15486,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/m"
  },
  {
    "path": "projects/vs2019/wren_shared.vcxproj.filters",
    "chars": 2754,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "projects/vs2019/wren_test.vcxproj",
    "chars": 16042,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/m"
  },
  {
    "path": "projects/vs2019/wren_test.vcxproj.filters",
    "chars": 3988,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "projects/xcode/wren.xcodeproj/project.pbxproj",
    "chars": 13631,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "projects/xcode/wren.xcworkspace/contents.xcworkspacedata",
    "chars": 269,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n\tversion = \"1.0\">\n\t<FileRef\n\t\tlocation = \"group:wren_test.xcodeproj\">\n"
  },
  {
    "path": "projects/xcode/wren_shared.xcodeproj/project.pbxproj",
    "chars": 13808,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "projects/xcode/wren_test.xcodeproj/project.pbxproj",
    "chars": 21677,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "src/README.md",
    "chars": 648,
    "preview": "This contains the Wren source code. It is organized like so:\r\n\r\n*   `include`: the public header directory for the VM. I"
  },
  {
    "path": "src/include/wren.h",
    "chars": 22928,
    "preview": "#ifndef wren_h\n#define wren_h\n\n#include <stdarg.h>\n#include <stdlib.h>\n#include <stdbool.h>\n\n// The Wren semantic versio"
  },
  {
    "path": "src/include/wren.hpp",
    "chars": 194,
    "preview": "#ifndef wren_hpp\n#define wren_hpp\n\n// This is a convenience header for users that want to compile Wren as C and\n// link "
  },
  {
    "path": "src/optional/wren_opt_meta.c",
    "chars": 2565,
    "preview": "#include \"wren_opt_meta.h\"\n\n#if WREN_OPT_META\n\n#include <string.h>\n\n#include \"wren_vm.h\"\n#include \"wren_opt_meta.wren.in"
  },
  {
    "path": "src/optional/wren_opt_meta.h",
    "chars": 482,
    "preview": "#ifndef wren_opt_meta_h\n#define wren_opt_meta_h\n\n#include \"wren_common.h\"\n#include \"wren.h\"\n\n// This module defines the "
  },
  {
    "path": "src/optional/wren_opt_meta.wren",
    "chars": 968,
    "preview": "class Meta {\n  static getModuleVariables(module) {\n    if (!(module is String)) Fiber.abort(\"Module name must be a strin"
  },
  {
    "path": "src/optional/wren_opt_meta.wren.inc",
    "chars": 1225,
    "preview": "// Generated automatically from src/optional/wren_opt_meta.wren. Do not edit.\nstatic const char* metaModuleSource =\n\"cla"
  },
  {
    "path": "src/optional/wren_opt_random.c",
    "chars": 3820,
    "preview": "#include \"wren_opt_random.h\"\n\n#if WREN_OPT_RANDOM\n\n#include <string.h>\n#include <time.h>\n\n#include \"wren.h\"\n#include \"wr"
  },
  {
    "path": "src/optional/wren_opt_random.h",
    "chars": 641,
    "preview": "#ifndef wren_opt_random_h\n#define wren_opt_random_h\n\n#include \"wren_common.h\"\n#include \"wren.h\"\n\n#if WREN_OPT_RANDOM\n\nco"
  },
  {
    "path": "src/optional/wren_opt_random.wren",
    "chars": 2622,
    "preview": "foreign class Random {\n  construct new() {\n    seed_()\n  }\n\n  construct new(seed) {\n    if (seed is Num) {\n      seed_(s"
  },
  {
    "path": "src/optional/wren_opt_random.wren.inc",
    "chars": 3135,
    "preview": "// Generated automatically from src/optional/wren_opt_random.wren. Do not edit.\nstatic const char* randomModuleSource =\n"
  },
  {
    "path": "src/vm/wren_common.h",
    "chars": 8573,
    "preview": "#ifndef wren_common_h\n#define wren_common_h\n\n// This header contains macros and defines used across the entire Wren\n// i"
  },
  {
    "path": "src/vm/wren_compiler.c",
    "chars": 127274,
    "preview": "#include <errno.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"wren_common.h\"\n#include \"wren_"
  },
  {
    "path": "src/vm/wren_compiler.h",
    "chars": 2634,
    "preview": "#ifndef wren_compiler_h\n#define wren_compiler_h\n\n#include \"wren.h\"\n#include \"wren_value.h\"\n\ntypedef struct sCompiler Com"
  },
  {
    "path": "src/vm/wren_core.c",
    "chars": 42444,
    "preview": "#include <ctype.h>\n#include <errno.h>\n#include <float.h>\n#include <math.h>\n#include <string.h>\n#include <time.h>\n\n#inclu"
  },
  {
    "path": "src/vm/wren_core.h",
    "chars": 960,
    "preview": "#ifndef wren_core_h\n#define wren_core_h\n\n#include \"wren_vm.h\"\n\n// This module defines the built-in classes and their pri"
  },
  {
    "path": "src/vm/wren_core.wren",
    "chars": 9630,
    "preview": "class Bool {}\nclass Fiber {}\nclass Fn {}\nclass Null {}\nclass Num {}\n\nclass Sequence {\n  all(f) {\n    var result = true\n "
  },
  {
    "path": "src/vm/wren_core.wren.inc",
    "chars": 11745,
    "preview": "// Generated automatically from src/vm/wren_core.wren. Do not edit.\nstatic const char* coreModuleSource =\n\"class Bool {}"
  },
  {
    "path": "src/vm/wren_debug.c",
    "chars": 10524,
    "preview": "#include <stdio.h>\n\n#include \"wren_debug.h\"\n\nvoid wrenDebugPrintStackTrace(WrenVM* vm)\n{\n  // Bail if the host doesn't e"
  },
  {
    "path": "src/vm/wren_debug.h",
    "chars": 820,
    "preview": "#ifndef wren_debug_h\n#define wren_debug_h\n\n#include \"wren_value.h\"\n#include \"wren_vm.h\"\n\n// Prints the stack trace for t"
  },
  {
    "path": "src/vm/wren_math.h",
    "chars": 701,
    "preview": "#ifndef wren_math_h\n#define wren_math_h\n\n#include <math.h>\n#include <stdint.h>\n\n// A union to let us reinterpret a doubl"
  },
  {
    "path": "src/vm/wren_opcodes.h",
    "chars": 7106,
    "preview": "// This defines the bytecode instructions used by the VM. It does so by invoking\n// an OPCODE() macro which is expected "
  },
  {
    "path": "src/vm/wren_primitive.c",
    "chars": 3389,
    "preview": "#include \"wren_primitive.h\"\n\n#include <math.h>\n\n// Validates that [value] is an integer within `[0, count)`. Also allows"
  },
  {
    "path": "src/vm/wren_primitive.h",
    "chars": 5864,
    "preview": "#ifndef wren_primitive_h\n#define wren_primitive_h\n\n#include \"wren_vm.h\"\n\n// Binds a primitive method named [name] (in Wr"
  },
  {
    "path": "src/vm/wren_utils.c",
    "chars": 4843,
    "preview": "#include <string.h>\n\n#include \"wren_utils.h\"\n#include \"wren_vm.h\"\n\nDEFINE_BUFFER(Byte, uint8_t);\nDEFINE_BUFFER(Int, int)"
  },
  {
    "path": "src/vm/wren_utils.h",
    "chars": 6549,
    "preview": "#ifndef wren_utils_h\n#define wren_utils_h\n\n#include \"wren.h\"\n#include \"wren_common.h\"\n\n// Reusable data structures and o"
  },
  {
    "path": "src/vm/wren_value.c",
    "chars": 37027,
    "preview": "#include <math.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"wren.h\"\n#include \"wren_value.h\"\n"
  },
  {
    "path": "src/vm/wren_value.h",
    "chars": 30963,
    "preview": "#ifndef wren_value_h\n#define wren_value_h\n\n#include <stdbool.h>\n#include <string.h>\n\n#include \"wren_common.h\"\n#include \""
  },
  {
    "path": "src/vm/wren_vm.c",
    "chars": 61230,
    "preview": "#include <stdarg.h>\n#include <string.h>\n\n#include \"wren.h\"\n#include \"wren_common.h\"\n#include \"wren_compiler.h\"\n#include "
  },
  {
    "path": "src/vm/wren_vm.h",
    "chars": 8568,
    "preview": "#ifndef wren_vm_h\n#define wren_vm_h\n\n#include \"wren_common.h\"\n#include \"wren_compiler.h\"\n#include \"wren_value.h\"\n#includ"
  },
  {
    "path": "test/README.md",
    "chars": 917,
    "preview": "This contains the automated validation suite for the VM and built-in libraries.\n\n* `benchmark/` - Performance tests. The"
  },
  {
    "path": "test/api/api_tests.c",
    "chars": 2997,
    "preview": "#include \"./api_tests.h\"\n\nstatic const char* testName = NULL;\n\nWrenForeignMethodFn APITest_bindForeignMethod(\n    WrenVM"
  },
  {
    "path": "test/api/api_tests.h",
    "chars": 877,
    "preview": "#pragma once\n#ifndef WREN_API_TESTS_H\n#define WREN_API_TESTS_H\n\n#include <stdio.h>\n#include <string.h>\n\n#include \"wren.h"
  },
  {
    "path": "test/api/benchmark.c",
    "chars": 2025,
    "preview": "#include <string.h>\n#include <time.h>\n\n#include \"benchmark.h\"\n\nstatic void arguments(WrenVM* vm)\n{\n  double result = 0;\n"
  },
  {
    "path": "test/api/benchmark.h",
    "chars": 83,
    "preview": "#include \"wren.h\"\n\nWrenForeignMethodFn benchmarkBindMethod(const char* signature);\n"
  },
  {
    "path": "test/api/call.c",
    "chars": 3491,
    "preview": "#include <stdio.h>\n#include <string.h>\n\n#include \"call.h\"\n\nint callRunTests(WrenVM* vm)\n{\n  wrenEnsureSlots(vm, 1);\n  wr"
  },
  {
    "path": "test/api/call.h",
    "chars": 49,
    "preview": "#include \"wren.h\"\n\nint callRunTests(WrenVM* vm);\n"
  },
  {
    "path": "test/api/call.wren",
    "chars": 1028,
    "preview": "class Call {\n  static noParams {\n    System.print(\"noParams\")\n  }\n\n  static zero() {\n    System.print(\"zero\")\n  }\n\n  sta"
  },
  {
    "path": "test/api/call_calls_foreign.c",
    "chars": 1119,
    "preview": "#include <stdio.h>\n#include <string.h>\n\n#include \"wren.h\"\n\nstatic void api(WrenVM *vm) {\n  // Grow the slot array. This "
  },
  {
    "path": "test/api/call_calls_foreign.h",
    "chars": 132,
    "preview": "#include \"wren.h\"\n\nWrenForeignMethodFn callCallsForeignBindMethod(const char* signature);\nint callCallsForeignRunTests(W"
  },
  {
    "path": "test/api/call_calls_foreign.wren",
    "chars": 548,
    "preview": "// Regression test for https://github.com/munificent/wren/issues/510.\n//\n// Tests that re-entrant API calls are handled "
  },
  {
    "path": "test/api/call_wren_call_root.c",
    "chars": 686,
    "preview": "#include <stdio.h>\n#include <string.h>\n\n#include \"wren.h\"\n#include \"../test.h\"\n\nint callWrenCallRootRunTests(WrenVM* vm)"
  },
  {
    "path": "test/api/call_wren_call_root.h",
    "chars": 61,
    "preview": "#include \"wren.h\"\n\nint callWrenCallRootRunTests(WrenVM* vm);\n"
  },
  {
    "path": "test/api/call_wren_call_root.wren",
    "chars": 312,
    "preview": "class Test {\n  static run() {\n    var root = Fiber.current\n    System.print(\"begin root\") // expect: begin root\n\n    Fib"
  },
  {
    "path": "test/api/error.c",
    "chars": 350,
    "preview": "#include <stdio.h>\n#include <string.h>\n\n#include \"error.h\"\n\nstatic void runtimeError(WrenVM* vm)\n{\n  wrenEnsureSlots(vm,"
  },
  {
    "path": "test/api/error.h",
    "chars": 79,
    "preview": "#include \"wren.h\"\n\nWrenForeignMethodFn errorBindMethod(const char* signature);\n"
  },
  {
    "path": "test/api/error.wren",
    "chars": 244,
    "preview": "class Error {\n  foreign static runtimeError\n}\n\nvar fiber = Fiber.new {\n  Error.runtimeError\n}\n\nvar error = fiber.try()\nS"
  },
  {
    "path": "test/api/foreign_class.c",
    "chars": 3063,
    "preview": "#include <stdio.h>\n#include <string.h>\n\n#include \"foreign_class.h\"\n\nstatic int finalized = 0;\n\nstatic void apiFinalized("
  },
  {
    "path": "test/api/foreign_class.h",
    "chars": 176,
    "preview": "#include \"wren.h\"\n\nWrenForeignMethodFn foreignClassBindMethod(const char* signature);\nvoid foreignClassBindClass(\n    co"
  },
  {
    "path": "test/api/foreign_class.wren",
    "chars": 1741,
    "preview": "class ForeignClass {\n  foreign static finalized\n}\n\n// Class with a default constructor.\nforeign class Counter {\n  constr"
  },
  {
    "path": "test/api/get_variable.c",
    "chars": 1830,
    "preview": "#include <string.h>\n\n#include \"get_variable.h\"\n\nstatic void beforeDefined(WrenVM* vm)\n{\n  wrenGetVariable(vm, \"./test/ap"
  },
  {
    "path": "test/api/get_variable.h",
    "chars": 85,
    "preview": "#include \"wren.h\"\n\nWrenForeignMethodFn getVariableBindMethod(const char* signature);\n"
  },
  {
    "path": "test/api/get_variable.wren",
    "chars": 1171,
    "preview": "import \"./get_variable_module\"\n\nclass GetVariable {\n  foreign static beforeDefined()\n  foreign static afterDefined()\n  f"
  },
  {
    "path": "test/api/get_variable_module.wren",
    "chars": 35,
    "preview": "// nontest\n\nvar Variable = \"value\"\n"
  },
  {
    "path": "test/api/handle.c",
    "chars": 476,
    "preview": "#include <string.h>\n\n#include \"handle.h\"\n\nstatic WrenHandle* handle;\n\nstatic void setValue(WrenVM* vm)\n{\n  handle = wren"
  },
  {
    "path": "test/api/handle.h",
    "chars": 80,
    "preview": "#include \"wren.h\"\n\nWrenForeignMethodFn handleBindMethod(const char* signature);\n"
  },
  {
    "path": "test/api/handle.wren",
    "chars": 229,
    "preview": "class Handle {\n  foreign static value=(value)\n  foreign static value\n}\n\nHandle.value = [\"list\", \"of\", \"strings\"]\n\n// Mak"
  },
  {
    "path": "test/api/lists.c",
    "chars": 1824,
    "preview": "#include <string.h>\n\n#include \"lists.h\"\n\nstatic void newList(WrenVM* vm)\n{\n  wrenSetSlotNewList(vm, 0);\n}\n\n// Helper fun"
  },
  {
    "path": "test/api/lists.h",
    "chars": 79,
    "preview": "#include \"wren.h\"\n\nWrenForeignMethodFn listsBindMethod(const char* signature);\n"
  }
]

// ... and 957 more files (download for full content)

About this extraction

This page contains the full source code of the wren-lang/wren GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1157 files (4.7 MB), approximately 1.3M tokens, and a symbol index with 972 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!