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 13 import devol.type; 14 import devol.argument; 15 import devol.line; 16 import devol.world; 17 import devol.individ; 18 19 enum ArgsStyle 20 { 21 CLASSIC_STYLE, 22 MASS_STYLE, 23 BINAR_STYLE, 24 UNAR_STYLE, 25 NULAR_STYLE, 26 CONTROL_STYLE 27 } 28 29 struct ArgInfo 30 { 31 Type type; 32 string[] exVals; 33 string min; 34 string max; 35 } 36 37 abstract class Operator 38 { 39 this(string name, string discr, ArgsStyle style) 40 { 41 sName = name; 42 sDiscr = discr; 43 mStyle = style; 44 45 args = new ArgInfo[0]; 46 47 assert(mRetType,"Return type isn't setted!"); 48 } 49 50 @property int argsNumber() 51 { 52 return cast(uint)(args.length); 53 } 54 55 @property ArgsStyle style() 56 { 57 return mStyle; 58 } 59 60 @property string name() 61 { 62 return sName; 63 } 64 65 @property string disrc() 66 { 67 return sDiscr; 68 } 69 70 @property Type rtype() 71 { 72 return mRetType; 73 } 74 75 ArgInfo opIndex( uint i ) 76 { 77 return args[i]; 78 } 79 80 ArgInfo[] opSlice( uint a, uint b ) 81 { 82 return args[a..b]; 83 } 84 85 uint opDollar() 86 { 87 return cast(uint)(args.length); 88 } 89 90 int opApply(int delegate(ref ArgInfo) dg) 91 { 92 int result = 0; 93 94 foreach( i, ref arg; args) 95 { 96 result = dg(arg); 97 if (result) break; 98 } 99 return result; 100 } 101 102 Argument generateArg( uint i ) 103 { 104 auto ainfo = args[i]; 105 return ainfo.type.getNewArg(ainfo.min, ainfo.max, ainfo.exVals); 106 } 107 108 Argument apply(IndAbstract ind, Line line, WorldAbstract world) 109 in 110 { 111 assert( line.length == args.length, text("Critical error: operator ", name, ", geted args count is ", line.length, " but needed ", args.length, "!")); 112 foreach(i,ai; args) 113 { 114 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, "!")); 115 } 116 } 117 out(result) 118 { 119 assert( result !is null, text("Critical error: operator ", name, ", return value is null! Forgeted to overload std apply?")); 120 } 121 body 122 { 123 return null; 124 } 125 126 protected: 127 ArgInfo[] args; 128 ArgsStyle mStyle; 129 string sName; 130 string sDiscr; 131 Type mRetType; 132 }