From d466189982a1705a4b134a023343c28332bf828b Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Thu, 29 Jun 2023 19:21:30 -0400 Subject: [PATCH] Convert Decoder.decode_code_point return type to a SumType --- assets/parser.d.erb | 166 +++++++++++++++++--------------------------- 1 file changed, 65 insertions(+), 101 deletions(-) diff --git a/assets/parser.d.erb b/assets/parser.d.erb index d5f5b03..0455fc7 100644 --- a/assets/parser.d.erb +++ b/assets/parser.d.erb @@ -2,8 +2,8 @@ module <%= @grammar.modulename %>; <% end %> - import std.stdio; +import std.sumtype; <% @grammar.code_blocks.each do |code| %> <%= code %> @@ -71,54 +71,23 @@ class <%= @classname %> static class Decoder { - struct Result + struct Success { - enum Type - { - SUCCESS, - EOF, - DECODE_ERROR, - } - private Type type; CodePoint code_point; 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) { - return Result.eof(); + return cast(ReturnType!decode_code_point)EOF(); } char c = input[0]; CodePoint code_point; @@ -158,11 +127,11 @@ class <%= @classname %> } else { - return Result.decode_error(); + return cast(ReturnType!decode_code_point)DecodeError(); } if (input.length <= following_bytes) { - return Result.decode_error(); + return cast(ReturnType!decode_code_point)DecodeError(); } code_point_length = following_bytes + 1u; for (size_t i = 0u; i < following_bytes; i++) @@ -170,12 +139,12 @@ class <%= @classname %> char b = input[i + 1u]; if ((b & 0xC0u) != 0x80u) { - return Result.decode_error(); + return cast(ReturnType!decode_code_point)DecodeError(); } 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; 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; - if (decoded.is_eof()) - { - /* We hit EOF. */ - if (longest_match.length > 0) - { - /* We have a match, so use it. */ - return longest_match; - } - else if (attempt_match.length != 0) - { - /* There is a partial match - error! */ - return FindLongestMatchResult.unexpected_input(attempt_match.length); - } - else - { - /* Valid EOF return. */ - return FindLongestMatchResult.eof(); - } - } - else - { - auto transition_result = transition(current_state, decoded.code_point); - if (transition_result.found()) - { - lex_continue = true; - attempt_match.length += decoded.code_point_length; - if (decoded.code_point == '\n') - { - attempt_match.delta_row++; - attempt_match.delta_col = 0u; - } - else - { - attempt_match.delta_col++; - } - current_state = transition_result.destination(); - if (states[current_state].accepts()) - { - attempt_match.accepting_state = &states[current_state]; - longest_match = attempt_match; - } - } - else if (longest_match.length > 0) - { - return longest_match; - } - else - { - return FindLongestMatchResult.unexpected_input(attempt_match.length + decoded.code_point_length); - } - } + Decoder.decode_code_point(m_input[(m_input_position + attempt_match.length)..(m_input.length)]).match!( + (Decoder.DecodeError de) {return FindLongestMatchResult.decode_error();}, + (Decoder.EOF e) { + /* We hit EOF. */ + if (longest_match.length > 0) + { + /* We have a match, so use it. */ + return longest_match; + } + else if (attempt_match.length != 0) + { + /* There is a partial match - error! */ + return FindLongestMatchResult.unexpected_input(attempt_match.length); + } + else + { + /* Valid EOF return. */ + return FindLongestMatchResult.eof(); + } + }, + (Decoder.Success decoded) { + auto transition_result = transition(current_state, decoded.code_point); + if (transition_result.found()) + { + lex_continue = true; + attempt_match.length += decoded.code_point_length; + if (decoded.code_point == '\n') + { + attempt_match.delta_row++; + attempt_match.delta_col = 0u; + } + else + { + attempt_match.delta_col++; + } + current_state = transition_result.destination(); + if (states[current_state].accepts()) + { + attempt_match.accepting_state = &states[current_state]; + longest_match = attempt_match; + } + } + else if (longest_match.length > 0) + { + return longest_match; + } + else + { + return FindLongestMatchResult.unexpected_input(attempt_match.length + decoded.code_point_length); + } + }); } }