1 /*
2 * cDirectInterpretASTVisitor.cc
3 * Avida
4 *
5 * Created by David on 3/4/08.
6 * Copyright 2008-2011 Michigan State University. All rights reserved.
7 *
8 *
9 * This file is part of Avida.
10 *
11 * Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
13 *
14 * Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License along with Avida.
18 * If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include "cDirectInterpretASTVisitor.h"
23
24 #include <cassert>
25 #include <cmath>
26
27 #include "avida/Avida.h"
28 #include "AvidaScript.h"
29
30 #include "cASFunction.h"
31 #include "cStringUtil.h"
32 #include "cSymbolTable.h"
33
34 #include "tMatrix.h"
35
36 using namespace AvidaScript;
37
38
39 #ifndef DEBUG_AS_DIRECT_INTERPRET
40 #define DEBUG_AS_DIRECT_INTERPRET 1
41 #endif
42
43 #define INTERPRET_ERROR(code, ...) reportError(AS_DIRECT_INTERPRET_ERR_ ## code, node.GetFilePosition(), __LINE__, ##__VA_ARGS__)
44
45 #define TOKEN(x) AS_TOKEN_ ## x
46 #define TYPE(x) AS_TYPE_ ## x
47
48
cDirectInterpretASTVisitor(cSymbolTable * global_symtbl)49 cDirectInterpretASTVisitor::cDirectInterpretASTVisitor(cSymbolTable* global_symtbl)
50 : m_global_symtbl(global_symtbl), m_cur_symtbl(global_symtbl), m_rtype(TYPE(INVALID)), m_call_stack(0, 2048), m_sp(0)
51 , m_has_returned(false), m_obj_assign(false)
52 {
53 m_call_stack.Resize(m_global_symtbl->GetNumVariables());
54 for (int i = 0; i < m_global_symtbl->GetNumVariables(); i++) {
55 switch (m_global_symtbl->GetVariableType(i).type) {
56 case TYPE(ARRAY): m_call_stack[i].value.as_array = new cLocalArray; break;
57 case TYPE(BOOL): m_call_stack[i].value.as_bool = false; break;
58 case TYPE(CHAR): m_call_stack[i].value.as_char = 0; break;
59 case TYPE(DICT): m_call_stack[i].value.as_dict = new cLocalDict; break;
60 case TYPE(INT): m_call_stack[i].value.as_int = 0; break;
61 case TYPE(FLOAT): m_call_stack[i].value.as_float = 0.0; break;
62 case TYPE(MATRIX): m_call_stack[i].value.as_matrix = NULL; break;
63 case TYPE(STRING): m_call_stack[i].value.as_string = NULL; break;
64
65 case TYPE(OBJECT_REF):
66 m_call_stack[i].value.as_ref = NULL;
67 m_call_stack[i].type.info = m_global_symtbl->GetVariableType(i).info;
68 break;
69
70 default: break;
71 }
72 }
73 }
74
~cDirectInterpretASTVisitor()75 cDirectInterpretASTVisitor::~cDirectInterpretASTVisitor()
76 {
77 for (int i = 0; i < m_global_symtbl->GetNumVariables(); i++) {
78 ASType_t type = m_global_symtbl->GetVariableType(i).type;
79 if (type == TYPE(VAR)) type = m_call_stack[i].type.type;
80
81 switch (type) {
82 case TYPE(ARRAY): m_call_stack[i].value.as_array->RemoveReference(); break;
83 case TYPE(BOOL): break;
84 case TYPE(CHAR): break;
85 case TYPE(DICT): m_call_stack[i].value.as_dict->RemoveReference(); break;
86 case TYPE(INT): break;
87 case TYPE(FLOAT): break;
88 case TYPE(MATRIX): m_call_stack[i].value.as_matrix->RemoveReference(); break;
89 case TYPE(OBJECT_REF): delete m_call_stack[i].value.as_ref; break;
90 case TYPE(STRING): delete m_call_stack[i].value.as_string; break;
91 default: break;
92 }
93 }
94
95 }
96
97
Interpret(cASTNode * node)98 int cDirectInterpretASTVisitor::Interpret(cASTNode* node)
99 {
100 node->Accept(*this);
101
102 if (m_has_returned) return asInt(m_rtype, m_rvalue, *node);
103
104 return 0;
105 }
106
107
VisitAssignment(cASTAssignment & node)108 void cDirectInterpretASTVisitor::VisitAssignment(cASTAssignment& node)
109 {
110 cSymbolTable* symtbl = node.IsVarGlobal() ? m_global_symtbl : m_cur_symtbl;
111 int sp = node.IsVarGlobal() ? 0 : m_sp;
112 int var_id = node.GetVarID();
113
114 node.GetExpression()->Accept(*this);
115
116 switch (symtbl->GetVariableType(var_id).type) {
117 case TYPE(BOOL): m_call_stack[sp + var_id].value.as_bool = asBool(m_rtype, m_rvalue, node); break;
118 case TYPE(CHAR): m_call_stack[sp + var_id].value.as_char = asChar(m_rtype, m_rvalue, node); break;
119 case TYPE(FLOAT): m_call_stack[sp + var_id].value.as_float = asFloat(m_rtype, m_rvalue, node); break;
120 case TYPE(INT): m_call_stack[sp + var_id].value.as_int = asInt(m_rtype, m_rvalue, node); break;
121
122 case TYPE(OBJECT_REF):
123 m_call_stack[sp + var_id].value.as_nobj->RemoveReference();
124 m_call_stack[sp + var_id].value.as_nobj = asNativeObject(symtbl->GetVariableType(var_id).info, m_rtype, m_rvalue, node);
125
126 case TYPE(VAR):
127 m_call_stack[sp + var_id].value = m_rvalue;
128 m_call_stack[sp + var_id].type = m_rtype;
129 break;
130
131 case TYPE(ARRAY):
132 m_call_stack[sp + var_id].value.as_array->RemoveReference();
133 m_call_stack[sp + var_id].value.as_array = asArray(m_rtype, m_rvalue, node);
134 break;
135
136
137 case TYPE(DICT):
138 m_call_stack[sp + var_id].value.as_dict->RemoveReference();
139 m_call_stack[sp + var_id].value.as_dict = asDict(m_rtype, m_rvalue, node);
140 break;
141
142
143 case TYPE(MATRIX):
144 m_call_stack[sp + var_id].value.as_matrix->RemoveReference();
145 m_call_stack[sp + var_id].value.as_matrix = asMatrix(m_rtype, m_rvalue, node);
146 break;
147
148 case TYPE(STRING):
149 delete m_call_stack[sp + var_id].value.as_string;
150 m_call_stack[sp + var_id].value.as_string = asString(m_rtype, m_rvalue, node);
151 break;
152
153 default:
154 INTERPRET_ERROR(INTERNAL);
155 }
156 }
157
158
VisitArgumentList(cASTArgumentList & node)159 void cDirectInterpretASTVisitor::VisitArgumentList(cASTArgumentList& node)
160 {
161 // Should never recurse into here. Argument lists are processed by their owners as needed.
162 INTERPRET_ERROR(INTERNAL);
163 }
164
165
VisitObjectAssignment(cASTObjectAssignment & node)166 void cDirectInterpretASTVisitor::VisitObjectAssignment(cASTObjectAssignment& node)
167 {
168 m_obj_assign = true;
169 node.GetTarget()->Accept(*this);
170 m_obj_assign = false;
171 cObjectRef* obj = m_rvalue.as_ref;
172
173 node.GetExpression()->Accept(*this);
174
175 sAggregateValue val(m_rtype, m_rvalue);
176 if (!obj->Set(val)) {
177 val.Cleanup();
178 INTERPRET_ERROR(OBJECT_ASSIGN_FAIL);
179 }
180 }
181
182
183
VisitReturnStatement(cASTReturnStatement & node)184 void cDirectInterpretASTVisitor::VisitReturnStatement(cASTReturnStatement& node)
185 {
186 node.GetExpression()->Accept(*this);
187 m_has_returned = true;
188 }
189
190
VisitStatementList(cASTStatementList & node)191 void cDirectInterpretASTVisitor::VisitStatementList(cASTStatementList& node)
192 {
193 tListIterator<cASTNode> it = node.Iterator();
194
195 cASTNode* stmt = NULL;
196 while (!m_has_returned && (stmt = it.Next())) {
197 stmt->Accept(*this);
198 }
199 }
200
201
202
VisitForeachBlock(cASTForeachBlock & node)203 void cDirectInterpretASTVisitor::VisitForeachBlock(cASTForeachBlock& node)
204 {
205 int var_id = node.GetVariable()->GetVarID();
206 sASTypeInfo var_type = node.GetVariable()->GetType();
207
208 node.GetValues()->Accept(*this);
209 cLocalArray* arr = asArray(m_rtype, m_rvalue, node);
210
211 int var_idx = m_sp + var_id;
212 for (int i = 0; i < arr->GetSize(); i++) {
213 // Set the variable value for this iteration
214 const sAggregateValue& val = arr->Get(i);
215 switch (var_type.type) {
216 case TYPE(BOOL): m_call_stack[var_idx].value.as_bool = asBool(val.type, val.value, node); break;
217 case TYPE(CHAR): m_call_stack[var_idx].value.as_char = asChar(val.type, val.value, node); break;
218 case TYPE(FLOAT): m_call_stack[var_idx].value.as_float = asFloat(val.type, val.value, node); break;
219 case TYPE(INT): m_call_stack[var_idx].value.as_int = asInt(val.type, val.value, node); break;
220 case TYPE(OBJECT_REF):
221 m_call_stack[var_idx].value.as_nobj->RemoveReference();
222 m_call_stack[var_idx].value.as_nobj = asNativeObject(var_type.info, val.type, val.value, node);
223 break;
224
225 case TYPE(ARRAY):
226 m_call_stack[var_idx].value.as_array->RemoveReference();
227 m_call_stack[var_idx].value.as_array = asArray(val.type, val.value, node);
228 break;
229
230 case TYPE(DICT):
231 m_call_stack[var_idx].value.as_dict->RemoveReference();
232 m_call_stack[var_idx].value.as_dict = asDict(val.type, val.value, node);
233 break;
234
235 case TYPE(VAR):
236 m_call_stack[var_idx].value = val.value;
237 m_call_stack[var_idx].type = val.type;
238 break;
239
240 case TYPE(MATRIX):
241 m_call_stack[var_idx].value.as_matrix->RemoveReference();
242 m_call_stack[var_idx].value.as_matrix = asMatrix(val.type, val.value, node);
243 break;
244
245 case TYPE(STRING):
246 delete m_call_stack[var_idx].value.as_string;
247 m_call_stack[var_idx].value.as_string = asString(val.type, val.value, node);
248 break;
249
250 default:
251 INTERPRET_ERROR(INTERNAL);
252 }
253
254 // Execute the body
255 node.GetCode()->Accept(*this);
256 }
257
258 arr->RemoveReference();
259 }
260
261
VisitIfBlock(cASTIfBlock & node)262 void cDirectInterpretASTVisitor::VisitIfBlock(cASTIfBlock& node)
263 {
264 node.GetCondition()->Accept(*this);
265
266 if (asBool(m_rtype, m_rvalue, node)) {
267 node.GetCode()->Accept(*this);
268 } else {
269 bool exec = false;
270 tListIterator<cASTIfBlock::cElseIf> it = node.ElseIfIterator();
271 cASTIfBlock::cElseIf* ei = NULL;
272 while ((ei = it.Next())) {
273 ei->GetCondition()->Accept(*this);
274 if (asBool(m_rtype, m_rvalue, node)) {
275 exec = true;
276 ei->GetCode()->Accept(*this);
277 break;
278 }
279 }
280
281 if (!exec && node.HasElse()) node.GetElseCode()->Accept(*this);
282 }
283 }
284
285
VisitWhileBlock(cASTWhileBlock & node)286 void cDirectInterpretASTVisitor::VisitWhileBlock(cASTWhileBlock& node)
287 {
288 node.GetCondition()->Accept(*this);
289 while (asBool(m_rtype, m_rvalue, node)) {
290 node.GetCode()->Accept(*this);
291 node.GetCondition()->Accept(*this);
292 }
293 }
294
295
296
VisitFunctionDefinition(cASTFunctionDefinition & node)297 void cDirectInterpretASTVisitor::VisitFunctionDefinition(cASTFunctionDefinition& node)
298 {
299 // Nothing to do here
300 }
301
302
VisitVariableDefinition(cASTVariableDefinition & node)303 void cDirectInterpretASTVisitor::VisitVariableDefinition(cASTVariableDefinition& node)
304 {
305 if (node.GetAssignmentExpression()) {
306 int var_id = node.GetVarID();
307
308 node.GetAssignmentExpression()->Accept(*this);
309
310 switch (node.GetType().type) {
311 case TYPE(ARRAY): m_call_stack[m_sp + var_id].value.as_array = asArray(m_rtype, m_rvalue, node); break;
312 case TYPE(BOOL): m_call_stack[m_sp + var_id].value.as_bool = asBool(m_rtype, m_rvalue, node); break;
313 case TYPE(CHAR): m_call_stack[m_sp + var_id].value.as_char = asChar(m_rtype, m_rvalue, node); break;
314 case TYPE(DICT): m_call_stack[m_sp + var_id].value.as_dict = asDict(m_rtype, m_rvalue, node); break;
315 case TYPE(FLOAT): m_call_stack[m_sp + var_id].value.as_float = asFloat(m_rtype, m_rvalue, node); break;
316 case TYPE(INT): m_call_stack[m_sp + var_id].value.as_int = asInt(m_rtype, m_rvalue, node); break;
317 case TYPE(OBJECT_REF): m_call_stack[m_sp + var_id].value.as_nobj = asNativeObject(node.GetType().info, m_rtype, m_rvalue, node); break;
318 case TYPE(MATRIX): m_call_stack[m_sp + var_id].value.as_matrix = asMatrix(m_rtype, m_rvalue, node); break;
319 case TYPE(STRING):
320 delete m_call_stack[m_sp + var_id].value.as_string;
321 m_call_stack[m_sp + var_id].value.as_string = asString(m_rtype, m_rvalue, node);
322 break;
323
324 case TYPE(VAR):
325 m_call_stack[m_sp + var_id].value = m_rvalue;
326 m_call_stack[m_sp + var_id].type = m_rtype;
327 break;
328
329 default:
330 INTERPRET_ERROR(INTERNAL);
331 }
332 } else if (node.GetDimensions()) {
333 if (node.GetType() == TYPE(ARRAY)) {
334 cASTNode* szn = node.GetDimensions()->Iterator().Next();
335 szn->Accept(*this);
336
337 cLocalArray* arr = new cLocalArray();
338 arr->Resize(asInt(m_rtype, m_rvalue, node));
339 m_call_stack[m_sp + node.GetVarID()].value.as_array = arr;
340 } else if (node.GetType() == TYPE(MATRIX)) {
341 tListIterator<cASTNode> it = node.GetDimensions()->Iterator();
342 it.Next()->Accept(*this);
343 int sz_x = asInt(m_rtype, m_rvalue, node);
344 it.Next()->Accept(*this);
345 int sz_y = asInt(m_rtype, m_rvalue, node);
346
347 cLocalMatrix* mat = new cLocalMatrix();
348 mat->Resize(sz_x, sz_y);
349 m_call_stack[m_sp + node.GetVarID()].value.as_matrix = mat;
350 } else {
351 INTERPRET_ERROR(INTERNAL);
352 }
353 } else if (node.GetType().type == TYPE(OBJECT_REF)) {
354 // @AS_TODO - set native object ref to special NULL value
355 }
356 }
357
358
VisitVariableDefinitionList(cASTVariableDefinitionList & node)359 void cDirectInterpretASTVisitor::VisitVariableDefinitionList(cASTVariableDefinitionList& node)
360 {
361 // Should never recurse into here. Variable definition lists are processed by function definitions.
362 INTERPRET_ERROR(INTERNAL);
363 }
364
365
366
VisitExpressionBinary(cASTExpressionBinary & node)367 void cDirectInterpretASTVisitor::VisitExpressionBinary(cASTExpressionBinary& node)
368 {
369 // Process the left and right side expressions
370 node.GetLeft()->Accept(*this);
371 uAnyType lval = m_rvalue;
372 sASTypeInfo ltype = m_rtype;
373 node.GetRight()->Accept(*this);
374 uAnyType rval = m_rvalue;
375 sASTypeInfo rtype = m_rtype;
376
377
378 switch (node.GetOperator()) {
379 case TOKEN(ARR_RANGE):
380 {
381 int l = asInt(ltype, lval, node);
382 int r = asInt(rtype, rval, node);
383 int sz = abs(r - l) + 1;
384
385 cLocalArray* arr = new cLocalArray(sz);
386 uAnyType val;
387 if (r > l) {
388 for (int i = 0; i < sz; i++) {
389 val.as_int = l + i;
390 arr->Set(i, TYPE(INT), val);
391 }
392 } else {
393 for (int i = 0; i < sz; i++) {
394 val.as_int = l - i;
395 arr->Set(i, TYPE(INT), val);
396 }
397 }
398
399 m_rvalue.as_array = arr;
400 m_rtype = TYPE(ARRAY);
401 }
402 break;
403
404 case TOKEN(ARR_EXPAN):
405 {
406 int n = asInt(rtype, rval, node);
407 if (n < 0) INTERPRET_ERROR(INVALID_ARRAY_SIZE);
408
409 cLocalArray* arr = new cLocalArray(n);
410 for (int i = 0; i < n; i++) arr->Set(i, ltype.type, lval);
411
412 m_rvalue.as_array = arr;
413 m_rtype = TYPE(ARRAY);
414 }
415 break;
416
417 case TOKEN(OP_LOGIC_AND):
418 case TOKEN(OP_LOGIC_OR):
419 {
420 bool l = asBool(ltype, lval, node);
421 bool r = asBool(rtype, rval, node);
422 m_rvalue.as_bool = (node.GetOperator() == TOKEN(OP_LOGIC_AND)) ? (l && r) : (l || r);
423 m_rtype = TYPE(BOOL);
424 }
425 break;
426
427 case TOKEN(OP_BIT_AND):
428 case TOKEN(OP_BIT_OR):
429 {
430 sASTypeInfo rettype = node.GetType();
431
432 // Determine the operation type if it is a runtime decision
433 if (rettype == TYPE(RUNTIME)) rettype = getRuntimeType(ltype.type, rtype.type);
434
435 if (rettype == TYPE(CHAR)) {
436 int l = asChar(ltype, lval, node);
437 int r = asChar(rtype, rval, node);
438 m_rvalue.as_char = (node.GetOperator() == TOKEN(OP_BIT_AND)) ? (l & r) : (l | r);
439 m_rtype = TYPE(CHAR);
440 } else if (rettype == TYPE(INT)) {
441 int l = asInt(ltype, lval, node);
442 int r = asInt(rtype, rval, node);
443 m_rvalue.as_int = (node.GetOperator() == TOKEN(OP_BIT_AND)) ? (l & r) : (l | r);
444 m_rtype = TYPE(INT);
445 } else {
446 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(node.GetOperator()), mapType(rettype));
447 }
448 }
449 break;
450
451 case TOKEN(OP_EQ):
452 case TOKEN(OP_NEQ):
453 {
454 ASType_t comptype = node.GetCompareType().type;
455
456 // Determine the operation type if it is a runtime decision
457 if (comptype == TYPE(RUNTIME)) comptype = getRuntimeType(ltype.type, rtype.type);
458
459 switch (comptype) {
460 case TYPE(BOOL):
461 {
462 bool l = asBool(ltype, lval, node);
463 bool r = asBool(rtype, rval, node);
464 m_rvalue.as_bool = (node.GetOperator() == TOKEN(OP_EQ)) ? (l == r) : (l != r);
465 }
466 break;
467
468 case TYPE(CHAR):
469 case TYPE(INT):
470 // Handle both char and int as integers
471 {
472 int l = asInt(ltype, lval, node);
473 int r = asInt(rtype, rval, node);
474 m_rvalue.as_bool = (node.GetOperator() == TOKEN(OP_EQ)) ? (l == r) : (l != r);
475 }
476 break;
477
478 case TYPE(FLOAT):
479 {
480 double l = asFloat(ltype, lval, node);
481 double r = asFloat(rtype, rval, node);
482 m_rvalue.as_bool = (node.GetOperator() == TOKEN(OP_EQ)) ? (l == r) : (l != r);
483 }
484 break;
485
486 case TYPE(STRING):
487 {
488 cString* l = asString(ltype, lval, node);
489 cString* r = asString(rtype, rval, node);
490 m_rvalue.as_bool = (node.GetOperator() == TOKEN(OP_EQ)) ? (*l == *r) : (*l != *r);
491 delete l;
492 delete r;
493 }
494 break;
495
496 default:
497 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(node.GetOperator()), mapType(comptype));
498 }
499
500 m_rtype = TYPE(BOOL);
501 }
502 break;
503
504 case TOKEN(OP_LE):
505 case TOKEN(OP_GE):
506 case TOKEN(OP_LT):
507 case TOKEN(OP_GT):
508 {
509 ASType_t comptype = node.GetCompareType().type;
510
511 // Determine the operation type if it is a runtime decision
512 if (comptype == TYPE(RUNTIME)) comptype = getRuntimeType(ltype.type, rtype.type);
513
514 switch (comptype) {
515 case TYPE(CHAR):
516 case TYPE(INT):
517 // Handle both char and int as integers
518 {
519 int l = asInt(ltype, lval, node);
520 int r = asInt(rtype, rval, node);
521 switch (node.GetOperator()) {
522 case TOKEN(OP_LE): m_rvalue.as_bool = (l <= r); break;
523 case TOKEN(OP_GE): m_rvalue.as_bool = (l >= r); break;
524 case TOKEN(OP_LT): m_rvalue.as_bool = (l < r); break;
525 case TOKEN(OP_GT): m_rvalue.as_bool = (l > r); break;
526 default: INTERPRET_ERROR(INTERNAL);
527 }
528 }
529 break;
530
531 case TYPE(FLOAT):
532 {
533 double l = asFloat(ltype, lval, node);
534 double r = asFloat(rtype, rval, node);
535 switch (node.GetOperator()) {
536 case TOKEN(OP_LE): m_rvalue.as_bool = (l <= r); break;
537 case TOKEN(OP_GE): m_rvalue.as_bool = (l >= r); break;
538 case TOKEN(OP_LT): m_rvalue.as_bool = (l < r); break;
539 case TOKEN(OP_GT): m_rvalue.as_bool = (l > r); break;
540 default: INTERPRET_ERROR(INTERNAL);
541 }
542 }
543 break;
544
545 default:
546 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(node.GetOperator()), mapType(comptype));
547 }
548
549 m_rtype = TYPE(BOOL);
550 }
551 break;
552
553
554 case TOKEN(OP_ADD):
555 {
556 ASType_t rettype = node.GetType().type;
557
558 // Determine the operation type if it is a runtime decision
559 if (rettype == TYPE(RUNTIME)) rettype = getRuntimeType(ltype.type, rtype.type, true);
560
561 switch (rettype) {
562 case TYPE(CHAR): m_rvalue.as_char = asChar(ltype, lval, node) + asChar(rtype, rval, node); break;
563 case TYPE(INT): m_rvalue.as_int = asInt(ltype, lval, node) + asInt(rtype, rval, node); break;
564 case TYPE(FLOAT): m_rvalue.as_float = asFloat(ltype, lval, node) + asFloat(rtype, rval, node); break;
565 case TYPE(MATRIX): matrixAdd(asMatrix(ltype, lval, node), asMatrix(rtype, rval, node), node); break;
566
567 case TYPE(STRING):
568 {
569 cString* l = asString(ltype, lval, node);
570 cString* r = asString(rtype, rval, node);
571 m_rvalue.as_string = new cString(*l + *r);
572 delete l;
573 delete r;
574 }
575 break;
576
577 case TYPE(ARRAY):
578 {
579 cLocalArray* l = asArray(ltype, lval, node);
580 cLocalArray* r = asArray(rtype, rval, node);
581 m_rvalue.as_array = new cLocalArray(l, r);
582 l->RemoveReference();
583 r->RemoveReference();
584 }
585 break;
586
587 default:
588 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(OP_ADD)), mapType(rettype));
589 }
590
591 m_rtype = rettype;
592 }
593 break;
594
595 case TOKEN(OP_SUB):
596 {
597 ASType_t rettype = node.GetType().type;
598
599 // Determine the operation type if it is a runtime decision
600 if (rettype == TYPE(RUNTIME)) rettype = getRuntimeType(ltype.type, rtype.type);
601
602 switch (rettype) {
603 case TYPE(CHAR): m_rvalue.as_char = asChar(ltype, lval, node) - asChar(rtype, rval, node); break;
604 case TYPE(INT): m_rvalue.as_int = asInt(ltype, lval, node) - asInt(rtype, rval, node); break;
605 case TYPE(FLOAT): m_rvalue.as_float = asFloat(ltype, lval, node) - asFloat(rtype, rval, node); break;
606 case TYPE(MATRIX): matrixSubtract(asMatrix(ltype, lval, node), asMatrix(rtype, rval, node), node); break;
607
608 default:
609 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(OP_ADD)), mapType(rettype));
610 }
611
612 m_rtype = rettype;
613 }
614 break;
615
616 case TOKEN(OP_MUL):
617 {
618 ASType_t rettype = node.GetType().type;
619
620 // Determine the operation type if it is a runtime decision
621 if (rettype == TYPE(RUNTIME)) rettype = getRuntimeType(ltype.type, rtype.type);
622
623 switch (rettype) {
624 case TYPE(CHAR): m_rvalue.as_char = asChar(ltype, lval, node) * asChar(rtype, rval, node); break;
625 case TYPE(INT): m_rvalue.as_int = asInt(ltype, lval, node) * asInt(rtype, rval, node); break;
626 case TYPE(FLOAT): m_rvalue.as_float = asFloat(ltype, lval, node) * asFloat(rtype, rval, node); break;
627 case TYPE(MATRIX): matrixMultiply(asMatrix(ltype, lval, node), asMatrix(rtype, rval, node), node); break;
628
629 default:
630 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(OP_ADD)), mapType(rettype));
631 }
632
633 m_rtype = rettype;
634 }
635 break;
636
637 case TOKEN(OP_DIV):
638 {
639 ASType_t rettype = node.GetType().type;
640
641 // Determine the operation type if it is a runtime decision
642 if (rettype == TYPE(RUNTIME)) rettype = getRuntimeType(ltype.type, rtype.type);
643
644 switch (rettype) {
645 case TYPE(CHAR):
646 {
647 char r = asChar(rtype, rval, node);
648 if (r == 0) INTERPRET_ERROR(DIVISION_BY_ZERO);
649 m_rvalue.as_char = asChar(ltype, lval, node) / r;
650 }
651 break;
652 case TYPE(INT):
653 {
654 int r = asInt(rtype, rval, node);
655 if (r == 0) INTERPRET_ERROR(DIVISION_BY_ZERO);
656 m_rvalue.as_int = asInt(ltype, lval, node) / r;
657 }
658 break;
659 case TYPE(FLOAT):
660 {
661 double r = asFloat(rtype, rval, node);
662 if (r == 0.0) INTERPRET_ERROR(DIVISION_BY_ZERO);
663 m_rvalue.as_float = asFloat(ltype, lval, node) / r;
664 }
665 break;
666
667 default:
668 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(OP_ADD)), mapType(rettype));
669 }
670
671 m_rtype = rettype;
672 }
673 break;
674
675 case TOKEN(OP_MOD):
676 {
677 ASType_t rettype = node.GetType().type;
678
679 // Determine the operation type if it is a runtime decision
680 if (rettype == TYPE(RUNTIME)) rettype = getRuntimeType(ltype.type, rtype.type);
681
682 switch (rettype) {
683 case TYPE(CHAR):
684 {
685 char r = asChar(rtype, rval, node);
686 if (r == 0) INTERPRET_ERROR(DIVISION_BY_ZERO);
687 m_rvalue.as_char = asChar(ltype, lval, node) % r;
688 }
689 break;
690 case TYPE(INT):
691 {
692 int r = asInt(rtype, rval, node);
693 if (r == 0) INTERPRET_ERROR(DIVISION_BY_ZERO);
694 m_rvalue.as_int = asInt(ltype, lval, node) % r;
695 }
696 break;
697 case TYPE(FLOAT):
698 {
699 double r = asFloat(rtype, rval, node);
700 if (r == 0.0) INTERPRET_ERROR(DIVISION_BY_ZERO);
701 m_rvalue.as_float = fmod(asFloat(ltype, lval, node), r);
702 }
703 break;
704
705 default:
706 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(OP_ADD)), mapType(rettype));
707 }
708
709 m_rtype = rettype;
710 }
711 break;
712
713 case TOKEN(IDX_OPEN):
714 if (m_obj_assign) {
715 cObjectRef* obj = lval.as_ref;
716 sAggregateValue idx(rtype, rval);
717 sAggregateValue o_val;
718
719 if (!obj->Get(o_val)) {
720 idx.Cleanup();
721 INTERPRET_ERROR(INDEX_ERROR);
722 }
723
724 switch (o_val.type.type) {
725 case TYPE(ARRAY):
726 case TYPE(DICT):
727 case TYPE(MATRIX):
728 case TYPE(STRING):
729 break;
730
731 default:
732 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(IDX_OPEN)), mapType(o_val.type));
733 }
734
735 m_rvalue.as_ref = new cObjectIndexRef(obj, idx);
736 m_rtype = TYPE(OBJECT_REF);
737 } else {
738
739 switch (ltype.type) {
740 case TYPE(ARRAY):
741 {
742 cLocalArray* arr = lval.as_array;
743 int idx = asInt(rtype, rval, node);
744
745 if (idx < 0 || idx >= arr->GetSize()) INTERPRET_ERROR(INDEX_OUT_OF_BOUNDS);
746
747 const sAggregateValue val = arr->Get(idx);
748 m_rtype = val.type;
749 m_rvalue = val.value;
750
751 arr->RemoveReference();
752 }
753 break;
754
755 case TYPE(DICT):
756 {
757 cLocalDict* dict = lval.as_dict;
758 sAggregateValue idx(rtype, rval);
759
760 sAggregateValue val;
761 if (!dict->Get(idx, val)) {
762 idx.Cleanup();
763 INTERPRET_ERROR(KEY_NOT_FOUND);
764 }
765
766 idx.Cleanup();
767
768 m_rtype = val.type;
769 m_rvalue = val.value;
770
771 dict->RemoveReference();
772 }
773 break;
774
775 case TYPE(MATRIX):
776 {
777 cLocalMatrix* mat = lval.as_matrix;
778 int idx = asInt(rtype, rval, node);
779
780 if (idx < 0 || idx >= mat->GetNumRows()) INTERPRET_ERROR(INDEX_OUT_OF_BOUNDS);
781
782 m_rtype = TYPE(ARRAY);
783 m_rvalue.as_array = mat->GetRow(idx);
784
785 mat->RemoveReference();
786 }
787 break;
788
789 case TYPE(STRING):
790 {
791 cString* str = lval.as_string;
792 int idx = asInt(rtype, rval, node);
793 if (idx < 0 || idx >= str->GetSize()) INTERPRET_ERROR(INDEX_OUT_OF_BOUNDS);
794
795 m_rtype = TYPE(CHAR);
796 m_rvalue.as_char = (*str)[idx];
797 delete str;
798 }
799 break;
800
801 default:
802 INTERPRET_ERROR(TYPE_CAST, mapType(ltype.type), mapType(TYPE(ARRAY)));
803 }
804
805
806 }
807 break;
808
809 default:
810 // Parser should not allow an invalid operator to pass
811 INTERPRET_ERROR(INTERNAL);
812 }
813 }
814
815
VisitExpressionUnary(cASTExpressionUnary & node)816 void cDirectInterpretASTVisitor::VisitExpressionUnary(cASTExpressionUnary& node)
817 {
818 node.GetExpression()->Accept(*this);
819
820 switch (node.GetOperator()) {
821 case TOKEN(OP_BIT_NOT):
822 switch (m_rtype.type) {
823 case TYPE(CHAR):
824 m_rvalue.as_char = ~m_rvalue.as_char;
825 break;
826 case TYPE(INT):
827 m_rvalue.as_int = ~m_rvalue.as_int;
828 break;
829
830 default:
831 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(OP_BIT_NOT)), mapType(m_rtype));
832 }
833 break;
834
835 case TOKEN(OP_LOGIC_NOT):
836 m_rvalue.as_bool = !asBool(m_rtype, m_rvalue, node);
837 m_rtype = TYPE(BOOL);
838 break;
839
840 case TOKEN(OP_SUB):
841 switch (m_rtype.type) {
842 case TYPE(CHAR):
843 m_rvalue.as_char = -m_rvalue.as_char;
844 break;
845 case TYPE(INT):
846 m_rvalue.as_int = -m_rvalue.as_int;
847 break;
848 case TYPE(FLOAT):
849 m_rvalue.as_float = -m_rvalue.as_float;
850 break;
851
852 default:
853 INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(OP_BIT_NOT)), mapType(m_rtype));
854 }
855 break;
856
857 default:
858 INTERPRET_ERROR(INTERNAL);
859 }
860 }
861
862
VisitBuiltInCall(cASTBuiltInCall & node)863 void cDirectInterpretASTVisitor::VisitBuiltInCall(cASTBuiltInCall& node)
864 {
865 cASTArgumentList* args = node.GetArguments();
866 cASTNode* trgt = node.GetTarget();
867
868 switch (node.GetBuiltIn()) {
869 case AS_BUILTIN_CAST_BOOL:
870 args->Iterator().Next()->Accept(*this);
871 m_rvalue.as_bool = asBool(m_rtype, m_rvalue, node);
872 m_rtype = TYPE(BOOL);
873 break;
874
875 case AS_BUILTIN_CAST_CHAR:
876 args->Iterator().Next()->Accept(*this);
877 m_rvalue.as_char = asChar(m_rtype, m_rvalue, node);
878 m_rtype = TYPE(CHAR);
879 break;
880
881 case AS_BUILTIN_CAST_INT:
882 args->Iterator().Next()->Accept(*this);
883 m_rvalue.as_int = asInt(m_rtype, m_rvalue, node);
884 m_rtype = TYPE(INT);
885 break;
886
887 case AS_BUILTIN_CAST_FLOAT:
888 args->Iterator().Next()->Accept(*this);
889 m_rvalue.as_float = asFloat(m_rtype, m_rvalue, node);
890 m_rtype = TYPE(FLOAT);
891 break;
892
893 case AS_BUILTIN_CAST_STRING:
894 args->Iterator().Next()->Accept(*this);
895 m_rvalue.as_string = asString(m_rtype, m_rvalue, node);
896 m_rtype = TYPE(STRING);
897 break;
898
899
900 case AS_BUILTIN_IS_ARRAY:
901 args->Iterator().Next()->Accept(*this);
902 {
903 sAggregateValue val(m_rtype, m_rvalue);
904 val.Cleanup();
905 }
906 m_rvalue.as_bool = m_rtype.type == TYPE(ARRAY);
907 m_rtype = TYPE(BOOL);
908 break;
909
910 case AS_BUILTIN_IS_BOOL:
911 args->Iterator().Next()->Accept(*this);
912 {
913 sAggregateValue val(m_rtype, m_rvalue);
914 val.Cleanup();
915 }
916 m_rvalue.as_bool = m_rtype.type == TYPE(BOOL);
917 m_rtype = TYPE(BOOL);
918 break;
919
920 case AS_BUILTIN_IS_CHAR:
921 args->Iterator().Next()->Accept(*this);
922 {
923 sAggregateValue val(m_rtype, m_rvalue);
924 val.Cleanup();
925 }
926 m_rvalue.as_bool = m_rtype.type == TYPE(CHAR);
927 m_rtype = TYPE(BOOL);
928 break;
929
930 case AS_BUILTIN_IS_DICT:
931 args->Iterator().Next()->Accept(*this);
932 {
933 sAggregateValue val(m_rtype, m_rvalue);
934 val.Cleanup();
935 }
936 m_rvalue.as_bool = m_rtype.type == TYPE(DICT);
937 m_rtype = TYPE(BOOL);
938 break;
939
940 case AS_BUILTIN_IS_INT:
941 args->Iterator().Next()->Accept(*this);
942 {
943 sAggregateValue val(m_rtype, m_rvalue);
944 val.Cleanup();
945 }
946 m_rvalue.as_bool = m_rtype.type == TYPE(INT);
947 m_rtype = TYPE(BOOL);
948 break;
949
950 case AS_BUILTIN_IS_FLOAT:
951 args->Iterator().Next()->Accept(*this);
952 {
953 sAggregateValue val(m_rtype, m_rvalue);
954 val.Cleanup();
955 }
956 m_rvalue.as_bool = m_rtype.type == TYPE(FLOAT);
957 m_rtype = TYPE(BOOL);
958 break;
959
960 case AS_BUILTIN_IS_MATRIX:
961 args->Iterator().Next()->Accept(*this);
962 {
963 sAggregateValue val(m_rtype, m_rvalue);
964 val.Cleanup();
965 }
966 m_rvalue.as_bool = m_rtype.type == TYPE(MATRIX);
967 m_rtype = TYPE(BOOL);
968 break;
969
970 case AS_BUILTIN_IS_STRING:
971 args->Iterator().Next()->Accept(*this);
972 {
973 sAggregateValue val(m_rtype, m_rvalue);
974 val.Cleanup();
975 }
976 m_rvalue.as_bool = m_rtype.type == TYPE(STRING);
977 m_rtype = TYPE(BOOL);
978 break;
979
980
981 case AS_BUILTIN_CLEAR:
982 trgt->Accept(*this);
983 if (m_rtype.type == TYPE(DICT)) {
984 m_rvalue.as_dict->Clear();
985 m_rvalue.as_dict->RemoveReference();
986 } else if (m_rtype.type == TYPE(MATRIX)) {
987 m_rvalue.as_matrix->Resize(0, 0);
988 m_rvalue.as_matrix->RemoveReference();
989 } else if (m_rtype.type == TYPE(ARRAY)) {
990 m_rvalue.as_array->Resize(0);
991 m_rvalue.as_array->RemoveReference();
992 } else {
993 INTERPRET_ERROR(UNDEFINED_TYPE_OP, "clear", mapType(m_rtype));
994 }
995 break;
996
997 case AS_BUILTIN_COPY:
998 trgt->Accept(*this);
999 if (m_rtype.type == TYPE(ARRAY)) {
1000 cLocalArray* arr = new cLocalArray(m_rvalue.as_array);
1001 m_rvalue.as_array->RemoveReference();
1002 m_rvalue.as_array = arr;
1003 } else {
1004 INTERPRET_ERROR(UNDEFINED_TYPE_OP, "copy", mapType(m_rtype));
1005 }
1006 break;
1007
1008 case AS_BUILTIN_HASKEY:
1009 trgt->Accept(*this);
1010 if (m_rtype.type == TYPE(DICT)) {
1011 cLocalDict* dict = m_rvalue.as_dict;
1012
1013 args->Iterator().Next()->Accept(*this);
1014 sAggregateValue idx(m_rtype, m_rvalue);
1015 m_rvalue.as_bool = dict->HasKey(idx);
1016 idx.Cleanup();
1017 dict->RemoveReference();
1018
1019 m_rtype = TYPE(BOOL);
1020 } else {
1021 INTERPRET_ERROR(UNDEFINED_TYPE_OP, "keys", mapType(m_rtype));
1022 }
1023 break;
1024
1025
1026 case AS_BUILTIN_KEYS:
1027 trgt->Accept(*this);
1028 if (m_rtype.type == TYPE(DICT)) {
1029 cLocalArray* arr = new cLocalArray();
1030 arr->SetWithKeys(m_rvalue.as_dict);
1031 m_rvalue.as_dict->RemoveReference();
1032 m_rvalue.as_array = arr;
1033 m_rtype = TYPE(ARRAY);
1034 } else {
1035 INTERPRET_ERROR(UNDEFINED_TYPE_OP, "keys", mapType(m_rtype));
1036 }
1037 break;
1038
1039 case AS_BUILTIN_VALUES:
1040 trgt->Accept(*this);
1041 if (m_rtype.type == TYPE(DICT)) {
1042 cLocalArray* arr = new cLocalArray();
1043 arr->SetWithValues(m_rvalue.as_dict);
1044 m_rvalue.as_dict->RemoveReference();
1045 m_rvalue.as_array = arr;
1046 m_rtype = TYPE(ARRAY);
1047 } else {
1048 INTERPRET_ERROR(UNDEFINED_TYPE_OP, "values", mapType(m_rtype));
1049 }
1050 break;
1051
1052
1053 case AS_BUILTIN_LEN:
1054 trgt->Accept(*this);
1055 if (m_rtype == TYPE(STRING)) {
1056 int sz = m_rvalue.as_string->GetSize();
1057 delete m_rvalue.as_string;
1058 m_rvalue.as_int = sz;
1059 } else {
1060 cLocalArray* arr = asArray(m_rtype, m_rvalue, node);
1061 m_rvalue.as_int = arr->GetSize();
1062 arr->RemoveReference();
1063 }
1064 m_rtype = TYPE(INT);
1065 break;
1066
1067 case AS_BUILTIN_REMOVE:
1068 trgt->Accept(*this);
1069 if (m_rtype.type == TYPE(DICT)) {
1070 cLocalDict* dict = m_rvalue.as_dict;
1071
1072 if (!dict->IsShared()) {
1073 dict->RemoveReference();
1074 break;
1075 }
1076
1077 args->Iterator().Next()->Accept(*this);
1078 sAggregateValue idx(m_rtype, m_rvalue);
1079 dict->Remove(idx);
1080 idx.Cleanup();
1081 dict->RemoveReference();
1082 } else if (m_rtype.type == TYPE(ARRAY)) {
1083 cLocalArray* arr = m_rvalue.as_array;
1084
1085 if (!arr->IsShared()) {
1086 arr->RemoveReference();
1087 break;
1088 }
1089
1090 args->Iterator().Next()->Accept(*this);
1091 int i = asInt(m_rtype, m_rvalue, node);
1092
1093 if (i < 0 || i >= arr->GetSize()) INTERPRET_ERROR(INDEX_OUT_OF_BOUNDS);
1094
1095 for (; i < (arr->GetSize() - 1); i++) arr->Set(i, arr->Get(i + 1));
1096 arr->Resize(arr->GetSize() - 1);
1097 } else {
1098 INTERPRET_ERROR(UNDEFINED_TYPE_OP, "remove", mapType(m_rtype));
1099 }
1100 break;
1101
1102 case AS_BUILTIN_RESIZE:
1103 trgt->Accept(*this);
1104 if (m_rtype.type == TYPE(MATRIX)) {
1105 cLocalMatrix* mat = m_rvalue.as_matrix;
1106
1107 if (args->GetSize() != 2) INTERPRET_ERROR(INVALID_ARRAY_SIZE);
1108
1109 if (!mat->IsShared()) {
1110 mat->RemoveReference();
1111 break;
1112 }
1113
1114 tListIterator<cASTNode> it = args->Iterator();
1115 it.Next()->Accept(*this);
1116 int sz_x = asInt(m_rtype, m_rvalue, node);
1117 it.Next()->Accept(*this);
1118 int sz_y = asInt(m_rtype, m_rvalue, node);
1119
1120 mat->Resize(sz_x, sz_y);
1121 mat->RemoveReference();
1122 } else if (m_rtype.type == TYPE(ARRAY)) {
1123 cLocalArray* arr = m_rvalue.as_array;
1124
1125 if (!arr->IsResizable()) INTERPRET_ERROR(CANNOT_RESIZE_MATRIX_ROW);
1126
1127 if (args->GetSize() != 1) INTERPRET_ERROR(INVALID_ARRAY_SIZE);
1128
1129 if (!arr->IsShared()) {
1130 arr->RemoveReference();
1131 break;
1132 }
1133
1134 args->Iterator().Next()->Accept(*this);
1135 int sz = asInt(m_rtype, m_rvalue, node);
1136
1137 arr->Resize(sz);
1138 arr->RemoveReference();
1139 } else {
1140 INTERPRET_ERROR(UNDEFINED_TYPE_OP, "resize", mapType(m_rtype));
1141 }
1142 break;
1143
1144 default:
1145 INTERPRET_ERROR(INTERNAL);
1146 break;
1147 }
1148 }
1149
1150
VisitFunctionCall(cASTFunctionCall & node)1151 void cDirectInterpretASTVisitor::VisitFunctionCall(cASTFunctionCall& node)
1152 {
1153 if (node.IsASFunction()) {
1154 // Call internal function
1155 const cASFunction* func = node.GetASFunction();
1156
1157 // Setup arguments
1158 cASCPPParameter* args = new cASCPPParameter[func->GetArity()];
1159 if (func->GetArity()) {
1160 tListIterator<cASTNode> cit = node.GetArguments()->Iterator();
1161 cASTNode* an = NULL;
1162 for (int i = 0; i < func->GetArity(); i++) {
1163 an = cit.Next();
1164 an->Accept(*this);
1165
1166 switch (func->GetArgumentType(i).type) {
1167 case TYPE(BOOL): args[i].Set(asBool(m_rtype, m_rvalue, node)); break;
1168 case TYPE(CHAR): args[i].Set(asChar(m_rtype, m_rvalue, node)); break;
1169 case TYPE(FLOAT): args[i].Set(asFloat(m_rtype, m_rvalue, node)); break;
1170 case TYPE(INT): args[i].Set(asInt(m_rtype, m_rvalue, node)); break;
1171 case TYPE(STRING): args[i].Set(asString(m_rtype, m_rvalue, node)); break;
1172 case TYPE(OBJECT_REF): args[i].Set(asNativeObject(func->GetArgumentType(i).info, m_rtype, m_rvalue, node)); break;
1173
1174 default:
1175 INTERPRET_ERROR(INTERNAL);
1176 }
1177 }
1178 }
1179
1180 // Call the function
1181 cASCPPParameter rvalue = func->Call(args);
1182
1183 // Handle the return value
1184 switch (node.GetType().type) {
1185 case TYPE(BOOL): m_rvalue.as_bool = rvalue.Get<bool>(); break;
1186 case TYPE(CHAR): m_rvalue.as_char = rvalue.Get<char>(); break;
1187 case TYPE(FLOAT): m_rvalue.as_float = rvalue.Get<double>(); break;
1188 case TYPE(INT): m_rvalue.as_int = rvalue.Get<int>(); break;
1189 case TYPE(STRING): m_rvalue.as_string = rvalue.Get<cString*>(); break;
1190 case TYPE(OBJECT_REF): m_rvalue.as_nobj = rvalue.Get<cASNativeObject*>(); break;
1191 case TYPE(VOID): break;
1192
1193 default:
1194 INTERPRET_ERROR(INTERNAL);
1195 }
1196 m_rtype = node.GetType();
1197
1198 // Clean up arguments
1199 for (int i = 0; i < func->GetArity(); i++) {
1200 switch (func->GetArgumentType(i).type) {
1201 case TYPE(BOOL): break;
1202 case TYPE(CHAR): break;
1203 case TYPE(FLOAT): break;
1204 case TYPE(INT): break;
1205 case TYPE(STRING): delete args[i].Get<cString*>(); break;
1206 case TYPE(OBJECT_REF):
1207 args[i].Get<cASNativeObject*>()->RemoveReference(); break;
1208
1209 default:
1210 INTERPRET_ERROR(INTERNAL);
1211 }
1212 }
1213 delete [] args;
1214
1215 } else {
1216 // Save previous scope information
1217 cSymbolTable* prev_symtbl = m_cur_symtbl;
1218
1219 // Get function information
1220 cSymbolTable* func_src_symtbl = node.IsFuncGlobal() ? m_global_symtbl : m_cur_symtbl;
1221 int fun_id = node.GetFuncID();
1222
1223 // Set current scope to the function symbol table
1224 cSymbolTable* func_symtbl = func_src_symtbl->GetFunctionSymbolTable(fun_id);
1225 int o_sp = m_sp;
1226 int sp = m_call_stack.GetSize();
1227 m_call_stack.Resize(m_call_stack.GetSize() + func_symtbl->GetNumVariables());
1228 for (int i = 0; i < func_symtbl->GetNumVariables(); i++) {
1229 switch (func_symtbl->GetVariableType(i).type) {
1230 case TYPE(ARRAY): m_call_stack[sp + i].value.as_array = new cLocalArray; break;
1231 case TYPE(BOOL): m_call_stack[sp + i].value.as_bool = false; break;
1232 case TYPE(CHAR): m_call_stack[sp + i].value.as_char = 0; break;
1233 case TYPE(DICT): m_call_stack[sp + i].value.as_dict = new cLocalDict; break;
1234 case TYPE(INT): m_call_stack[sp + i].value.as_int = 0; break;
1235 case TYPE(FLOAT): m_call_stack[sp + i].value.as_float = 0.0; break;
1236 case TYPE(MATRIX): m_call_stack[sp + i].value.as_matrix = NULL; break;
1237 case TYPE(OBJECT_REF): m_call_stack[sp + i].value.as_ref = NULL; break;
1238 case TYPE(STRING): m_call_stack[sp + i].value.as_string = NULL; break;
1239 case TYPE(VAR): m_call_stack[sp + i].type = TYPE(INVALID); break;
1240 default: break;
1241 }
1242 }
1243
1244 // Process the arguments to the function
1245 tListIterator<cASTVariableDefinition> sit = func_src_symtbl->GetFunctionSignature(fun_id)->Iterator();
1246 tListIterator<cASTNode> cit = node.GetArguments()->Iterator();
1247 cASTVariableDefinition* arg_def = NULL;
1248 while ((arg_def = sit.Next())) {
1249 cASTNode* arg = cit.Next();
1250 if (arg) arg->Accept(*this);
1251 else arg_def->GetAssignmentExpression()->Accept(*this);
1252
1253 int var_id = arg_def->GetVarID();
1254
1255 switch (func_symtbl->GetVariableType(var_id).type) {
1256 case TYPE(ARRAY): m_call_stack[sp + var_id].value.as_array = asArray(m_rtype, m_rvalue, node); break;
1257 case TYPE(BOOL): m_call_stack[sp + var_id].value.as_bool = asBool(m_rtype, m_rvalue, node); break;
1258 case TYPE(CHAR): m_call_stack[sp + var_id].value.as_char = asChar(m_rtype, m_rvalue, node); break;
1259 case TYPE(DICT): m_call_stack[sp + var_id].value.as_dict = asDict(m_rtype, m_rvalue, node); break;
1260 case TYPE(FLOAT): m_call_stack[sp + var_id].value.as_float = asFloat(m_rtype, m_rvalue, node); break;
1261 case TYPE(INT): m_call_stack[sp + var_id].value.as_int = asInt(m_rtype, m_rvalue, node); break;
1262 case TYPE(OBJECT_REF): m_call_stack[sp + var_id].value.as_nobj = asNativeObject(func_symtbl->GetVariableType(var_id).info, m_rtype, m_rvalue, node); break;
1263 case TYPE(MATRIX): m_call_stack[sp + var_id].value.as_matrix = asMatrix(m_rtype, m_rvalue, node); break;
1264 case TYPE(STRING):
1265 {
1266 m_call_stack[sp + var_id].value.as_string = asString(m_rtype, m_rvalue, node);
1267 }
1268 break;
1269
1270 case TYPE(VAR):
1271 m_call_stack[sp + var_id].value = m_rvalue;
1272 m_call_stack[sp + var_id].type = m_rtype;
1273 break;
1274
1275 default:
1276 INTERPRET_ERROR(INTERNAL);
1277 }
1278 }
1279
1280
1281 // Execute the function
1282 m_cur_symtbl = func_symtbl;
1283 m_sp = sp;
1284 func_src_symtbl->GetFunctionDefinition(fun_id)->Accept(*this);
1285
1286 // Handle function return value
1287 switch (node.GetType().type) {
1288 case TYPE(ARRAY): m_rvalue.as_array = asArray(m_rtype, m_rvalue, node); break;
1289 case TYPE(BOOL): m_rvalue.as_bool = asBool(m_rtype, m_rvalue, node); break;
1290 case TYPE(CHAR): m_rvalue.as_char = asChar(m_rtype, m_rvalue, node); break;
1291 case TYPE(DICT): m_rvalue.as_dict = asDict(m_rtype, m_rvalue, node); break;
1292 case TYPE(FLOAT): m_rvalue.as_float = asFloat(m_rtype, m_rvalue, node); break;
1293 case TYPE(INT): m_rvalue.as_int = asInt(m_rtype, m_rvalue, node); break;
1294 case TYPE(OBJECT_REF): m_rvalue.as_nobj = asNativeObject(node.GetType().info, m_rtype, m_rvalue, node); break;
1295 case TYPE(MATRIX): m_rvalue.as_matrix = asMatrix(m_rtype, m_rvalue, node); break;
1296 case TYPE(STRING): m_rvalue.as_string = asString(m_rtype, m_rvalue, node); break;
1297 case TYPE(VAR): break;
1298 case TYPE(VOID): break;
1299
1300 default:
1301 INTERPRET_ERROR(INTERNAL);
1302 }
1303 if (node.GetType() != TYPE(VAR)) m_rtype = node.GetType();
1304
1305 // Clean up variables in the current scope
1306 for (int i = 0; i < func_symtbl->GetNumVariables(); i++) {
1307 ASType_t type = func_symtbl->GetVariableType(i).type;
1308 if (type == TYPE(VAR)) type = m_call_stack[sp + i].type.type;
1309
1310 switch (type) {
1311 case TYPE(ARRAY): m_call_stack[sp + i].value.as_array->RemoveReference(); break;
1312 case TYPE(DICT): m_call_stack[sp + i].value.as_dict->RemoveReference(); break;
1313 case TYPE(MATRIX): m_call_stack[sp + i].value.as_matrix->RemoveReference(); break;
1314 case TYPE(OBJECT_REF): delete m_call_stack[sp + i].value.as_ref; break;
1315 case TYPE(STRING): delete m_call_stack[sp + i].value.as_string; break;
1316 default: break;
1317 }
1318 }
1319
1320 // Restore previous scope
1321 m_has_returned = false;
1322 m_call_stack.Resize(m_call_stack.GetSize() - m_cur_symtbl->GetNumVariables());
1323 m_sp = o_sp;
1324 m_cur_symtbl = prev_symtbl;
1325 }
1326 }
1327
1328
VisitLiteral(cASTLiteral & node)1329 void cDirectInterpretASTVisitor::VisitLiteral(cASTLiteral& node)
1330 {
1331 switch (node.GetType().type) {
1332 case TYPE(BOOL):
1333 if (node.GetValue() == "true") m_rvalue.as_bool = true;
1334 else m_rvalue.as_bool = false;
1335 m_rtype = TYPE(BOOL);
1336 break;
1337 case TYPE(CHAR):
1338 m_rvalue.as_char = node.GetValue()[0];
1339 m_rtype = TYPE(CHAR);
1340 break;
1341 case TYPE(INT):
1342 m_rvalue.as_int = node.GetValue().AsInt();
1343 m_rtype = TYPE(INT);
1344 break;
1345 case TYPE(FLOAT):
1346 m_rvalue.as_float = node.GetValue().AsDouble();
1347 m_rtype = TYPE(FLOAT);
1348 break;
1349 case TYPE(STRING):
1350 m_rvalue.as_string = new cString(node.GetValue());
1351 m_rtype = TYPE(STRING);
1352 break;
1353 default:
1354 INTERPRET_ERROR(INTERNAL);
1355 }
1356 }
1357
1358
VisitLiteralArray(cASTLiteralArray & node)1359 void cDirectInterpretASTVisitor::VisitLiteralArray(cASTLiteralArray& node)
1360 {
1361 cASTArgumentList* vals = node.GetValues();
1362
1363 if (node.IsMatrix()) {
1364 cLocalMatrix* mat = new cLocalMatrix();
1365
1366 int sz_y = 1;
1367 bool first = true;
1368
1369 tListIterator<cASTNode> it = vals->Iterator();
1370 cASTNode* val = NULL;
1371 int i = 0;
1372 while ((val = it.Next())) {
1373 val->Accept(*this);
1374 if (first && m_rtype.type == TYPE(ARRAY)) {
1375 sz_y = m_rvalue.as_array->GetSize();
1376 }
1377
1378 mat->Resize(i + 1, sz_y);
1379
1380 if (sz_y > 1) {
1381 if (m_rtype.type != TYPE(ARRAY)) INTERPRET_ERROR(INVALID_ARRAY_SIZE);
1382 mat->Set(i, m_rvalue.as_array);
1383 } else {
1384 mat->GetRow(i)->Set(0, m_rtype, m_rvalue);
1385 }
1386
1387 sAggregateValue val(m_rtype, m_rvalue);
1388 val.Cleanup();
1389 first = false;
1390 i++;
1391 }
1392
1393 m_rvalue.as_matrix = mat;
1394 m_rtype = TYPE(MATRIX);
1395 } else {
1396 cLocalArray* arr = new cLocalArray(vals->GetSize());
1397
1398 tListIterator<cASTNode> it = vals->Iterator();
1399 cASTNode* val = NULL;
1400 int i = 0;
1401 while ((val = it.Next())) {
1402 val->Accept(*this);
1403 arr->Set(i++, m_rtype.type, m_rvalue);
1404 }
1405
1406 m_rvalue.as_array = arr;
1407 m_rtype = TYPE(ARRAY);
1408 }
1409 }
1410
VisitLiteralDict(cASTLiteralDict & node)1411 void cDirectInterpretASTVisitor::VisitLiteralDict(cASTLiteralDict& node)
1412 {
1413 cLocalDict* dict = new cLocalDict();
1414
1415 sAggregateValue idx,val;
1416 tListIterator<cASTLiteralDict::sMapping> it(node.Iterator());
1417 cASTLiteralDict::sMapping* mapping = NULL;
1418 while ((mapping = it.Next())) {
1419 mapping->idx->Accept(*this);
1420 idx.type = m_rtype;
1421 idx.value = m_rvalue;
1422 mapping->val->Accept(*this);
1423 val.type = m_rtype;
1424 val.value = m_rvalue;
1425 dict->Set(idx, val);
1426 }
1427
1428 m_rvalue.as_dict = dict;
1429 m_rtype = TYPE(DICT);
1430 }
1431
VisitObjectCall(cASTObjectCall & node)1432 void cDirectInterpretASTVisitor::VisitObjectCall(cASTObjectCall& node)
1433 {
1434 node.GetObject()->Accept(*this);
1435
1436 if (m_rtype.type != TYPE(OBJECT_REF))
1437 INTERPRET_ERROR(TYPE_CAST, mapType(m_rtype.type), mapType(TYPE(OBJECT_REF)));
1438
1439 cASNativeObject* nobj = m_rvalue.as_nobj;
1440
1441 int mid = -1;
1442 if (!nobj->LookupMethod(node.GetName(), mid))
1443 INTERPRET_ERROR(NOBJ_METHOD_LOOKUP_FAILED, *node.GetName(), *m_rtype.info);
1444
1445 int arity = nobj->GetArity(mid);
1446 // Setup arguments
1447 cASCPPParameter* args = new cASCPPParameter[arity];
1448 if (arity) {
1449 tListIterator<cASTNode> cit = node.GetArguments()->Iterator();
1450 cASTNode* an = NULL;
1451 for (int i = 0; i < arity; i++) {
1452 an = cit.Next();
1453 an->Accept(*this);
1454
1455 switch (nobj->GetArgumentType(mid, i).type) {
1456 case TYPE(BOOL): args[i].Set(asBool(m_rtype, m_rvalue, node)); break;
1457 case TYPE(CHAR): args[i].Set(asChar(m_rtype, m_rvalue, node)); break;
1458 case TYPE(FLOAT): args[i].Set(asFloat(m_rtype, m_rvalue, node)); break;
1459 case TYPE(INT): args[i].Set(asInt(m_rtype, m_rvalue, node)); break;
1460 case TYPE(STRING): args[i].Set(asString(m_rtype, m_rvalue, node)); break;
1461
1462 default:
1463 INTERPRET_ERROR(INTERNAL);
1464 }
1465 }
1466 }
1467
1468 // Call the function
1469 cASCPPParameter rvalue = nobj->CallMethod(mid, args);
1470
1471 // Handle the return value
1472 m_rtype = nobj->GetReturnType(mid);
1473 switch (m_rtype.type) {
1474 case TYPE(BOOL): m_rvalue.as_bool = rvalue.Get<bool>(); break;
1475 case TYPE(CHAR): m_rvalue.as_char = rvalue.Get<char>(); break;
1476 case TYPE(FLOAT): m_rvalue.as_float = rvalue.Get<double>(); break;
1477 case TYPE(INT): m_rvalue.as_int = rvalue.Get<int>(); break;
1478 case TYPE(STRING): m_rvalue.as_string = rvalue.Get<cString*>(); break;
1479 case TYPE(OBJECT_REF): m_rvalue.as_nobj = rvalue.Get<cASNativeObject*>(); break;
1480 case TYPE(VOID): break;
1481
1482 default:
1483 INTERPRET_ERROR(INTERNAL);
1484 }
1485
1486 // Clean up arguments
1487 for (int i = 0; i < arity; i++) {
1488 switch (nobj->GetArgumentType(mid, i).type) {
1489 case TYPE(BOOL): break;
1490 case TYPE(CHAR): break;
1491 case TYPE(FLOAT): break;
1492 case TYPE(INT): break;
1493 case TYPE(STRING): delete args[i].Get<cString*>(); break;
1494
1495 default:
1496 INTERPRET_ERROR(INTERNAL);
1497 }
1498 }
1499 delete [] args;
1500
1501 }
1502
VisitObjectReference(cASTObjectReference & node)1503 void cDirectInterpretASTVisitor::VisitObjectReference(cASTObjectReference& node)
1504 {
1505 // @AS_TODO - handle object reference
1506 INTERPRET_ERROR(INTERNAL);
1507 }
1508
VisitVariableReference(cASTVariableReference & node)1509 void cDirectInterpretASTVisitor::VisitVariableReference(cASTVariableReference& node)
1510 {
1511 int var_id = node.GetVarID();
1512 int sp = node.IsVarGlobal() ? 0 : m_sp;
1513
1514 if (m_obj_assign) {
1515 switch (node.GetType().type) {
1516 case TYPE(ARRAY): m_rvalue.as_ref = new cArrayVarRef(m_call_stack[sp + var_id].value); break;
1517 case TYPE(DICT): m_rvalue.as_ref = new cDictVarRef(m_call_stack[sp + var_id].value); break;
1518 case TYPE(OBJECT_REF): m_rvalue.as_ref = new cNativeObjectVarRef(m_call_stack[sp + var_id].value); break;
1519 case TYPE(MATRIX): m_rvalue.as_ref = new cMatrixVarRef(m_call_stack[sp + var_id].value); break;
1520 case TYPE(STRING): m_rvalue.as_ref = new cStringVarRef(m_call_stack[sp + var_id].value); break;
1521
1522 default:
1523 INTERPRET_ERROR(INTERNAL);
1524 }
1525 m_rtype = TYPE(OBJECT_REF);
1526 } else {
1527 ASType_t type = node.GetType().type;
1528 if (type == TYPE(VAR)) type = m_call_stack[sp + var_id].type.type;
1529
1530 m_rtype = sASTypeInfo(type);
1531
1532 switch (type) {
1533 case TYPE(ARRAY): m_rvalue.as_array = m_call_stack[sp + var_id].value.as_array->GetReference(); break;
1534 case TYPE(BOOL): m_rvalue.as_bool = m_call_stack[sp + var_id].value.as_bool; break;
1535 case TYPE(CHAR): m_rvalue.as_char = m_call_stack[sp + var_id].value.as_char; break;
1536 case TYPE(DICT): m_rvalue.as_dict = m_call_stack[sp + var_id].value.as_dict->GetReference(); break;
1537 case TYPE(FLOAT): m_rvalue.as_float = m_call_stack[sp + var_id].value.as_float; break;
1538 case TYPE(INT): m_rvalue.as_int = m_call_stack[sp + var_id].value.as_int; break;
1539 case TYPE(MATRIX): m_rvalue.as_matrix = m_call_stack[sp + var_id].value.as_matrix->GetReference(); break;
1540 case TYPE(STRING): m_rvalue.as_string = new cString(*m_call_stack[sp + var_id].value.as_string); break;
1541
1542
1543 case TYPE(OBJECT_REF):
1544 m_rvalue.as_nobj = m_call_stack[sp + var_id].value.as_nobj->GetReference();
1545 m_rtype.info = m_call_stack[sp + var_id].type.info;
1546 break;
1547
1548 default:
1549 INTERPRET_ERROR(INTERNAL);
1550 }
1551 }
1552 }
1553
1554
VisitUnpackTarget(cASTUnpackTarget & node)1555 void cDirectInterpretASTVisitor::VisitUnpackTarget(cASTUnpackTarget& node)
1556 {
1557 node.GetExpression()->Accept(*this);
1558 cLocalArray* arr = m_rvalue.as_array;
1559
1560 int unpack_size = node.GetSize();
1561 if (node.IsLastNamed()) unpack_size--;
1562 if (unpack_size > arr->GetSize()) INTERPRET_ERROR(UNPACK_VALUE_TOO_SMALL);
1563 if (unpack_size < arr->GetSize() && !node.IsLastWild()) INTERPRET_ERROR(UNPACK_VALUE_TOO_LARGE);
1564
1565 // Unpack the values up to the last non-wild value
1566 for (int i = 0; i < unpack_size; i++) {
1567 sASTypeInfo var_type = (node.IsVarGlobal(i) ? m_global_symtbl : m_cur_symtbl)->GetVariableType(node.GetVarID(i));
1568 int var_idx = (node.IsVarGlobal(i) ? 0 : m_sp) + node.GetVarID(i);
1569
1570 // Set the variable value for this iteration
1571 const sAggregateValue& val = arr->Get(i);
1572 switch (var_type.type) {
1573 case TYPE(BOOL): m_call_stack[var_idx].value.as_bool = asBool(val.type, val.value, node); break;
1574 case TYPE(CHAR): m_call_stack[var_idx].value.as_char = asChar(val.type, val.value, node); break;
1575 case TYPE(FLOAT): m_call_stack[var_idx].value.as_float = asFloat(val.type, val.value, node); break;
1576 case TYPE(INT): m_call_stack[var_idx].value.as_int = asInt(val.type, val.value, node); break;
1577 case TYPE(OBJECT_REF):
1578 m_call_stack[var_idx].value.as_nobj->RemoveReference();
1579 m_call_stack[var_idx].value.as_nobj = asNativeObject(var_type.info, val.type, val.value, node);
1580 break;
1581
1582 case TYPE(VAR):
1583 m_call_stack[var_idx].value = val.value;
1584 m_call_stack[var_idx].type = val.type;
1585 break;
1586
1587 case TYPE(ARRAY):
1588 m_call_stack[var_idx].value.as_array->RemoveReference();
1589 m_call_stack[var_idx].value.as_array = asArray(val.type, val.value, node);
1590 break;
1591
1592 case TYPE(DICT):
1593 m_call_stack[var_idx].value.as_dict->RemoveReference();
1594 m_call_stack[var_idx].value.as_dict = asDict(val.type, val.value, node);
1595 break;
1596
1597 case TYPE(MATRIX):
1598 m_call_stack[var_idx].value.as_matrix->RemoveReference();
1599 m_call_stack[var_idx].value.as_matrix = asMatrix(val.type, val.value, node);
1600 break;
1601
1602 case TYPE(STRING):
1603 delete m_call_stack[var_idx].value.as_string;
1604 m_call_stack[var_idx].value.as_string = asString(val.type, val.value, node);
1605 break;
1606
1607 default:
1608 INTERPRET_ERROR(INTERNAL);
1609 }
1610 }
1611
1612 if (node.IsLastNamed()) {
1613 int var_idx = (node.IsVarGlobal(unpack_size) ? 0 : m_sp) + node.GetVarID(unpack_size);
1614 int sz = arr->GetSize() - unpack_size;
1615
1616 cLocalArray* wild = new cLocalArray(sz);
1617
1618 for (int i = 0; i < sz; i++) {
1619 const sAggregateValue& val = arr->Get(i + unpack_size);
1620 wild->Set(i, val.type, val.value);
1621 }
1622
1623 m_call_stack[var_idx].value.as_array->RemoveReference();
1624 m_call_stack[var_idx].value.as_array = wild;
1625 }
1626
1627 arr->RemoveReference();
1628 }
1629
asArray(const sASTypeInfo & type,uAnyType value,cASTNode & node)1630 cDirectInterpretASTVisitor::cLocalArray* cDirectInterpretASTVisitor::asArray(const sASTypeInfo& type, uAnyType value, cASTNode& node)
1631 {
1632 switch (type.type) {
1633 case TYPE(ARRAY):
1634 return value.as_array;
1635
1636 case TYPE(MATRIX):
1637 {
1638 cLocalMatrix* mat = value.as_matrix;
1639 cLocalArray* arr = new cLocalArray(mat->GetNumRows());
1640 uAnyType val;
1641 for (int i = 0; i < mat->GetNumRows(); i++) {
1642 val.as_array = new cLocalArray(mat->GetRow(i));
1643 arr->Set(i, TYPE(ARRAY), val);
1644 }
1645 mat->RemoveReference();
1646 return arr;
1647 }
1648
1649 case TYPE(STRING):
1650 {
1651 cString* str = value.as_string;
1652 cLocalArray* arr = new cLocalArray(str->GetSize());
1653 for (int i = 0; i < str->GetSize(); i++) {
1654 uAnyType val;
1655 val.as_char = (*str)[i];
1656 arr->Set(i, TYPE(CHAR), val);
1657 }
1658 delete str;
1659 return arr;
1660 }
1661
1662 default:
1663 INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(ARRAY)));
1664 }
1665
1666 return false;
1667 }
1668
asBool(const sASTypeInfo & type,uAnyType value,cASTNode & node)1669 bool cDirectInterpretASTVisitor::asBool(const sASTypeInfo& type, uAnyType value, cASTNode& node)
1670 {
1671 switch (type.type) {
1672 case TYPE(ARRAY):
1673 {
1674 bool rval = (value.as_array->GetSize());
1675 value.as_array->RemoveReference();
1676 return rval;
1677 }
1678
1679 case TYPE(DICT):
1680 {
1681 bool rval = (value.as_dict->GetSize());
1682 value.as_dict->RemoveReference();
1683 return rval;
1684 }
1685
1686 case TYPE(MATRIX):
1687 {
1688 bool rval = (value.as_matrix->GetNumRows() && value.as_matrix->GetNumCols());
1689 value.as_matrix->RemoveReference();
1690 return rval;
1691 }
1692
1693 case TYPE(BOOL):
1694 return value.as_bool;
1695 case TYPE(CHAR):
1696 return (value.as_char);
1697 case TYPE(FLOAT):
1698 return (value.as_float != 0);
1699 case TYPE(INT):
1700 return (value.as_int);
1701 case TYPE(STRING):
1702 {
1703 bool rval = (*value.as_string != "");
1704 delete value.as_string;
1705 return rval;
1706 }
1707
1708
1709 case TYPE(OBJECT_REF): // @AS_TODO - implement asBool
1710 INTERPRET_ERROR(INTERNAL);
1711
1712 default:
1713 INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(BOOL)));
1714 }
1715
1716 return false;
1717 }
1718
1719
asChar(const sASTypeInfo & type,uAnyType value,cASTNode & node)1720 char cDirectInterpretASTVisitor::asChar(const sASTypeInfo& type, uAnyType value, cASTNode& node)
1721 {
1722 switch (type.type) {
1723 case TYPE(BOOL):
1724 return (value.as_bool) ? 1 : 0;
1725 case TYPE(CHAR):
1726 return value.as_char;
1727 case TYPE(INT):
1728 return (char)value.as_int;
1729
1730 default:
1731 INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(CHAR)));
1732 }
1733
1734 return 0;
1735 }
1736
1737
asDict(const sASTypeInfo & type,uAnyType value,cASTNode & node)1738 cDirectInterpretASTVisitor::cLocalDict* cDirectInterpretASTVisitor::asDict(const sASTypeInfo& type, uAnyType value,
1739 cASTNode& node)
1740 {
1741 switch (type.type) {
1742 case TYPE(DICT):
1743 return value.as_dict;
1744
1745 case TYPE(ARRAY):
1746 {
1747 cLocalDict* dict = new cLocalDict();
1748 cLocalArray* arr = value.as_array;
1749
1750 sAggregateValue idx;
1751 idx.type.type = TYPE(INT);
1752
1753 for (idx.value.as_int = 0; idx.value.as_int < arr->GetSize(); idx.value.as_int++) {
1754 dict->Set(idx, arr->Get(idx.value.as_int));
1755 }
1756
1757 arr->RemoveReference();
1758 return dict;
1759 }
1760
1761 default:
1762 INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(CHAR)));
1763 }
1764
1765 return false;
1766 }
1767
asInt(const sASTypeInfo & type,uAnyType value,cASTNode & node)1768 int cDirectInterpretASTVisitor::asInt(const sASTypeInfo& type, uAnyType value, cASTNode& node)
1769 {
1770 switch (type.type) {
1771 case TYPE(BOOL):
1772 return (value.as_bool) ? 1 : 0;
1773 case TYPE(CHAR):
1774 return (int)value.as_char;
1775 case TYPE(INT):
1776 return value.as_int;
1777 case TYPE(FLOAT):
1778 return (int)value.as_float;
1779 case TYPE(STRING):
1780 {
1781 int rval = value.as_string->AsInt();
1782 delete value.as_string;
1783 return rval;
1784 }
1785
1786 default:
1787 INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(INT)));
1788 }
1789
1790 return 0;
1791 }
1792
1793
asFloat(const sASTypeInfo & type,uAnyType value,cASTNode & node)1794 double cDirectInterpretASTVisitor::asFloat(const sASTypeInfo& type, uAnyType value, cASTNode& node)
1795 {
1796 switch (type.type) {
1797 case TYPE(BOOL):
1798 return (value.as_bool) ? 1.0 : 0.0;
1799 case TYPE(CHAR):
1800 return (double)value.as_char;
1801 case TYPE(INT):
1802 return (double)value.as_int;
1803 case TYPE(FLOAT):
1804 return value.as_float;
1805 case TYPE(STRING):
1806 {
1807 double rval = value.as_string->AsDouble();
1808 delete value.as_string;
1809 return rval;
1810 }
1811
1812 default:
1813 INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(FLOAT)));
1814 }
1815
1816 return 0.0;
1817 }
1818
1819
asMatrix(const sASTypeInfo & type,uAnyType value,cASTNode & node)1820 cDirectInterpretASTVisitor::cLocalMatrix* cDirectInterpretASTVisitor::asMatrix(const sASTypeInfo& type, uAnyType value,
1821 cASTNode& node)
1822 {
1823 switch (type.type) {
1824 case TYPE(BOOL):
1825 case TYPE(CHAR):
1826 case TYPE(FLOAT):
1827 case TYPE(INT):
1828 {
1829 sAggregateValue val(type, value);
1830 cLocalMatrix* mat = new cLocalMatrix();
1831 mat->Resize(1, 1);
1832 mat->GetRow(0)->Set(0, val);
1833 return mat;
1834 }
1835
1836 case TYPE(MATRIX):
1837 return value.as_matrix;
1838
1839 default:
1840 INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(MATRIX)));
1841 }
1842
1843 return NULL;
1844 }
1845
1846
asNativeObject(const cString & info,const sASTypeInfo & type,uAnyType value,cASTNode & node)1847 cASNativeObject* cDirectInterpretASTVisitor::asNativeObject(const cString& info, const sASTypeInfo& type, uAnyType value,
1848 cASTNode& node)
1849 {
1850 switch (type.type) {
1851 case TYPE(OBJECT_REF):
1852 if (type.info != info) INTERPRET_ERROR(NOBJ_TYPE_MISMATCH, *info, *type.info);
1853 return value.as_nobj;
1854
1855 default:
1856 INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(OBJECT_REF)));
1857 }
1858
1859 return NULL;
1860 }
1861
1862
asString(const sASTypeInfo & type,uAnyType value,cASTNode & node)1863 cString* cDirectInterpretASTVisitor::asString(const sASTypeInfo& type, uAnyType value, cASTNode& node)
1864 {
1865 switch (type.type) {
1866 case TYPE(BOOL): return new cString(cStringUtil::Convert(value.as_bool));
1867 case TYPE(CHAR): { cString* str = new cString(1); (*str)[0] = value.as_char; return str; }
1868 case TYPE(INT): return new cString(cStringUtil::Convert(value.as_int));
1869 case TYPE(FLOAT): return new cString(cStringUtil::Convert(value.as_float));
1870 case TYPE(STRING): return value.as_string;
1871
1872 case TYPE(ARRAY):
1873 {
1874 cString* str = new cString(cStringUtil::Stringf("< array(%d) >", value.as_array->GetSize()));
1875 value.as_array->RemoveReference();
1876 return str;
1877 }
1878
1879 case TYPE(DICT):
1880 {
1881 cString* str = new cString(cStringUtil::Stringf("< dict(%d) >", value.as_dict->GetSize()));
1882 value.as_dict->RemoveReference();
1883 return str;
1884 }
1885
1886 case TYPE(MATRIX):
1887 {
1888 cString* str = new cString(cStringUtil::Stringf("< matrix(%d, %d) >", value.as_matrix->GetNumRows(), value.as_matrix->GetNumCols()));
1889 return str;
1890 }
1891
1892 case TYPE(OBJECT_REF):
1893 {
1894 cString* str = new cString(cStringUtil::Stringf("< %s object @ %p >", value.as_nobj->GetType(), value.as_nobj));
1895 return str;
1896 }
1897
1898 default:
1899 INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(STRING)));
1900 }
1901
1902 return NULL;
1903 }
1904
1905
1906
getRuntimeType(ASType_t ltype,ASType_t rtype,bool allow_str)1907 ASType_t cDirectInterpretASTVisitor::getRuntimeType(ASType_t ltype, ASType_t rtype, bool allow_str)
1908 {
1909 switch (ltype) {
1910 case TYPE(ARRAY):
1911 return TYPE(ARRAY);
1912 case TYPE(BOOL):
1913 switch (rtype) {
1914 case TYPE(ARRAY):
1915 case TYPE(BOOL):
1916 case TYPE(CHAR):
1917 case TYPE(FLOAT):
1918 case TYPE(INT):
1919 case TYPE(MATRIX):
1920 case TYPE(OBJECT_REF):
1921 case TYPE(STRING):
1922 return TYPE(BOOL);
1923
1924 default: break;
1925 }
1926 break;
1927 case TYPE(CHAR):
1928 switch (rtype) {
1929 case TYPE(ARRAY): return TYPE(ARRAY);
1930 case TYPE(BOOL): return TYPE(CHAR);
1931 case TYPE(CHAR): return TYPE(CHAR);
1932 case TYPE(FLOAT): return TYPE(FLOAT);
1933 case TYPE(INT): return TYPE(INT);
1934 case TYPE(MATRIX): return TYPE(MATRIX);
1935 case TYPE(STRING): if (allow_str) return TYPE(STRING); break;
1936 default: break;
1937 }
1938 break;
1939 case TYPE(DICT):
1940 return TYPE(DICT);
1941 case TYPE(FLOAT):
1942 switch (rtype) {
1943 case TYPE(ARRAY): return TYPE(ARRAY);
1944 case TYPE(BOOL): return TYPE(FLOAT);
1945 case TYPE(CHAR): return TYPE(FLOAT);
1946 case TYPE(FLOAT): return TYPE(FLOAT);
1947 case TYPE(INT): return TYPE(FLOAT);
1948 case TYPE(MATRIX): return TYPE(MATRIX);
1949 case TYPE(STRING): if (allow_str) return TYPE(FLOAT); break;
1950 default: break;
1951 }
1952 break;
1953 case TYPE(INT):
1954 switch (rtype) {
1955 case TYPE(ARRAY): return TYPE(ARRAY);
1956 case TYPE(BOOL): return TYPE(INT);
1957 case TYPE(CHAR): return TYPE(INT);
1958 case TYPE(FLOAT): return TYPE(FLOAT);
1959 case TYPE(INT): return TYPE(INT);
1960 case TYPE(MATRIX): return TYPE(MATRIX);
1961 case TYPE(STRING): if (allow_str) return TYPE(INT); break;
1962 default: break;
1963 }
1964 break;
1965 case TYPE(MATRIX):
1966 return TYPE(MATRIX);
1967 case TYPE(STRING):
1968 if (allow_str) return TYPE(STRING); break;
1969
1970 default: break;
1971 }
1972
1973 return TYPE(INVALID);
1974 }
1975
1976
matrixAdd(cLocalMatrix * m1,cLocalMatrix * m2,cASTNode & node)1977 void cDirectInterpretASTVisitor::matrixAdd(cLocalMatrix* m1, cLocalMatrix* m2, cASTNode& node)
1978 {
1979 INTERPRET_ERROR(INTERNAL); // @AS_TODO - handle matrix add
1980 }
1981
1982
matrixSubtract(cLocalMatrix * m1,cLocalMatrix * m2,cASTNode & node)1983 void cDirectInterpretASTVisitor::matrixSubtract(cLocalMatrix* m1, cLocalMatrix* m2, cASTNode& node)
1984 {
1985 INTERPRET_ERROR(INTERNAL); // @AS_TODO - handle matrix sub
1986 }
1987
1988
matrixMultiply(cLocalMatrix * m1,cLocalMatrix * m2,cASTNode & node)1989 void cDirectInterpretASTVisitor::matrixMultiply(cLocalMatrix* m1, cLocalMatrix* m2, cASTNode& node)
1990 {
1991 // Validate all values in matrix operands and determine operation type
1992 ASType_t op_type = TYPE(INT);
1993 for (int i = 0; i < m1->GetNumRows(); i++) {
1994 cLocalArray* row = m1->GetRow(i);
1995 for (int j = 0; j < m1->GetNumCols(); j++) {
1996 switch (row->Get(j).type.type) {
1997 case TYPE(BOOL):
1998 case TYPE(CHAR):
1999 case TYPE(INT):
2000 case TYPE(STRING):
2001 break;
2002
2003 case TYPE(FLOAT):
2004 op_type = TYPE(FLOAT);
2005 break;
2006
2007 default:
2008 INTERPRET_ERROR(MATRIX_OP_TYPE_MISMATCH, mapToken(TOKEN(OP_MUL)), mapType(row->Get(j).type));
2009 }
2010 }
2011 }
2012 for (int i = 0; i < m2->GetNumRows(); i++) {
2013 cLocalArray* row = m2->GetRow(i);
2014 for (int j = 0; j < m2->GetNumCols(); j++) {
2015 switch (row->Get(j).type.type) {
2016 case TYPE(BOOL):
2017 case TYPE(CHAR):
2018 case TYPE(INT):
2019 case TYPE(STRING):
2020 break;
2021
2022 case TYPE(FLOAT):
2023 op_type = TYPE(FLOAT);
2024 break;
2025
2026 default:
2027 INTERPRET_ERROR(MATRIX_OP_TYPE_MISMATCH, mapToken(TOKEN(OP_MUL)), mapType(row->Get(j).type));
2028 }
2029 }
2030 }
2031
2032
2033
2034 if (m1->GetNumRows() == 1 && m1->GetNumCols() == 1) {
2035 // left op scalar multiply
2036
2037 if (op_type == TYPE(INT)) matrixMultiply_ScalarInt(m1, m2, node);
2038 else matrixMultiply_ScalarFloat(m1, m2, node);
2039
2040 } else if (m2->GetNumRows() == 1 && m2->GetNumCols() == 1) {
2041 // right op scalar multiply
2042
2043 if (op_type == TYPE(INT)) matrixMultiply_ScalarInt(m2, m1, node);
2044 else matrixMultiply_ScalarFloat(m2, m1, node);
2045
2046 } else {
2047 // full multiply
2048
2049 if (m1->GetNumCols() != m2->GetNumRows()) INTERPRET_ERROR(MATRIX_SIZE_MISMATCH, mapToken(TOKEN(OP_MUL)));
2050
2051 if (op_type == TYPE(INT)) matrixMultiply_FullInt(m1, m2, node);
2052 else matrixMultiply_FullFloat(m1, m2, node);
2053 }
2054 }
2055
matrixMultiply_ScalarInt(cLocalMatrix * s,cLocalMatrix * m,cASTNode & node)2056 void cDirectInterpretASTVisitor::matrixMultiply_ScalarInt(cLocalMatrix* s, cLocalMatrix* m, cASTNode& node)
2057 {
2058 int scalar = 0;
2059 tMatrix<int> op(m->GetNumRows(), m->GetNumCols());
2060
2061 const sAggregateValue& val = s->GetRow(0)->Get(0);
2062 switch (val.type.type) {
2063 case TYPE(BOOL): scalar = (val.value.as_bool) ? 1 : 0; break;
2064 case TYPE(CHAR): scalar = (int)val.value.as_char; break;
2065 case TYPE(INT): scalar = val.value.as_int; break;
2066 case TYPE(STRING): scalar = val.value.as_string->AsInt(); break;
2067
2068 default:
2069 INTERPRET_ERROR(MATRIX_OP_TYPE_MISMATCH, mapToken(TOKEN(OP_MUL)), mapType(val.type));
2070 }
2071
2072 for (int i = 0; i < m->GetNumRows(); i++) {
2073 cLocalArray* row = m->GetRow(i);
2074 for (int j = 0; j < m->GetNumCols(); j++) {
2075 const sAggregateValue& val = row->Get(j);
2076 switch (val.type.type) {
2077 case TYPE(BOOL): op[i][j] = (val.value.as_bool) ? 1 : 0; break;
2078 case TYPE(CHAR): op[i][j] = (int)val.value.as_char; break;
2079 case TYPE(INT): op[i][j] = val.value.as_int; break;
2080 case TYPE(STRING): op[i][j] = val.value.as_string->AsInt(); break;
2081
2082 default:
2083 INTERPRET_ERROR(MATRIX_OP_TYPE_MISMATCH, mapToken(TOKEN(OP_MUL)), mapType(row->Get(j).type));
2084 }
2085 }
2086 }
2087
2088 int sz_x = m->GetNumRows();
2089 int sz_y = m->GetNumCols();
2090 cLocalMatrix* mat = new cLocalMatrix();
2091 mat->Resize(sz_x, sz_y);
2092
2093 sASTypeInfo op_type(TYPE(INT));
2094 for (int i = 0; i < sz_x; i++) {
2095 cLocalArray* row = mat->GetRow(i);
2096 for (int j = 0; j < sz_y; j++) {
2097 uAnyType val;
2098 val.as_int = scalar * op[i][j];
2099 row->Set(j, op_type, val);
2100 }
2101 }
2102
2103 m_rvalue.as_matrix = mat;
2104 m_rtype = TYPE(MATRIX);
2105 }
2106
matrixMultiply_ScalarFloat(cLocalMatrix * s,cLocalMatrix * m,cASTNode & node)2107 void cDirectInterpretASTVisitor::matrixMultiply_ScalarFloat(cLocalMatrix* s, cLocalMatrix* m, cASTNode& node)
2108 {
2109 double scalar = 0.0;
2110 tMatrix<double> op(m->GetNumRows(), m->GetNumCols());
2111
2112 const sAggregateValue& val = s->GetRow(0)->Get(0);
2113 switch (val.type.type) {
2114 case TYPE(BOOL): scalar = (val.value.as_bool) ? 1.0 : 0.0; break;
2115 case TYPE(CHAR): scalar = (double)val.value.as_char; break;
2116 case TYPE(INT): scalar = (double)val.value.as_int; break;
2117 case TYPE(FLOAT): scalar = val.value.as_float; break;
2118 case TYPE(STRING): scalar = val.value.as_string->AsDouble(); break;
2119
2120 default:
2121 INTERPRET_ERROR(MATRIX_OP_TYPE_MISMATCH, mapToken(TOKEN(OP_MUL)), mapType(val.type));
2122 }
2123
2124 for (int i = 0; i < m->GetNumRows(); i++) {
2125 cLocalArray* row = m->GetRow(i);
2126 for (int j = 0; j < m->GetNumCols(); j++) {
2127 const sAggregateValue& val = row->Get(j);
2128 switch (val.type.type) {
2129 case TYPE(BOOL): op[i][j] = (val.value.as_bool) ? 1.0 : 0.0; break;
2130 case TYPE(CHAR): op[i][j] = (double)val.value.as_char; break;
2131 case TYPE(INT): op[i][j] = (double)val.value.as_int; break;
2132 case TYPE(FLOAT): op[i][j] = val.value.as_float; break;
2133 case TYPE(STRING): op[i][j] = val.value.as_string->AsDouble(); break;
2134
2135 default:
2136 INTERPRET_ERROR(MATRIX_OP_TYPE_MISMATCH, mapToken(TOKEN(OP_MUL)), mapType(row->Get(j).type));
2137 }
2138 }
2139 }
2140
2141 int sz_x = m->GetNumRows();
2142 int sz_y = m->GetNumCols();
2143 cLocalMatrix* mat = new cLocalMatrix();
2144 mat->Resize(sz_x, sz_y);
2145
2146 sASTypeInfo op_type(TYPE(FLOAT));
2147 for (int i = 0; i < sz_x; i++) {
2148 cLocalArray* row = mat->GetRow(i);
2149 for (int j = 0; j < sz_y; j++) {
2150 uAnyType val;
2151 val.as_float = scalar * op[i][j];
2152 row->Set(j, op_type, val);
2153 }
2154 }
2155
2156 m_rvalue.as_matrix = mat;
2157 m_rtype = TYPE(MATRIX);
2158 }
2159
matrixMultiply_FullInt(cLocalMatrix * m1,cLocalMatrix * m2,cASTNode & node)2160 void cDirectInterpretASTVisitor::matrixMultiply_FullInt(cLocalMatrix* m1, cLocalMatrix* m2, cASTNode& node)
2161 {
2162 tMatrix<int> op1(m1->GetNumRows(), m1->GetNumCols());
2163 tMatrix<int> op2(m2->GetNumRows(), m2->GetNumCols());
2164
2165 for (int i = 0; i < m1->GetNumRows(); i++) {
2166 cLocalArray* row = m1->GetRow(i);
2167 for (int j = 0; j < m1->GetNumCols(); j++) {
2168 const sAggregateValue& val = row->Get(j);
2169 switch (val.type.type) {
2170 case TYPE(BOOL): op1[i][j] = (val.value.as_bool) ? 1 : 0; break;
2171 case TYPE(CHAR): op1[i][j] = (int)val.value.as_char; break;
2172 case TYPE(INT): op1[i][j] = val.value.as_int; break;
2173 case TYPE(STRING): op1[i][j] = val.value.as_string->AsInt(); break;
2174
2175 default:
2176 INTERPRET_ERROR(MATRIX_OP_TYPE_MISMATCH, mapToken(TOKEN(OP_MUL)), mapType(row->Get(j).type));
2177 }
2178 }
2179 }
2180 for (int i = 0; i < m2->GetNumRows(); i++) {
2181 cLocalArray* row = m2->GetRow(i);
2182 for (int j = 0; j < m2->GetNumCols(); j++) {
2183 const sAggregateValue& val = row->Get(j);
2184 switch (val.type.type) {
2185 case TYPE(BOOL): op2[i][j] = (val.value.as_bool) ? 1 : 0; break;
2186 case TYPE(CHAR): op2[i][j] = (int)val.value.as_char; break;
2187 case TYPE(INT): op2[i][j] = val.value.as_int; break;
2188 case TYPE(STRING): op2[i][j] = val.value.as_string->AsInt(); break;
2189
2190 default:
2191 INTERPRET_ERROR(MATRIX_OP_TYPE_MISMATCH, mapToken(TOKEN(OP_MUL)), mapType(row->Get(j).type));
2192 }
2193 }
2194 }
2195
2196 int sz_x = m1->GetNumRows();
2197 int sz_y = m2->GetNumCols();
2198 cLocalMatrix* mat = new cLocalMatrix();
2199 mat->Resize(sz_x, sz_y);
2200
2201 sASTypeInfo op_type(TYPE(INT));
2202 for (int i = 0; i < sz_x; i++) {
2203 cLocalArray* row = mat->GetRow(i);
2204 for (int j = 0; j < sz_y; j++) {
2205 uAnyType sum;
2206 sum.as_int = 0;
2207 for (int k = 0; k < m1->GetNumCols(); k++) sum.as_int += op1[i][k] * op2[k][j];
2208 row->Set(j, op_type, sum);
2209 }
2210 }
2211
2212 m_rvalue.as_matrix = mat;
2213 m_rtype = TYPE(MATRIX);
2214 }
2215
2216
matrixMultiply_FullFloat(cLocalMatrix * m1,cLocalMatrix * m2,cASTNode & node)2217 void cDirectInterpretASTVisitor::matrixMultiply_FullFloat(cLocalMatrix* m1, cLocalMatrix* m2, cASTNode& node)
2218 {
2219 tMatrix<double> op1(m1->GetNumRows(), m1->GetNumCols());
2220 tMatrix<double> op2(m2->GetNumRows(), m2->GetNumCols());
2221
2222 for (int i = 0; i < m1->GetNumRows(); i++) {
2223 cLocalArray* row = m1->GetRow(i);
2224 for (int j = 0; j < m1->GetNumCols(); j++) {
2225 const sAggregateValue& val = row->Get(j);
2226 switch (val.type.type) {
2227 case TYPE(BOOL): op1[i][j] = (val.value.as_bool) ? 1.0 : 0.0; break;
2228 case TYPE(CHAR): op1[i][j] = (double)val.value.as_char; break;
2229 case TYPE(INT): op1[i][j] = (double)val.value.as_int; break;
2230 case TYPE(FLOAT): op1[i][j] = val.value.as_float; break;
2231 case TYPE(STRING): op1[i][j] = val.value.as_string->AsDouble(); break;
2232
2233 default:
2234 INTERPRET_ERROR(MATRIX_OP_TYPE_MISMATCH, mapToken(TOKEN(OP_MUL)), mapType(row->Get(j).type));
2235 }
2236 }
2237 }
2238 for (int i = 0; i < m2->GetNumRows(); i++) {
2239 cLocalArray* row = m2->GetRow(i);
2240 for (int j = 0; j < m2->GetNumCols(); j++) {
2241 const sAggregateValue& val = row->Get(j);
2242 switch (val.type.type) {
2243 case TYPE(BOOL): op2[i][j] = (val.value.as_bool) ? 1.0 : 0.0; break;
2244 case TYPE(CHAR): op2[i][j] = (double)val.value.as_char; break;
2245 case TYPE(INT): op2[i][j] = (double)val.value.as_int; break;
2246 case TYPE(FLOAT): op2[i][j] = val.value.as_float; break;
2247 case TYPE(STRING): op2[i][j] = val.value.as_string->AsDouble(); break;
2248
2249 default:
2250 INTERPRET_ERROR(MATRIX_OP_TYPE_MISMATCH, mapToken(TOKEN(OP_MUL)), mapType(row->Get(j).type));
2251 }
2252 }
2253 }
2254
2255 int sz_x = m1->GetNumRows();
2256 int sz_y = m2->GetNumCols();
2257 cLocalMatrix* mat = new cLocalMatrix();
2258 mat->Resize(sz_x, sz_y);
2259
2260 sASTypeInfo op_type(TYPE(FLOAT));
2261 for (int i = 0; i < sz_x; i++) {
2262 cLocalArray* row = mat->GetRow(i);
2263 for (int j = 0; j < sz_y; j++) {
2264 uAnyType sum;
2265 sum.as_float = 0.0;
2266 for (int k = 0; k < m1->GetNumCols(); k++) sum.as_float += op1[i][k] * op2[k][j];
2267 row->Set(j, op_type, sum);
2268 }
2269 }
2270
2271 m_rvalue.as_matrix = mat;
2272 m_rtype = TYPE(MATRIX);
2273 }
2274
2275
2276
2277
Cleanup()2278 void cDirectInterpretASTVisitor::sAggregateValue::Cleanup()
2279 {
2280 switch (type.type) {
2281 case TYPE(ARRAY): value.as_array->RemoveReference(); break;
2282 case TYPE(DICT): value.as_dict->RemoveReference(); break;
2283 case TYPE(MATRIX): value.as_matrix->RemoveReference(); break;
2284 case TYPE(OBJECT_REF): delete value.as_ref; break;
2285 case TYPE(STRING): delete value.as_string; break;
2286 default: break;
2287 }
2288 }
2289
operator ==(const sAggregateValue & lval)2290 bool cDirectInterpretASTVisitor::sAggregateValue::operator==(const sAggregateValue& lval)
2291 {
2292 if (type == lval.type) {
2293 switch (type.type) {
2294 case TYPE(BOOL): return value.as_bool == lval.value.as_bool;
2295 case TYPE(CHAR): return value.as_char == lval.value.as_char;
2296 case TYPE(INT): return value.as_int == lval.value.as_int;
2297 case TYPE(FLOAT): return value.as_float == lval.value.as_float;
2298 case TYPE(STRING): return *value.as_string == *lval.value.as_string;
2299 case TYPE(ARRAY): return value.as_array == lval.value.as_array;
2300 case TYPE(DICT): return value.as_dict == lval.value.as_dict;
2301 case TYPE(MATRIX): return value.as_matrix == lval.value.as_matrix;
2302 case TYPE(OBJECT_REF): return value.as_nobj == lval.value.as_nobj;
2303
2304 default:
2305 break;
2306 }
2307 }
2308
2309 return false;
2310 }
2311
Set(int i,const sASTypeInfo & type,uAnyType value)2312 void cDirectInterpretASTVisitor::cLocalArray::Set(int i, const sASTypeInfo& type, uAnyType value)
2313 {
2314 m_storage[i].Cleanup();
2315
2316 m_storage[i].type = type;
2317
2318 switch (type.type) {
2319 case TYPE(BOOL):
2320 case TYPE(CHAR):
2321 case TYPE(INT):
2322 case TYPE(FLOAT):
2323 m_storage[i].value = value;
2324 break;
2325
2326 case TYPE(STRING):
2327 m_storage[i].value.as_string = new cString(*value.as_string);
2328 break;
2329
2330 case TYPE(ARRAY):
2331 m_storage[i].value.as_array = value.as_array->GetReference();
2332 break;
2333
2334 case TYPE(DICT):
2335 m_storage[i].value.as_dict = value.as_dict->GetReference();
2336 break;
2337
2338 case TYPE(MATRIX):
2339 m_storage[i].value.as_matrix = value.as_matrix->GetReference();
2340 break;
2341
2342 default: break;
2343 }
2344
2345 }
2346
copy(int offset,tArray<sAggregateValue> & in_storage)2347 void cDirectInterpretASTVisitor::cLocalArray::copy(int offset, tArray<sAggregateValue>& in_storage)
2348 {
2349 for (int i = 0; i < in_storage.GetSize(); i++) {
2350 m_storage[i + offset].type = in_storage[i].type;
2351 switch (in_storage[i].type.type) {
2352 case TYPE(BOOL): m_storage[i + offset].value.as_bool = in_storage[i].value.as_bool; break;
2353 case TYPE(CHAR): m_storage[i + offset].value.as_char = in_storage[i].value.as_char; break;
2354 case TYPE(INT): m_storage[i + offset].value.as_int = in_storage[i].value.as_int; break;
2355 case TYPE(FLOAT): m_storage[i + offset].value.as_float = in_storage[i].value.as_float; break;
2356 case TYPE(STRING): m_storage[i + offset].value.as_string = new cString(*in_storage[i].value.as_string); break;
2357 case TYPE(ARRAY): m_storage[i + offset].value.as_array = in_storage[i].value.as_array->GetReference(); break;
2358 case TYPE(DICT): m_storage[i + offset].value.as_dict = in_storage[i].value.as_dict->GetReference(); break;
2359 case TYPE(MATRIX): m_storage[i + offset].value.as_matrix = in_storage[i].value.as_matrix->GetReference(); break;
2360
2361 default: break;
2362 }
2363 }
2364 }
2365
2366
Resize(int sz)2367 void cDirectInterpretASTVisitor::cLocalArray::Resize(int sz)
2368 {
2369 int o_sz = m_storage.GetSize();
2370
2371 // Cleanup values if we are shrinking
2372 for (int i = sz; i < o_sz; i++) m_storage[i].Cleanup();
2373
2374 m_storage.Resize(sz);
2375
2376 // Initialize values if we are growing
2377 for (int i = o_sz; i < sz; i++) {
2378 m_storage[i].value.as_int = 0;
2379 m_storage[i].type = TYPE(INT);
2380 }
2381 }
2382
SetWithArray(cLocalArray * arr)2383 void cDirectInterpretASTVisitor::cLocalArray::SetWithArray(cLocalArray* arr)
2384 {
2385 Resize(arr->GetSize());
2386
2387 for (int i = 0; i < arr->GetSize(); i++) Set(i, arr->Get(i));
2388 }
2389
SetWithKeys(cLocalDict * dict)2390 void cDirectInterpretASTVisitor::cLocalArray::SetWithKeys(cLocalDict* dict)
2391 {
2392 Resize(0);
2393
2394 dict->GetKeys(m_storage);
2395
2396 for (int i = 0; i < m_storage.GetSize(); i++) {
2397 switch (m_storage[i].type.type) {
2398 case TYPE(STRING): m_storage[i].value.as_string = new cString(*m_storage[i].value.as_string); break;
2399 case TYPE(ARRAY): m_storage[i].value.as_array->GetReference(); break;
2400 case TYPE(DICT): m_storage[i].value.as_dict->GetReference(); break;
2401 case TYPE(MATRIX): m_storage[i].value.as_matrix->GetReference(); break;
2402
2403 default: break;
2404 }
2405 }
2406 }
2407
2408
SetWithValues(cLocalDict * dict)2409 void cDirectInterpretASTVisitor::cLocalArray::SetWithValues(cLocalDict* dict)
2410 {
2411 Resize(0);
2412
2413 dict->GetValues(m_storage);
2414
2415 for (int i = 0; i < m_storage.GetSize(); i++) {
2416 switch (m_storage[i].type.type) {
2417 case TYPE(STRING): m_storage[i].value.as_string = new cString(*m_storage[i].value.as_string); break;
2418 case TYPE(ARRAY): m_storage[i].value.as_array->GetReference(); break;
2419 case TYPE(DICT): m_storage[i].value.as_dict->GetReference(); break;
2420 case TYPE(MATRIX): m_storage[i].value.as_matrix->GetReference(); break;
2421
2422 default: break;
2423 }
2424 }
2425 }
2426
2427
~cLocalArray()2428 cDirectInterpretASTVisitor::cLocalArray::~cLocalArray()
2429 {
2430 int sz = m_storage.GetSize();
2431
2432 // Cleanup values stored in the array
2433 for (int i = 0; i < sz; i++) m_storage[i].Cleanup();
2434 }
2435
2436
Resize(int sz_x,int sz_y)2437 void cDirectInterpretASTVisitor::cLocalMatrix::Resize(int sz_x, int sz_y)
2438 {
2439 int o_sz = m_storage.GetSize();
2440 m_storage.Resize(sz_x);
2441
2442 // Resize the columns
2443 for (int i = (m_sz_y == sz_y) ? o_sz : 0; i < sz_x; i++) {
2444 m_storage[i].SetNonResizable();
2445 m_storage[i].Resize(sz_y);
2446 }
2447
2448 m_sz_y = sz_y;
2449 }
2450
2451
2452
2453
Set(const sAggregateValue & idx,const sAggregateValue & val)2454 void cDirectInterpretASTVisitor::cLocalDict::Set(const sAggregateValue& idx, const sAggregateValue& val)
2455 {
2456 sAggregateValue o_val;
2457 if (m_storage.Find(idx, o_val)) {
2458 o_val.Cleanup();
2459 m_storage.SetValue(idx, val);
2460 } else {
2461 m_storage.SetValue(idx, val);
2462 }
2463
2464 }
2465
Clear()2466 void cDirectInterpretASTVisitor::cLocalDict::Clear()
2467 {
2468 tList<sAggregateValue> keys;
2469 tList<sAggregateValue> vals;
2470
2471 m_storage.AsListsUnsorted(keys, vals);
2472
2473 sAggregateValue* av = NULL;
2474
2475 tListIterator<sAggregateValue> kit(keys);
2476 while ((av = kit.Next())) av->Cleanup();
2477
2478 tListIterator<sAggregateValue> vit(vals);
2479 while ((av = vit.Next())) av->Cleanup();
2480
2481 m_storage.ClearAll();
2482 }
2483
~cLocalDict()2484 cDirectInterpretASTVisitor::cLocalDict::~cLocalDict()
2485 {
2486 tList<sAggregateValue> keys;
2487 tList<sAggregateValue> vals;
2488
2489 m_storage.AsListsUnsorted(keys, vals);
2490
2491 sAggregateValue* av = NULL;
2492
2493 tListIterator<sAggregateValue> kit(keys);
2494 while ((av = kit.Next())) av->Cleanup();
2495
2496 tListIterator<sAggregateValue> vit(vals);
2497 while ((av = vit.Next())) av->Cleanup();
2498 }
2499
2500
Get(const sAggregateValue & idx,sAggregateValue & val)2501 bool cDirectInterpretASTVisitor::cArrayVarRef::Get(const sAggregateValue& idx, sAggregateValue& val)
2502 {
2503 int idxi = -1;
2504 switch (idx.type.type) {
2505 case TYPE(BOOL): idxi = (idx.value.as_bool) ? 1 : 0; break;
2506 case TYPE(CHAR): idxi = (int)idx.value.as_char; break;
2507 case TYPE(INT): idxi = idx.value.as_int; break;
2508 case TYPE(FLOAT): idxi = (int)idx.value.as_float; break;
2509 case TYPE(STRING): idxi = idx.value.as_string->AsInt(); break;
2510 default: break;
2511 }
2512
2513 if (idxi < 0 || idxi >= m_var.as_array->GetSize()) return false;
2514
2515 val = m_var.as_array->Get(idxi);
2516 return true;
2517 }
2518
Set(sAggregateValue & idx,sAggregateValue & val)2519 bool cDirectInterpretASTVisitor::cArrayVarRef::Set(sAggregateValue& idx, sAggregateValue& val)
2520 {
2521 int idxi = -1;
2522 switch (idx.type.type) {
2523 case TYPE(BOOL): idxi = (idx.value.as_bool) ? 1 : 0; break;
2524 case TYPE(CHAR): idxi = (int)idx.value.as_char; break;
2525 case TYPE(INT): idxi = idx.value.as_int; break;
2526 case TYPE(FLOAT): idxi = (int)idx.value.as_float; break;
2527 case TYPE(STRING): idxi = idx.value.as_string->AsInt(); delete idx.value.as_string; break;
2528 case TYPE(ARRAY): idx.value.as_array->RemoveReference(); break;
2529 case TYPE(DICT): idx.value.as_dict->RemoveReference(); break;
2530 case TYPE(MATRIX): idx.value.as_matrix->RemoveReference(); break;
2531 case TYPE(OBJECT_REF): delete idx.value.as_ref; break;
2532 default: break;
2533 }
2534
2535 if (idxi < 0 || idxi >= m_var.as_array->GetSize()) return false;
2536
2537 m_var.as_array->Set(idxi, val.type, val.value);
2538
2539 return true;
2540 }
2541
2542
Get(const sAggregateValue & idx,sAggregateValue & val)2543 bool cDirectInterpretASTVisitor::cDictVarRef::Get(const sAggregateValue& idx, sAggregateValue& val)
2544 {
2545 return m_var.as_dict->Get(idx, val);
2546 }
2547
Set(sAggregateValue & idx,sAggregateValue & val)2548 bool cDirectInterpretASTVisitor::cDictVarRef::Set(sAggregateValue& idx, sAggregateValue& val)
2549 {
2550 m_var.as_dict->Set(idx, val);
2551 return true;
2552 }
2553
2554
Get(const sAggregateValue & idx,sAggregateValue & val)2555 bool cDirectInterpretASTVisitor::cMatrixVarRef::Get(const sAggregateValue& idx, sAggregateValue& val)
2556 {
2557 int idxi = -1;
2558 switch (idx.type.type) {
2559 case TYPE(BOOL): idxi = (idx.value.as_bool) ? 1 : 0; break;
2560 case TYPE(CHAR): idxi = (int)idx.value.as_char; break;
2561 case TYPE(INT): idxi = idx.value.as_int; break;
2562 case TYPE(FLOAT): idxi = (int)idx.value.as_float; break;
2563 case TYPE(STRING): idxi = idx.value.as_string->AsInt(); break;
2564 default: break;
2565 }
2566
2567 if (idxi < 0 || idxi >= m_var.as_matrix->GetNumRows()) return false;
2568
2569 val.value.as_array = m_var.as_matrix->GetRow(idxi);
2570 val.type = TYPE(ARRAY);
2571 return true;
2572 }
2573
Set(sAggregateValue & idx,sAggregateValue & val)2574 bool cDirectInterpretASTVisitor::cMatrixVarRef::Set(sAggregateValue& idx, sAggregateValue& val)
2575 {
2576 int idxi = -1;
2577 switch (idx.type.type) {
2578 case TYPE(BOOL): idxi = (idx.value.as_bool) ? 1 : 0; break;
2579 case TYPE(CHAR): idxi = (int)idx.value.as_char; break;
2580 case TYPE(INT): idxi = idx.value.as_int; break;
2581 case TYPE(FLOAT): idxi = (int)idx.value.as_float; break;
2582 case TYPE(STRING): idxi = idx.value.as_string->AsInt(); delete idx.value.as_string; break;
2583 case TYPE(ARRAY): idx.value.as_array->RemoveReference(); break;
2584 case TYPE(DICT): idx.value.as_dict->RemoveReference(); break;
2585 case TYPE(MATRIX): idx.value.as_matrix->RemoveReference(); break;
2586 case TYPE(OBJECT_REF): delete idx.value.as_ref; break;
2587 default: break;
2588 }
2589
2590 if (idxi < 0 || idxi >= m_var.as_matrix->GetNumRows()) return false;
2591
2592 if (m_var.as_matrix->GetNumCols() == 0) return false;
2593 if (val.type.type != TYPE(ARRAY)) return false;
2594 if (val.value.as_array->GetSize() != m_var.as_matrix->GetNumCols()) return false;
2595 m_var.as_matrix->Set(idxi, val.value.as_array);
2596
2597 return true;
2598 }
2599
2600
Get(const sAggregateValue & idx,sAggregateValue & val)2601 bool cDirectInterpretASTVisitor::cNativeObjectVarRef::Get(const sAggregateValue& idx, sAggregateValue& val)
2602 {
2603 // @AS_TODO - get indexed native var
2604 return false;
2605 }
2606
Set(sAggregateValue & idx,sAggregateValue & val)2607 bool cDirectInterpretASTVisitor::cNativeObjectVarRef::Set(sAggregateValue& idx, sAggregateValue& val)
2608 {
2609 // @AS_TODO - set indexed native var
2610 return false;
2611 }
2612
2613
2614
2615
Get(const sAggregateValue & idx,sAggregateValue & val)2616 bool cDirectInterpretASTVisitor::cObjectIndexRef::Get(const sAggregateValue& idx, sAggregateValue& val)
2617 {
2618 sAggregateValue o_val;
2619
2620 if (!m_obj->Get(m_idx, o_val)) return false;
2621
2622 switch (o_val.type.type) {
2623 case TYPE(ARRAY):
2624 {
2625 cLocalArray* arr = o_val.value.as_array;
2626
2627 int idxi = -1;
2628 switch (idx.type.type) {
2629 case TYPE(BOOL): idxi = (idx.value.as_bool) ? 1 : 0; break;
2630 case TYPE(CHAR): idxi = (int)idx.value.as_char; break;
2631 case TYPE(INT): idxi = idx.value.as_int; break;
2632 case TYPE(FLOAT): idxi = (int)idx.value.as_float; break;
2633 case TYPE(STRING): idxi = idx.value.as_string->AsInt(); break;
2634 default: break;
2635 }
2636 if (idxi < 0 || idxi >= arr->GetSize()) return false;
2637 val = arr->Get(idxi);
2638 return true;
2639 }
2640
2641 case TYPE(DICT):
2642 return o_val.value.as_dict->Get(idx, val);
2643
2644 case TYPE(MATRIX):
2645 {
2646 cLocalMatrix* mat = o_val.value.as_matrix;
2647
2648 int idxi = -1;
2649 switch (idx.type.type) {
2650 case TYPE(BOOL): idxi = (idx.value.as_bool) ? 1 : 0; break;
2651 case TYPE(CHAR): idxi = (int)idx.value.as_char; break;
2652 case TYPE(INT): idxi = idx.value.as_int; break;
2653 case TYPE(FLOAT): idxi = (int)idx.value.as_float; break;
2654 case TYPE(STRING): idxi = idx.value.as_string->AsInt(); break;
2655 default: break;
2656 }
2657 if (idxi < 0 || idxi >= mat->GetNumRows()) return false;
2658 val.value.as_array = mat->GetRow(idxi);
2659 val.type = TYPE(ARRAY);
2660 return true;
2661 }
2662
2663 default:
2664 break;
2665 }
2666
2667
2668 return false;
2669 }
2670
2671
Set(sAggregateValue & idx,sAggregateValue & val)2672 bool cDirectInterpretASTVisitor::cObjectIndexRef::Set(sAggregateValue& idx, sAggregateValue& val)
2673 {
2674 sAggregateValue o_val;
2675
2676 if (!m_obj->Get(m_idx, o_val)) {
2677 idx.Cleanup();
2678 return false;
2679 }
2680
2681 switch (o_val.type.type) {
2682 case TYPE(ARRAY):
2683 {
2684 cLocalArray* arr = o_val.value.as_array;
2685
2686 int idxi = -1;
2687 switch (idx.type.type) {
2688 case TYPE(BOOL): idxi = (idx.value.as_bool) ? 1 : 0; break;
2689 case TYPE(CHAR): idxi = (int)idx.value.as_char; break;
2690 case TYPE(INT): idxi = idx.value.as_int; break;
2691 case TYPE(FLOAT): idxi = (int)idx.value.as_float; break;
2692 case TYPE(STRING): idxi = idx.value.as_string->AsInt(); delete idx.value.as_string; break;
2693 case TYPE(ARRAY): idx.value.as_array->RemoveReference(); break;
2694 case TYPE(DICT): idx.value.as_dict->RemoveReference(); break;
2695 case TYPE(MATRIX): idx.value.as_matrix->RemoveReference(); break;
2696 case TYPE(OBJECT_REF): delete idx.value.as_ref; break;
2697 default: break;
2698 }
2699 if (idxi < 0 || idxi >= arr->GetSize()) return false;
2700
2701 arr->Set(idxi, val.type, val.value);
2702 }
2703 return true;
2704
2705 case TYPE(DICT):
2706 o_val.value.as_dict->Set(idx, val);
2707 return true;
2708
2709 case TYPE(MATRIX):
2710 {
2711 cLocalMatrix* mat = o_val.value.as_matrix;
2712
2713 int idxi = -1;
2714 switch (idx.type.type) {
2715 case TYPE(BOOL): idxi = (idx.value.as_bool) ? 1 : 0; break;
2716 case TYPE(CHAR): idxi = (int)idx.value.as_char; break;
2717 case TYPE(INT): idxi = idx.value.as_int; break;
2718 case TYPE(FLOAT): idxi = (int)idx.value.as_float; break;
2719 case TYPE(STRING): idxi = idx.value.as_string->AsInt(); delete idx.value.as_string; break;
2720 case TYPE(ARRAY): idx.value.as_array->RemoveReference(); break;
2721 case TYPE(DICT): idx.value.as_dict->RemoveReference(); break;
2722 case TYPE(MATRIX): idx.value.as_matrix->RemoveReference(); break;
2723 case TYPE(OBJECT_REF): delete idx.value.as_ref; break;
2724 default: break;
2725 }
2726 if (idxi < 0 || idxi >= mat->GetNumRows()) return false;
2727
2728 if (mat->GetNumCols() == 0) return false;
2729 if (val.type.type != TYPE(ARRAY)) return false;
2730 if (val.value.as_array->GetSize() != mat->GetNumCols()) return false;
2731 mat->Set(idxi, val.value.as_array);
2732 }
2733 return true;
2734
2735 default:
2736 break;
2737 }
2738
2739 idx.Cleanup();
2740 return false;
2741 }
2742
2743
Get(const sAggregateValue & idx,sAggregateValue & val)2744 bool cDirectInterpretASTVisitor::cStringVarRef::Get(const sAggregateValue& idx, sAggregateValue& val)
2745 {
2746 int idxi = -1;
2747 switch (idx.type.type) {
2748 case TYPE(BOOL): idxi = (idx.value.as_bool) ? 1 : 0; break;
2749 case TYPE(CHAR): idxi = (int)idx.value.as_char; break;
2750 case TYPE(INT): idxi = idx.value.as_int; break;
2751 case TYPE(FLOAT): idxi = (int)idx.value.as_float; break;
2752 case TYPE(STRING): idxi = idx.value.as_string->AsInt(); break;
2753 default: break;
2754 }
2755
2756 if (idxi < 0 || idxi >= m_var.as_string->GetSize()) return false;
2757
2758 val.value.as_char = (*m_var.as_string)[idxi];
2759 val.type = TYPE(CHAR);
2760 return true;
2761 }
2762
Set(sAggregateValue & idx,sAggregateValue & val)2763 bool cDirectInterpretASTVisitor::cStringVarRef::Set(sAggregateValue& idx, sAggregateValue& val)
2764 {
2765 int idxi = -1;
2766 switch (idx.type.type) {
2767 case TYPE(BOOL): idxi = (idx.value.as_bool) ? 1 : 0; break;
2768 case TYPE(CHAR): idxi = (int)idx.value.as_char; break;
2769 case TYPE(INT): idxi = idx.value.as_int; break;
2770 case TYPE(FLOAT): idxi = (int)idx.value.as_float; break;
2771 case TYPE(STRING): idxi = idx.value.as_string->AsInt(); delete idx.value.as_string; break;
2772 case TYPE(ARRAY): idx.value.as_array->RemoveReference(); break;
2773 case TYPE(DICT): idx.value.as_dict->RemoveReference(); break;
2774 case TYPE(MATRIX): idx.value.as_matrix->RemoveReference(); break;
2775 case TYPE(OBJECT_REF): delete idx.value.as_ref; break;
2776 default: break;
2777 }
2778
2779 if (idxi < 0 || idxi >= m_var.as_string->GetSize()) return false;
2780
2781 switch (val.type.type) {
2782 case TYPE(BOOL): (*m_var.as_string)[idxi] = (val.value.as_bool) ? 1 : 0; break;
2783 case TYPE(CHAR): (*m_var.as_string)[idxi] = val.value.as_char; break;
2784 case TYPE(INT): (*m_var.as_string)[idxi] = (char)val.value.as_int; break;
2785
2786 default:
2787 return false;
2788 }
2789
2790 return true;
2791 }
2792
2793
2794
reportError(ASDirectInterpretError_t err,const cASFilePosition & fp,const int line,...)2795 void cDirectInterpretASTVisitor::reportError(ASDirectInterpretError_t err, const cASFilePosition& fp, const int line, ...)
2796 {
2797 #if DEBUG_AS_DIRECT_INTERPRET
2798 # define ERR_ENDL " (cDirectInterpretASTVisitor.cc:" << line << ")" << std::endl
2799 #else
2800 # define ERR_ENDL std::endl
2801 #endif
2802
2803 #define VA_ARG_STR va_arg(vargs, const char*)
2804
2805 std::cerr << fp.GetFilename() << ":" << fp.GetLineNumber() << ": error: ";
2806
2807 va_list vargs;
2808 va_start(vargs, line);
2809 switch (err) {
2810 case AS_DIRECT_INTERPRET_ERR_CANNOT_RESIZE_MATRIX_ROW:
2811 std::cerr << "cannot directly resize matrix row" << ERR_ENDL;
2812 break;
2813 case AS_DIRECT_INTERPRET_ERR_DIVISION_BY_ZERO:
2814 std::cerr << "division by zero" << ERR_ENDL;
2815 break;
2816 case AS_DIRECT_INTERPRET_ERR_INDEX_ERROR:
2817 std::cerr << "index operation failed" << ERR_ENDL;
2818 break;
2819 case AS_DIRECT_INTERPRET_ERR_INDEX_OUT_OF_BOUNDS:
2820 std::cerr << "array index out of bounds" << ERR_ENDL;
2821 break;
2822 case AS_DIRECT_INTERPRET_ERR_INVALID_ARRAY_SIZE:
2823 std::cerr << "invalid array dimension" << ERR_ENDL;
2824 break;
2825 case AS_DIRECT_INTERPRET_ERR_KEY_NOT_FOUND:
2826 std::cerr << "key not found" << ERR_ENDL;
2827 break;
2828 case AS_DIRECT_INTERPRET_ERR_MATRIX_OP_TYPE_MISMATCH:
2829 {
2830 const char* op = VA_ARG_STR;
2831 const char* type = VA_ARG_STR;
2832 std::cerr << "matrix '" << op << "' undefined for contained value of type '" << type << "'" << ERR_ENDL;
2833 }
2834 break;
2835 case AS_DIRECT_INTERPRET_ERR_MATRIX_SIZE_MISMATCH:
2836 std::cerr << "matrix size mismatch for '" << VA_ARG_STR << "' operation" << ERR_ENDL;
2837 break;
2838 case AS_DIRECT_INTERPRET_ERR_NOBJ_METHOD_LOOKUP_FAILED:
2839 {
2840 const char* meth = VA_ARG_STR;
2841 const char* itype = VA_ARG_STR;
2842 std::cerr << "method '" << meth << "' not supported by '" << itype << "'" << ERR_ENDL;
2843 }
2844 break;
2845 case AS_DIRECT_INTERPRET_ERR_NOBJ_TYPE_MISMATCH:
2846 {
2847 const char* otype = VA_ARG_STR;
2848 const char* itype = VA_ARG_STR;
2849 std::cerr << "expected object of type '" << otype << "', received '" << itype << "'" << ERR_ENDL;
2850 }
2851 break;
2852 case AS_DIRECT_INTERPRET_ERR_OBJECT_ASSIGN_FAIL:
2853 std::cerr << "aggregate assignment failed" << ERR_ENDL;
2854 break;
2855 case AS_DIRECT_INTERPRET_ERR_TYPE_CAST:
2856 {
2857 const char* type1 = VA_ARG_STR;
2858 const char* type2 = VA_ARG_STR;
2859 std::cerr << "cannot convert '" << type1 << "' to '" << type2 << "'" << ERR_ENDL;
2860 }
2861 break;
2862 case AS_DIRECT_INTERPRET_ERR_UNDEFINED_TYPE_OP:
2863 {
2864 const char* op = VA_ARG_STR;
2865 const char* type = VA_ARG_STR;
2866 std::cerr << "'" << op << "' operation undefined for type '" << type << "'" << ERR_ENDL;
2867 }
2868 break;
2869 case AS_DIRECT_INTERPRET_ERR_UNPACK_VALUE_TOO_LARGE:
2870 std::cerr << "unpack value too large" << ERR_ENDL;
2871 break;
2872 case AS_DIRECT_INTERPRET_ERR_UNPACK_VALUE_TOO_SMALL:
2873 std::cerr << "unpack value too small" << ERR_ENDL;
2874 break;
2875
2876 case AS_DIRECT_INTERPRET_ERR_INTERNAL:
2877 std::cerr << "internal interpreter error at cDirectInterpretASTVisitor.cc:" << line << std::endl;
2878 break;
2879 case AS_DIRECT_INTERPRET_ERR_UNKNOWN:
2880 default:
2881 std::cerr << "unknown error" << std::endl;
2882 }
2883 va_end(vargs);
2884
2885 exit(AS_EXIT_FAIL_INTERPRET);
2886
2887 #undef ERR_ENDL
2888 #undef VA_ARG_STR
2889 }
2890
2891 #undef INTERPRET_ERROR()
2892 #undef TOKEN()
2893 #undef TYPE()
2894