1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
2 // Licensed under the MIT License:
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 
22 module org.capnproto.benchmark.Eval;
23 
24 import capnproto.StructList;
25 import capnproto.Text;
26 
27 import capnproto.benchmark.evalschema;
28 import capnproto.benchmark.Common;
29 import capnproto.benchmark.TestCase;
30 
31 void main(string[] args)
32 {
33 	auto testCase = new Eval();
34 	testCase.execute(args);
35 }
36 
37 class Eval : TestCase!(Expression, EvaluationResult, int)
38 {
39 public: //Methods.
40 	static int makeExpression(Expression.Builder exp, int depth)
41 	{
42 		exp.setOp(operations[fastRand(Operation.modulus + 1)]);
43 		
44 		int left = 0;
45 		if(fastRand(8) < depth)
46 		{
47 			int tmp = fastRand(128) + 1;
48 			exp.getLeft().setValue(tmp);
49 			left = tmp;
50 		}
51 		else
52 			left = makeExpression(exp.getLeft().initExpression(), depth + 1);
53 		
54 		int right = 0;
55 		if(fastRand(8) < depth)
56 		{
57 			int tmp = fastRand(128) + 1;
58 			exp.getRight().setValue(tmp);
59 			right = tmp;
60 		}
61 		else
62 			right = makeExpression(exp.getRight().initExpression(), depth + 1);
63 		
64 		switch(exp.getOp())
65 		{
66 			case Operation.add:
67 				return left + right;
68 			case Operation.subtract:
69 				return left - right;
70 			case Operation.multiply:
71 				return left * right;
72 			case Operation.divide:
73 				return div(left, right);
74 			case Operation.modulus:
75 				return mod(left, right);
76 			default:
77 				throw new Error("impossible");
78 		}
79 	}
80 	
81 	static int evaluateExpression(Expression.Reader exp)
82 	{
83 		int left = 0, right = 0;
84 		
85 		switch(exp.getLeft().which())
86 		{
87 			case Expression.Left.Which.value:
88 				left = exp.getLeft().getValue();
89 				break;
90 			case Expression.Left.Which.expression:
91 				left = evaluateExpression(exp.getLeft().getExpression());
92 				break;
93 			default:
94 				break;
95 		}
96 		
97 		switch(exp.getRight().which())
98 		{
99 			case Expression.Right.Which.value:
100 				right = exp.getRight().getValue();
101 				break;
102 			case Expression.Right.Which.expression:
103 				right = evaluateExpression(exp.getRight().getExpression());
104 				break;
105 			default:
106 				break;
107 		}
108 		
109 		switch(exp.getOp())
110 		{
111 			case Operation.add:
112 				return left + right;
113 			case Operation.subtract:
114 				return left - right;
115 			case Operation.multiply:
116 				return left * right;
117 			case Operation.divide:
118 				return div(left, right);
119 			case Operation.modulus:
120 				return mod(left, right);
121 			default:
122 				throw new Error("impossible");
123 		}
124 	}
125 	
126 	override int setupRequest(Expression.Builder request)
127 	{
128 		return makeExpression(request, 0);
129 	}
130 	
131 	override void handleRequest(Expression.Reader request, EvaluationResult.Builder response)
132 	{
133 		response.setValue(evaluateExpression(request));
134 	}
135 	
136 	override bool checkResponse(EvaluationResult.Reader response, int expected)
137 	{
138 		return response.getValue() == expected;
139 	}
140 
141 private: //Variables.
142 	import std.traits : EnumMembers;
143 	static operations = [EnumMembers!Operation];
144 }