Skip to content

Commit 8b5c68f

Browse files
committed
Add universal modules page
1 parent 765e806 commit 8b5c68f

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
defmodule ComponentsGuideWeb.UniversalModulesController do
2+
use ComponentsGuideWeb, :controller
3+
4+
def index(conn, _params) do
5+
source = "
6+
const pi = 3.14;
7+
8+
const answer = 42;
9+
"
10+
decoded = decode_module(source)
11+
render(conn, "index.html", source: source, decoded: inspect(decoded))
12+
end
13+
14+
defp decode_module(source) do
15+
decode_module(nil, source, [])
16+
end
17+
18+
defp decode_module(nil, <<"\n", rest::bitstring>>, result),
19+
do: decode_module(nil, rest, result)
20+
21+
# Skip semicolons
22+
defp decode_module(nil, <<";", rest::bitstring>>, result),
23+
do: decode_module(nil, rest, result)
24+
25+
# Skip semicolons
26+
defp decode_module(nil, <<" ", rest::bitstring>>, result),
27+
do: decode_module(nil, rest, result)
28+
29+
defp decode_module(nil, <<"const ", rest::bitstring>>, result) do
30+
decode_module({:const, :expect_identifier, []}, rest, result)
31+
end
32+
33+
# Skip whitespace
34+
defp decode_module({_, :expect_identifier, []} = context, <<" ", rest::bitstring>>, result),
35+
do: decode_module(context, rest, result)
36+
37+
# Skip whitespace
38+
defp decode_module({_, :expect_expression, []} = context, <<" ", rest::bitstring>>, result),
39+
do: decode_module(context, rest, result)
40+
41+
defp decode_module(
42+
{:const, :expect_identifier, _} = context,
43+
<<" ", rest::bitstring>>,
44+
result
45+
) do
46+
decode_module(context, rest, result)
47+
end
48+
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
57+
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
65+
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)
85+
end
86+
end
87+
88+
defp decode_module(nil, "", result) do
89+
{:ok, Enum.reverse(result)}
90+
end
91+
92+
defp decode_module(context, source, result) do
93+
err(context, source, result)
94+
end
95+
96+
defp err(context, source, result) do
97+
{:err, context, source, result}
98+
end
99+
end
100+
101+
defmodule ComponentsGuideWeb.UniversalModulesView do
102+
use ComponentsGuideWeb, :view
103+
end

apps/components_guide_web/lib/components_guide_web/router.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ defmodule ComponentsGuideWeb.Router do
6767
get("/react+typescript", ReactTypescriptController, :index)
6868
get("/react+typescript/:article", ReactTypescriptController, :show)
6969

70+
get("/universal-modules", UniversalModulesController, :index)
71+
7072
resources("/text", TextController)
7173
get("/text/:id/text/:format", TextController, :show_text_format)
7274

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<pre>
2+
<%= @source %>
3+
</pre>
4+
5+
<pre>
6+
<%= @decoded %>
7+
</pre>

0 commit comments

Comments
 (0)