Skip to content

Commit 3caa377

Browse files
committed
Refactor
1 parent 6f42f73 commit 3caa377

File tree

1 file changed

+116
-70
lines changed

1 file changed

+116
-70
lines changed

apps/components_guide_web/lib/components_guide_web/controllers/universal_modules_controller.ex

Lines changed: 116 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,146 @@
11
defmodule ComponentsGuideWeb.UniversalModulesController do
22
use ComponentsGuideWeb, :controller
33

4+
alias ComponentsGuideWeb.UniversalModulesParser, as: Parser
5+
46
def index(conn, _params) do
57
source = "
68
const pi = 3.14;
79
810
const answer = 42;
11+
const negativeAnswer = -42;
12+
13+
const isEnabled = true;
14+
const verbose = false;
915
"
10-
decoded = decode_module(source)
11-
render(conn, "index.html", source: source, decoded: inspect(decoded))
16+
# decoded = decode_module(source)
17+
decoded = Parser.decode(source)
18+
19+
render(conn, "index.html",
20+
page_title: "Universal Modules",
21+
source: source,
22+
decoded: inspect(decoded)
23+
)
1224
end
25+
end
1326

14-
defp decode_module(source) do
15-
decode_module(nil, source, [])
27+
defmodule ComponentsGuideWeb.UniversalModulesParser do
28+
def switch(submodule, input, result) do
29+
mod = Module.concat(__MODULE__, submodule)
30+
apply(mod, :decode, [input, result])
1631
end
1732

18-
defp decode_module(nil, <<"\n", rest::bitstring>>, result),
19-
do: decode_module(nil, rest, result)
33+
def decode(input), do: switch(Root, input, [])
2034

21-
# Skip semicolons
22-
defp decode_module(nil, <<";", rest::bitstring>>, result),
23-
do: decode_module(nil, rest, result)
35+
defmodule Root do
36+
def decode("", result), do: {:ok, Enum.reverse(result)}
37+
def decode(<<"\n", rest::bitstring>>, result), do: decode(rest, result)
38+
def decode(<<" ", rest::bitstring>>, result), do: decode(rest, result)
39+
def decode(<<";", rest::bitstring>>, result), do: decode(rest, result)
2440

25-
# Skip semicolons
26-
defp decode_module(nil, <<" ", rest::bitstring>>, result),
27-
do: decode_module(nil, rest, result)
41+
def decode(<<"const ", rest::bitstring>>, result) do
42+
ComponentsGuideWeb.UniversalModulesParser.switch(Const, rest, result)
43+
end
2844

29-
defp decode_module(nil, <<"const ", rest::bitstring>>, result) do
30-
decode_module({:const, :expect_identifier, []}, rest, result)
45+
def decode(input, result) do
46+
{:err, :unexpected_eof, input, result}
47+
end
3148
end
3249

33-
# Skip whitespace
34-
defp decode_module({_, :expect_identifier, []} = context, <<" ", rest::bitstring>>, result),
35-
do: decode_module(context, rest, result)
50+
defmodule Const do
51+
def decode(input, result) do
52+
decode({:expect_identifier, []}, input, result)
53+
end
3654

37-
# Skip whitespace
38-
defp decode_module({_, :expect_expression, []} = context, <<" ", rest::bitstring>>, result),
39-
do: decode_module(context, rest, result)
55+
defp decode(
56+
{:expect_identifier, _} = context,
57+
<<" ", rest::bitstring>>,
58+
result
59+
) do
60+
decode(context, rest, result)
61+
end
4062

41-
defp decode_module(
42-
{:const, :expect_identifier, _} = context,
43-
<<" ", rest::bitstring>>,
44-
result
45-
) do
46-
decode_module(context, rest, result)
47-
end
63+
defp decode(
64+
{:expect_identifier, reverse_identifier},
65+
<<"=", rest::bitstring>>,
66+
result
67+
) do
68+
identifier = reverse_identifier |> Enum.reverse() |> :binary.list_to_bin()
69+
decode({identifier, :expect_expression, []}, rest, result)
70+
end
4871

49-
defp decode_module(
50-
{:const, :expect_identifier, reverse_identifier},
51-
<<"=", rest::bitstring>>,
52-
result
53-
) do
54-
identifier = reverse_identifier |> Enum.reverse() |> :binary.list_to_bin()
55-
decode_module({{:const, identifier}, :expect_expression, []}, rest, result)
56-
end
72+
defp decode(
73+
{:expect_identifier, reverse_identifier},
74+
<<char::utf8, rest::bitstring>>,
75+
result
76+
) do
77+
decode({:expect_identifier, [char | reverse_identifier]}, rest, result)
78+
end
5779

58-
defp decode_module(
59-
{:const, :expect_identifier, reverse_identifier},
60-
<<char::utf8, rest::bitstring>>,
61-
result
62-
) do
63-
decode_module({:const, :expect_identifier, [char | reverse_identifier]}, rest, result)
64-
end
80+
# Skip whitespace
81+
defp decode({_, :expect_expression, []} = context, <<" ", rest::bitstring>>, result),
82+
do: decode(context, rest, result)
83+
84+
defp decode(
85+
{identifier, :expect_expression, expression},
86+
<<";", rest::bitstring>>,
87+
result
88+
),
89+
do: Root.decode(rest, [{:const, identifier, expression} | result])
90+
91+
defp decode(
92+
{identifier, :expect_expression, []},
93+
<<"true", rest::bitstring>>,
94+
result
95+
) do
96+
decode({identifier, :expect_expression, [true]}, rest, result)
97+
end
6598

66-
defp decode_module(
67-
{{:const, identifier}, :expect_expression, expression},
68-
<<";", rest::bitstring>>,
69-
result
70-
),
71-
do: decode_module(nil, rest, [{:const, identifier, expression} | result])
72-
73-
defp decode_module(
74-
{{:const, identifier}, :expect_expression, []} = context,
75-
<<char::utf8, _::bitstring>> = source,
76-
result
77-
)
78-
when char in [?0, ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9] do
79-
case Float.parse(source) do
80-
:error ->
81-
err(context, source, result)
82-
83-
{f, rest} ->
84-
decode_module({{:const, identifier}, :expect_expression, [f]}, rest, result)
99+
defp decode(
100+
{identifier, :expect_expression, []},
101+
<<"false", rest::bitstring>>,
102+
result
103+
) do
104+
decode({identifier, :expect_expression, [false]}, rest, result)
85105
end
86-
end
87106

88-
defp decode_module(nil, "", result) do
89-
{:ok, Enum.reverse(result)}
90-
end
107+
defp decode(
108+
{identifier, :expect_expression, []},
109+
<<"null", rest::bitstring>>,
110+
result
111+
) do
112+
decode({identifier, :expect_expression, [nil]}, rest, result)
113+
end
91114

92-
defp decode_module(context, source, result) do
93-
err(context, source, result)
94-
end
115+
defp decode(
116+
{identifier, :expect_expression, []} = context,
117+
<<char::utf8, _::bitstring>> = source,
118+
result
119+
)
120+
when char in '0123456789' do
121+
case Float.parse(source) do
122+
:error ->
123+
{:err, context, source, result}
124+
125+
{f, rest} ->
126+
decode({identifier, :expect_expression, [f]}, rest, result)
127+
end
128+
end
95129

96-
defp err(context, source, result) do
97-
{:err, context, source, result}
130+
defp decode(
131+
{identifier, :expect_expression, []} = context,
132+
<<"-", char::utf8, _::bitstring>> = source,
133+
result
134+
)
135+
when char in '0123456789' do
136+
case Float.parse(source) do
137+
:error ->
138+
{:err, context, source, result}
139+
140+
{f, rest} ->
141+
decode({identifier, :expect_expression, [f]}, rest, result)
142+
end
143+
end
98144
end
99145
end
100146

0 commit comments

Comments
 (0)