diff options
-rw-r--r-- | Cargo.lock | 252 | ||||
-rw-r--r-- | Cargo.toml | 14 | ||||
-rw-r--r-- | src/eval.rs | 8 | ||||
-rw-r--r-- | src/main.rs | 188 |
4 files changed, 307 insertions, 155 deletions
diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..b853519 --- /dev/null +++ b/Cargo.lock | |||
@@ -0,0 +1,252 @@ | |||
1 | # This file is automatically @generated by Cargo. | ||
2 | # It is not intended for manual editing. | ||
3 | version = 3 | ||
4 | |||
5 | [[package]] | ||
6 | name = "aho-corasick" | ||
7 | version = "1.1.3" | ||
8 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
9 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" | ||
10 | dependencies = [ | ||
11 | "memchr", | ||
12 | ] | ||
13 | |||
14 | [[package]] | ||
15 | name = "argh" | ||
16 | version = "0.1.12" | ||
17 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
18 | checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219" | ||
19 | dependencies = [ | ||
20 | "argh_derive", | ||
21 | "argh_shared", | ||
22 | ] | ||
23 | |||
24 | [[package]] | ||
25 | name = "argh_derive" | ||
26 | version = "0.1.12" | ||
27 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
28 | checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a" | ||
29 | dependencies = [ | ||
30 | "argh_shared", | ||
31 | "proc-macro2", | ||
32 | "quote", | ||
33 | "syn", | ||
34 | ] | ||
35 | |||
36 | [[package]] | ||
37 | name = "argh_shared" | ||
38 | version = "0.1.12" | ||
39 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
40 | checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531" | ||
41 | dependencies = [ | ||
42 | "serde", | ||
43 | ] | ||
44 | |||
45 | [[package]] | ||
46 | name = "cc" | ||
47 | version = "1.0.106" | ||
48 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
49 | checksum = "066fce287b1d4eafef758e89e09d724a24808a9196fe9756b8ca90e86d0719a2" | ||
50 | |||
51 | [[package]] | ||
52 | name = "memchr" | ||
53 | version = "2.7.4" | ||
54 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
55 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" | ||
56 | |||
57 | [[package]] | ||
58 | name = "minimal-lexical" | ||
59 | version = "0.2.1" | ||
60 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
61 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" | ||
62 | |||
63 | [[package]] | ||
64 | name = "nom" | ||
65 | version = "7.1.3" | ||
66 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
67 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" | ||
68 | dependencies = [ | ||
69 | "memchr", | ||
70 | "minimal-lexical", | ||
71 | ] | ||
72 | |||
73 | [[package]] | ||
74 | name = "proc-macro2" | ||
75 | version = "1.0.86" | ||
76 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
77 | checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" | ||
78 | dependencies = [ | ||
79 | "unicode-ident", | ||
80 | ] | ||
81 | |||
82 | [[package]] | ||
83 | name = "quote" | ||
84 | version = "1.0.36" | ||
85 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
86 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" | ||
87 | dependencies = [ | ||
88 | "proc-macro2", | ||
89 | ] | ||
90 | |||
91 | [[package]] | ||
92 | name = "regex" | ||
93 | version = "1.10.5" | ||
94 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
95 | checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" | ||
96 | dependencies = [ | ||
97 | "aho-corasick", | ||
98 | "memchr", | ||
99 | "regex-automata", | ||
100 | "regex-syntax", | ||
101 | ] | ||
102 | |||
103 | [[package]] | ||
104 | name = "regex-automata" | ||
105 | version = "0.4.7" | ||
106 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
107 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" | ||
108 | dependencies = [ | ||
109 | "aho-corasick", | ||
110 | "memchr", | ||
111 | "regex-syntax", | ||
112 | ] | ||
113 | |||
114 | [[package]] | ||
115 | name = "regex-syntax" | ||
116 | version = "0.8.4" | ||
117 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
118 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" | ||
119 | |||
120 | [[package]] | ||
121 | name = "serde" | ||
122 | version = "1.0.204" | ||
123 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
124 | checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" | ||
125 | dependencies = [ | ||
126 | "serde_derive", | ||
127 | ] | ||
128 | |||
129 | [[package]] | ||
130 | name = "serde_derive" | ||
131 | version = "1.0.204" | ||
132 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
133 | checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" | ||
134 | dependencies = [ | ||
135 | "proc-macro2", | ||
136 | "quote", | ||
137 | "syn", | ||
138 | ] | ||
139 | |||
140 | [[package]] | ||
141 | name = "syn" | ||
142 | version = "2.0.71" | ||
143 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
144 | checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" | ||
145 | dependencies = [ | ||
146 | "proc-macro2", | ||
147 | "quote", | ||
148 | "unicode-ident", | ||
149 | ] | ||
150 | |||
151 | [[package]] | ||
152 | name = "tbsp" | ||
153 | version = "0.1.0" | ||
154 | dependencies = [ | ||
155 | "argh", | ||
156 | "nom", | ||
157 | "regex", | ||
158 | "serde", | ||
159 | "thiserror", | ||
160 | "tree-sitter", | ||
161 | "tree-sitter-javascript", | ||
162 | "tree-sitter-md", | ||
163 | "tree-sitter-python", | ||
164 | "tree-sitter-rust", | ||
165 | "tree-sitter-typescript", | ||
166 | ] | ||
167 | |||
168 | [[package]] | ||
169 | name = "thiserror" | ||
170 | version = "1.0.62" | ||
171 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
172 | checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" | ||
173 | dependencies = [ | ||
174 | "thiserror-impl", | ||
175 | ] | ||
176 | |||
177 | [[package]] | ||
178 | name = "thiserror-impl" | ||
179 | version = "1.0.62" | ||
180 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
181 | checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" | ||
182 | dependencies = [ | ||
183 | "proc-macro2", | ||
184 | "quote", | ||
185 | "syn", | ||
186 | ] | ||
187 | |||
188 | [[package]] | ||
189 | name = "tree-sitter" | ||
190 | version = "0.21.0" | ||
191 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
192 | checksum = "705bf7c0958d0171dd7d3a6542f2f4f21d87ed5f1dc8db52919d3a6bed9a359a" | ||
193 | dependencies = [ | ||
194 | "cc", | ||
195 | "regex", | ||
196 | ] | ||
197 | |||
198 | [[package]] | ||
199 | name = "tree-sitter-javascript" | ||
200 | version = "0.21.4" | ||
201 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
202 | checksum = "8710a71bc6779e33811a8067bdda3ed08bed1733296ff915e44faf60f8c533d7" | ||
203 | dependencies = [ | ||
204 | "cc", | ||
205 | "tree-sitter", | ||
206 | ] | ||
207 | |||
208 | [[package]] | ||
209 | name = "tree-sitter-md" | ||
210 | version = "0.2.3" | ||
211 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
212 | checksum = "d9c3cfd068f2527250bbd8ff407431164e12b17863e7eafb76e311dd3f96965a" | ||
213 | dependencies = [ | ||
214 | "cc", | ||
215 | "tree-sitter", | ||
216 | ] | ||
217 | |||
218 | [[package]] | ||
219 | name = "tree-sitter-python" | ||
220 | version = "0.21.0" | ||
221 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
222 | checksum = "b4066c6cf678f962f8c2c4561f205945c84834cce73d981e71392624fdc390a9" | ||
223 | dependencies = [ | ||
224 | "cc", | ||
225 | "tree-sitter", | ||
226 | ] | ||
227 | |||
228 | [[package]] | ||
229 | name = "tree-sitter-rust" | ||
230 | version = "0.21.2" | ||
231 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
232 | checksum = "277690f420bf90741dea984f3da038ace46c4fe6047cba57a66822226cde1c93" | ||
233 | dependencies = [ | ||
234 | "cc", | ||
235 | "tree-sitter", | ||
236 | ] | ||
237 | |||
238 | [[package]] | ||
239 | name = "tree-sitter-typescript" | ||
240 | version = "0.21.2" | ||
241 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
242 | checksum = "ecb35d98a688378e56c18c9c159824fd16f730ccbea19aacf4f206e5d5438ed9" | ||
243 | dependencies = [ | ||
244 | "cc", | ||
245 | "tree-sitter", | ||
246 | ] | ||
247 | |||
248 | [[package]] | ||
249 | name = "unicode-ident" | ||
250 | version = "1.0.12" | ||
251 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
252 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" | ||
@@ -1,22 +1,22 @@ | |||
1 | [package] | 1 | [package] |
2 | name = "trawk" | 2 | name = "tbsp" |
3 | version = "0.1.0" | 3 | version = "0.1.0" |
4 | edition = "2021" | 4 | edition = "2021" |
5 | 5 | ||
6 | [lib] | 6 | [lib] |
7 | 7 | ||
8 | [dependencies] | 8 | [dependencies] |
9 | tree-sitter = "0.20" | 9 | tree-sitter = "0.21" |
10 | regex = "1.3" | 10 | regex = "1.3" |
11 | thiserror = "1.0.61" | 11 | thiserror = "1.0.61" |
12 | serde = "1.0.204" | 12 | serde = "1.0.204" |
13 | nom = "7.1.3" | 13 | nom = "7.1.3" |
14 | 14 | ||
15 | tree-sitter-md = {version = "0.1", optional = true} | 15 | tree-sitter-md = {version = "0.2", optional = true} |
16 | tree-sitter-typescript = {version = "0.20.1", optional = true} | 16 | tree-sitter-typescript = {version = "0.21", optional = true} |
17 | tree-sitter-javascript = {version = "0.20.0", optional = true} | 17 | tree-sitter-javascript = {version = "0.21", optional = true} |
18 | tree-sitter-python = {version = "0.20.4", optional = true} | 18 | tree-sitter-python = {version = "0.21", optional = true} |
19 | tree-sitter-rust = {version = "0.20.3", optional = true} | 19 | tree-sitter-rust = {version = "0.21", optional = true} |
20 | argh = "0.1.12" | 20 | argh = "0.1.12" |
21 | 21 | ||
22 | [features] | 22 | [features] |
diff --git a/src/eval.rs b/src/eval.rs index e13cec3..029cffe 100644 --- a/src/eval.rs +++ b/src/eval.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | //! tree walking interpreter for trawk | 1 | //! tree walking interpreter for tbsp |
2 | 2 | ||
3 | use crate::ast; | 3 | use crate::ast; |
4 | use std::{collections::HashMap, fmt}; | 4 | use std::{collections::HashMap, fmt}; |
@@ -112,6 +112,8 @@ impl Value { | |||
112 | fn mul(&self, other: &Self) -> Result { | 112 | fn mul(&self, other: &Self) -> Result { |
113 | match (self, other) { | 113 | match (self, other) { |
114 | (Self::Integer(s), Self::Integer(o)) => Ok(Self::Integer(*s * *o)), | 114 | (Self::Integer(s), Self::Integer(o)) => Ok(Self::Integer(*s * *o)), |
115 | (Self::Integer(s), Self::String(o)) => Ok(Self::String(o.repeat(*s as usize))), | ||
116 | (Self::String(_), Self::Integer(_)) => other.mul(self), | ||
115 | _ => Err(Error::UndefinedBinOp( | 117 | _ => Err(Error::UndefinedBinOp( |
116 | ast::BinOp::Arith(ast::ArithOp::Mul), | 118 | ast::BinOp::Arith(ast::ArithOp::Mul), |
117 | self.ty(), | 119 | self.ty(), |
@@ -656,13 +658,13 @@ impl<'a> Context<'a> { | |||
656 | 658 | ||
657 | pub fn evaluate(file: &str, program: &str, language: tree_sitter::Language) -> Result { | 659 | pub fn evaluate(file: &str, program: &str, language: tree_sitter::Language) -> Result { |
658 | let mut parser = tree_sitter::Parser::new(); | 660 | let mut parser = tree_sitter::Parser::new(); |
659 | let _ = parser.set_language(language); | 661 | let _ = parser.set_language(&language); |
660 | 662 | ||
661 | let tree = parser.parse(file, None).unwrap(); | 663 | let tree = parser.parse(file, None).unwrap(); |
662 | let cursor = tree.walk(); | 664 | let cursor = tree.walk(); |
663 | 665 | ||
664 | let program = ast::Program::new().from_str(program).unwrap(); | 666 | let program = ast::Program::new().from_str(program).unwrap(); |
665 | let mut ctx = Context::new(tree_sitter_md::language()) | 667 | let mut ctx = Context::new(language) |
666 | .with_input(file.to_owned()) | 668 | .with_input(file.to_owned()) |
667 | .with_cursor(cursor) | 669 | .with_cursor(cursor) |
668 | .with_program(program)?; | 670 | .with_program(program)?; |
diff --git a/src/main.rs b/src/main.rs index 6196a32..ed024fc 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | /// TBSP: tree-based source processor | 1 | /// tree-based source processor |
2 | #[derive(argh::FromArgs)] | 2 | #[derive(argh::FromArgs)] |
3 | struct Cli { | 3 | struct Cli { |
4 | /// read the TBSP program source from a file | 4 | /// read the TBSP program source from a file |
@@ -14,42 +14,43 @@ struct Cli { | |||
14 | file: Option<std::path::PathBuf>, | 14 | file: Option<std::path::PathBuf>, |
15 | } | 15 | } |
16 | 16 | ||
17 | fn main() { | 17 | impl Cli { |
18 | let cli: Cli = argh::from_env(); | 18 | fn program(&self) -> String { |
19 | 19 | std::fs::read_to_string(&self.program_file).unwrap_or_else(|e| { | |
20 | let program = std::fs::read_to_string(&cli.program_file).unwrap_or_else(|e| { | 20 | eprintln!( |
21 | eprintln!( | 21 | "failed to read program-file from `{}`: {e}", |
22 | "failed to read program-file from `{}`: {e}", | 22 | self.program_file.display() |
23 | cli.program_file.display() | 23 | ); |
24 | ); | ||
25 | std::process::exit(-1); | ||
26 | }); | ||
27 | |||
28 | let language = match cli.language.as_str() { | ||
29 | "md" => tree_sitter_md::language(), | ||
30 | "typescript" => tree_sitter_typescript::language_typescript(), | ||
31 | "javascript" => tree_sitter_javascript::language(), | ||
32 | "python" => tree_sitter_python::language(), | ||
33 | "rust" => tree_sitter_rust::language(), | ||
34 | lang => { | ||
35 | eprintln!("unknown language `{lang}`"); | ||
36 | std::process::exit(-1); | 24 | std::process::exit(-1); |
37 | } | 25 | }) |
38 | }; | 26 | } |
39 | 27 | ||
40 | let file = cli | 28 | fn language(&self) -> tree_sitter::Language { |
41 | .file | 29 | match self.language.as_str() { |
42 | .map(std::fs::read_to_string) | 30 | "md" => tree_sitter_md::language(), |
43 | .unwrap_or_else(try_consume_stdin) | 31 | "typescript" => tree_sitter_typescript::language_typescript(), |
44 | .unwrap_or_else(|e| { | 32 | "javascript" => tree_sitter_javascript::language(), |
45 | eprintln!("{e}"); | 33 | "python" => tree_sitter_python::language(), |
46 | std::process::exit(-1) | 34 | "rust" => tree_sitter_rust::language(), |
47 | }); | 35 | lang => { |
36 | eprintln!("unknown language `{lang}`"); | ||
37 | std::process::exit(-1); | ||
38 | } | ||
39 | } | ||
40 | } | ||
48 | 41 | ||
49 | trawk::evaluate(&file, &program, language).unwrap_or_else(|e| { | 42 | fn file(&self) -> String { |
50 | eprintln!("{e:?}"); | 43 | match self.file.as_ref() { |
51 | std::process::exit(-1); | 44 | Some(f) => std::fs::read_to_string(f).unwrap_or_else(|e| { |
52 | }); | 45 | eprintln!("failed to read input-file from `{}`: {e}", f.display()); |
46 | std::process::exit(-1); | ||
47 | }), | ||
48 | None => try_consume_stdin().unwrap_or_else(|e| { | ||
49 | eprintln!("failed to read input-file from stdin: {e}"); | ||
50 | std::process::exit(-1); | ||
51 | }), | ||
52 | } | ||
53 | } | ||
53 | } | 54 | } |
54 | 55 | ||
55 | fn try_consume_stdin() -> std::io::Result<String> { | 56 | fn try_consume_stdin() -> std::io::Result<String> { |
@@ -69,114 +70,11 @@ fn try_consume_stdin() -> std::io::Result<String> { | |||
69 | } | 70 | } |
70 | } | 71 | } |
71 | 72 | ||
72 | // fn main() { | 73 | fn main() { |
73 | // let src = r#" | 74 | let cli: Cli = argh::from_env(); |
74 | // # foo1 | 75 | |
75 | // | 76 | tbsp::evaluate(&cli.file(), &cli.program(), cli.language()).unwrap_or_else(|e| { |
76 | // bar | 77 | eprintln!("{e:?}"); |
77 | // | 78 | std::process::exit(-1); |
78 | // ## foo1.1 | 79 | }); |
79 | // | 80 | } |
80 | // bar baz | ||
81 | // | ||
82 | // # foo2 | ||
83 | // | ||
84 | // bar baz | ||
85 | // | ||
86 | // ``` | ||
87 | // fn main() { | ||
88 | // } | ||
89 | // ``` | ||
90 | // | ||
91 | // - foo | ||
92 | // - bar | ||
93 | // - baz | ||
94 | // | ||
95 | // "# | ||
96 | // .to_owned(); | ||
97 | // | ||
98 | // let program = Program::new() | ||
99 | // .from_str( | ||
100 | // r#" | ||
101 | // BEGIN { | ||
102 | // int depth = 0; | ||
103 | // | ||
104 | // print("<html>\n"); | ||
105 | // print("<body>\n"); | ||
106 | // } | ||
107 | // | ||
108 | // enter section { | ||
109 | // depth += 1; | ||
110 | // } | ||
111 | // leave section { | ||
112 | // depth -= 1; | ||
113 | // } | ||
114 | // | ||
115 | // enter atx_heading { | ||
116 | // print("<h"); | ||
117 | // print(depth); | ||
118 | // print(">"); | ||
119 | // } | ||
120 | // leave atx_heading { | ||
121 | // print("</h"); | ||
122 | // print(depth); | ||
123 | // print(">\n"); | ||
124 | // } | ||
125 | // | ||
126 | // enter paragraph { | ||
127 | // print("<p>"); | ||
128 | // } | ||
129 | // leave paragraph { | ||
130 | // print("</p>\n"); | ||
131 | // } | ||
132 | // | ||
133 | // enter list { | ||
134 | // print("<ol>"); | ||
135 | // } | ||
136 | // leave list { | ||
137 | // print("</ol>\n"); | ||
138 | // } | ||
139 | // | ||
140 | // enter list_item { | ||
141 | // print("<li>"); | ||
142 | // } | ||
143 | // leave list_item { | ||
144 | // print("</li>\n"); | ||
145 | // } | ||
146 | // | ||
147 | // enter fenced_code_block { | ||
148 | // print("<pre>"); | ||
149 | // } | ||
150 | // leave fenced_code_block { | ||
151 | // print("</pre>\n"); | ||
152 | // } | ||
153 | // | ||
154 | // enter inline { | ||
155 | // print(text(node)); | ||
156 | // } | ||
157 | // enter code_fence_content { | ||
158 | // print(text(node)); | ||
159 | // } | ||
160 | // | ||
161 | // END { | ||
162 | // print("</body>\n"); | ||
163 | // print("</html>\n"); | ||
164 | // } | ||
165 | // "#, | ||
166 | // ) | ||
167 | // .unwrap(); | ||
168 | // | ||
169 | // let mut parser = tree_sitter::Parser::new(); | ||
170 | // let _ = parser.set_language(&tree_sitter_md::language()); | ||
171 | // | ||
172 | // let tree = parser.parse(&src, None).unwrap(); | ||
173 | // let cursor = tree.walk(); | ||
174 | // | ||
175 | // let mut ctx = Context::new(tree_sitter_md::language()) | ||
176 | // .with_input(src) | ||
177 | // .with_cursor(cursor) | ||
178 | // .with_program(program) | ||
179 | // .unwrap(); | ||
180 | // | ||
181 | // let _ = ctx.eval(); | ||
182 | // } | ||