After seven months of intense development, we're happy to announce version 0.6 of Tokay as another milestone towards a stable and final version of the language.
Self-contained parser
One of the main goals of this release was to make tokay.tok become Tokay's main grammar. This eliminates the maintenance of two parsers (parser.rs and tokay.tok), and clears the way for extensive future changes on the grammar and AST.
parser.rs, which is Tokay's internal parser, is now generated from a version of tokay.tok parsing tokay.tok executed by Tokay. It's quite like a lizard eating its own tail, but yeah, it is!
This made the entire macro-based compiler, with a grammar expressed as Rust macro callls, obsolete.
Object improvements
Plenty of improvements went into the object system.
dict allows to use any immutable Tokay value as keys
Most values in Tokay have been declared as immutable - the only mutable values are dict and list, as in this case the content of the value object is modified, rather than replaced (as it is the case with atomic values).
This finally made it possible to use any Tokay value - except list and dict - as keys for dict as well, and not only str.
d = dict()
d[true] = 1
d[42] = true
d[23.5] = "yes"
Enforcement of void paradigm
The void-value defines nothing and can be used so. To remove an item from d above, just set it to void:
d[true] = void
In case a defined "nothing" should be set, use null.
Syntax
The syntax was enhanced as well. Tokay v0.6 also contains a syntax draft for the upcoming generic parselets feature. The language accepts syntax, which might raise a todo!()-call and stop.
Inline sequences
Within brackets (...), Tokay now accepts for inline-sequences in an improved version. () defines the empty list.
Other sequences either result in a list or in a dict, depending on their content. This behavior should be changed im Tokay v0.7, so that lists can be defined explicitly, and everything else is a dict.
Item retrieval and assignment
The retrieval of items in objects has been standardized. This is done using the methods *_get_item and *_set_item*.
l = (1, 2, 3)
l[0] # 1
l[1] = 4
d = (a => 1, b => 2)
d["a"] # 1
d["c"] = 3 # inserts 3 as "c"
The current implementations are
- dict:
- dict_get_item
- dict_set_item
- list:
- list_get_item
- list_set_item
- str:
- str_get_item
str objects cannot be modified,
Char-builtin replaces [...]-syntax and .
The previous [...]-syntax for character-classes was removed as it is reserved for the upcoming list syntax, and was replaced by the Char<>-builtin.
Char # previously `.`
Char<a-z> # previously `[a-z]`
Char<^a-z>+ # previosuly `[^a-z]+`
The new syntax already follows the planned syntax design principle for generic parselets, but is integrated into the language and yields in Char-tokens.
Area syntax @(...)
This new syntax allows to define a parseable sequences with in-place reader extend.
Given the program
x = (Int ',' Int | Ident)
print(repr(x))
the print will never be executed, because the sequence in the assignment matches input, and Tokay's default behavor in a block is to accept a matching sequence as an alternative.
To avoid this behavior (which, indeed, might be a wanted behavior!) and without introducting a new parselet to resolve this, the area syntax can be used:
x = @(Int ',' Int | Ident)
print(repr(x))
The region inside the @(...) gets parsed separately, and the reader is extended so that the program continues as expected.
Changelog
This is the full changelog of this version.
- General
- Use of num-parse for
Intand internal string-to-int conversion ("parseInt()"-like behavior) (#65) - Updated
clapcommand-line parser to v3 (#61) - Improving internal
testcasefunction and moving all prior#[test]-functions into separate Tokay testcases (#86)
- Use of num-parse for
- Syntax
- Operator
//for integer division implemented (#92) - Operator
%for modulo operation implemented - Area syntax
@(...)for in-place reader extend (#78) - Character-class syntax changed from
[a-z]intoChar<a-z>,.andAnysubstituted byChar(#98) ) - Improved syntax for inline blocks and sequences (
|-operator) - Improved list syntax
()the empty list(1,)list with one item (explicit comma required)
- Implemented
x[...]item access syntax for rvalue and lvalue (#80) - Preliminaries for generic parselets (#10)
- New built-in signatures (#84)
- Operator
- Compiler
- Parser
parser.rsis now generated fromtokay.tok; syntax-changes are only done intokay.toknow! (#93)- Removed
macros.rsand macro-based bootstrap parser entirely
- Internal revision
- Removed structs
UsageandImlResult - Integrating all
impl Compileables intoImlOp - Code construction now happens in
ImlOpas well - Added required changes to
- determine whether a part of code consumes input
- preliminaries to generic parselets (yet unfinished)
- Removed structs
prelude.tokprovides some default-parselets defined in Tokay itselfNumbermatches eitherFloatorIntTokenmatches arbitrary tokens
- Parser
- Virtual Machine
- Internal refactoring of the essential
Context::collect()-function (#67) Frameis now managed byContext
- Internal refactoring of the essential
- Values
- Turned Value::Int to crate num-bigint, replaced Value::Addr by the same type (#55)
- Definition of mutable objects; Imutable objects push a clone of, mutable objects push a ref on the object
dictnow allow for any non-mutable value as key (#96)
- Builtins
- Added
dict.clone(),dict_push(),dict.pop(),dict.get_item(),dict.set_item(),list.get_item(),list.set_item(),str.get_item() - Renamed
dict_update()intodict_merge()
- Added
- Examples
- The self-hosted Tokay parser in
examples/tokay.tokwas now moved intosrc/compiler/tokay.tokand is used to generatesrc/compiler/parser.rs(#93) - The JSON parser example in
examples/json.tokwas improved to latest developments
- The self-hosted Tokay parser in