Skip to content

Commit 18f2337

Browse files
committed
lol
1 parent 83272ce commit 18f2337

File tree

11 files changed

+882
-506
lines changed

11 files changed

+882
-506
lines changed

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,7 @@ include = [
1818
]
1919

2020
[workspace]
21-
members = ["demo/caller", "demo/wa", "runtime/tests"]
21+
members = ["demo/caller", "demo/wa", "runtime/tests", "proc-macro"]
22+
23+
[patch.crates-io]
24+
watt = { path = "." }

demo/impl/src/lib.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1-
use proc_macro2::TokenStream;
1+
use proc_macro2::*;
22
use quote::quote;
33
use syn::DeriveInput;
44

55
#[no_mangle]
6-
pub extern "C" fn demo(input: TokenStream) -> TokenStream {
7-
proc_macro2::set_wasm_panic_hook();
8-
9-
let input: DeriveInput = match syn::parse2(input) {
6+
pub extern "C" fn demo(input: RawTokenStream) -> RawTokenStream {
7+
let input: DeriveInput = match syn::parse2(input.into_token_stream()) {
108
Ok(input) => input,
11-
Err(err) => return err.to_compile_error(),
9+
Err(err) => return err.to_compile_error().into_raw_token_stream(),
1210
};
1311

1412
let ident = input.ident;
1513
let message = format!("Hello from WASM! My name is {}.", ident);
1614

17-
quote! {
15+
let ret = quote! {
1816
impl #ident {
1917
pub const MESSAGE: &'static str = #message;
2018
}
21-
}
19+
};
20+
ret.into_raw_token_stream()
2221
}

demo/wa/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ publish = false
99
proc-macro = true
1010

1111
[dependencies]
12-
watt = { path = "../.." }
12+
watt = "0.1"

proc-macro/src/decode.rs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
use super::*;
2+
use std::str;
3+
4+
pub fn decode(mut buf: &[u8]) -> TokenStream {
5+
let ret = TokenStream::decode(&mut buf);
6+
assert!(buf.is_empty());
7+
return ret;
8+
}
9+
10+
trait Decode {
11+
fn decode(data: &mut &[u8]) -> Self;
12+
}
13+
14+
fn byte(data: &mut &[u8]) -> u8 {
15+
let ret = data[0];
16+
*data = &data[1..];
17+
ret
18+
}
19+
20+
fn str<'a>(data: &mut &'a [u8]) -> &'a str {
21+
let len = u32::decode(data) as usize;
22+
let ret = str::from_utf8(&data[..len]).unwrap();
23+
*data = &data[len..];
24+
return ret;
25+
}
26+
27+
impl Decode for TokenStream {
28+
fn decode(data: &mut &[u8]) -> Self {
29+
let mut tokens = Vec::new();
30+
loop {
31+
match byte(data) {
32+
0 => break,
33+
1 => tokens.push(TokenTree::Group(Group::decode(data))),
34+
2 => tokens.push(TokenTree::Ident(Ident::decode(data))),
35+
3 => tokens.push(TokenTree::Punct(Punct::decode(data))),
36+
_ => tokens.push(TokenTree::Literal(Literal::decode(data))),
37+
}
38+
}
39+
TokenStream { inner: tokens }
40+
}
41+
}
42+
43+
impl Decode for Group {
44+
fn decode(data: &mut &[u8]) -> Self {
45+
let delimiter = Delimiter::decode(data);
46+
let span = Span::decode(data);
47+
let stream = TokenStream::decode(data);
48+
let mut ret = Group::new(delimiter, stream);
49+
ret.set_span(span);
50+
return ret;
51+
}
52+
}
53+
54+
impl Decode for Delimiter {
55+
fn decode(data: &mut &[u8]) -> Self {
56+
match byte(data) {
57+
0 => Delimiter::Parenthesis,
58+
1 => Delimiter::Brace,
59+
2 => Delimiter::Bracket,
60+
_ => Delimiter::None,
61+
}
62+
}
63+
}
64+
65+
impl Decode for Span {
66+
fn decode(data: &mut &[u8]) -> Self {
67+
Span {
68+
handle: u32::decode(data),
69+
}
70+
}
71+
}
72+
73+
impl Decode for u32 {
74+
fn decode(data: &mut &[u8]) -> Self {
75+
let ret = ((data[0] as u32) << 0)
76+
| ((data[1] as u32) << 8)
77+
| ((data[2] as u32) << 16)
78+
| ((data[3] as u32) << 24);
79+
*data = &data[4..];
80+
return ret;
81+
}
82+
}
83+
84+
impl Decode for Ident {
85+
fn decode(data: &mut &[u8]) -> Self {
86+
let span = Span::decode(data);
87+
let name = str(data);
88+
Ident::new(name, span)
89+
}
90+
}
91+
92+
impl Decode for Punct {
93+
fn decode(data: &mut &[u8]) -> Self {
94+
let mut p = Punct::new(
95+
char::from_u32(u32::decode(data)).unwrap(),
96+
Spacing::decode(data),
97+
);
98+
p.set_span(Span::decode(data));
99+
return p;
100+
}
101+
}
102+
103+
impl Decode for Spacing {
104+
fn decode(data: &mut &[u8]) -> Self {
105+
match byte(data) {
106+
0 => Spacing::Alone,
107+
_ => Spacing::Joint,
108+
}
109+
}
110+
}
111+
112+
impl Decode for Literal {
113+
fn decode(data: &mut &[u8]) -> Self {
114+
Literal {
115+
span: Span::decode(data),
116+
text: str(data).to_string(),
117+
}
118+
}
119+
}

proc-macro/src/encode.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
use super::*;
2+
use std::convert::TryFrom;
3+
4+
pub fn encode(stream: TokenStream) -> Vec<u8> {
5+
let mut dst = Vec::new();
6+
stream.encode(&mut dst);
7+
dst
8+
}
9+
10+
trait Encode {
11+
fn encode(self, dst: &mut Vec<u8>);
12+
}
13+
14+
impl Encode for TokenStream {
15+
fn encode(self, dst: &mut Vec<u8>) {
16+
for token in self {
17+
token.encode(dst);
18+
}
19+
dst.push(0);
20+
}
21+
}
22+
23+
impl Encode for TokenTree {
24+
fn encode(self, dst: &mut Vec<u8>) {
25+
match self {
26+
TokenTree::Group(g) => {
27+
dst.push(1);
28+
g.encode(dst);
29+
}
30+
TokenTree::Ident(i) => {
31+
dst.push(2);
32+
i.encode(dst);
33+
}
34+
TokenTree::Punct(p) => {
35+
dst.push(3);
36+
p.encode(dst);
37+
}
38+
TokenTree::Literal(l) => {
39+
dst.push(4);
40+
l.encode(dst);
41+
}
42+
}
43+
}
44+
}
45+
46+
impl Encode for Group {
47+
fn encode(self, dst: &mut Vec<u8>) {
48+
self.delimiter().encode(dst);
49+
self.span().encode(dst);
50+
self.stream().encode(dst);
51+
}
52+
}
53+
54+
impl Encode for Delimiter {
55+
fn encode(self, dst: &mut Vec<u8>) {
56+
dst.push(self as u8);
57+
}
58+
}
59+
60+
impl Encode for Span {
61+
fn encode(self, dst: &mut Vec<u8>) {
62+
self.handle.encode(dst);
63+
}
64+
}
65+
66+
impl Encode for u32 {
67+
fn encode(self, dst: &mut Vec<u8>) {
68+
dst.extend_from_slice(&self.to_le_bytes());
69+
}
70+
}
71+
72+
impl Encode for usize {
73+
fn encode(self, dst: &mut Vec<u8>) {
74+
u32::try_from(self).unwrap().encode(dst)
75+
}
76+
}
77+
78+
impl Encode for Ident {
79+
fn encode(self, dst: &mut Vec<u8>) {
80+
self.span().encode(dst);
81+
self.to_string().encode(dst);
82+
}
83+
}
84+
85+
impl Encode for String {
86+
fn encode(self, dst: &mut Vec<u8>) {
87+
self.len().encode(dst);
88+
dst.extend_from_slice(self.as_bytes());
89+
}
90+
}
91+
92+
impl Encode for Punct {
93+
fn encode(self, dst: &mut Vec<u8>) {
94+
self.as_char().encode(dst);
95+
self.spacing().encode(dst);
96+
self.span().encode(dst);
97+
}
98+
}
99+
100+
impl Encode for char {
101+
fn encode(self, dst: &mut Vec<u8>) {
102+
(self as u32).encode(dst);
103+
}
104+
}
105+
106+
impl Encode for Spacing {
107+
fn encode(self, dst: &mut Vec<u8>) {
108+
dst.push(self as u8);
109+
}
110+
}
111+
112+
impl Encode for Literal {
113+
fn encode(self, dst: &mut Vec<u8>) {
114+
self.span().encode(dst);
115+
self.to_string().encode(dst);
116+
}
117+
}

0 commit comments

Comments
 (0)