Skip to content

Commit

Permalink
renderable error type
Browse files Browse the repository at this point in the history
  • Loading branch information
bcpeinhardt committed Oct 29, 2024
1 parent 4e52852 commit 5e3e238
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 50 deletions.
51 changes: 10 additions & 41 deletions squared_away/src/squared_away.gleam
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import renderable_error
import gleam/dict
import gleam/int
import gleam/list
Expand Down Expand Up @@ -130,7 +131,7 @@ fn view(model: Model) -> element.Element(Msg) {
list.find_map(model.errors_to_display, fn(e) {
case Some(e.0) == model.active_cell {
False -> Error(Nil)
True -> Ok(error_view(e.1))
True -> Ok(error_view(e.1 |> error.to_renderable_error))
}
})
|> result.unwrap(or: html.div([], []))
Expand Down Expand Up @@ -221,47 +222,15 @@ fn view(model: Model) -> element.Element(Msg) {
])
}

fn error_view(e: error.CompileError) {
case e {
error.TypeError(te) -> {
case te {
type_error.IncorrectTypesForBinaryOp(lhs, rhs, bo) ->
html.div([], [
html.h4(
[],
t(
"Type Error: Incorrect types for binary operation "
<> type_error.describe_binary_op_kind_for_err(bo),
),
),
html.p(
[],
t(
"The `&&` operator is specifically for booleans values (TRUE/FALSE). ",
),
),
html.p(
[],
t(
"You provided a "
<> typ.to_string(lhs)
<> " on the left and a "
<> typ.to_string(rhs)
<> " on the right",
),
),
html.p(
[],
t(
"Hint: If you're trying to verify both values have been provided, use the global `notempty` function like so: notempty(myvar) && notempty(myothervar).",
),
),
])
type_error.TypeError(txt) -> html.div([], t(txt))
}
fn error_view(re: renderable_error.RenderableError) {
html.div([], [
html.h4([], t(re.title)),
html.p([], t(re.info)),
.. case re.hint {
None -> []
Some(hint) -> [html.p([], t(hint))]
}
_ -> html.p([], t(error.to_string(e)))
}
])
}

fn t(input: String) {
Expand Down
14 changes: 14 additions & 0 deletions squared_away_lang/src/renderable_error.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import gleam/option.{type Option}

/// This type represents an error we want to render. The idea is that the
/// various error types implement converstion functions to this, rather than
/// individual to_string, to_html, etc. functions, which cuts down on work for
/// me as just one person.
/// It will hopefully also help to keep error's looking consistent in the UI.
pub type RenderableError {
RenderableError(
title: String,
info: String,
hint: Option(String)
)
}
15 changes: 6 additions & 9 deletions squared_away_lang/src/squared_away_lang/error.gleam
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import renderable_error
import squared_away_lang/interpreter/runtime_error
import squared_away_lang/parser/parse_error
import squared_away_lang/scanner/scan_error
import squared_away_lang/typechecker/type_error
import gleam/option.{None}

pub type CompileError {
ScanError(scan_error.ScanError)
Expand All @@ -10,15 +12,10 @@ pub type CompileError {
RuntimeError(runtime_error.RuntimeError)
}

pub fn to_string(e: CompileError) -> String {
case e {
ParseError(parse_error.ParseError(txt)) ->
error_type_string(e) <> ": " <> txt
RuntimeError(runtime_error.RuntimeError(txt)) ->
error_type_string(e) <> ": " <> txt
ScanError(scan_error.ScanError) ->
error_type_string(e) <> ": Unrecognized token"
TypeError(te) -> type_error.to_string(te)
pub fn to_renderable_error(ce: CompileError) -> renderable_error.RenderableError {
case ce {
TypeError(te) -> type_error.to_renderable_error(te)
_ -> renderable_error.RenderableError(title: "Compiler error", info: "Todo: implement this error description", hint: None)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import renderable_error
import squared_away_lang/parser/expr
import squared_away_lang/typechecker/typ
import gleam/option.{None}

pub type TypeError {
TypeError(context: String)
Expand All @@ -10,6 +12,16 @@ pub type TypeError {
)
}

pub fn to_renderable_error(te: TypeError) -> renderable_error.RenderableError {
case te {
IncorrectTypesForBinaryOp(lhs, rhs, op) -> renderable_error.RenderableError(
title: "Unexpected arguments to binary operation `&&`",
info: "Expected booleans. Got " <> typ.to_string(lhs) <> " on the left and " <> typ.to_string(rhs) <> " on the right",
hint: None)
TypeError(_) -> renderable_error.RenderableError(title: "Type Error", info: "Todo: Fill in this error", hint: None)
}
}

pub fn to_string(te: TypeError) -> String {
case te {
IncorrectTypesForBinaryOp(lhs:, rhs:, binary_op:) -> "Type Error:\n
Expand Down

0 comments on commit 5e3e238

Please sign in to comment.