This required a massive cross-cutting rework to the scope system,
multiple subtle bugfixes and relearning of the parser internals, but it
does appear that functions are working correctly.
A few caveats: for now, parameters are always constant, regardless of
type, return values can't be specified, and some script tests have been
written.
Most importantly, a key feature is working: closures.
Also fixed a minor bug with printing, and removed the ability to
configure the parser.
Added and updated QUICKSTART.md as a quick way to get people started.
There's some broken scripts under 'scripts/' that require functions to
work properly.
Functions are having issues with being copied around, especially
between buckets, leading to the scopes getting looped. The program gets
stuck in 'incrementRefCount()'.
It's past my time limit, so I'll keep working on it tomorrow with a
fresh mind.
All function stuff is still untested.
See #163
Parameter lists are read manually, rather than delegating to
parsePrecedence, because that was causing issues.
function bodies are read as block-level statements, just like the entire
files.
They're no-ops in compilation for now, and param types aren't parsed.
'return' keyword needs to be implemented.
Was distracted by bugfixes in v2 and v2-docs.
The definition of '&&':
Return the first falsy value, or the last value, skipping the evaluation of other operands.
The definition of '||':
Return the first truthy value, or the last value, skipping the evaluation of other operands.
Toy now follows these definitions.
Fixed#154
I added reference values in 62ca7a1fb7,
but forgot to mention it. I'm now using references to assign to the
internals of an array, no matter how many levels deep it is.
I had intended to solve the Advent of Code puzzles in Toy, but they
don't work without arrays. I wasn't able to enable arrays in time, so
I need to focus on doing things correctly.
The most immediate tasks are marked with 'URGENT', and a lot of tests
need writing.
I've brought the tests up to scratch, except for compounds im the
parser, because I'm too damn tired to do that over SSH. It looks like
collections are right-recursive, whixh was unintended but still works
just fine.
I've also added the '--verbose' flag to the repl to control the
debugging output.
Several obscure bugs have been fixed, and comments have been tweaked.
Mustfail tests are still needed, but that's a low priority. See #142.
Fixed#151
The assert keyword works, but I want to add a cmd option to suppress or
disable the errors.
The tests need some serious TLC. I know that, but I'm kicking it down
the road for now.
I was coding earlier this week, but my brain was so foggy I ended up not
knowing what I was doing. After a few days break, I've cleaned up the
mess, which took hours.
Changes:
* Variables can be assigned
* Added new value types as placeholders
* Added 'compare' and 'assign' to the AST
* Added duplicate opcode
* Added functions to copy and free values
* Max name length is 255 chars
* Compound assigns are squeezed into one word
To be completed:
* Tests for this commit's changes
* Compound assignments
* Variable access
Strings, due to their potentially large size, are stored outside of a
routine's code section, in the data section. To access the correct
string, you must read the jump index, then the real address from the
jump table - and extra layer of indirection will result in more flexible
data down the road, I hope.
Other changes include:
* Added string concat operator ..
* Added TOY_STRING_MAX_LENGTH
* Strings can't be created or concatenated longer than the max length
* The parser will display a warning if the bucket is too small for a
string at max length, but it will continue
* Added TOY_BUCKET_IDEAL to correspend with max string length
* The bucket now allocates an address that is 4-byte aligned
* Fixed missing entries in the parser rule table
* Corrected some failing TOY_BITNESS tests
To help with storing strings within tables, I've replaced the unused
'_padding' member of 'Toy_String' with 'cachedHash', which is set to
zero on string allocation.
The hash of a string isn't generated and stored until it's actually
needed, as the rope pattern means not every string needs a hash -
hopefully this will save unnecessarily wasted time.
When a hash of a string is needed, the hashing function first checks to
see if that string already has one, and if so, returns it. Again, less
time wasted.
When generating a new string hash, the hashing function takes the
string's type into account, as node-based strings first need their
contents assembled into a simple char buffer.
Other changes include:
* Changed 'TOY_VALUE_TO_*' to 'TOY_VALUE_FROM_*'
* Changed 'TOY_VALUE_IS_EQUAL' to 'TOY_VALUES_ARE_EQUAL'
* Added a missing '#pragma once' to 'toy_print.h'