1 /**
2 *   Copyright: © 2012-2014 Anton Gushcha
3 *   License: Subject to the terms of the MIT license, as written in the included LICENSE file.
4 *   Authors:  NCrashed <ncrashed@gmail.com>,
5 *             LeMarwin <lemarwin42@gmail.com>,
6 *             Nazgull09 <nazgull90@gmail.com>
7 */
8 module devol.std.argscope;
9 
10 import std.conv;
11 import std.random;
12 import std.algorithm;
13 
14 import devol.std.container;
15 import devol.std.random;
16 import devol.std.typescope;
17 
18 import devol.line;
19 
20 class ArgScope : Container
21 {
22 	private Line[] lines;
23 	
24 	this(Type t)
25 	{
26 		lines = new Line[0];
27 		super( t );
28 	}
29 
30 	override @property string tostring(uint depth=0)
31 	{
32 		string ret = "";
33 		
34 		foreach( l; lines )
35 		{
36 			ret ~= l.tostring(depth) ~ to!char(0x0A);
37 		}
38 		
39 		return ret;
40 	}
41 
42 	override void randomChange()
43 	{
44 		
45 	}
46 	
47 	override void randomChange(string maxChange)
48 	{
49 		
50 	}
51 	
52 	override Argument getRandomElement()
53 	{
54 		return lines[uniform(0, lines.length)];
55 	}
56 	
57 	override Argument getRandomElement(double[] chances)
58 	{
59 		Argument ret;
60 		randomRange!(
61 			(int k)
62 			{
63 				ret = lines[k];
64 			}
65 			)(chances[0..lines.length]);
66 		return ret;
67 	}
68 	
69 	override void replaceRandomElement(Argument narg)
70 	{
71 		if (cast(Line)(narg) is null) return;
72 		lines[uniform(0, lines.length)] = cast(Line)(narg);
73 	}
74 	
75 	override void replaceRandomElement(double[] chances, Argument narg)
76 	{
77 		if (cast(Line)(narg) is null) return;
78 		randomRange!(
79 			(int k)
80 			{
81 				lines[k] = cast(Line)(narg);
82 			}
83 			)(chances[0..lines.length]);		
84 	}
85 	
86 	override void replaceRandomElement(Argument delegate(Type t) del)
87 	{
88 		auto i = uniform(0, lines.length);
89 		Line l = cast(Line)del( lines[i].operator.rtype );
90 		if (l !is null)
91 			lines[ i ] = l;
92 	}
93 	
94 	override void replaceRandomElement(Argument delegate(Type t) del, double[] chances)
95 	{
96 		randomRange!((int k)
97 			{
98 				Line l = cast(Line)del( lines[k].operator.rtype );
99 				if (l !is null)
100 					lines[k] = l;
101 			})(chances[0..lines.length]);		
102 	}
103 	
104 	override Argument getRandomLeaf()
105 	{
106 		return null;
107 	}
108 	
109 	override Argument getRandomLeaf(double[] chances)
110 	{
111 		return null;
112 	}
113 	
114 	override uint getLeafCount()
115 	{
116 		return 0;
117 	}
118 	
119 	override void addElement( Argument arg )
120 	{
121 		auto l = cast(Line)arg;
122 		if (l is null) return;
123 		lines ~= l;
124 	}
125 	
126 	override void removeElement(int i)
127 	{
128 		if (i>0 && i<lines.length) return;
129 		lines.remove(i);
130 	}
131 	
132 	override void removeAll()
133 	{
134 		lines.clear();
135 	}
136 
137 
138 	override Line opIndex( uint i )
139 	{
140 		return lines[i];
141 	}
142 	
143 	int opApply(int delegate(Line) dg)
144 	{
145 		int result = 0;
146 		
147 		foreach( i, l; lines)
148 		{
149 			result = dg(l);
150 			if (result) break;
151 		}
152 		return result;
153 	}
154 	
155 	override int opApply(int delegate(Argument) dg)
156 	{
157 		int result = 0;
158 		
159 		foreach( i, l; lines)
160 		{
161 			result = dg(l);
162 			if (result) break;
163 		}
164 		return result;
165 	}
166 	
167 	override @property ulong children()
168 	{
169 		ulong res = 1;
170 		foreach( l; lines)
171 			res+=l.children;
172 		return res;
173 	}
174 	
175 	override @property ulong leafs()
176 	{
177 		ulong res = 0;
178 		foreach( l; lines)
179 			res+=l.children;
180 		return res;
181 	}
182 	
183 	override @property Argument dup()
184 	{
185 		auto dscope = new ArgScope(type);
186 		
187 		foreach(l; lines)
188 			dscope.lines ~= l.dup();
189 			
190 		return dscope;
191 	}
192 	
193 	override void opIndexAssign( Argument val, uint i )
194 	{
195 		auto l = cast(Line)(val);
196 		if (l !is null)
197 			lines[i] = l;
198 	}
199 	
200 	override Argument[] opSlice( uint a, uint b )
201 	{
202 		return cast(Argument[])lines[a .. b];
203 	}
204 	
205 	override uint opDollar()
206 	{
207 		return cast(uint)lines.length;
208 	}
209 	
210 	override @property uint length()
211 	{
212 		return cast(uint)lines.length;
213 	}
214 }