aboutsummaryrefslogtreecommitdiff
path: root/lib/xixanta/src/parser.rs
Commit message (Collapse)AuthorAgeFilesLines
* assembler: Add support for asan:reserve,ignoreMiquel Sabaté Solà2025-09-021-79/+163
| | | | | | | | This is the initial support for both directives for the address sanitizer. Note that asan:weak has been moved into asan:ignore, which is not exactly the same but for now it should suffice. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* parser: Add asan:reserve and asan:weak supportMiquel Sabaté Solà2025-08-281-19/+210
| | | | | | | | | | These are special directives that happen on comments, and hence this parser will no longer simply ignore comments. This feature is not used by the assembler, but following commits should build up address sanitizer strategies from it. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Apply suggested style fixes from clippyMiquel Sabaté Solà2025-08-171-13/+11
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* parser: Fix disambiguation paren on first argumentMiquel Sabaté Solà2025-08-171-3/+99
| | | | | | | | | | | | | | | | | | | Arguments can be put inside of enclosing parenthesis, but the parser was assuming that if an opening paren was found when parsing the first argument on an argument list, then that was all it was needed to be parsed. This though conflicts with situations like: .byte ($01 << 2) | ($01 << 1) In this case, the parser would have ignored everything past the first closing paren. This commit provides a fix in which if an operation is found past the first enclosing parenthesis, then this assumption is discarded in favor of a parenthesis being used for disambiguating on an arithmetical/logical expression. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Add support for a single equal sign operatorMiquel Sabaté Solà2025-01-231-1/+4
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Remove dependency to the rand crateMiquel Sabaté Solà2025-01-221-3/+10
| | | | | | | | This dependency was easily avoidable and it brought with it a lot of inner dependencies of its own, most notably 'zerocopy-derive', which forbid us to compile the affected programs purely statically. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Be more explicit on empty identifiersMiquel Sabaté Solà2025-01-211-6/+3
| | | | | | | If the programmer only wrote a single special character for an identifier, then we will consider it empty to avoid shenanigans. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Allow dot characters on identifiersMiquel Sabaté Solà2025-01-211-19/+67
| | | | | | | | In fact, they were always allowed, but they were in kind of grey area, as they could be defined but not used, and sometimes they could be used in the middle of identifiers, which was unexpected. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Introduce looking ahead when parsing literalsMiquel Sabaté Solà2025-01-211-192/+295
| | | | | | | | | | | | | | | | | | | | | | There were certain situations in which syntax ambiguity could arise. For example, the parser as it stood could treat a valid expression such as 'lda #$80 >> 2' in an unexpected 'lda #$(80 >> 2)'. This is of course bad, and it came from the fact that literals don't have enclosing characters, and white spaces are not enough to provide disambiguation in some cases. Because of this fact, the parser now has a "look ahead" capability similar to many other parsers, and it's applied for now only to literals. This looking ahead actually honors parenthesis, so these can be added if the programmer wants to explicitely disambiguate an expression. This involved quite the heavy lifting, and some functions like 'parse_expression_with_identifier' had to be removed with the rewrite. This had the side effect of having (hopefully) more sane functions all around, and the parser also has a better capability to differentiate between regular Values and Calls. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Track the level of recursive callsMiquel Sabaté Solà2025-01-201-18/+35
| | | | | | | | | This is in preparation to some heavy lifting that is to be done to the parser so it more properly handles nested expressions, but in general it's a good idea to have some limits to functions that expect to be called recursively quite heavily. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Whitelist valid identifier charactersMiquel Sabaté Solà2025-01-161-3/+13
| | | | | | | | Instead of making up a list of characters that end an identifier, do the other way around since it's far less cumbersome and it prevents from silly bugs such as "var+1" being considered a single identifier. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Implement .ifdef/.ifndef statementsMiquel Sabaté Solà2025-01-161-3/+11
| | | | | | | They are just synonyms for ".if .defined" and ".if !.defined" respectively. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Implement .if/.elsif/.else statementsMiquel Sabaté Solà2025-01-161-30/+104
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Add boolean operatorsMiquel Sabaté Solà2025-01-161-4/+22
| | | | | | | | | | | Allow for expressions that evaluate to a boolean expression. This in turn mean that the value is just set to 0 or 1 depending on the given condition. As with other assemblers, only a value of 0 evaluates to 0, and others go to 1. So, something like "1 && 2" evaluates to 1 even if it doesn't make much sense at first glance (as an assembler we just assume that the programmer knows what it's doing). Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Fix error with strings containing equal operatorMiquel Sabaté Solà2025-01-151-10/+7
| | | | | | | | | | | As with e27a1593c8d8 ("Allow semicolons inside of strings"), the parser was too naive and regarded any '=' operator as part of an assignment, despite that it could be art of string literal. Luckily the fix was already done inside of the parsing of assignments, we just needed to move it up. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Allow semicolons inside of stringsMiquel Sabaté Solà2025-01-151-9/+43
| | | | | | | | | | | | The parser was too naive and assumed that a semicolon immediately implied an inline comment, and that might not just be the case as it is with string literals. Hence, the end of each semantic line has to consider not only whether there is an inline comment, but also if a string literal is being used and whether it surrounds or not the given semicolon. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Simplify string arguments for control statementsMiquel Sabaté Solà2025-01-151-7/+25
| | | | | | | | | | | Some control statements (e.g. '.incbin', '.asciiz') only require a double-quoted string as an argument. In fact, for these functions there's only one argument required, which is this string one. Given this fact, the parsing on these functions don't have to go through the (expensive) general argument parsing function, and they can simply assume that a double-quoted string will be provided. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Disambiguate unary/binary operatorsMiquel Sabaté Solà2025-01-151-1/+8
| | | | | | | Some operators like '<' and '<<' could be mistakingly be treated as the other. Let's remove this ambiguity when checking for unary operators. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Move check for ASCII-only strings into the parserMiquel Sabaté Solà2025-01-151-0/+4
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Split 'parse_expression' into more functionsMiquel Sabaté Solà2025-01-151-70/+86
| | | | | | | | The other cases in which fetching an "identifier" is not needed were starting to pile up. Hence, split them into separate functions and allow 'parse_expression' to be more simple. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Parse a string literal as a single objectMiquel Sabaté Solà2025-01-151-0/+47
| | | | | | | | | Before this it was left to the `parse_identifier` to figure things out, but this was prone to silly errors like "a: b", in which it would mistake it as the start of a label. Instead of any of this, just consume a string literal if it has been detected. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Improve the message on bad file includesMiquel Sabaté Solà2025-01-101-14/+6
| | | | | | Also remove some pending TODOs. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Rename SourceInfo::working_directory to directoryMiquel Sabaté Solà2025-01-091-4/+3
| | | | | | Also documented the struct as it is exported. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Merge all error types into a single oneMiquel Sabaté Solà2025-01-091-42/+49
| | | | | | | | They started with good intentions, but in the end they were all pretty much alike. Hence, it makes sense to simplify everything and provide a single struct. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Implement the .include statementMiquel Sabaté Solà2025-01-091-86/+310
| | | | | | | | | | | | | | This needed some heavy lifting when it comes to how files were located. This means that statements like .include/.incbin now take into consideration a new list made out of SourceInfo, which holds enough information to translate from which file a node comes from. This has also been added into errors, so they are more informative on what went wrong. In order to tests this, besides all the regular unit tests, a new e2e test has been added. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Restrict literal characters furtherMiquel Sabaté Solà2025-01-091-2/+25
| | | | | | | | | | In bad314e1cfbf ("Prevent numeric literals from having spaces") it was added already the restriction on not having whitespace characters in literal expressions. Here we go a step further and we more explicitely limit which symbol combinations can go into a literal declaration (e.g. "#$2" is valid but "##2" is not). Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Prevent numeric literals from having spacesMiquel Sabaté Solà2025-01-091-4/+25
| | | | | | | | It has been found that having literals like "# 20" can potentially be troublesome and even introduce crashes. Hence, as it's done in other assemblers, disallow this kind of syntax. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Add the .repeat control statementMiquel Sabaté Solà2025-01-071-4/+94
| | | | | | | | | | | | | | | | | | | | | | | | This is a control statement which acts similarly as .proc/.macro/.scope, in which an inner block is allocated for it. Hence, all the previous work from 1f8a6becc7cd ("parser: Implement block bodies") and ec8b709fa24c ("Implement block bodies inside of the assembler") make this one out possible, as .repeat statements don't have an identifier that can be used for hashing. From the parser perspective this introduction raises two new things. First of all this control statement also needed a differentiation between the amount of required arguments, and the allowed ones, since there is a second optional argument to it. And second, even the identifier is not given, we have to generate one so to add a context for it. This was at first not needed, but introducing .repeat-only variables means that we have to have inner contexts which need to be named somehow so we can retrieve the context later when picking up the value for them again. This last thing brought the need for a new dependency: rand. This is used to generate a random string to identify the .repeat block. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* parser: Move out the parsing of control statementsMiquel Sabaté Solà2025-01-051-50/+63
| | | | | | | | | The parsing of control statements have become more complex since the introduction of block bodies in 1f8a6becc7cd ("parser: Implement block bodies"); so it makes sense to move it into its own thing and keep `parse_statement` more clear. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Implement block bodies inside of the assemblerMiquel Sabaté Solà2025-01-051-13/+15
| | | | | | | | | | | Following 1f8a6becc7cd ("parser: Implement block bodies"), the support for the new way of managing block bodies have also been added into the assembler. There are still some things to iron out, but they will be fixed in later commits. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* parser: Implement block bodiesMiquel Sabaté Solà2025-01-041-106/+269
| | | | | | | | | | These are bodies which are the right node of some proc controls. This way the parser comes back to sanity for statements like .macro and the likes, and behaves more like a usual parser. This was not done in the past because I thought things could have been simpler this way, but it ended up making the assembler way more complicated that it needed to. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* parser: Add support for operatorsMiquel Sabaté Solà2024-12-191-12/+178
| | | | | | | | This includes support for both binary and unary operators. Not all of them as listed by ca65 have been moved in. Let's do that whenever it make sense on each case. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* parser: Allow for parenthesized expressionsMiquel Sabaté Solà2024-12-191-0/+43
| | | | | | | | | | Some expressions might be enclosed with parenthesis in order to avoid ambiguations when evaluating them. Account for this on the parser when parsing expressions. Note that this is strictly only on the `parse_expression` function; statements or other top level constructs cannot be enclosed inside of parenthesis. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* parser: Fix crash on non-ASCII char literalsMiquel Sabaté Solà2024-12-131-3/+3
| | | | | | | | | | | | | If the given char literal was not an ASCII one, there was the chance for the character iterator to mess things up. Hence, when checking the closing single quote, it might encounter a None value. This is simply mitigated my moving the check of ASCII alphanumeric before checking for the closing quote. Fixes: b1623996c76f ("Add support for character literals") Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Add support for character literalsMiquel Sabaté Solà2024-12-121-2/+76
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Don't rely on the identifier for control identityMiquel Sabaté Solà2024-12-121-11/+59
| | | | | | | | | Instead, use a new enum type to identify the control statements that we actually support. This way the assembler is more easily aware on the control that it's dealing with, and can be more sure on certain aspects of the implementation on control support. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Initial support for branchingMiquel Sabaté Solà2024-12-121-0/+2
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Re-work the support on labels, variables and jumpsMiquel Sabaté Solà2024-12-121-22/+27
| | | | | | | | | | | As a way to firstly adapt on the latest changes from the parser since 184c39579227 ("Re-work the parser from scratch"), the assembler had to leave out some features on 16114b2ca358 ("Adapt the assembler to the changes on the parser"). This commit reintroduces support for settings labels, variables and referencing them, while also providing a more robust implementation at that. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Allow for relative jumps at the parser levelMiquel Sabaté Solà2024-12-121-20/+153
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Adapt the assembler to the changes on the parserMiquel Sabaté Solà2024-12-121-232/+347
| | | | | | | | | | | As of 184c39579227 ("Re-work the parser from scratch") the parser has a proper AST, and the assembler has to traverse it accordingly. Moreover, the assembler has been stripped from a lot of unneeded memory allocations and it's overall more keen on using mere references when possible. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* ci: Add fuzzy testing to the parserMiquel Sabaté Solà2024-12-121-2/+0
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Re-work the parser from scratchMiquel Sabaté Solà2024-12-121-0/+1496
The initial implementation was incredibly naive on how complex an assembler can actually be. Because of this, it never bothered to define and produce a proper AST, and hence it was overall extremely fragile on (not so) corner cases. This commit re-writes everything from scratch for the parser, and it should really be the last fundamental change to the parser other than minor additions/features here and there. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>