Branch data Line data Source code
1 : : /*
2 : : Copyright (c) 2010-2014 Jeremiah Martell
3 : : All rights reserved.
4 : :
5 : : Redistribution and use in source and binary forms, with or without modification,
6 : : are permitted provided that the following conditions are met:
7 : :
8 : : - Redistributions of source code must retain the above copyright notice,
9 : : this list of conditions and the following disclaimer.
10 : : - Redistributions in binary form must reproduce the above copyright notice,
11 : : this list of conditions and the following disclaimer in the documentation
12 : : and/or other materials provided with the distribution.
13 : : - Neither the name of Jeremiah Martell nor the name of GeekHorse nor the
14 : : name of Trot nor the names of its contributors may be used to endorse or
15 : : promote products derived from this software without specific prior written
16 : : permission.
17 : :
18 : : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 : : ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 : : WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 : : DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 : : ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 : : (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 : : LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 : : ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 : : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 : : SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 : : */
29 : :
30 : : /******************************************************************************/
31 : : /*!
32 : : \file
33 : : Implements the integer math logic on a list. Used when running Trot code.
34 : : */
35 : : #define TROT_FILE_NUMBER 3
36 : :
37 : : /******************************************************************************/
38 : : #include "trot.h"
39 : : #include "trotInternal.h"
40 : :
41 : : /******************************************************************************/
42 : : /*!
43 : : \brief Does an int operand on the last single or last two values in the
44 : : list.
45 : : \param[in] l List to "work" on.
46 : : \param[in] op Which operand to do.
47 : : \return TROT_RC
48 : :
49 : : l will be modified according to op.
50 : :
51 : : Example:
52 : : If l is [ 1 2 3 4 ] and op is TROT_OP_ADD then l will become:
53 : : [ 1 2 7 ]
54 : :
55 : : Example:
56 : : If l is [ 1 2 3 4 ] and op is TROT_OP_NEG then l will become:
57 : : [ 1 2 3 -4 ]
58 : : */
59 : 192 : TROT_RC trotListIntOperand( TrotList *l, TROT_OP op )
60 : : {
61 : : /* DATA */
62 : 192 : TROT_RC rc = TROT_RC_SUCCESS;
63 : :
64 : 192 : TrotListActual *la = NULL;
65 : 192 : TrotListNode *node = NULL;
66 : 192 : TROT_INT value = 0;
67 : :
68 : :
69 : : /* PRECOND */
70 [ + + ]: 192 : ERR_IF( l == NULL, TROT_RC_ERROR_PRECOND );
71 : : /* We'll catch an invalid op later on */
72 : :
73 : :
74 : : /* CODE */
75 : 191 : la = l->laPointsTo;
76 : :
77 : 191 : node = la->tail->prev;
78 : :
79 : : /* check that last value in list is an int */
80 [ + + ]: 191 : ERR_IF_1( node->kind != NODE_KIND_INT, TROT_RC_ERROR_WRONG_KIND, node->kind );
81 : :
82 : : /* handle single value ops */
83 [ + + ]: 187 : if ( op == TROT_OP_NEG )
84 : : {
85 : 2 : node->n[ (node->count) - 1 ] = (-(node->n[ (node->count) - 1 ] ) );
86 : 2 : return TROT_RC_SUCCESS;
87 : : }
88 : :
89 [ + + ]: 185 : if ( op == TROT_OP_LOGICAL_NOT )
90 : : {
91 : 4 : node->n[ (node->count) - 1 ] = ! ( node->n[ (node->count) - 1 ] );
92 : 4 : return TROT_RC_SUCCESS;
93 : : }
94 : :
95 : : /* check that second-to-last value in list is an int */
96 : : /* We technically don't have to do this here, but since we're
97 : : going to remove an int, I would rather leave the list
98 : : untouched on error. So let's catch the error here. */
99 [ + + ]: 181 : if ( node->count <= 1 )
100 : : {
101 [ + + ]: 61 : ERR_IF_1( node->prev->kind != NODE_KIND_INT, TROT_RC_ERROR_WRONG_KIND, node->prev->kind );
102 : : }
103 : :
104 : : /* remove last int */
105 : 179 : value = node->n[ (node->count) - 1 ];
106 : 179 : node->count -= 1;
107 : 179 : la->childrenCount -= 1;
108 : :
109 [ + + ]: 179 : if ( node->count == 0 )
110 : : {
111 : 59 : node->prev->next = node->next;
112 : 59 : node->next->prev = node->prev;
113 : :
114 : 59 : trotHookFree( node->n );
115 : 59 : trotHookFree( node );
116 : : }
117 : :
118 : : /* now we can call trotListIntOperandValue */
119 : 179 : rc = trotListIntOperandValue( l, op, value );
120 : :
121 : :
122 : : /* CLEANUP */
123 : : cleanup:
124 : :
125 : 192 : return rc;
126 : : }
127 : :
128 : : /******************************************************************************/
129 : : /*!
130 : : \brief Does an int operand on the last value in the list and the passed in
131 : : value.
132 : : \param[in] l Pointer to a trotList.
133 : : \param[in] op Which operand to do.
134 : : \param[in] value Value to use with the last value in the list.
135 : : \return TROT_RC
136 : :
137 : : l will be modified according to op and value.
138 : :
139 : : Example:
140 : : If l is [ 1 2 3 4 ] and op is TROT_OP_ADD and value is 5 then l will become:
141 : : [ 1 2 3 9 ]
142 : : */
143 : 360 : TROT_RC trotListIntOperandValue( TrotList *l, TROT_OP op, TROT_INT value )
144 : : {
145 : : /* DATA */
146 : 360 : TROT_RC rc = TROT_RC_SUCCESS;
147 : :
148 : 360 : TrotListActual *la = NULL;
149 : 360 : TrotListNode *node = NULL;
150 : :
151 : :
152 : : /* PRECOND */
153 [ + + ]: 360 : ERR_IF( l == NULL, TROT_RC_ERROR_PRECOND );
154 : :
155 : :
156 : : /* CODE */
157 : 359 : la = l->laPointsTo;
158 : :
159 : 359 : node = la->tail->prev;
160 : :
161 [ + + ]: 359 : ERR_IF_1( node->kind != NODE_KIND_INT, TROT_RC_ERROR_WRONG_KIND, node->kind );
162 : :
163 [ + + + + : 357 : switch ( op )
+ + + + +
+ + ]
164 : : {
165 : : case TROT_OP_ADD:
166 : 24 : node->n[ (node->count) - 1 ] += value;
167 : 24 : break;
168 : : case TROT_OP_SUB:
169 : 24 : node->n[ (node->count) - 1 ] -= value;
170 : 24 : break;
171 : : case TROT_OP_MUL:
172 : 24 : node->n[ (node->count) - 1 ] *= value;
173 : 24 : break;
174 : : case TROT_OP_DIV:
175 [ + + ]: 25 : ERR_IF( value == 0, TROT_RC_ERROR_DIVIDE_BY_ZERO );
176 : 24 : node->n[ (node->count) - 1 ] /= value;
177 : 24 : break;
178 : : case TROT_OP_MOD:
179 [ + + ]: 25 : ERR_IF( value == 0, TROT_RC_ERROR_DIVIDE_BY_ZERO );
180 : 24 : node->n[ (node->count) - 1 ] %= value;
181 : 24 : break;
182 : :
183 : : case TROT_OP_LESS_THAN:
184 : 54 : node->n[ (node->count) - 1 ] = node->n[ (node->count) - 1 ] < value;
185 : 54 : break;
186 : : case TROT_OP_GREATER_THAN:
187 : 54 : node->n[ (node->count) - 1 ] = node->n[ (node->count) - 1 ] > value;
188 : 54 : break;
189 : : case TROT_OP_EQUALS:
190 : 54 : node->n[ (node->count) - 1 ] = node->n[ (node->count) - 1 ] == value;
191 : 54 : break;
192 : :
193 : : case TROT_OP_LOGICAL_AND:
194 [ + + ][ + + ]: 36 : node->n[ (node->count) - 1 ] = node->n[ (node->count) - 1 ] && value;
195 : 36 : break;
196 : : case TROT_OP_LOGICAL_OR:
197 [ + + ][ + + ]: 36 : node->n[ (node->count) - 1 ] = node->n[ (node->count) - 1 ] || value;
198 : 36 : break;
199 : : default:
200 : 1 : ERR_IF_1( 1, TROT_RC_ERROR_INVALID_OP, op );
201 : : }
202 : :
203 : :
204 : : /* CLEANUP */
205 : : cleanup:
206 : :
207 : 360 : return rc;
208 : : }
209 : :
|