added
CHANGELOG.md
|
@@ -0,0 +1,47 @@
|
1
|
+ # Changelog
|
2
|
+
|
3
|
+ All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+ ## [0.0.2] - 2023-07-24
|
6
|
+
|
7
|
+ ### Bug Fixes
|
8
|
+
|
9
|
+ - Allow warnings
|
10
|
+ - Formatting
|
11
|
+
|
12
|
+ ### Features
|
13
|
+
|
14
|
+ - Add identifiers (names)
|
15
|
+ - Support reserved identifiers
|
16
|
+ - Add keywords
|
17
|
+ - Add punctuation
|
18
|
+ - Add operators
|
19
|
+
|
20
|
+ ### Refactor
|
21
|
+
|
22
|
+ - Make sections obvious
|
23
|
+
|
24
|
+ ## [0.0.1] - 2023-07-20
|
25
|
+
|
26
|
+ ### Bug Fixes
|
27
|
+
|
28
|
+ - Register lexer correctly
|
29
|
+
|
30
|
+ ### Features
|
31
|
+
|
32
|
+ - Add `Makeup.Lexer` boilerplate implementation
|
33
|
+ - Add literals, comments, whitespace
|
34
|
+
|
35
|
+ ### Miscellaneous Tasks
|
36
|
+
|
37
|
+ - Generate new mix project
|
38
|
+ - Prepare for publishing
|
39
|
+ - Add CI
|
40
|
+ - Add format config
|
41
|
+ - Add ex_doc package
|
42
|
+
|
43
|
+ ### Refactor
|
44
|
+
|
45
|
+ - Remove unused combinators
|
46
|
+
|
47
|
+ <!-- generated by git-cliff -->
|
changed
hex_metadata.config
|
@@ -7,7 +7,7 @@
|
7
7
|
<<"lib/makeup/lexers/swift_lexer.ex">>,<<"lib/makeup/lexers/swift_lexer">>,
|
8
8
|
<<"lib/makeup/lexers/swift_lexer/testing.ex">>,
|
9
9
|
<<"lib/makeup/lexers/swift_lexer/application.ex">>,<<".formatter.exs">>,
|
10
|
- <<"mix.exs">>,<<"README.md">>,<<"LICENSE">>]}.
|
10
|
+ <<"mix.exs">>,<<"README.md">>,<<"LICENSE">>,<<"CHANGELOG.md">>]}.
|
11
11
|
{<<"licenses">>,[<<"MIT">>]}.
|
12
12
|
{<<"links">>,[{<<"GitHub">>,<<"https://github.com/jesse-c/makeup_swift">>}]}.
|
13
13
|
{<<"name">>,<<"makeup_swift">>}.
|
|
@@ -22,4 +22,4 @@
|
22
22
|
{<<"optional">>,false},
|
23
23
|
{<<"repository">>,<<"hexpm">>},
|
24
24
|
{<<"requirement">>,<<"~> 1.3">>}]]}.
|
25
|
- {<<"version">>,<<"0.0.1">>}.
|
25
|
+ {<<"version">>,<<"0.0.2">>}.
|
changed
lib/makeup/lexers/swift_lexer.ex
|
@@ -19,7 +19,9 @@ defmodule Makeup.Lexers.SwiftLexer do
|
19
19
|
|
20
20
|
@inline Application.compile_env(:makeup_html, :inline, false)
|
21
21
|
|
22
|
+ # -----------------------------------------------------------------------------
|
22
23
|
# Lines
|
24
|
+ # -----------------------------------------------------------------------------
|
23
25
|
|
24
26
|
# LF/U+000A
|
25
27
|
line_feed = ascii_char([?\n])
|
|
@@ -33,10 +35,14 @@ defmodule Makeup.Lexers.SwiftLexer do
|
33
35
|
concat(line_feed, carriage_return)
|
34
36
|
])
|
35
37
|
|
38
|
+ # -----------------------------------------------------------------------------
|
36
39
|
# Whitespace
|
40
|
+ # -----------------------------------------------------------------------------
|
41
|
+
|
37
42
|
whitespace_item = [?\r, ?\s, ?\n, ?\f]
|
38
43
|
whitespace = whitespace_item |> ascii_string(min: 1) |> token(:whitespace)
|
39
44
|
|
45
|
+ # -----------------------------------------------------------------------------
|
40
46
|
# Literals
|
41
47
|
#
|
42
48
|
# A literal is the source code representation of a value of a type, such as a number or string.
|
|
@@ -48,6 +54,7 @@ defmodule Makeup.Lexers.SwiftLexer do
|
48
54
|
# "Hello, world!" // String literal
|
49
55
|
# /Hello, .*/ // Regular expression literal
|
50
56
|
# true // Boolean literal
|
57
|
+ # -----------------------------------------------------------------------------
|
51
58
|
|
52
59
|
## String
|
53
60
|
quoted_text_item = utf8_string([], 1)
|
|
@@ -102,7 +109,10 @@ defmodule Makeup.Lexers.SwiftLexer do
|
102
109
|
numeric_literal
|
103
110
|
])
|
104
111
|
|
112
|
+ # ------------------------------------------------------------------------------
|
105
113
|
# Comments
|
114
|
+ # ------------------------------------------------------------------------------
|
115
|
+
|
106
116
|
comment_text = utf8_string([], 1)
|
107
117
|
|
108
118
|
## Inline
|
|
@@ -119,7 +129,73 @@ defmodule Makeup.Lexers.SwiftLexer do
|
119
129
|
|> many_surrounded_by("/*", "*/")
|
120
130
|
|> token(:comment_multiline)
|
121
131
|
|
132
|
+ # -----------------------------------------------------------------------------
|
133
|
+ # Identifiers
|
134
|
+ # -----------------------------------------------------------------------------
|
135
|
+
|
136
|
+ backtick = utf8_char([?`])
|
137
|
+
|
138
|
+ identifier_head = utf8_char([?a..?z, ?A..?Z, ?_])
|
139
|
+
|
140
|
+ identifier_character = choice([identifier_head, utf8_char([?0..?9])])
|
141
|
+
|
142
|
+ identifier_characters = repeat(identifier_character)
|
143
|
+
|
144
|
+ identifier =
|
145
|
+ optional(backtick)
|
146
|
+ |> concat(identifier_head)
|
147
|
+ |> concat(optional(identifier_characters))
|
148
|
+ |> concat(optional(backtick))
|
149
|
+ |> token(:name)
|
150
|
+
|
151
|
+ # -----------------------------------------------------------------------------
|
152
|
+ # Keywords
|
153
|
+ # -----------------------------------------------------------------------------
|
154
|
+
|
155
|
+ @keywords_declarations ~w[associatedtype class deinit enum extension fileprivate func import init inout internal let open operator private precedencegroup protocol public rethrows static struct subscript typealias var]
|
156
|
+ @keywords_statements ~w[break case catch continue default defer do else fallthrough for guard if in repeat return throw switch where while]
|
157
|
+ @keywords_expressions_and_types ~w[Any as await catch false is nil rethrows self Self super throw throws true try]
|
158
|
+ @keywords_begin_with_a_number_sign ~w[#available #colorLiteral #elseif #else #endif #if #imageLiteral #keyPath #selector #sourceLocation]
|
159
|
+ @keywords List.flatten([
|
160
|
+ @keywords_declarations,
|
161
|
+ @keywords_statements,
|
162
|
+ @keywords_expressions_and_types,
|
163
|
+ @keywords_begin_with_a_number_sign
|
164
|
+ ])
|
165
|
+
|
166
|
+ keyword =
|
167
|
+ @keywords
|
168
|
+ |> word_from_list()
|
169
|
+ # A naïve way to avoid identifiers of reserved keywords
|
170
|
+ |> lookahead_not(backtick)
|
171
|
+ |> token(:keyword)
|
172
|
+
|
173
|
+ # -----------------------------------------------------------------------------
|
174
|
+ # Punctuation
|
175
|
+ # -----------------------------------------------------------------------------
|
176
|
+
|
177
|
+ punctuation =
|
178
|
+ choice([
|
179
|
+ ascii_char([?(, ?), ?{, ?}, ?[, ?], ?., ?,, ?:, ?;, ?=, ?@, ?#, ?&, ?`, ??, ?!]),
|
180
|
+ string("->")
|
181
|
+ ])
|
182
|
+ |> token(:punctuation)
|
183
|
+
|
184
|
+ # -----------------------------------------------------------------------------
|
185
|
+ # Operators
|
186
|
+ # -----------------------------------------------------------------------------
|
187
|
+
|
188
|
+ operator_head = ascii_char([?/, ?=, ?-, ?+, ?!, ?*, ?%, ?<, ?>, ?&, ?|, ?^, ?~, ??])
|
189
|
+ operator_character = operator_head
|
190
|
+ operator_characters = operator_character |> concat(optional(operator_character))
|
191
|
+ operator = operator_head |> concat(optional(operator_characters)) |> token(:operator)
|
192
|
+ infix_operator = operator
|
193
|
+ prefix_operator = operator
|
194
|
+ postfix_operator = operator
|
195
|
+
|
196
|
+ # -----------------------------------------------------------------------------
|
122
197
|
# Root
|
198
|
+ # -----------------------------------------------------------------------------
|
123
199
|
|
124
200
|
root_element_combinator =
|
125
201
|
choice([
|
|
@@ -129,20 +205,30 @@ defmodule Makeup.Lexers.SwiftLexer do
|
129
205
|
literal,
|
130
206
|
# Comments
|
131
207
|
inline_comment,
|
132
|
- multiline_comment
|
208
|
+ multiline_comment,
|
209
|
+ # Keywords,
|
210
|
+ keyword,
|
211
|
+ # Identifiers
|
212
|
+ identifier,
|
213
|
+ # Punctuation
|
214
|
+ punctuation,
|
215
|
+ # Operators
|
216
|
+ infix_operator,
|
217
|
+ prefix_operator,
|
218
|
+ postfix_operator
|
133
219
|
])
|
134
220
|
|
135
|
- @doc false
|
136
|
- def __as_swift_language__({ttype, meta, value}) do
|
137
|
- {ttype, Map.put(meta, :language, :swift), value}
|
138
|
- end
|
139
|
-
|
140
221
|
##############################################################################
|
141
222
|
# Semi-public API: these two functions can be used by someone who wants to
|
142
223
|
# embed this lexer into another lexer, but other than that, they are not
|
143
224
|
# meant to be used by end-users
|
144
225
|
##############################################################################
|
145
226
|
|
227
|
+ @doc false
|
228
|
+ def __as_swift_language__({ttype, meta, value}) do
|
229
|
+ {ttype, Map.put(meta, :language, :swift), value}
|
230
|
+ end
|
231
|
+
|
146
232
|
@impl Makeup.Lexer
|
147
233
|
defparsec(
|
148
234
|
:root_element,
|
changed
mix.exs
|
@@ -4,7 +4,7 @@ defmodule MakeupSwift.MixProject do
|
4
4
|
def project do
|
5
5
|
[
|
6
6
|
app: :makeup_swift,
|
7
|
- version: "0.0.1",
|
7
|
+ version: "0.0.2",
|
8
8
|
elixir: "~> 1.14",
|
9
9
|
start_permanent: Mix.env() == :prod,
|
10
10
|
deps: deps(),
|