summaryrefslogtreecommitdiff
path: root/src/stages/intermediate.rs
Commit message (Collapse)AuthorAge
* Defer evaluation of block argumentsBen Bridle4 days
| | | | | | | | | | | | | | | | | | | When a block value is evaluated, the address tracker is immediately incremented for each word in the evaluated block. This was causing an issue when a block value was passed as an argument to a macro invocation, because argument values would all be evaluated before the macro body was evaluated. This meant that the value of every label in the macro body would be pushed forward by the size of the block argument, even if the block argument is inserted later in the macro. Furthermore, the address tracker would be incremented exactly once for each word in the block, even if the block is never inserted into the macro or is inserted multiple times. To fix this, we now defer evaluation of a block argument until exactly when that block argument is inserted into a macro. Because a block argument could be an invocation with a set of arguments passed to it, we also store a copy of the current environment alongside the block value so that it can be evaluated correctly at any time in the future.
* Move parse_macro_definition_body function closer to calling siteBen Bridle4 days
| | | | This simplifies the next commit.
* Convert single-element lists to integers when an integer is requiredBen Bridle2025-12-04
| | | | | | This allows an integer invocation with arguments to be wrapped in `[]` square brackets so that it can be passed to another invocation as an argument.
* Use invocation source for integer type error, not macro sourceBen Bridle2025-11-26
|
* Remove semantic::ListLiteral::InvocationBen Bridle2025-11-26
| | | | | | This variant was never needed or constructed, I would have added it to match the invocation variants of the block and integer tokens (which do have a use).
* Raise an error if recursion depth exceeds a maximum valueBen Bridle2025-10-15
| | | | | | This is preferable to having the assembler crash with a stack overflow error, because the user can now see which invocation caused the overflow.
* Implement new bytecode stageBen Bridle2025-10-14
| | | | | This completes the Torque version 3 rewrite, other than some extensive testing that is yet to be done.
* Implement new intermediate stageBen Bridle2025-10-14
| | | | | | | | Massive improvement. Label references can be used anywhere in the program, with the program being assembled repeatedly until all labels have stabilised. The bytecode stage will just be a tiny stage tacked onto the end, rather than the old bytecode stage that would resolve labels and expressions.
* Allow label references in pinned address calculationsBen Bridle2025-04-26
| | | | | | | | | | | | | | | | This is a relaxation of the rule where a label reference could not be used in any context that could change the length of an assembled program. We implement this in the bytecode stage by naively calculating an initial address for each label as before. If a pinned address is calculated from a label reference, some of the calculated addresses could be incorrect. We then attempt to run the bytecode stage, which will calculate a more accurate address for each label based on how pinned addresses are calculated. If the address of any label was changed by running this stage, we re-run the stage up to three more times until all labels stabilise. If the labels fail to stabilise, we return an error.
* Implement first-class string literalsBen Bridle2025-04-26
| | | | | | | | | | | This feature promotes strings to a first-class type in the language. If a string is passed to an invocation via the new string-type argument, the string will be passed as a whole value. String arguments can still be passed to an invocation via an integer-type argument, in which case they'll be broken apart into individual characters with the macro being invoked once per character. String-type macro arguments are declared like "name".
* Allow a macro to invoke itself safelyBen Bridle2025-04-18
| | | | | | | A macro can now invoke itself if the invocation is inside a conditional block that will eventually return false. The assembler stack can still overflow if the macro recurses too deeply, or if a macro calls itself without a conditional block.
* Allow a macro to invoke itselfBen Bridle2025-04-18
| | | | | This will currently cause the assembler to hang in all situations where it is used.
* Rewrite entire assemblerBen Bridle2025-03-11
The language is now more general, the code is better structured, error reporting is more detailed, and many new language features have been implemented: - conditional blocks - first-class strings - more expression operators - binary literals - negative values - invocations in constant expressions