1#![forbid(unsafe_code)]
2#![warn(clippy::dbg_macro)]
3#![allow(clippy::cognitive_complexity)]
4#![allow(clippy::manual_range_contains)]
5
6extern crate wain_ast;
7
8pub mod ast;
9pub mod compose;
10pub mod lexer;
11pub mod parser;
12pub mod source;
13pub mod wat2wasm;
14
15use compose::{ComposeError, Composer};
16use parser::{ParseError, Parser};
17use source::TextSource;
18use std::fmt;
19use wat2wasm::{wat2wasm, TransformError};
20
21pub enum Error<'source> {
23 Parse(Box<ParseError<'source>>),
24 Transform(Box<TransformError<'source>>),
25 Compose(Box<ComposeError<'source>>),
26}
27
28impl<'s> Error<'s> {
29 pub fn location(&self) -> (&'s str, usize) {
30 match self {
31 Error::Parse(e) => (e.source(), e.offset()),
32 Error::Transform(e) => (e.source(), e.offset()),
33 Error::Compose(e) => (e.source(), e.offset()),
34 }
35 }
36}
37
38macro_rules! from_errors {
39 ($($ty:ty => $kind:ident,)+) => {
40 $(
41 impl<'s> From<Box<$ty>> for Error<'s> {
42 fn from(err: Box<$ty>) -> Error<'s> {
43 Error::$kind(err)
44 }
45 }
46 )+
47
48 impl<'s> fmt::Display for Error<'s> {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 match self {
51 $(
52 Error::$kind(err) => err.fmt(f),
53 )+
54 }
55 }
56 }
57 };
58}
59from_errors! {
60 ParseError<'s> => Parse,
61 TransformError<'s> => Transform,
62 ComposeError<'s> => Compose,
63}
64
65pub fn parse(source: &'_ str) -> Result<wain_ast::Root<'_, TextSource>, Error<'_>> {
66 let mut parser = Parser::new(source);
67 let parsed = parser.parse()?;
68 let mut tree = wat2wasm(parsed, source)?;
69
70 while !parser.is_done() {
72 let parsed = parser.parse()?;
73 let module = wat2wasm(parsed, source)?.module;
74 let composer = Composer::new(tree.module, source);
75 tree.module = composer.compose(module)?;
76 }
77
78 Ok(tree)
79}