1 |
root |
1.1 |
/* |
2 |
|
|
* representation of l-systems and their evaluation |
3 |
|
|
* |
4 |
|
|
* the order of definitions here is the most crucial I've ever encountered |
5 |
|
|
* => maybe this indicates design problem? |
6 |
|
|
*/ |
7 |
|
|
|
8 |
|
|
#ifndef lsys_h |
9 |
|
|
#define lsys_h |
10 |
|
|
|
11 |
|
|
#include <set> |
12 |
|
|
#include <map> |
13 |
|
|
|
14 |
|
|
#include <vector> |
15 |
|
|
#include <string> |
16 |
|
|
#include <sstream> |
17 |
|
|
#include <cstdio> |
18 |
|
|
#include <list> |
19 |
|
|
#include <string> |
20 |
|
|
|
21 |
|
|
#include "util.h" |
22 |
|
|
|
23 |
|
|
//#include <tr1/unordered_set> |
24 |
|
|
|
25 |
|
|
#if 0 |
26 |
|
|
template<> |
27 |
|
|
struct hash<string> |
28 |
|
|
{ |
29 |
|
|
size_t operator()(const string &s) const t_no |
30 |
|
|
{ |
31 |
|
|
size_t h = 0; |
32 |
|
|
|
33 |
|
|
for(string::const_iterator i = s.begin (); i != s.end (); ++i) |
34 |
|
|
h = h*5 + *i; |
35 |
|
|
|
36 |
|
|
return h; |
37 |
|
|
} |
38 |
|
|
}; |
39 |
|
|
#endif |
40 |
|
|
|
41 |
|
|
#define hash_map map |
42 |
|
|
|
43 |
|
|
struct file_pos { |
44 |
|
|
string path; |
45 |
|
|
int line; |
46 |
|
|
int col; |
47 |
|
|
|
48 |
|
|
file_pos (const string &p = string (), int l = -1, int c = -1) t_no |
49 |
|
|
: path(p), line(l), col(c) {}; |
50 |
|
|
}; |
51 |
|
|
|
52 |
|
|
template<typename T> |
53 |
|
|
struct auto_vec : shared_vector<T> { |
54 |
|
|
const T &first () const t_no { return shared< vector<T> >::obj->front (); }; |
55 |
|
|
const T &second() const t_no { return shared< vector<T> >::obj->operator[](1); }; |
56 |
|
|
const T &third () const t_no { return shared< vector<T> >::obj->operator[](2); }; |
57 |
|
|
const T &fourth() const t_no { return shared< vector<T> >::obj->operator[](3); }; |
58 |
|
|
}; |
59 |
|
|
|
60 |
|
|
typedef auto_vec<module> module_vec; |
61 |
|
|
|
62 |
|
|
struct module : module_vec { |
63 |
|
|
double num; |
64 |
|
|
string str; |
65 |
|
|
int is_expr:1; |
66 |
|
|
int is_num:1; |
67 |
|
|
|
68 |
|
|
file_pos where; |
69 |
|
|
|
70 |
|
|
module() t_no |
71 |
|
|
: is_expr(0), is_num(0) { }; |
72 |
|
|
module(double d) t_no |
73 |
|
|
: num(d), is_expr(0), is_num(1) { char s[79]; sprintf (s, "%g", d); str = s; }; |
74 |
|
|
module(const string &n) t_no |
75 |
|
|
: str(n), is_expr(0), is_num(0) { }; |
76 |
|
|
module(const string &n, const module &arg1) t_no |
77 |
|
|
: str(n), is_expr(0), is_num(0) { push_back (arg1); }; |
78 |
|
|
module(const string &n, const module &arg1, const module &arg2) t_no |
79 |
|
|
: str(n), is_expr(0), is_num(0) { push_back (arg1); push_back (arg2); }; |
80 |
|
|
|
81 |
|
|
module_vec wrap () const t_no |
82 |
|
|
{ module_vec w; w.push_back (*this); return w; }; |
83 |
|
|
|
84 |
|
|
void erase () t_no |
85 |
|
|
{ str = ""; num = 0; is_expr = is_num = 0; module_vec::erase (); }; |
86 |
|
|
|
87 |
|
|
bool is_func (const string &func) const t_no; |
88 |
|
|
bool is_func (const string &func, double &arg1) const t_no; |
89 |
|
|
bool is_func (const string &func, string &arg1, double &arg2) const t_no; |
90 |
|
|
bool is_func (const string &func, string &arg1, string &arg2) const t_no; |
91 |
|
|
bool is_func (const string &func, string &arg1, module &arg2) const t_no; |
92 |
|
|
|
93 |
|
|
operator double() const t_err; |
94 |
|
|
operator const string &() const t_no { return str; }; |
95 |
|
|
operator string () t_no { return str; }; |
96 |
|
|
|
97 |
|
|
bool match (const module &m) const { return m.str == str && m.size () == size (); }; |
98 |
|
|
|
99 |
|
|
friend bool operator <(const module &a, const module &b) t_no; |
100 |
|
|
}; |
101 |
|
|
|
102 |
|
|
bool operator <(const module &a, const module &b) t_no; |
103 |
|
|
|
104 |
|
|
typedef map<string, module> module_map; |
105 |
|
|
typedef map<string, module&> module_ref_map; |
106 |
|
|
typedef module_vec::const_iterator module_pos; |
107 |
|
|
|
108 |
|
|
struct rule : public module { |
109 |
|
|
module_vec pre; |
110 |
|
|
module_vec post; |
111 |
|
|
module constraint; |
112 |
|
|
|
113 |
|
|
module_vec repl; |
114 |
|
|
module iterations; |
115 |
|
|
}; |
116 |
|
|
|
117 |
|
|
typedef hash_map<string, list<rule> > rule_map; |
118 |
|
|
|
119 |
|
|
struct lsys : public module { |
120 |
|
|
lsys *parent; |
121 |
|
|
hash_map<string, lsys *> sub_lsys; // "local" lsystems |
122 |
|
|
|
123 |
|
|
set<string> ignore_module; |
124 |
|
|
rule_map rules; |
125 |
|
|
module_map defines; |
126 |
|
|
|
127 |
|
|
struct arg_spec { |
128 |
|
|
string str; |
129 |
|
|
int nargs; |
130 |
|
|
int arg; |
131 |
|
|
}; |
132 |
|
|
set<arg_spec> arg_is_numeric; |
133 |
|
|
|
134 |
|
|
lsys () t_no; |
135 |
|
|
~lsys () t_no; |
136 |
|
|
|
137 |
|
|
bool match_rule (const rule &r, const module_vec &v, module_pos i, module_map &vars) const t_err; |
138 |
|
|
|
139 |
|
|
private:void mark_numeric (const map<string, arg_spec> &which, const module &v) t_no; |
140 |
|
|
public: void add_rule (rule r) t_err; |
141 |
|
|
void add_lsys (lsys *l) t_err; |
142 |
|
|
|
143 |
|
|
module expand (const module_map &c, const module &v) const t_err; |
144 |
|
|
|
145 |
|
|
bool eval (module_vec &v) const t_err; // true, if changed |
146 |
|
|
module_vec operator ()(const module_vec &v) const t_no |
147 |
|
|
{ module_vec res (v); eval (res); return res; }; |
148 |
|
|
|
149 |
|
|
public: double eval_numeric (const module &expr, module_map context) const t_err; |
150 |
|
|
}; |
151 |
|
|
|
152 |
|
|
bool operator <(const lsys::arg_spec &a, const lsys::arg_spec &b) t_no; |
153 |
|
|
|
154 |
|
|
double eval_expr (const module &expr, |
155 |
|
|
const module_map &locals = module_map (), |
156 |
|
|
const module_map &globals = module_map ()) t_err; |
157 |
|
|
|
158 |
|
|
// otherwise needed a forward reference; |
159 |
|
|
inline module::operator double() const t_err |
160 |
|
|
{ return eval_expr (*this); } |
161 |
|
|
|
162 |
|
|
ostream &operator <<(ostream &o, const file_pos &p) t_no; |
163 |
|
|
ostream &operator <<(ostream &o, const module_vec &v) t_no; |
164 |
|
|
ostream &operator <<(ostream &o, const module &m) t_no; |
165 |
|
|
ostream &operator <<(ostream &o, const rule &r) t_no; |
166 |
|
|
ostream &operator <<(ostream &o, const lsys &l) t_no; |
167 |
|
|
|
168 |
|
|
#endif |