wain_syntax_text/
lib.rs

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
21// TODO: Unify all error types into one error type
22pub 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    // Compose multiple modules: https://webassembly.github.io/spec/core/text/modules.html#text-module
71    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}