From 7d4dd52b8cfc865ae1b975ca3b6a3e72a812ebb9 Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Fri, 14 Feb 2025 09:36:52 +1300 Subject: Rewrite library --- src/stages/semantic_tokens.rs | 101 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/stages/semantic_tokens.rs (limited to 'src/stages/semantic_tokens.rs') diff --git a/src/stages/semantic_tokens.rs b/src/stages/semantic_tokens.rs new file mode 100644 index 0000000..ca5b27a --- /dev/null +++ b/src/stages/semantic_tokens.rs @@ -0,0 +1,101 @@ +use crate::*; + +use std::collections::HashMap; + + +pub struct Program { + pub definitions: HashMap>, + pub tokens: Vec>, +} + +pub struct Definition { + pub kind: DefinitionKind, + pub definition: usize, + pub references: Vec, + pub deep_references: Vec<(usize, usize)>, +} + +impl Definition { + pub fn new(i: usize, kind: DefinitionKind) -> Self { + Self { + kind, + definition: i, + references: Vec::new(), + deep_references: Vec::new(), + } + } +} + +pub enum DefinitionKind { + MacroDefinition(Vec>), + LabelDefinition, +} + +pub enum SemanticToken { + Comment(String), + + LabelDefinition(String), + MacroDefinition(Tracked), + + RawValue(Value), + Instruction(Instruction), + Invocation(String), + + Padding(Value), + String(Vec), + + BlockOpen(usize), + BlockClose(usize), +} + +pub enum SemanticError { + InvocationBeforeDefinition, +} + + +pub fn report_semantic_errors(errors: &[Tracked], source_code: &str) { + for error in errors { + report_semantic_error(error, source_code); + } +} + +fn report_semantic_error(error: &Tracked, source_code: &str) { + let context = Context { source_code: &source_code, source: &error.source }; + let message = match &error.value { + SemanticError::InvocationBeforeDefinition => + "Invocation before definition", + }; + + report_source_issue(LogLevel::Error, &context, message); +} + + +pub fn print_semantic_token(i: usize, token: &SemanticToken, definitions: &HashMap>) { + match token { + SemanticToken::Comment(_) => + indent!(i, "Comment"), + + SemanticToken::LabelDefinition(name) => + indent!(i, "LabelDefinition({name})"), + SemanticToken::MacroDefinition(name) => { + indent!(i, "MacroDefinition({name})"); + if let Some(definition) = definitions.get(name.as_str()) { + if let DefinitionKind::MacroDefinition(body) = &definition.kind { + for token in body { + print_semantic_token(i+1, token, definitions); + } + } + } + } + + SemanticToken::RawValue(value) => indent!(i, "RawValue({value})"), + SemanticToken::Instruction(instruction) => indent!(i, "Instruction({instruction})"), + SemanticToken::Invocation(name) => indent!(i, "Invocation({name})"), + + SemanticToken::Padding(value) => indent!(i, "Padding({value})"), + SemanticToken::String(bytes) => indent!(i, "String({})", String::from_utf8_lossy(bytes)), + + SemanticToken::BlockOpen(pointer) => indent!(i, "BlockOpen(*{pointer})"), + SemanticToken::BlockClose(pointer) => indent!(i, "BlockOpen(*{pointer})"), + } +} -- cgit v1.2.3-70-g09d2