diff options
author | Ben Bridle <bridle.benjamin@gmail.com> | 2025-02-14 09:36:52 +1300 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-03-18 12:23:27 +1300 |
commit | 7d4dd52b8cfc865ae1b975ca3b6a3e72a812ebb9 (patch) | |
tree | 14ca9fa0ddcdd8c5155ddeaac241cd4f55486b6e /src/stages/syntactic_tokens.rs | |
parent | f69a8f8c312ded212446082682bcabba8e3a9c9f (diff) | |
download | bedrock-asm-7d4dd52b8cfc865ae1b975ca3b6a3e72a812ebb9.zip |
Rewrite library
Diffstat (limited to 'src/stages/syntactic_tokens.rs')
-rw-r--r-- | src/stages/syntactic_tokens.rs | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/stages/syntactic_tokens.rs b/src/stages/syntactic_tokens.rs new file mode 100644 index 0000000..57e78e7 --- /dev/null +++ b/src/stages/syntactic_tokens.rs @@ -0,0 +1,107 @@ +use crate::*; + +pub enum SyntacticToken { + Comment(String), + + LabelDefinition(String), + MacroDefinition(SyntacticMacroDefinition), + + RawValue(Value), + Instruction(Instruction), + Invocation(String), + + Padding(Value), + String(Vec<u8>), + + BlockOpen, + BlockClose, +} + +pub struct SyntacticMacroDefinition { + pub name: Tracked<String>, + pub body: Vec<Tracked<SyntacticToken>>, +} + +pub enum SyntacticError { + UnterminatedBlock, + UnterminatedComment, + UnterminatedRawString, + UnterminatedNullString, + UnterminatedMacroDefinition, + + UnmatchedBlockTerminator, + UnmatchedCommentTerminator, + UnmatchedMacroTerminator, + + InvalidPaddingValue, + + MacroDefinitionInMacroDefinition, + LabelDefinitionInMacroDefinition, +} + + +pub fn report_syntactic_errors(errors: &[Tracked<SyntacticError>], source_code: &str) { + for error in errors { + report_syntactic_error(error, source_code); + } +} + +fn report_syntactic_error(error: &Tracked<SyntacticError>, source_code: &str) { + let context = Context { source_code: &source_code, source: &error.source }; + let message = match &error.value { + SyntacticError::UnterminatedBlock => + "Block was not terminated, add a '}}' character to terminate", + SyntacticError::UnterminatedComment => + "Comment was not terminated, add a ')' character to terminate", + SyntacticError::UnterminatedRawString => + "Raw string was not terminated, add a ' character to terminate", + SyntacticError::UnterminatedNullString => + "Null-terminated string was not terminated, add a '\"' character to terminate", + SyntacticError::UnterminatedMacroDefinition => + "Macro definition was not terminated, add a ';' character to terminate", + + SyntacticError::UnmatchedBlockTerminator => + "Attempted to terminate a block, but no block was in progress", + SyntacticError::UnmatchedCommentTerminator => + "Attempted to terminate a comment, but no comment was in progress", + SyntacticError::UnmatchedMacroTerminator => + "Attempted to terminate a macro definition, but no macro definition was in progress", + + SyntacticError::InvalidPaddingValue => + "The padding value must be either two or four hexadecimal digits", + + SyntacticError::MacroDefinitionInMacroDefinition => + "A macro cannot be defined inside another macro", + SyntacticError::LabelDefinitionInMacroDefinition => + "A label cannot be defined inside a macro", + }; + + report_source_issue(LogLevel::Error, &context, message); +} + + +pub fn print_syntactic_token(i: usize, token: &SyntacticToken) { + match token { + SyntacticToken::Comment(_) => + indent!(i, "Comment"), + + SyntacticToken::LabelDefinition(name) => + indent!(i, "LabelDefinition({name})"), + SyntacticToken::MacroDefinition(definition) => { + indent!(i, "MacroDefinition({})", definition.name); + for token in &definition.body { + print_syntactic_token(i+1, token); + } + } + + SyntacticToken::RawValue(value) => indent!(i, "RawValue({value})"), + SyntacticToken::Instruction(instruction) => indent!(i, "Instruction({instruction})"), + SyntacticToken::Invocation(name) => indent!(i, "Invocation({name})"), + + SyntacticToken::Padding(value) => indent!(i, "Padding({value})"), + SyntacticToken::String(bytes) => indent!(i, "String({})", String::from_utf8_lossy(bytes)), + + SyntacticToken::BlockOpen => indent!(i, "BlockOpen"), + SyntacticToken::BlockClose => indent!(i, "BlockOpen"), + } +} |