code / nomsu

Lines6.6K Lua5.1K PEG1.3K make117
2 others 83
Markdown60 Bourne Again Shell23
(241 lines)
1 -- Nomsu version 5
2 file <-
3 {:curr_indent: ' '* :}
4 (((methodcall / action / expression / inline_block / indented_block) eol !.)
5 / file_chunks / empty_block)
6 {:curr_indent: %nil :}
7 !.
9 shebang <- "#!" (!"nomsu" [^%nl])* "nomsu" ws+ "-V" ws* [0-9.]+ [^%nl]* (%nl / !.)
11 eof <- !.
13 file_chunks (FileChunks) <-
14 {:shebang: shebang :}?
15 (top_block (nl_nodent section_division top_block)*)
16 blank_lines?
17 unexpected_indent? unexpected_chunk?
19 top_block (Block) <-
20 ((blank_lines nodent) / (comment nl_nodent))? statement (nl_nodent statement)*
22 empty_block (Block) <-
23 comment? blank_lines?
25 nodent <- (unexpected_indent [^%nl]* / =curr_indent)
26 indent <- {~ =curr_indent (ws / (%tab -> ' '))+ ~}
27 blank_lines <- %nl ((nodent comment / ws*) %nl)*
28 eol <- ws* (!. / &%nl)
30 nl_nodent <- blank_lines nodent
31 nl_indent <- blank_lines tab_error? {:curr_indent: indent :} (comment nl_nodent)*
33 comment (Comment) <-
34 "#" {~ [^%nl]* (%nl+ (indent -> '') [^%nl]*)* (%nl &%nl)* ~}
36 unexpected_code <- ws* _unexpected_code
37 _unexpected_code (Error) <-
38 {:error: {~ [^%nl]+ -> "Couldn't parse this code." ~} :}
39 unexpected_chunk (Error) <-
40 {:error: {~ .+ -> "Couldn't parse this chunk of code." ~} :}
41 unexpected_indent (Error) <-
42 {:error: {~ (=curr_indent ws+) -> "This indentation is messed up." ~} :}
43 {:hint: {~ '' -> 'This line should either have the same indentation as the line above it, or exactly 4 spaces more.' ~} :}
44 missing_paren_err (Error) <-
45 {:error: {~ eol -> 'Line ended without finding a closing )-parenthesis' ~} :}
46 {:hint: {~ '' -> 'Put a ")" here' ~} :}
47 missing_quote_err (Error) <-
48 {:error: {~ eol -> "Line ended without finding a closing quotation mark." ~} :}
49 {:hint: {~ "" -> "Put a quotation mark here." ~} :}
50 missing_indented_quote_err (Error) <-
51 {:error: {~ eol -> "This text doesn't have a closing quotation mark." ~} :}
52 {:hint: {~ "" -> "Put a quotation mark here on its own line." ~} :}
53 missing_bracket_error (Error) <-
54 {:error: {~ eol -> "Line ended before finding a closing ]-bracket" ~} :}
55 {:hint: {~ '' -> 'Put a "]" here' ~} :}
56 missing_brace_error (Error) <-
57 {:error: {~ eol -> "Line ended before finding a closing }-brace" ~} :}
58 {:hint: {~ '' -> 'Put a "}" here' ~} :}
59 tab_error (Error) <-
60 &(=curr_indent %tab)
61 {:error: {~ '' -> 'Tabs are not allowed for indentation.' ~} :}
62 {:hint: {~ '' -> 'Use spaces instead of tabs.' ~} :}
64 section_division <- ("~")^+3 eol
66 inline_block <-
67 "(" ws* inline_block ws* (eof / ")") / raw_inline_block
68 raw_inline_block (Block) <-
69 (!"::") ":" ws* ((inline_statement (ws* ";" ws* inline_statement)*) / !(eol nl_indent))
70 indented_block (Block) <-
71 ":" eol nl_indent statement (nl_nodent statement)*
72 (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
73 {:curr_indent: %nil :}
75 statement <-
76 (methodcall / action / expression) (eol / unexpected_code)
78 inline_statement <- (inline_methodcall / inline_action / inline_expression)
80 noindex_inline_expression <-
81 number / variable / inline_text / inline_list / inline_dict / inline_nomsu
82 / ( "("
83 ws* (inline_methodcall / inline_action / inline_expression) ws*
84 (")" / eof / missing_paren_err / unexpected_code)
86 inline_expression <- index_chain / noindex_inline_expression
87 indented_expression <-
88 indented_text / indented_nomsu / indented_list / indented_dict / ({|
89 "(..)" eol nl_indent
90 (methodcall / action / expression) (eol / unexpected_code)
91 (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
92 {:curr_indent: %nil :}
93 |} -> unpack)
94 expression <-
95 inline_expression / indented_expression
97 inline_nomsu (EscapedNomsu) <- "\" (inline_expression / inline_block)
98 indented_nomsu (EscapedNomsu) <-
99 "\" (noindex_inline_expression / inline_block / indented_expression / indented_block)
101 index_chain (IndexChain) <-
102 noindex_inline_expression
103 ("." (hex_integer / integer / text_word / noindex_inline_expression))+
105 index_chain_before_method (IndexChain) <-
106 noindex_inline_expression
107 ("." (hex_integer / integer / text_word / noindex_inline_expression) &".")+
109 -- Actions need 1 argument and either another argument or a word.
110 inline_action (Action) <-
111 !section_division
112 ( (word (ws* (inline_arg / word))*)
113 /(inline_arg (ws* (inline_arg / word))+))
114 inline_arg <- inline_expression / inline_block
115 inline_methodcall (MethodCall) <-
116 (index_chain / noindex_inline_expression / "(" inline_block ")")
117 "|" inline_action (ws* ";" ws* inline_action)*
119 action (Action) <-
120 !section_division
121 ( (word ((linesplit / ws*) (arg / word))*)
122 /(arg ((linesplit / ws*) (arg / word))+))
123 linesplit <- (ws* "\")? eol nl_nodent ".." ws*
124 arg <- expression / inline_block / indented_block
125 methodcall (MethodCall) <-
126 (index_chain / noindex_inline_expression / indented_expression / "(" inline_block ")" / indented_block)
127 linesplit? "|"
128 ((ws* inline_action ws* ";")* ws* action
129 / eol nl_indent
130 (action eol) (nl_nodent action eol)*
131 (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*)
133 word <- !number { operator_char+ / ident_char+ }
135 text_word (Text) <- word
137 inline_text (Text) <-
138 !(indented_text)
139 '"' _inline_text* ('"' / eof / missing_quote_err / unexpected_code)
140 _inline_text <-
141 {~ (('\"' -> '"') / ('\\' -> '\') / escaped_char / text_char+)+ ~}
142 / inline_text_interpolation / illegal_char
143 inline_text_interpolation <-
144 "\" (
145 variable / inline_list / inline_dict
146 / ("("
147 ws* ((inline_methodcall / inline_action / inline_expression) ws*)?
148 (")" / eof / missing_paren_err / unexpected_code))
151 text_char <- %utf8_char / !["\] %print / %tab
152 illegal_char (Error) <-
153 {:error: {~ (!(%nl / %tab / %print) .) -> "Illegal unprintable character here (it may not be visible, but it's there)" ~} :}
154 {:hint: {~ '' -> "This sort of thing can happen when copying and pasting code. Try deleting and retyping the code." ~} :}
156 terminal_quote <- '"' !([^%nl] / (%nl (ws* eol)?)+ =curr_indent [^%nl])
157 nonterminal_quote <- !terminal_quote '"'
158 indented_text (Text) <-
159 '"' %nl {%nl*} {:curr_indent: indent :}
160 (indented_plain_text / text_interpolation / illegal_char / blank_text_lines)*
161 (terminal_quote eol / eof / missing_indented_quote_err)
162 {:curr_indent: %nil :}
163 -- Tracking text-lines-within-indented-text as separate objects allows for better debugging line info
164 indented_plain_text (Text) <-
166 ((("\" blank_lines =curr_indent "..") -> "") / ('\\' -> '\')
167 / (!text_interpolation ((!("\n") escaped_char) / '\'))
168 / (nonterminal_quote / text_char)+)+
169 blank_text_lines?
171 blank_text_lines <-
172 {~ (%nl ((ws* -> '') eol / (=curr_indent -> '') &[^%nl]))+ ~}
174 text_interpolation <-
175 ("\" indented_expression (blank_lines =curr_indent "..")?) / inline_text_interpolation
177 number <-
178 hex_integer / real_number / integer
180 integer (Number) <-
181 (("-"? [0-9]+)-> tonumber)
183 hex_integer (Number) <-
184 (("-"? "0x" [0-9a-fA-F]+)-> tonumber)
185 {:hex: '' -> 'yes' :}
187 real_number (Number) <-
188 (("-"? ([0-9]+ "." [0-9]+) / ("." [0-9]+))-> tonumber)
190 variable (Var) <- "$" ({ident_char+} / "(" {(ws+ / operator_char+ / ident_char+)*} ")" / {''})
192 inline_list (List) <-
193 !('[..]')
194 "[" ws*
195 (inline_list_item (ws* ',' ws* inline_list_item)* (ws* ',')?)? ws*
196 ("]" / eof / (","? (missing_bracket_error / unexpected_code)))
197 indented_list (List) <-
198 "[..]" eol nl_indent
199 list_line (nl_nodent list_line)*
200 (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
201 (","? unexpected_code)?
202 list_line <-
203 (inline_list_item ws* "," ws*)+ eol
204 / (inline_list_item ws* "," ws*)* (methodcall / action / expression / inline_block / indented_block) eol
205 inline_list_item <- inline_methodcall / inline_action / inline_expression / inline_block
207 inline_dict (Dict) <-
208 !('{..}')
209 "{" ws*
210 (inline_dict_entry (ws* ',' ws* inline_dict_entry)*)? ws*
211 ("}" / eof / (","? (missing_brace_error / unexpected_code)))
212 indented_dict (Dict) <-
213 "{..}" eol nl_indent
214 dict_line (nl_nodent dict_line)*
215 (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
216 (","? unexpected_code)?
217 dict_line <-
218 (inline_dict_entry ws* "," ws*)+ eol
219 / (inline_dict_entry ws* "," ws*)* dict_entry eol
220 _dict_entry(DictEntry) <-
221 dict_key (ws* ":" ws* (methodcall / action / expression))?
222 dict_entry <-
223 _dict_entry / inline_block / indented_block
224 _inline_dict_entry(DictEntry) <-
225 dict_key (ws* ":" ws* (inline_methodcall / inline_action / inline_expression)?)?
226 inline_dict_entry <-
227 _inline_dict_entry / inline_block
228 dict_key <-
229 text_word / inline_expression
231 operator_char <- [#'`~@^&*+=|<>?/%!-]
232 ident_char <- [a-zA-Z0-9_] / %utf8_char
233 ws <- " "
235 escaped_char <-
236 ("\"->'') (
237 (([xX]->'') ((({[0-9a-fA-F]^2} %number_16) -> tonumber) -> tochar))
238 / ((([0-9] [0-9]^-2) -> tonumber) -> tochar)
239 / ("a"->ascii_7) / ("b"->ascii_8) / ("t"->ascii_9) / ("n"->ascii_10)
240 / ("v"->ascii_11) / ("f"->ascii_12) / ("r"->ascii_13)