On Sat, Mar 01, 2003 at 09:22:35PM +0000, Simon Jenkins wrote: > [EMAIL PROTECTED] wrote: > > >>>is it in C ? > >>> > >>> > >>> > >>Yes, but you'll have to excuse the "accent". > >> > >> > > > >:-) where did you get that accent from ? > >the only functional langage i know is python and > >i use it imperative most of the time... > > > > > Stuff like the brackets in... > #define WHATEVER (6) > is habit due to having a very defensive coding standard at work.
well i dont consider this an accent... i find your macros for accessing the RecursionInfo struct a little strange :) but after getting accustomed to these they should provide better readability... > The functional stuff is where the code gets heavily recursive: First a > recursive descent parser to parse the structure of the .amble files, then > a recursive "expansion" which turns a graph containing subgraphs > containing sub-subgraphs (etc) into one giant, flat graph which only > contains the real components. ok... this is nice for the task amble is designed for... in galan the user builds the net incrementally while its running. expansion would only be useful for loading a sheet containing references to other sheets (which is currently not implemented) galan files are only static :( > > The weird stuff is experimentation. which stuff do you mean ? > > >>The graph ordering part of it is messily entwined with the rest of it > >>though, and its poorly structured: I didn't know the correct way to > >>structure it until after I'd finished. (That being part of the point > >>of doing it). > >> > >> > > > >had a 10 minute glance on the code but did not understand yet... > > > >Is the ordering done only in CalculateRenderOrder ? > > > >what does the Graph expansion do ? > > > What happens is this: > 1) ambLoadModule parses the .amble file. > > 2) Graph expansion recursively blows up the graph-to-render into a > big flat graph containing nothing but the "real" (ie code) components. > As it does so, it generates the mangled names that will be used > during code generation to make every instance of a code component > unique. > > 3) CalculateRenderOrder sorts the graph (ie the big, flat, expanded > graph). There's nothing special about the sorting to deal with the > nesting, its all expanded out before CalculateRenderOrder sees it. yeah this is nice. > > 4) ambGenerateCode generates the code from the render order, > substituting the mangled names for the placeholders that were > in the original CFRAG {{ }} sections of the .amble file. > > The placeholders in the CFRAG {{ }} sections are... > In:xxxx input > Out:xxxx output > Mv:xxxx member variable > Sv:xxxx shared variable > Def:xxxx definition i am missing Ctl:xxxx for controling the net from the outside... (ie not an input buffer but only one value) but i could be mistaken and it could be modeled with input.. > > >>I'm seriously thinking about neatly encapsulating the graph > >>ordering algorithm, extending it to address concerns which > >>other apps might have but which amble doesn't, making sure > >>it actually is correct, and releasing it as an LGPL library. > >> > >> > > > >i'd be your first client... > >if it also did the tmp var allocation :) > > > erm... amble cheats and leaves var allocation to the C compiler. It > just generates a local var for every output and lets the compiler > optimise most of them away. The only special handling is when > an output is the beginning of a feedback path, in which case amble > generates a static local var so the previous value persists between > calls to the process function. i would have done that too... > > >let me think about an API which would fit my needs... > >to be continued... > > > I'd definitely like to see people's thoughts on an API. I liked the > style of encapsulation used in ssm but a C++ interface, especially > with STL on top, might prevent a lot of people from considering it. > Better a C library and a C++ wrapper for it. (Or a C++ library with > a C callable interface? It would be nice to use STL on the inside, its > just exposing it on the outside that I'm worried about). well i am glib fan... gives me hashes, relations, lists, gasyncqueue... all i need... ok ... now to the API... lets first sum up the input we have: we have a set of components C two sets of Inputs I and Outputs O two functions ci: I -> C co: O -> C one relation conn: I <-^-> O and a set of root components which is subset of C. (are these ordered ?) the goal is: find the correct order of C which is a list. the only check we need is equality here so the elements of the sets could very well be pointers. (or better references but this would forbid using void *, which i consider a feature here) co is evaluated inversely so we need it to be a relation also. but it might be ok to convert it to a relation before traversing. i will leave it a hash for now. ci is a hash. so how about something like this: GList *get_ordered_list( GHashTable *ci, GHashTable *co, GRelation *conn, GList *roots ); the roots could also be a Hashtable i dont know if using glib is ok though... for gtk programms it would. i know that glib is not as justified as STL but i see it as the STL for C. now lets make the tuple (ci, co, conn, root) a struct Graph. these seem to be the trivial functions for maintaining the graph: Graph *graph_new( void ); void graph_free( Graph * ); void graph_add_comp( Graph *self, GHashTable *ins, GHashTable *outs ); void graph_add_root( Grapth *self, Component *root ); void graph_remove_comp( Graph *self, Component *comp ); void graph_remove_root( Graph *self, Component *root ); void graph_connect( Graph *self, Output *output, Input *input ); void graph_unconnect( Graph *self, Output *output, Input *input ); GList *graph_get_ordered_list( Graph *self ); in the struct graph there could be some more state which saves the diffs to the graph since the last call to get_ordered_list perhaps making it possible to calculate the new ordered list faster the fact that co is a relation could be hidden in there also. -- torben Hohn http://galan.sourceforge.net -- The graphical Audio language