1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
use crate::*;
use log::LogLevel;
use SemanticTokenVariant as SemVar;
use SemanticParseError as SemErr;
use SyntacticParseError as SynErr;
/// Print all errors found in the semantic tokens, including those inside macro
/// definitions. Returns true if at least one error was printed.
pub fn print_semantic_errors(semantic_tokens: &[SemanticToken], source_code: &str) -> bool {
let mut found_error = false;
for semantic_token in semantic_tokens {
match &semantic_token.variant {
SemVar::Error(err) => {
let context = Context {
source_code: source_code,
source: &semantic_token.source,
};
found_error = true;
print_semantic_error(&err, context)
}
SemVar::MacroDefinition(definition) => {
for body_token in &definition.body_tokens {
if let SemVar::Error(err) = &body_token.variant {
let context = Context {
source_code: source_code,
source: &body_token.source,
};
found_error = true;
print_semantic_error(err, context)
}
}
}
_ => (),
}
}
return found_error;
}
fn print_semantic_error(error: &SemanticParseError, context: Context) {
let message = get_message_for_semantic_error(error);
report_source_issue(LogLevel::Error, &context, &message);
}
fn get_message_for_semantic_error(error: &SemanticParseError) -> String {
match error {
SemErr::LabelDefinitionInMacroDefinition =>
format!("Label cannot be defined inside a macro"),
SemErr::MacroDefinitionInMacroDefinition =>
format!("Macro cannot be defined inside a macro"),
SemErr::StrayMacroTerminator =>
format!("Macro definition terminator is missing a macro definition"),
SemErr::StrayBlockClose =>
format!("Block was not opened, add a '{{' character to open"),
SemErr::UnclosedBlock =>
format!("Block was not closed, add a '}}' character to close"),
SemErr::UndefinedSymbol(name) =>
format!("Undefined symbol, no label or macro has been defined with the name {name:?}"),
SemErr::RedefinedSymbol((_, source)) =>
format!("Redefined symbol, first defined at {}", source.location()),
SemErr::MacroInvocationBeforeDefinition((_, source)) =>
format!("Macro used before definition, definition is at {}", source.location()),
SemErr:: SyntaxError(syntax_error) => match syntax_error {
SynErr::UnterminatedComment =>
format!("Unclosed comment, add a ')' character to close"),
SynErr::UnterminatedRawString =>
format!("Unclosed string, add a ' character to close"),
SynErr::UnterminatedNullString =>
format!("Unclosed string, add a \" character to close"),
SynErr::InvalidPaddingValue(_) =>
format!("Padding value must be two or four hexadecimal digits"),
}
}
}
|