From 2fb095896be1c81cd91c29624011abe7bcf8a6c3 Mon Sep 17 00:00:00 2001 From: Araozu Date: Sun, 28 Jul 2024 16:51:53 -0500 Subject: [PATCH] Add visual indicator to lexical errors in code snippets --- src/components/Code.astro | 11 +++++++-- src/components/docs/CodeError.astro | 8 +++++++ src/lexer/highlighter.ts | 26 ++++++++++++++++++--- src/pages/learn/classes/readonly.mdx | 8 +++++++ src/pages/learn/templating/control-flow.mdx | 4 ++-- 5 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 src/components/docs/CodeError.astro diff --git a/src/components/Code.astro b/src/components/Code.astro index de68a4d..0b13a5c 100644 --- a/src/components/Code.astro +++ b/src/components/Code.astro @@ -1,10 +1,17 @@ --- import { native_highlighter } from "../lexer/highlighter"; +import CodeError from "./docs/CodeError.astro"; const { thpcode } = Astro.props; -const native_html = await native_highlighter(thpcode); +const [native_html, error_message] = await native_highlighter(thpcode); ---
thp
+ class="language-thp">thp + +{ + error_message !== null && ( + {error_message} + ) +} diff --git a/src/components/docs/CodeError.astro b/src/components/docs/CodeError.astro new file mode 100644 index 0000000..3a1f314 --- /dev/null +++ b/src/components/docs/CodeError.astro @@ -0,0 +1,8 @@ +--- +const { error_type = "Unknown" } = Astro.props; +--- + +
+ {error_type} error: + +
diff --git a/src/lexer/highlighter.ts b/src/lexer/highlighter.ts index 064a2d2..478f53e 100644 --- a/src/lexer/highlighter.ts +++ b/src/lexer/highlighter.ts @@ -45,13 +45,13 @@ export interface LexError { } -export async function native_highlighter(code: string): Promise { +export async function native_highlighter(code: string): Promise<[string, string | null]> { let formatted_code = leftTrimDedent(code).join("\n"); const result = await native_lex(formatted_code); if (result.Err) { - throw new Error(JSON.stringify(result.Err.Lex) + "\n" + code); + return lex_error_highlighter(formatted_code, result.Err!.Lex); } const tokens = result.Ok!; @@ -82,7 +82,27 @@ export async function native_highlighter(code: string): Promise { current_pos = token_end; } - return output; + return [output, null]; +} + + +/** + * Highlights code that has a lexic error + */ +function lex_error_highlighter(code: string, error: LexError): [string, string] { + // Create a single error token + + const err_pos = error.position; + const before_err = code.substring(0, err_pos); + const err_str = code[err_pos]; + const after_err = code.substring(err_pos + 1); + + const token = `${err_str}`; + + const all = `${before_err}${token}${after_err}`; + + // TODO: Transform absolute posijion (error.position) into line:column + return [all, error.reason + " at position " + error.position] } function translate_token_type(tt: TokenType, value: string): string { diff --git a/src/pages/learn/classes/readonly.mdx b/src/pages/learn/classes/readonly.mdx index 35c0536..83dc4b0 100644 --- a/src/pages/learn/classes/readonly.mdx +++ b/src/pages/learn/classes/readonly.mdx @@ -5,3 +5,11 @@ title: Readonly import Code from "../../../components/Code.astro" # Readonly + + + + diff --git a/src/pages/learn/templating/control-flow.mdx b/src/pages/learn/templating/control-flow.mdx index bff0474..1246251 100644 --- a/src/pages/learn/templating/control-flow.mdx +++ b/src/pages/learn/templating/control-flow.mdx @@ -57,11 +57,11 @@ fun UserDetail(User user) -> HTML {
@match user.type - case ::Admin + @case ::Admin { } - case ::User + @case ::User { }