-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathscratch
148 lines (105 loc) · 5.84 KB
/
scratch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
Unrelated:
- hypermedia 'shell' approach, where you have a multipart resource with 'segments' of different multilevelmime-types, with ~etags so you can cache the 'presentation' segment, and then the other segments are 'data', so you can do the 'more efficient' approach.
- an advanced form of 'snowflaking' that can change between a format that is 'uniform and complete' (but fuckhueg) with one that has a 'shell' part and then 'specialised' 'small' formats eg text/json+'forapp' or text/xml+'forapp'...
- 'link bundles' or etc, which may need a 'negotiation' step to see which sub resources are needed
---
array each name $array =>
for i in get each element from array
out += quoted_span! {root=> $(#name #i)};
return do_with_in_explicit... out
array map should_isolate name {stuff} $array
mut new_v = v.clone()
mut restore_old_name: Option<String> = None;
for i in get each element from array
if (should_isolate) {
new_v = v.clone();
} else {
restore_old_name = new_v.variables.get(name)
};
new_v.variables.insert(name, stuff)
out += match do_with_in_explicit new_v, stuff {
Ok((x, y)) => y,
Err((x, y) => {
out.extend(x);
out.extend(quote_spanned!{sp=> compile_error!{"Blah!"}});
return Err((x, out));
},
}
match restore_old_name {
None => new_v.variables.remove(name),
Some(x) => new_v.variables.set(name, x),
};
return ...
---
names:
make $0...$n, $n+1...$m for (left to right) the _'s and then the named things
do inside and outside separately
single token ⇒ use that token for inside and outside name
single _ *can* result in a different inner and outer numbering
if there is an =..., this is the default
TokenTree2::Ident's, TokenTree2::Literal's, and $identifiers can be unbracketed
TokenStream2's (including dwi arrays) must be inside a TokenTree2::Group
If there are any non-default variables without a value, return an error with the unspecified necessary args.
Create new environment from existing environment
Make empty variables for every internal name (both explicit, when it exists, and number for all).
Go left to right from definitions, running the code for that value with the existing environment, and then set the number (and, if it exists, explicit) variable in the environment to that value.
alias -> creates new aliasinternalhandler with data "nameoforiginalhandler", and assigns it to the handler datastructure with name "name given"
aliasinternalhandler -> snips off the first entry in t, creates a new tokenstream2 with "nameoforiginalhandler" (taken from data), then extends it with t. Calls the handler called "name given" with the new tokenstream; returns that.
$(marker "name" => {value},...)
$(runMarkers location name*)
$(runAllMarkers location*)
macro_rules! matcher... to activate on a series of tokens and then pass through the values to an inner bit of code
Args in vecs
with arrays that list offsets in to that vec, so we can go by unnamed or named
for inner and outer:
vec of positions (with named coming in at the end from left to right)
vec of Names (with nameless being $0, $1, $2 etc based on positions for $ as sigil)
vec of default values
get arg values from caller to populate actual values based on args, push all of those to env, then got through defaults pushing in to the environment left-to-right in the declaration
$pi ≡ Punct("_") or Ident
$val ≡ Group or Ident or Literal
($pi $pi? ("=" $val)?),*
---
try_and, try_or, try_one_until_first_success, try_all_until_first_failure
parse_str <- takes a string and turns it into a TokenStream2 or fails
file_str <- return a string with the contents of a file
parse_file <- conceptually $(parse_str $(file_str ...)) but able to print the filename in the error
---
Note to self:
Check whether the c,v smuggling *actually* works - my hunch is that it won't, as the 'timing' of stage execution doesn't match up.
If so, rehydrate *inside* the proc macro, by adding a TokenTree:Group to the start of the TokenStream that containst the configuration and variables
Add a 'FromTokens'/'rehydrate' trait, which lets you instantiate the thing from a tokenstream
Always instantiate Configuration<T> as Configuration<DoMarker> as we won't be using this for things with new preludes
Add a 'FromTokens'-y stash as a TokenStream that the handlers will have access to; this can be used for eg code to be interpreted by an interpreter handler rather than trying to rez the whole thing from a token stream per se.
---
The environment
- configuration
* are handlers allowed
* what is the variable sigil
* what is the code sigil
* what handlers are there
* what are the 'do', 'with', and 'in' identifiers, and are 'with' and 'in' allowed
* What is the default 'with' and 'in' tokenstream?
- variables in two namespaces
* set by $ ways eg in 'with', inside a function defined in 'with' via its arg list
* set by % ways eg by a handler
Handlers
%(...) sends ... plus the environment to a handler, picked based on the first token in ...
Handlers get registered. A set of defaults provides for, if/else, etc
#[proc_macro_attribute]
fn make_do(args: TokenStream, body: TokenStream) -> TokenStream {
}
#[proc_macro]
fn do_with_in(t: TokenStream) -> TokenStream {
let mut handlers: HashMap<String,
}
Collapse into single namespace? with/in become just handlers too? Handlers return (TokenStream, Variables) and so can do things like add in new variables? Handlers are taken care of in the same place/way as variables?
What about difference between ⌜$foo(bar, Baz, [quux, n, m])⌝ vs ⌜in { }⌝ vs ⌜$(for $i in ... { })⌝ vs ⌜$(if $i is empty { } else { })⌝?
What if I make it all $(foo bar baz quux)
No, lets just have
$a for simple substitutions, and $(a ...) for a(...)=...
fn each_with_variable_maker(args: ArgList, body: Body) -> Handler {
|c: Configuration, v: Variables, t: TokenStream| {
(v, t)
}
}