authorgravatar for 11367844+lino-levan@users.noreply.github.comLino Le Van <11367844+lino-levan@users.noreply.github.com> 2024-01-01 16:20:52+01:00
committergravatar for 11367844+lino-levan@users.noreply.github.comLino Le Van <11367844+lino-levan@users.noreply.github.com> 2024-01-01 16:20:52+01:00
log1d5c7d0343ace11cd5a441a9d59c131181c78dc6
treec503354f20d93b5f24eea38ac836172088267f1b

feat: start work on compiler


11 files changed, 846 insertions(+), 0 deletions(-)

.gitignore created+1
...@@ -0,0 +1 @@
1/target
Cargo.lock created+532
...@@ -0,0 +1,532 @@
1# This file is automatically @generated by Cargo.
2# It is not intended for manual editing.
3version = 3
4
5[[package]]
6name = "addr2line"
7version = "0.21.0"
8source = "registry+https://github.com/rust-lang/crates.io-index"
9checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
10dependencies = [
11 "gimli",
12]
13
14[[package]]
15name = "adler"
16version = "1.0.2"
17source = "registry+https://github.com/rust-lang/crates.io-index"
18checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
19
20[[package]]
21name = "anstream"
22version = "0.6.5"
23source = "registry+https://github.com/rust-lang/crates.io-index"
24checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6"
25dependencies = [
26 "anstyle",
27 "anstyle-parse",
28 "anstyle-query",
29 "anstyle-wincon",
30 "colorchoice",
31 "utf8parse",
32]
33
34[[package]]
35name = "anstyle"
36version = "1.0.4"
37source = "registry+https://github.com/rust-lang/crates.io-index"
38checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
39
40[[package]]
41name = "anstyle-parse"
42version = "0.2.3"
43source = "registry+https://github.com/rust-lang/crates.io-index"
44checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
45dependencies = [
46 "utf8parse",
47]
48
49[[package]]
50name = "anstyle-query"
51version = "1.0.2"
52source = "registry+https://github.com/rust-lang/crates.io-index"
53checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
54dependencies = [
55 "windows-sys",
56]
57
58[[package]]
59name = "anstyle-wincon"
60version = "3.0.2"
61source = "registry+https://github.com/rust-lang/crates.io-index"
62checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
63dependencies = [
64 "anstyle",
65 "windows-sys",
66]
67
68[[package]]
69name = "backtrace"
70version = "0.3.69"
71source = "registry+https://github.com/rust-lang/crates.io-index"
72checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
73dependencies = [
74 "addr2line",
75 "cc",
76 "cfg-if",
77 "libc",
78 "miniz_oxide",
79 "object",
80 "rustc-demangle",
81]
82
83[[package]]
84name = "backtrace-ext"
85version = "0.2.1"
86source = "registry+https://github.com/rust-lang/crates.io-index"
87checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50"
88dependencies = [
89 "backtrace",
90]
91
92[[package]]
93name = "bitflags"
94version = "2.4.1"
95source = "registry+https://github.com/rust-lang/crates.io-index"
96checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
97
98[[package]]
99name = "blight"
100version = "0.1.0"
101dependencies = [
102 "clap",
103 "miette",
104 "thiserror",
105]
106
107[[package]]
108name = "cc"
109version = "1.0.83"
110source = "registry+https://github.com/rust-lang/crates.io-index"
111checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
112dependencies = [
113 "libc",
114]
115
116[[package]]
117name = "cfg-if"
118version = "1.0.0"
119source = "registry+https://github.com/rust-lang/crates.io-index"
120checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
121
122[[package]]
123name = "clap"
124version = "4.4.12"
125source = "registry+https://github.com/rust-lang/crates.io-index"
126checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d"
127dependencies = [
128 "clap_builder",
129 "clap_derive",
130]
131
132[[package]]
133name = "clap_builder"
134version = "4.4.12"
135source = "registry+https://github.com/rust-lang/crates.io-index"
136checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9"
137dependencies = [
138 "anstream",
139 "anstyle",
140 "clap_lex",
141 "strsim",
142]
143
144[[package]]
145name = "clap_derive"
146version = "4.4.7"
147source = "registry+https://github.com/rust-lang/crates.io-index"
148checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
149dependencies = [
150 "heck",
151 "proc-macro2",
152 "quote",
153 "syn",
154]
155
156[[package]]
157name = "clap_lex"
158version = "0.6.0"
159source = "registry+https://github.com/rust-lang/crates.io-index"
160checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
161
162[[package]]
163name = "colorchoice"
164version = "1.0.0"
165source = "registry+https://github.com/rust-lang/crates.io-index"
166checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
167
168[[package]]
169name = "errno"
170version = "0.3.8"
171source = "registry+https://github.com/rust-lang/crates.io-index"
172checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
173dependencies = [
174 "libc",
175 "windows-sys",
176]
177
178[[package]]
179name = "gimli"
180version = "0.28.1"
181source = "registry+https://github.com/rust-lang/crates.io-index"
182checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
183
184[[package]]
185name = "heck"
186version = "0.4.1"
187source = "registry+https://github.com/rust-lang/crates.io-index"
188checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
189
190[[package]]
191name = "hermit-abi"
192version = "0.3.3"
193source = "registry+https://github.com/rust-lang/crates.io-index"
194checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
195
196[[package]]
197name = "is-terminal"
198version = "0.4.10"
199source = "registry+https://github.com/rust-lang/crates.io-index"
200checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455"
201dependencies = [
202 "hermit-abi",
203 "rustix",
204 "windows-sys",
205]
206
207[[package]]
208name = "is_ci"
209version = "1.1.1"
210source = "registry+https://github.com/rust-lang/crates.io-index"
211checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb"
212
213[[package]]
214name = "libc"
215version = "0.2.151"
216source = "registry+https://github.com/rust-lang/crates.io-index"
217checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
218
219[[package]]
220name = "linux-raw-sys"
221version = "0.4.12"
222source = "registry+https://github.com/rust-lang/crates.io-index"
223checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
224
225[[package]]
226name = "memchr"
227version = "2.7.1"
228source = "registry+https://github.com/rust-lang/crates.io-index"
229checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
230
231[[package]]
232name = "miette"
233version = "5.10.0"
234source = "registry+https://github.com/rust-lang/crates.io-index"
235checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e"
236dependencies = [
237 "backtrace",
238 "backtrace-ext",
239 "is-terminal",
240 "miette-derive",
241 "once_cell",
242 "owo-colors",
243 "supports-color",
244 "supports-hyperlinks",
245 "supports-unicode",
246 "terminal_size",
247 "textwrap",
248 "thiserror",
249 "unicode-width",
250]
251
252[[package]]
253name = "miette-derive"
254version = "5.10.0"
255source = "registry+https://github.com/rust-lang/crates.io-index"
256checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c"
257dependencies = [
258 "proc-macro2",
259 "quote",
260 "syn",
261]
262
263[[package]]
264name = "miniz_oxide"
265version = "0.7.1"
266source = "registry+https://github.com/rust-lang/crates.io-index"
267checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
268dependencies = [
269 "adler",
270]
271
272[[package]]
273name = "object"
274version = "0.32.2"
275source = "registry+https://github.com/rust-lang/crates.io-index"
276checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
277dependencies = [
278 "memchr",
279]
280
281[[package]]
282name = "once_cell"
283version = "1.19.0"
284source = "registry+https://github.com/rust-lang/crates.io-index"
285checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
286
287[[package]]
288name = "owo-colors"
289version = "3.5.0"
290source = "registry+https://github.com/rust-lang/crates.io-index"
291checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
292
293[[package]]
294name = "proc-macro2"
295version = "1.0.73"
296source = "registry+https://github.com/rust-lang/crates.io-index"
297checksum = "2dd5e8a1f1029c43224ad5898e50140c2aebb1705f19e67c918ebf5b9e797fe1"
298dependencies = [
299 "unicode-ident",
300]
301
302[[package]]
303name = "quote"
304version = "1.0.34"
305source = "registry+https://github.com/rust-lang/crates.io-index"
306checksum = "22a37c9326af5ed140c86a46655b5278de879853be5573c01df185b6f49a580a"
307dependencies = [
308 "proc-macro2",
309]
310
311[[package]]
312name = "rustc-demangle"
313version = "0.1.23"
314source = "registry+https://github.com/rust-lang/crates.io-index"
315checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
316
317[[package]]
318name = "rustix"
319version = "0.38.28"
320source = "registry+https://github.com/rust-lang/crates.io-index"
321checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
322dependencies = [
323 "bitflags",
324 "errno",
325 "libc",
326 "linux-raw-sys",
327 "windows-sys",
328]
329
330[[package]]
331name = "smawk"
332version = "0.3.2"
333source = "registry+https://github.com/rust-lang/crates.io-index"
334checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
335
336[[package]]
337name = "strsim"
338version = "0.10.0"
339source = "registry+https://github.com/rust-lang/crates.io-index"
340checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
341
342[[package]]
343name = "supports-color"
344version = "2.1.0"
345source = "registry+https://github.com/rust-lang/crates.io-index"
346checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89"
347dependencies = [
348 "is-terminal",
349 "is_ci",
350]
351
352[[package]]
353name = "supports-hyperlinks"
354version = "2.1.0"
355source = "registry+https://github.com/rust-lang/crates.io-index"
356checksum = "f84231692eb0d4d41e4cdd0cabfdd2e6cd9e255e65f80c9aa7c98dd502b4233d"
357dependencies = [
358 "is-terminal",
359]
360
361[[package]]
362name = "supports-unicode"
363version = "2.0.0"
364source = "registry+https://github.com/rust-lang/crates.io-index"
365checksum = "4b6c2cb240ab5dd21ed4906895ee23fe5a48acdbd15a3ce388e7b62a9b66baf7"
366dependencies = [
367 "is-terminal",
368]
369
370[[package]]
371name = "syn"
372version = "2.0.44"
373source = "registry+https://github.com/rust-lang/crates.io-index"
374checksum = "92d27c2c202598d05175a6dd3af46824b7f747f8d8e9b14c623f19fa5069735d"
375dependencies = [
376 "proc-macro2",
377 "quote",
378 "unicode-ident",
379]
380
381[[package]]
382name = "terminal_size"
383version = "0.1.17"
384source = "registry+https://github.com/rust-lang/crates.io-index"
385checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
386dependencies = [
387 "libc",
388 "winapi",
389]
390
391[[package]]
392name = "textwrap"
393version = "0.15.2"
394source = "registry+https://github.com/rust-lang/crates.io-index"
395checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d"
396dependencies = [
397 "smawk",
398 "unicode-linebreak",
399 "unicode-width",
400]
401
402[[package]]
403name = "thiserror"
404version = "1.0.53"
405source = "registry+https://github.com/rust-lang/crates.io-index"
406checksum = "b2cd5904763bad08ad5513ddbb12cf2ae273ca53fa9f68e843e236ec6dfccc09"
407dependencies = [
408 "thiserror-impl",
409]
410
411[[package]]
412name = "thiserror-impl"
413version = "1.0.53"
414source = "registry+https://github.com/rust-lang/crates.io-index"
415checksum = "3dcf4a824cce0aeacd6f38ae6f24234c8e80d68632338ebaa1443b5df9e29e19"
416dependencies = [
417 "proc-macro2",
418 "quote",
419 "syn",
420]
421
422[[package]]
423name = "unicode-ident"
424version = "1.0.12"
425source = "registry+https://github.com/rust-lang/crates.io-index"
426checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
427
428[[package]]
429name = "unicode-linebreak"
430version = "0.1.5"
431source = "registry+https://github.com/rust-lang/crates.io-index"
432checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
433
434[[package]]
435name = "unicode-width"
436version = "0.1.11"
437source = "registry+https://github.com/rust-lang/crates.io-index"
438checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
439
440[[package]]
441name = "utf8parse"
442version = "0.2.1"
443source = "registry+https://github.com/rust-lang/crates.io-index"
444checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
445
446[[package]]
447name = "winapi"
448version = "0.3.9"
449source = "registry+https://github.com/rust-lang/crates.io-index"
450checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
451dependencies = [
452 "winapi-i686-pc-windows-gnu",
453 "winapi-x86_64-pc-windows-gnu",
454]
455
456[[package]]
457name = "winapi-i686-pc-windows-gnu"
458version = "0.4.0"
459source = "registry+https://github.com/rust-lang/crates.io-index"
460checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
461
462[[package]]
463name = "winapi-x86_64-pc-windows-gnu"
464version = "0.4.0"
465source = "registry+https://github.com/rust-lang/crates.io-index"
466checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
467
468[[package]]
469name = "windows-sys"
470version = "0.52.0"
471source = "registry+https://github.com/rust-lang/crates.io-index"
472checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
473dependencies = [
474 "windows-targets",
475]
476
477[[package]]
478name = "windows-targets"
479version = "0.52.0"
480source = "registry+https://github.com/rust-lang/crates.io-index"
481checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
482dependencies = [
483 "windows_aarch64_gnullvm",
484 "windows_aarch64_msvc",
485 "windows_i686_gnu",
486 "windows_i686_msvc",
487 "windows_x86_64_gnu",
488 "windows_x86_64_gnullvm",
489 "windows_x86_64_msvc",
490]
491
492[[package]]
493name = "windows_aarch64_gnullvm"
494version = "0.52.0"
495source = "registry+https://github.com/rust-lang/crates.io-index"
496checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
497
498[[package]]
499name = "windows_aarch64_msvc"
500version = "0.52.0"
501source = "registry+https://github.com/rust-lang/crates.io-index"
502checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
503
504[[package]]
505name = "windows_i686_gnu"
506version = "0.52.0"
507source = "registry+https://github.com/rust-lang/crates.io-index"
508checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
509
510[[package]]
511name = "windows_i686_msvc"
512version = "0.52.0"
513source = "registry+https://github.com/rust-lang/crates.io-index"
514checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
515
516[[package]]
517name = "windows_x86_64_gnu"
518version = "0.52.0"
519source = "registry+https://github.com/rust-lang/crates.io-index"
520checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
521
522[[package]]
523name = "windows_x86_64_gnullvm"
524version = "0.52.0"
525source = "registry+https://github.com/rust-lang/crates.io-index"
526checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
527
528[[package]]
529name = "windows_x86_64_msvc"
530version = "0.52.0"
531source = "registry+https://github.com/rust-lang/crates.io-index"
532checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
Cargo.toml created+11
...@@ -0,0 +1,11 @@
1[package]
2name = "blight"
3version = "0.1.0"
4edition = "2021"
5
6# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
8[dependencies]
9clap = { version = "4.4.12", features = ["derive"] }
10miette = { version = "5.10.0", features = ["fancy"] }
11thiserror = "1.0.53"
README.md created+3
...@@ -0,0 +1,3 @@
1# Blight
2
3Blight sure is a programming language.
examples/easy.blight created+3
...@@ -0,0 +1,3 @@
1var x: int = 0;
2var y: float = 0;
3var z: bigint = 0;
src/main.rs created+40
...@@ -0,0 +1,40 @@
1use std::path::PathBuf;
2
3use miette::{Result, NamedSource};
4use clap::{Parser, Subcommand};
5
6mod transpile;
7
8#[derive(Parser)]
9#[command(author, version, about, long_about = None)]
10struct Cli {
11 /// Turn debugging information on
12 #[arg(short, long, action = clap::ArgAction::Count)]
13 debug: u8,
14
15 #[command(subcommand)]
16 command: Commands,
17}
18
19#[derive(Subcommand)]
20enum Commands {
21 /// Compiles a file into javascript
22 Compile {
23 /// lists test values
24 file: PathBuf
25 },
26}
27
28fn main() -> Result<()> {
29 let cli = Cli::parse();
30
31 match cli.command {
32 Commands::Compile { file } => {
33 let contents = std::fs::read_to_string(file.clone()).unwrap();
34 let result = transpile::transpile(contents.clone())?;
35 std::fs::write(file.with_extension("js"), result).unwrap();
36 }
37 }
38
39 Ok(())
40}
src/transpile/ast.rs created+102
...@@ -0,0 +1,102 @@
1use miette::{Result, Diagnostic};
2use thiserror::Error;
3
4use super::tokenizer::Token;
5use super::util::PeekableIterator;
6
7#[derive(Error, Diagnostic, Debug)]
8#[error("AstError")]
9struct AstError {
10 #[help]
11 error: String
12}
13
14impl AstError {
15 fn new(error: &'static str) -> AstError {
16 AstError { error: String::from(error) }
17 }
18}
19
20#[derive(Debug)]
21pub enum Type {
22 Int,
23 Float,
24 Bigint
25}
26
27#[derive(Debug)]
28pub enum Ast {
29 VariableDeclaration {
30 name: String,
31 typ: Type,
32 value: Box<Ast>
33 },
34 Number(String),
35}
36
37fn parse_expression(tokens: &mut dyn PeekableIterator<Item=&Token>) -> Result<Ast> {
38 match tokens.next() {
39 Some(token) => match token {
40 Token::Number(number) => Token::Number(number.clone()),
41 _ => return Err(AstError::new("Expected expression, but did not get it").into())
42 },
43 None => return Err(AstError::new("Expected expression, but got nothing instead").into())
44
45 };
46 Ok(Ast::Number(String::from("10")))
47}
48
49/// Precondition: There is at least one token in the iterator
50fn parse_statement(tokens: &mut dyn PeekableIterator<Item=&Token>) -> Result<Ast> {
51 match tokens.next().unwrap() {
52 Token::Var => {
53 let name = match tokens.next() {
54 Some(Token::Identifier(name)) => name,
55 _ => return Err(AstError::new("Expected identifier after var").into())
56 };
57 let typ = match tokens.next() {
58 Some(Token::Colon) => {
59 match tokens.next() {
60 Some(Token::Identifier(typ)) => {
61 match typ.as_str() {
62 "int" => Type::Int,
63 "float" => Type::Float,
64 "bigint" => Type::Bigint,
65 _ => return Err(AstError::new("Expected type after colon").into())
66 }
67 },
68 _ => return Err(AstError::new("Expected type after colon").into())
69 }
70 },
71 _ => return Err(AstError::new("Expected colon after identifier").into())
72 };
73 let value = match tokens.next() {
74 Some(Token::Equals) => parse_expression(tokens)?,
75 _ => return Err(AstError::new("Expected equals after identifier").into())
76 };
77 match tokens.next() {
78 Some(Token::Semicolon) => (),
79 _ => return Err(AstError::new("Expected semicolon after variable declaration").into())
80 };
81 Ok(Ast::VariableDeclaration {
82 name: name.clone(),
83 typ,
84 value: Box::new(value),
85 })
86 },
87 Token::Number(number) => Ok(Ast::Number(number.clone())),
88 _ => return Err(AstError::new("Unexpected token").into())
89 }
90}
91
92
93pub fn parse(tokens: Vec<Token>) -> Result<Vec<Ast>> {
94 let mut iter = tokens.iter().peekable();
95 let mut ast: Vec<Ast> = Vec::new();
96
97 while iter.peek().is_some() {
98 ast.push(parse_statement(&mut iter)?);
99 }
100
101 Ok(ast)
102}
src/transpile/mod.rs created+19
...@@ -0,0 +1,19 @@
1use miette::{Result};
2
3mod tokenizer;
4mod ast;
5mod walker;
6
7mod util;
8
9pub fn transpile(content: String) -> Result<String> {
10 // 1. Tokenize the input
11 let tokens = tokenizer::tokenize(content)?;
12 // 2. Parse the tokens into an AST
13 let tree = ast::parse(tokens)?;
14 print!("{:?}", tree);
15 // 3. Transpile the AST into javascript
16 let result = walker::transpile(tree);
17 // 4. Return the javascript
18 return Ok(result);
19}
src/transpile/tokenizer.rs created+101
...@@ -0,0 +1,101 @@
1use miette::{Result, Diagnostic};
2use thiserror::Error;
3
4#[derive(Error, Diagnostic, Debug)]
5#[error("UnknownCharacter")]
6struct UnknownCharacter {
7 #[help]
8 error: String
9}
10
11#[derive(Debug, Clone)]
12pub enum Operator {
13 Add,
14 Substract,
15 Multiply,
16 Divide,
17}
18
19#[derive(Debug, Clone)]
20pub enum Token {
21 // Literals
22 Identifier(String),
23 Number(String),
24 // Keywords
25 Var,
26 Colon,
27 Equals,
28 Semicolon,
29 // Operators
30 Operator(Operator)
31}
32
33pub fn tokenize(content: String) -> Result<Vec<Token>> {
34 let mut tokens: Vec<Token> = Vec::new();
35 let mut chars = content.chars().enumerate().peekable();
36
37 loop {
38 match chars.next() {
39 Some((i, c)) => {
40 match c {
41 'a'..='z' | 'A'..='Z' | '_' => {
42 let mut current_token = String::new();
43 current_token.push(c);
44 loop {
45 let c = chars.peek();
46 if c.is_none() {
47 break;
48 }
49 let (_, c) = c.unwrap();
50 match c {
51 'a'..='z' | 'A'..='Z' | '_' | '0'..='9' => {
52 current_token.push(*c);
53 chars.next();
54 },
55 _ => break,
56 }
57 }
58
59 match current_token.as_str() {
60 "var" => tokens.push(Token::Var),
61 _ => tokens.push(Token::Identifier(current_token)),
62 }
63 },
64 '0'..='9' => {
65 let mut current_token = String::new();
66 current_token.push(c);
67 loop {
68 let c = chars.peek();
69 if c.is_none() {
70 break;
71 }
72 let (_, c) = c.unwrap();
73 match c {
74 '0'..='9' => {
75 current_token.push(*c);
76 chars.next();
77 },
78 _ => break,
79 }
80 }
81 tokens.push(Token::Number(current_token));
82 },
83 ':' => tokens.push(Token::Colon),
84 '=' => tokens.push(Token::Equals),
85 ';' => tokens.push(Token::Semicolon),
86 '+' => tokens.push(Token::Operator(Operator::Add)),
87 '-' => tokens.push(Token::Operator(Operator::Substract)),
88 '*' => tokens.push(Token::Operator(Operator::Multiply)),
89 '/' => tokens.push(Token::Operator(Operator::Divide)),
90 s if s.is_whitespace() => (),
91 _ => {
92 return Err(UnknownCharacter { error: format!("Unsupported character: {}", c)}.into())
93 }
94 }
95 }
96 None => break,
97 }
98 }
99
100 Ok(tokens)
101}
src/transpile/util.rs created+11
...@@ -0,0 +1,11 @@
1// Rust why do you not have a peekable iterator in the standard library?
2// Stolen from https://users.rust-lang.org/t/peekable-argument-there-has-to-be-a-simpler-way/6959
3pub trait PeekableIterator : std::iter::Iterator {
4 fn peek(&mut self) -> Option<&Self::Item>;
5}
6
7impl<I: std::iter::Iterator> PeekableIterator for std::iter::Peekable<I> {
8 fn peek(&mut self) -> Option<&Self::Item> {
9 std::iter::Peekable::peek(self)
10 }
11}
src/transpile/walker.rs created+23
...@@ -0,0 +1,23 @@
1use super::ast::{Ast, Type};
2
3fn transpile_helper(tree: Ast) -> String {
4 match tree {
5 Ast::Number(number) => format!("{}", number),
6 Ast::VariableDeclaration { name, typ, value } => {
7 match typ {
8 Type::Bigint => format!("let {} = BigInt({});\n", name, transpile_helper(*value)),
9 _ => format!("let {} = {};\n", name, transpile_helper(*value))
10 }
11 },
12 }
13}
14
15pub fn transpile(forest: Vec<Ast>) -> String {
16 let mut result = String::new();
17
18 for tree in forest {
19 result.push_str(&transpile_helper(tree));
20 }
21
22 result
23}