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 }