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 = 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 as Configuration 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 Handler { |c: Configuration, v: Variables, t: TokenStream| { (v, t) } }