code / nomsu

Lines6.6K Lua5.1K PEG1.3K make117
2 others 83
Markdown60 Bourne Again Shell23
(200 lines)
1 -- Nomsu version 3
2 file <-
3 {:curr_indent: ' '* :}
4 (((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* {:version: [0-9.]+ :} [^%nl]*
11 file_chunks (FileChunks) <-
12 shebang? comment? blank_lines?
13 (top_block (nl_nodent section_division top_block)*)
14 blank_lines?
15 unexpected_indent? unexpected_chunk?
17 top_block (Block) <-
18 ((blank_lines nodent) / (comment nl_nodent))? statement (nl_nodent statement)*
20 empty_block (Block) <-
21 comment? blank_lines?
23 nodent <- (unexpected_indent [^%nl]* / =curr_indent)
24 indent <- =curr_indent " "
25 blank_lines <- %nl ((nodent comment / ws*) %nl)*
26 eol <- ws* eol_comment? (!. / &%nl)
28 nl_nodent <- blank_lines nodent
29 nl_indent <- blank_lines {:curr_indent: indent :} (comment nl_nodent)*
31 comment (Comment) <-
32 "#" {~ [^%nl]* (%nl+ (indent -> '') [^%nl]*)* ~}
33 eol_comment (Comment) <-
34 "#" {[^%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 before finding a closing double quotation mark' ~} :}
49 {:hint: {~ "" -> "Put a quotation mark here" ~} :}
50 missing_bracket_error (Error) <-
51 {:error: {~ eol -> "Line ended before finding a closing ]-bracket" ~} :}
52 {:hint: {~ '' -> 'Put a "]" here' ~} :}
53 missing_brace_error (Error) <-
54 {:error: {~ eol -> "Line ended before finding a closing }-brace" ~} :}
55 {:hint: {~ '' -> 'Put a "}" here' ~} :}
57 section_division <- ("~")^+3 eol
59 inline_block <-
60 "(" ws* inline_block ws* ")" / raw_inline_block
61 raw_inline_block (Block) <-
62 (!"::") ":" ws* ((inline_statement (ws* ";" ws* inline_statement)*) / !(eol nl_indent))
63 indented_block (Block) <-
64 ":" eol nl_indent statement (nl_nodent statement)*
65 (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
66 {:curr_indent: %nil :}
68 statement <-
69 (action / expression) (eol / unexpected_code)
71 inline_statement <- (inline_action / inline_expression)
73 noindex_inline_expression <-
74 number / variable / inline_text / inline_list / inline_dict / inline_nomsu
75 / ( "("
76 ws* (inline_action / inline_expression) ws*
77 (ws* ',' ws* (inline_action / inline_expression) ws*)*
78 (")" / missing_paren_err / unexpected_code)
80 inline_expression <- index_chain / noindex_inline_expression
81 indented_expression <-
82 indented_text / indented_nomsu / indented_list / indented_dict / ({|
83 "(..)" nl_indent
84 (action / expression) (eol / unexpected_code)
85 (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
86 {:curr_indent: %nil :}
87 |} -> unpack)
88 expression <-
89 inline_expression / indented_expression
91 inline_nomsu (EscapedNomsu) <- "\" (inline_expression / inline_block)
92 indented_nomsu (EscapedNomsu) <-
93 "\" (noindex_inline_expression / inline_block / indented_expression / indented_block)
95 index_chain (IndexChain) <-
96 noindex_inline_expression ("." (text_word / noindex_inline_expression))+
98 inline_action <- inline_methodcall / _inline_action
99 inline_methodcall <-
100 inline_arg ws* "::" ws* _inline_action
101 -- Actions need either at least 1 word, or at least 2 tokens
102 _inline_action (Action) <-
103 !section_division
104 ( (inline_arg (ws* (inline_arg / word))+)
105 / (word (ws* (inline_arg / word))*))
106 (ws* inline_block)?
107 inline_arg <- inline_expression / inline_block
109 action <- methodcall / _action
110 methodcall <-
111 arg (nl_nodent "..")? ws* "::" (nl_nodent "..")? ws* _action
112 _action (Action) <-
113 !section_division
114 ( (arg ((nl_nodent "..")? ws* (arg / word))+)
115 / (word ((nl_nodent "..")? ws* (arg / word))*))
116 arg <- expression / inline_block / indented_block
118 word <- !number { operator_char+ / ident_char+ }
120 text_word (Text) <- word
122 inline_text (Text) <-
123 !(indented_text)
124 ('"' _inline_text* ('"' / missing_quote_err / unexpected_code))
125 _inline_text <-
126 {~ (('\"' -> '"') / ('\\' -> '\') / escaped_char / [^%nl\"]+)+ ~}
127 / inline_text_interpolation
128 inline_text_interpolation <-
129 "\" (
130 variable / inline_list / inline_dict / inline_text
131 / ("("
132 ws* (inline_action / inline_expression) ws*
133 (ws* ',' ws* (inline_action / inline_expression) ws*)*
134 (")" / missing_paren_err / unexpected_code))
137 indented_text (Text) <-
138 '".."' eol %nl {%nl+}? {:curr_indent: indent :}
139 (indented_plain_text / text_interpolation / {~ %nl+ (=curr_indent -> "") ~})*
140 unexpected_code?
141 {:curr_indent: %nil :}
142 -- Tracking text-lines-within-indented-text as separate objects allows for better debugging line info
143 indented_plain_text (Text) <-
144 {~ (("\\" -> "\") / (("\" blank_lines =curr_indent "..") -> "") / (!text_interpolation "\") / [^%nl\]+)+
145 (%nl+ (=curr_indent -> ""))* ~}
146 text_interpolation <-
147 inline_text_interpolation / ("\" indented_expression (blank_lines =curr_indent "..")?)
149 number (Number) <- (("-"? (([0-9]+ "." [0-9]+) / ("." [0-9]+) / "0x" [0-9a-fA-F]+ / ([0-9]+)))-> tonumber)
151 -- Variables can be nameless (i.e. just %) and can only contain identifier chars.
152 -- This ensures you don't get weird parsings of `%x+%y` or `%'s thing`.
153 variable (Var) <- "%" {ident_char*}
155 inline_list (List) <-
156 !('[..]')
157 "[" ws*
158 (inline_list_item (ws* ',' ws* inline_list_item)* (ws* ',')?)? ws*
159 ("]" / (","? (missing_bracket_error / unexpected_code)))
160 indented_list (List) <-
161 "[..]" eol nl_indent
162 list_line (nl_nodent list_line)*
163 (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
164 (","? unexpected_code)?
165 list_line <-
166 (inline_list_item ws* "," ws*)+ eol
167 / (inline_list_item ws* "," ws*)* (action / expression) eol
168 inline_list_item <- inline_action / inline_expression
170 inline_dict (Dict) <-
171 !('{..}')
172 "{" ws*
173 (inline_dict_entry (ws* ',' ws* inline_dict_entry)*)? ws*
174 ("}" / (","? (missing_brace_error / unexpected_code)))
175 indented_dict (Dict) <-
176 "{..}" eol nl_indent
177 dict_line (nl_nodent dict_line)*
178 (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
179 (","? unexpected_code)?
180 dict_line <-
181 (inline_dict_entry ws* "," ws*)+ eol
182 / (inline_dict_entry ws* "," ws*)* dict_entry eol
183 dict_entry(DictEntry) <-
184 dict_key (ws* ":" ws* (action / expression))?
185 inline_dict_entry(DictEntry) <-
186 dict_key (ws* ":" ws* (inline_action / inline_expression)?)?
187 dict_key <-
188 text_word / inline_expression
190 operator_char <- ['`~!@$^&*+=|<>?/-]
191 ident_char <- [a-zA-Z0-9_] / %utf8_char
192 ws <- [ %tab]
194 escaped_char <-
195 ("\"->'') (
196 (([xX]->'') ((({[0-9a-fA-F]^2} %number_16) -> tonumber) -> tochar))
197 / ((([0-9] [0-9]^-2) -> tonumber) -> tochar)
198 / ("a"->ascii_7) / ("b"->ascii_8) / ("t"->ascii_9) / ("n"->ascii_10)
199 / ("v"->ascii_11) / ("f"->ascii_12) / ("r"->ascii_13)