Highlight syntax errors in code snippets
This commit is contained in:
parent
bb6478b474
commit
c038f6d55a
@ -52,6 +52,7 @@ export interface TokenizeResult {
|
|||||||
Err?: Err,
|
Err?: Err,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const error_classes = "underline decoration-wavy decoration-red-500";
|
||||||
|
|
||||||
export async function native_highlighter(code: string): Promise<[string, string, string | null]> {
|
export async function native_highlighter(code: string): Promise<[string, string, string | null]> {
|
||||||
let formatted_code = leftTrimDedent(code).join("\n");
|
let formatted_code = leftTrimDedent(code).join("\n");
|
||||||
@ -67,7 +68,6 @@ export async function native_highlighter(code: string): Promise<[string, string,
|
|||||||
return lex_error_highlighter(formatted_code, result.Err!.Lex!);
|
return lex_error_highlighter(formatted_code, result.Err!.Lex!);
|
||||||
}
|
}
|
||||||
else if (result.TokensOnly) {
|
else if (result.TokensOnly) {
|
||||||
// TODO
|
|
||||||
const [tokens, error] = result.TokensOnly!;
|
const [tokens, error] = result.TokensOnly!;
|
||||||
return syntax_error_highlighter(formatted_code, tokens, error.Syntax!);
|
return syntax_error_highlighter(formatted_code, tokens, error.Syntax!);
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ function lex_error_highlighter(code: string, error: LexError): [string, string,
|
|||||||
const err_str = code[err_pos];
|
const err_str = code[err_pos];
|
||||||
const after_err = code.substring(err_pos + 1);
|
const after_err = code.substring(err_pos + 1);
|
||||||
|
|
||||||
const token = `<span class="token underline decoration-wavy decoration-red-500">${err_str}</span>`;
|
const token = `<span class="token ${error_classes}">${err_str}</span>`;
|
||||||
|
|
||||||
const all = `${before_err}${token}${after_err}`;
|
const all = `${before_err}${token}${after_err}`;
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ function lex_error_highlighter(code: string, error: LexError): [string, string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
function syntax_error_highlighter(code: string, tokens: Array<Token>, error: SyntaxError): [string, string, string] {
|
function syntax_error_highlighter(code: string, tokens: Array<Token>, error: SyntaxError): [string, string, string] {
|
||||||
const highlighted = highlight_tokens(code, tokens);
|
const highlighted = highlight_tokens(code, tokens, error.error_start, error.error_end);
|
||||||
|
|
||||||
const error_message = `${error.reason} from position ${error.error_start} to ${error.error_end}`;
|
const error_message = `${error.reason} from position ${error.error_start} to ${error.error_end}`;
|
||||||
return [highlighted, "Syntax", error_message];
|
return [highlighted, "Syntax", error_message];
|
||||||
@ -110,7 +110,16 @@ function compiler_error(code: string, error: Error): [string, string, string] {
|
|||||||
return [code, "Fatal Compiler", error.message];
|
return [code, "Fatal Compiler", error.message];
|
||||||
}
|
}
|
||||||
|
|
||||||
function highlight_tokens(input: string, tokens: Array<Token>): string {
|
/**
|
||||||
|
* Transforms a list of tokens into colored HTML, and underlines errors
|
||||||
|
* if present
|
||||||
|
* @param input The original source code
|
||||||
|
* @param tokens The list of tokens
|
||||||
|
* @param error_start Absolute position from where the error starts.
|
||||||
|
* @param error_end Absolute position to where the error ends.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function highlight_tokens(input: string, tokens: Array<Token>, error_start = -1, error_end = -1): string {
|
||||||
const input_chars = input.split("");
|
const input_chars = input.split("");
|
||||||
let output = "";
|
let output = "";
|
||||||
|
|
||||||
@ -120,6 +129,9 @@ function highlight_tokens(input: string, tokens: Array<Token>): string {
|
|||||||
const token_start = t.position;
|
const token_start = t.position;
|
||||||
const token_end = t.position + t.value.length;
|
const token_end = t.position + t.value.length;
|
||||||
|
|
||||||
|
let is_errored = (token_start == error_start);
|
||||||
|
|
||||||
|
|
||||||
// There are some tokens that are empty, ignore them
|
// There are some tokens that are empty, ignore them
|
||||||
if (t.value == "") {
|
if (t.value == "") {
|
||||||
continue;
|
continue;
|
||||||
@ -131,7 +143,7 @@ function highlight_tokens(input: string, tokens: Array<Token>): string {
|
|||||||
// Append the token
|
// Append the token
|
||||||
const token_value = t.value.replaceAll(/</g, "<").replaceAll(/>/g, ">");
|
const token_value = t.value.replaceAll(/</g, "<").replaceAll(/>/g, ">");
|
||||||
const token_type = translate_token_type(t.token_type, token_value);
|
const token_type = translate_token_type(t.token_type, token_value);
|
||||||
output += `<span class="token ${token_type}">${token_value}</span>`;
|
output += `<span class="token ${token_type} ${is_errored ? error_classes : ""}">${token_value}</span>`;
|
||||||
|
|
||||||
current_pos = token_end;
|
current_pos = token_end;
|
||||||
}
|
}
|
||||||
|
@ -117,8 +117,8 @@ doesn't match a previous level.
|
|||||||
|
|
||||||
<Code thpcode={`
|
<Code thpcode={`
|
||||||
if true { // 0 indentation
|
if true { // 0 indentation
|
||||||
// print() // 4 indentation
|
print() // 4 indentation
|
||||||
// print() // 2 indentation. Error. There is no 2-indentation level
|
print() // 2 indentation. Error. There is no 2-indentation level
|
||||||
}
|
}
|
||||||
`} />
|
`} />
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user