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.operator; 9 10 import std..string; 11 import std.conv; 12 import std.array; 13 14 import devol.type; 15 import devol.argument; 16 import devol.std.line; 17 import devol.world; 18 import devol.individ; 19 import devol.serializable; 20 import devol.operatormng; 21 22 import dyaml.all; 23 24 enum ArgsStyle 25 { 26 CLASSIC_STYLE, 27 MASS_STYLE, 28 BINAR_STYLE, 29 UNAR_STYLE, 30 NULAR_STYLE, 31 CONTROL_STYLE 32 } 33 34 struct ArgInfo 35 { 36 Type type; 37 string[] exVals; 38 string min; 39 string max; 40 bool eval = true; 41 } 42 43 abstract class Operator : ISerializable 44 { 45 this(string name, string discr, ArgsStyle style) 46 { 47 sName = name; 48 sDiscr = discr; 49 mStyle = style; 50 51 args = new ArgInfo[0]; 52 53 assert(mRetType,"Return type isn't set!"); 54 } 55 56 @property int argsNumber() 57 { 58 return cast(uint)(args.length); 59 } 60 61 @property ArgsStyle style() 62 { 63 return mStyle; 64 } 65 66 @property string name() 67 { 68 return sName; 69 } 70 71 @property string disrc() 72 { 73 return sDiscr; 74 } 75 76 @property Type rtype() 77 { 78 return mRetType; 79 } 80 81 ArgInfo opIndex( size_t i ) 82 { 83 return args[i]; 84 } 85 86 ArgInfo[] opSlice( size_t a, size_t b ) 87 { 88 return args[a..b]; 89 } 90 91 size_t opDollar() 92 { 93 return args.length; 94 } 95 96 int opApply(int delegate(ref ArgInfo) dg) 97 { 98 int result = 0; 99 100 foreach( i, ref arg; args) 101 { 102 result = dg(arg); 103 if (result) break; 104 } 105 return result; 106 } 107 108 Argument generateArg( size_t i ) 109 { 110 auto ainfo = args[i]; 111 return ainfo.type.getNewArg(ainfo.min, ainfo.max, ainfo.exVals); 112 } 113 114 Argument apply(IndAbstract ind, Line line, WorldAbstract world) 115 in 116 { 117 assert( line.length == args.length, text("Critical error: operator ", name, ", got args count is ", line.length, " but needed ", args.length, "!")); 118 foreach(i,ai; args) 119 { 120 assert( ai.type.name == line[0].type.name, text("Critical error: operator ", name, ", argument №", i, " is type of ", ai.type.name, " but needed ", line[0].type.name, "!")); 121 } 122 } 123 out(result) 124 { 125 assert( result !is null, text("Critical error: operator ", name, ", return value is null! Forgotten to overload std apply?")); 126 } 127 body 128 { 129 return null; 130 } 131 132 void saveBinary(OutputStream stream) 133 { 134 assert(sName != "", "Operator name is empty string!"); 135 stream.write(sName); 136 } 137 138 Node saveYaml() 139 { 140 return Node(sName); 141 } 142 143 static Operator loadBinary(InputStream stream) 144 { 145 char[] opname; 146 stream.read(opname); 147 148 return OperatorMng.getSingleton().getOperator(opname.idup); 149 } 150 151 static Operator loadYaml(Node node) 152 { 153 return OperatorMng.getSingleton().getOperator(node.as!string); 154 } 155 156 string genDot(ref size_t nameIndex, out string nodeName) 157 { 158 auto builder = appender!string; 159 nodeName = "p"~to!string(nameIndex++); 160 161 builder.put(nodeName); 162 builder.put("; \n"); 163 164 builder.put(nodeName); 165 builder.put("[label=\""); 166 builder.put(sName); 167 builder.put("\"] ;\n"); 168 169 return builder.data; 170 } 171 172 protected: 173 ArgInfo[] args; 174 ArgsStyle mStyle; 175 string sName; 176 string sDiscr; 177 Type mRetType; 178 }