339
|
1 /*
|
|
2 lwval.c
|
|
3 Copyright © 2008 William Astle
|
|
4
|
|
5 This file is part of LWASM.
|
|
6
|
|
7 LWASM is free software: you can redistribute it and/or modify it under the
|
|
8 terms of the GNU General Public License as published by the Free Software
|
|
9 Foundation, either version 3 of the License, or (at your option) any later
|
|
10 version.
|
|
11
|
|
12 This program is distributed in the hope that it will be useful, but WITHOUT
|
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
15 more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License along with
|
|
18 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
19 */
|
|
20
|
|
21 /*
|
|
22 This file contains implementations associated with the expression evaluator
|
|
23 used by LWASM.
|
|
24
|
|
25 */
|
|
26 #include <config.h>
|
|
27
|
|
28 #include <malloc.h>
|
|
29
|
|
30 #define __lwval_c_seen__
|
|
31 #include "lwval.h"
|
|
32
|
|
33 LWVAL *lwval_construct_int(int value)
|
|
34 {
|
|
35 LWVAL *v;
|
|
36
|
|
37 v = malloc(sizeof(LWVAL));
|
|
38 if (!v)
|
|
39 return NULL;
|
|
40
|
|
41 v -> lwval_type = LWVAL_TYPE_INT;
|
|
42 v -> dt.lwval_int = value;
|
|
43
|
|
44 return v;
|
|
45 }
|
|
46
|
|
47 LWVAL *lwval_construct_err(int errno)
|
|
48 {
|
|
49 LWVAL *v;
|
|
50
|
|
51 v = malloc(sizeof(LWVAL));
|
|
52 if (!v)
|
|
53 return NULL;
|
|
54
|
|
55 v -> lwval_type = LWVAL_TYPE_ERR;
|
|
56 v -> dt.lwval_int = errno;
|
|
57
|
|
58 return v;
|
|
59 }
|
|
60
|
|
61 LWVAL *lwval_construct_nan(void)
|
|
62 {
|
|
63 LWVAL *v;
|
|
64
|
|
65 v = malloc(sizeof(LWVAL));
|
|
66 if (!v)
|
|
67 return NULL;
|
|
68
|
|
69 v -> lwval_type = LWVAL_TYPE_NAN;
|
|
70
|
|
71 return v;
|
|
72 }
|
|
73
|
|
74 LWVAL *lwval_construct_undef(void)
|
|
75 {
|
|
76 LWVAL *v;
|
|
77
|
|
78 v = malloc(sizeof(LWVAL));
|
|
79 if (!v)
|
|
80 return NULL;
|
|
81
|
|
82 v -> lwval_type = LWVAL_TYPE_UNDEF;
|
|
83
|
|
84 return v;
|
|
85 }
|
|
86
|
|
87 LWVAL *lwval_construct_expr(LWVAL *v1, LWVAL *v2, int op)
|
|
88 {
|
|
89 LWVAL *v;
|
|
90 v = malloc(sizeof(LWVAL));
|
|
91 if (!v)
|
|
92 return NULL;
|
|
93
|
|
94 v -> lwval_type = LWVAL_TYPE_EXPR;
|
|
95 v -> dt.expr.v1 = v1;
|
|
96 v -> dt.expr.v2 = v2;
|
|
97 v -> dt.expr.op = op;
|
|
98 return v;
|
|
99 }
|
|
100
|
|
101 void lwval_destroy(LWVAL *value)
|
|
102 {
|
|
103 if (value)
|
|
104 {
|
|
105 lwval_clear(value);
|
|
106 free(value);
|
|
107 }
|
|
108 }
|
|
109
|
|
110 // performs a deep copy of an LWVAL, including ALL referenced values
|
|
111 void lwval_dup(LWVAL *v1, LWVAL *v2)
|
|
112 {
|
|
113 lwval_clear(v2);
|
|
114
|
|
115 switch (v1 -> lwval_type)
|
|
116 {
|
|
117 case LWVAL_TYPE_INT:
|
|
118 case LWVAL_TYPE_ERR:
|
|
119 v2 -> dt.lwval_int = v1 -> dt.lwval_int;
|
|
120 break;
|
|
121
|
|
122 case LWVAL_TYPE_EXPR:
|
|
123 v2 -> dt.expr.op = v1 -> dt.expr.op;
|
|
124 if (v1 -> dt.expr.v1)
|
|
125 {
|
|
126 v2 -> dt.expr.v1 = lwval_construct_undef();
|
|
127 lwval_dup(v1 -> dt.expr.v1, v2 -> dt.expr.v1);
|
|
128 }
|
|
129 else
|
|
130 v2 -> dt.expr.v1 = NULL;
|
|
131 if (v1 -> dt.expr.v2)
|
|
132 {
|
|
133 v2 -> dt.expr.v2 = lwval_construct_undef();
|
|
134 lwval_dup(v1 -> dt.expr.v2, v2 -> dt.expr.v2);
|
|
135 }
|
|
136 else
|
|
137 v2 -> dt.expr.v2 = NULL;
|
|
138 break;
|
|
139 }
|
|
140
|
|
141 v2 -> lwval_type = v1 -> lwval_type;
|
|
142 }
|
|
143
|
|
144 void lwval_clear(LWVAL *value)
|
|
145 {
|
|
146 switch (value -> lwval_type)
|
|
147 {
|
|
148 case LWVAL_TYPE_EXPR:
|
|
149 lwval_destroy(value -> dt.expr.v1);
|
|
150 lwval_destroy(value -> dt.expr.v2);
|
|
151 break;
|
|
152 }
|
|
153 value -> lwval_type = LWVAL_TYPE_UNDEF;
|
|
154 }
|
|
155
|
|
156 // for integer, simply negate value
|
|
157 // for expr, change to "-1 * (expr)"
|
|
158 // everything else: error
|
|
159 LWVAL *lwval_neg(LWVAL *v1)
|
|
160 {
|
|
161 switch (v1 -> lwval_type)
|
|
162 {
|
|
163 case LWVAL_TYPE_INT:
|
|
164 v1 -> dt.lwval_int = -(v1 -> dt.lwval_int);
|
|
165 break;
|
|
166
|
|
167 case LWVAL_TYPE_EXPR:
|
|
168 {
|
|
169 LWVAL *v, *v2;
|
|
170 v = lwval_construct_undef();
|
|
171 lwval_dup(v1, v);
|
|
172 lwval_clear(v1);
|
|
173 v2 = lwval_construct_expr(lwval_construct_int(-1), v, '*');
|
|
174 lwval_dup(v2, v1);
|
|
175 lwval_destroy(v2);
|
|
176 }
|
|
177 break;
|
|
178
|
|
179 default:
|
|
180 lwval_clear(v1);
|
|
181 v1 -> lwval_type = LWVAL_TYPE_ERR;
|
|
182 v1 -> dt.lwval_int = 1;
|
|
183 }
|
|
184
|
|
185 return v1;
|
|
186 }
|
|
187
|
|
188 // v1 + v2 -> v1
|
|
189 LWVAL *lwval_add(LWVAL *v1, LWVAL *v2)
|
|
190 {
|
|
191 }
|
|
192
|
|
193 // v1 - v2 -> v1
|
|
194 LWVAL *lwval_sub(LWVAL *v1, LWVAL *v2)
|
|
195 {
|
|
196 }
|
|
197
|
|
198 // v1 * v2 -> v1
|
|
199 LWVAL *lwval_mul(LWVAL *v1, LWVAL *v2)
|
|
200 {
|
|
201 }
|
|
202
|
|
203 // v1 / v2 -> v1
|
|
204 LWVAL *lwval_div(LWVAL *v1, LWVAL *v2)
|
|
205 {
|
|
206 }
|
|
207
|
|
208 // v1 % v2 -> v1
|
|
209 LWVAL *lwval_mod(LWVAL *v1, LWVAL *v2)
|
|
210 {
|
|
211 }
|