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 import std.stream; 14 import std.array; 15 16 import devol.std.container; 17 import devol.std.random; 18 import devol.std.typescope; 19 import devol.typemng; 20 import devol.std.line; 21 22 import dyaml.all; 23 24 class ArgScope : Container 25 { 26 private Line[] lines; 27 28 this(Type t) 29 { 30 lines = new Line[0]; 31 super( t ); 32 } 33 34 override @property string tostring(uint depth=0) 35 { 36 string ret = ""; 37 38 foreach( l; lines ) 39 { 40 ret ~= l.tostring(depth) ~ to!char(0x0A); 41 } 42 43 return ret; 44 } 45 46 override void randomChange() 47 { 48 49 } 50 51 override void randomChange(string maxChange) 52 { 53 54 } 55 56 override Argument getRandomElement() 57 { 58 return lines[uniform(0, lines.length)]; 59 } 60 61 override Argument getRandomElement(double[] chances) 62 { 63 Argument ret; 64 randomRange!( 65 (int k) 66 { 67 ret = lines[k]; 68 } 69 )(chances[0..lines.length]); 70 return ret; 71 } 72 73 override void replaceRandomElement(Argument narg) 74 { 75 if (cast(Line)(narg) is null) return; 76 lines[uniform(0, lines.length)] = cast(Line)(narg); 77 } 78 79 override void replaceRandomElement(double[] chances, Argument narg) 80 { 81 if (cast(Line)(narg) is null) return; 82 randomRange!( 83 (int k) 84 { 85 lines[k] = cast(Line)(narg); 86 } 87 )(chances[0..lines.length]); 88 } 89 90 override void replaceRandomElement(Argument delegate(Type t) del) 91 { 92 auto i = uniform(0, lines.length); 93 Line l = cast(Line)del( lines[i].operator.rtype ); 94 if (l !is null) 95 lines[ i ] = l; 96 } 97 98 override void replaceRandomElement(Argument delegate(Type t) del, double[] chances) 99 { 100 randomRange!((int k) 101 { 102 Line l = cast(Line)del( lines[k].operator.rtype ); 103 if (l !is null) 104 lines[k] = l; 105 })(chances[0..lines.length]); 106 } 107 108 override Argument getRandomLeaf() 109 { 110 return null; 111 } 112 113 override Argument getRandomLeaf(double[] chances) 114 { 115 return null; 116 } 117 118 override uint getLeafCount() 119 { 120 return 0; 121 } 122 123 override void addElement( Argument arg ) 124 { 125 auto l = cast(Line)arg; 126 if (l is null) return; 127 lines ~= l; 128 } 129 130 override void removeElement(size_t i) 131 { 132 if (i>0 && i<lines.length) return; 133 lines.remove(i); 134 } 135 136 override void removeAll() 137 { 138 lines.clear(); 139 } 140 141 142 override Line opIndex( size_t i ) 143 { 144 return lines[i]; 145 } 146 147 int opApply(int delegate(Line) dg) 148 { 149 int result = 0; 150 151 foreach( i, l; lines) 152 { 153 result = dg(l); 154 if (result) break; 155 } 156 return result; 157 } 158 159 override int opApply(int delegate(Argument) dg) 160 { 161 int result = 0; 162 163 foreach( i, l; lines) 164 { 165 result = dg(l); 166 if (result) break; 167 } 168 return result; 169 } 170 171 override @property ulong children() 172 { 173 ulong res = 1; 174 foreach( l; lines) 175 res+=l.children; 176 return res; 177 } 178 179 override @property ulong leafs() 180 { 181 if(lines.length == 0) return 1; 182 183 ulong res = 0; 184 foreach( l; lines) 185 res+=l.children; 186 return res; 187 } 188 189 override @property Argument dup() 190 { 191 auto dscope = new ArgScope(type); 192 193 foreach(l; lines) 194 dscope.lines ~= l.dup(); 195 196 return dscope; 197 } 198 199 override void opIndexAssign( Argument val, size_t i ) 200 { 201 auto l = cast(Line)(val); 202 if (l !is null) 203 lines[i] = l; 204 } 205 206 override Argument[] opSlice( size_t a, size_t b ) 207 { 208 return cast(Argument[])lines[a .. b]; 209 } 210 211 override size_t opDollar() 212 { 213 return lines.length; 214 } 215 216 override @property size_t length() 217 { 218 return lines.length; 219 } 220 221 static ArgScope loadBinary(InputStream stream) 222 { 223 ulong length; 224 stream.read(length); 225 226 auto ascope = new ArgScope(TypeMng.getSingleton().getType("TypeVoid")); 227 228 foreach(i; 0..cast(size_t)length) 229 { 230 char[] mark; 231 stream.read(mark); 232 assert(mark.idup == "line"); 233 234 ascope.addElement(Line.loadBinary(stream)); 235 } 236 return ascope; 237 } 238 239 static Argument loadYaml(Node node) 240 { 241 auto ascope = new ArgScope(TypeMng.getSingleton().getType("TypeVoid")); 242 243 foreach(Node subnode; node["lines"]) 244 { 245 ascope.addElement(Line.loadYaml(subnode)); 246 } 247 return ascope; 248 } 249 250 void saveBinary(OutputStream stream) 251 { 252 stream.write("scope"); 253 254 stream.write(cast(ulong)lines.length); 255 foreach(line; lines) 256 { 257 line.saveBinary(stream); 258 } 259 } 260 261 override Node saveYaml() 262 { 263 auto builder = appender!(Node[]); 264 foreach(line; lines) 265 { 266 builder.put(line.saveYaml()); 267 } 268 269 auto map = [ 270 "class": Node("scope") 271 ]; 272 273 if(builder.data.length > 0) 274 { 275 map["lines"] = Node(builder.data); 276 } 277 278 return Node(map); 279 } 280 281 override string genDot(ref size_t nameIndex, out string nodeName) 282 { 283 auto builder = appender!string; 284 285 nodeName = "p"~to!string(nameIndex++); 286 287 builder.put(nodeName); 288 builder.put("; \n"); 289 290 builder.put(nodeName); 291 builder.put("[label=\""); 292 builder.put("scope"); 293 builder.put("\"] ;\n"); 294 295 foreach(line; lines) 296 { 297 string lineNode; 298 builder.put(line.genDot(nameIndex, lineNode)); 299 300 builder.put(nodeName); 301 builder.put(" -> "); 302 builder.put(lineNode); 303 builder.put(";\n"); 304 } 305 306 return builder.data; 307 } 308 }