Convert Decoder.decode_code_point return type to a SumType

This commit is contained in:
Josh Holtrop 2023-06-29 19:21:30 -04:00
parent 9895733a05
commit d466189982

View File

@ -2,8 +2,8 @@
module <%= @grammar.modulename %>; module <%= @grammar.modulename %>;
<% end %> <% end %>
import std.stdio; import std.stdio;
import std.sumtype;
<% @grammar.code_blocks.each do |code| %> <% @grammar.code_blocks.each do |code| %>
<%= code %> <%= code %>
@ -71,54 +71,23 @@ class <%= @classname %>
static class Decoder static class Decoder
{ {
struct Result struct Success
{ {
enum Type
{
SUCCESS,
EOF,
DECODE_ERROR,
}
private Type type;
CodePoint code_point; CodePoint code_point;
uint code_point_length; uint code_point_length;
static Result success(CodePoint code_point, uint code_point_length)
{
return Result(Type.SUCCESS, code_point, code_point_length);
}
bool is_success()
{
return type == Type.SUCCESS;
}
static Result eof()
{
return Result(Type.EOF);
}
bool is_eof()
{
return type == Type.EOF;
}
static Result decode_error()
{
return Result(Type.DECODE_ERROR);
}
bool is_decode_error()
{
return type == Type.DECODE_ERROR;
}
} }
struct EOF {}
struct DecodeError {}
static Result decode_code_point(string input) static SumType!(
Success,
EOF,
DecodeError)
decode_code_point(string input)
{ {
if (input.length == 0u) if (input.length == 0u)
{ {
return Result.eof(); return cast(ReturnType!decode_code_point)EOF();
} }
char c = input[0]; char c = input[0];
CodePoint code_point; CodePoint code_point;
@ -158,11 +127,11 @@ class <%= @classname %>
} }
else else
{ {
return Result.decode_error(); return cast(ReturnType!decode_code_point)DecodeError();
} }
if (input.length <= following_bytes) if (input.length <= following_bytes)
{ {
return Result.decode_error(); return cast(ReturnType!decode_code_point)DecodeError();
} }
code_point_length = following_bytes + 1u; code_point_length = following_bytes + 1u;
for (size_t i = 0u; i < following_bytes; i++) for (size_t i = 0u; i < following_bytes; i++)
@ -170,12 +139,12 @@ class <%= @classname %>
char b = input[i + 1u]; char b = input[i + 1u];
if ((b & 0xC0u) != 0x80u) if ((b & 0xC0u) != 0x80u)
{ {
return Result.decode_error(); return cast(ReturnType!decode_code_point)DecodeError();
} }
code_point = (code_point << 6u) | (b & 0x3Fu); code_point = (code_point << 6u) | (b & 0x3Fu);
} }
} }
return Result.success(code_point, code_point_length); return cast(ReturnType!decode_code_point)Success(code_point, code_point_length);
} }
} }
@ -498,63 +467,58 @@ class <%= @classname %>
uint current_state = modes[m_mode].state_table_offset; uint current_state = modes[m_mode].state_table_offset;
for (;;) for (;;)
{ {
auto decoded = Decoder.decode_code_point(m_input[(m_input_position + attempt_match.length)..(m_input.length)]);
if (decoded.is_decode_error())
{
return FindLongestMatchResult.decode_error();
}
bool lex_continue = false; bool lex_continue = false;
if (decoded.is_eof()) Decoder.decode_code_point(m_input[(m_input_position + attempt_match.length)..(m_input.length)]).match!(
{ (Decoder.DecodeError de) {return FindLongestMatchResult.decode_error();},
/* We hit EOF. */ (Decoder.EOF e) {
if (longest_match.length > 0) /* We hit EOF. */
{ if (longest_match.length > 0)
/* We have a match, so use it. */ {
return longest_match; /* We have a match, so use it. */
} return longest_match;
else if (attempt_match.length != 0) }
{ else if (attempt_match.length != 0)
/* There is a partial match - error! */ {
return FindLongestMatchResult.unexpected_input(attempt_match.length); /* There is a partial match - error! */
} return FindLongestMatchResult.unexpected_input(attempt_match.length);
else }
{ else
/* Valid EOF return. */ {
return FindLongestMatchResult.eof(); /* Valid EOF return. */
} return FindLongestMatchResult.eof();
} }
else },
{ (Decoder.Success decoded) {
auto transition_result = transition(current_state, decoded.code_point); auto transition_result = transition(current_state, decoded.code_point);
if (transition_result.found()) if (transition_result.found())
{ {
lex_continue = true; lex_continue = true;
attempt_match.length += decoded.code_point_length; attempt_match.length += decoded.code_point_length;
if (decoded.code_point == '\n') if (decoded.code_point == '\n')
{ {
attempt_match.delta_row++; attempt_match.delta_row++;
attempt_match.delta_col = 0u; attempt_match.delta_col = 0u;
} }
else else
{ {
attempt_match.delta_col++; attempt_match.delta_col++;
} }
current_state = transition_result.destination(); current_state = transition_result.destination();
if (states[current_state].accepts()) if (states[current_state].accepts())
{ {
attempt_match.accepting_state = &states[current_state]; attempt_match.accepting_state = &states[current_state];
longest_match = attempt_match; longest_match = attempt_match;
} }
} }
else if (longest_match.length > 0) else if (longest_match.length > 0)
{ {
return longest_match; return longest_match;
} }
else else
{ {
return FindLongestMatchResult.unexpected_input(attempt_match.length + decoded.code_point_length); return FindLongestMatchResult.unexpected_input(attempt_match.length + decoded.code_point_length);
} }
} });
} }
} }