diff --git a/cx/include/cx_async.h b/cx/include/cx_async.h
index 9075813f..c666e28e 100644
--- a/cx/include/cx_async.h
+++ b/cx/include/cx_async.h
@@ -70,7 +70,7 @@ int cx_ainc(int* count);
int cx_adec(int* count);
/* use GNU atomic compare and swap */
-#define cx_cas(ptr,old,new) __sync_bool_compare_and_swap(ptr,old,new)
+#define cx_cas(ptr, old, new) __sync_bool_compare_and_swap(ptr, old, new)
#ifdef __cplusplus
}
diff --git a/cx/include/cx_def.h b/cx/include/cx_def.h
index ec384d04..d3f2d730 100644
--- a/cx/include/cx_def.h
+++ b/cx/include/cx_def.h
@@ -64,14 +64,16 @@ typedef struct cx_ll_s* cx_ll;
/* C language binding type definition macro's */
#define CX_ANY(__type) typedef struct __type {cx_type type; void *value; cx_bool owner;} __type
#define CX_ITERATOR(__type) typedef struct __type {\
+ void *current;\
cx_collection type;\
+ cx_bool (*next)(void* iterator);\
union {\
struct { /* CX_ARRAY and CX_SEQUENCE */\
void *array;\
- void *element;\
+ int32_t elementSize;\
+ void* max;\
} array;\
struct {\
- cx_ll *ll;\
cx_iter iter;\
} ll;\
} is;\
diff --git a/cx/include/cx_iterator.h b/cx/include/cx_iterator.h
index 5f6bbc4c..fdf8b3e3 100644
--- a/cx/include/cx_iterator.h
+++ b/cx/include/cx_iterator.h
@@ -20,6 +20,7 @@ extern "C" {
/* $header() */
cx_int16 cx_iterator_set(void *_this, void *collection, cx_collection collectionType);
+cx_bool cx_iterator_next(void *_this);
/* $end */
/* virtual ::cortex::lang::iterator::castable(type type) */
@@ -37,9 +38,6 @@ cx_bool cx_iterator_compatible_v(cx_iterator _this, cx_type type);
/* ::cortex::lang::iterator::init() */
cx_int16 cx_iterator_init(cx_iterator _this);
-cx_bool cx_iterator_hasNext(void *_this);
-void *cx_iterator_next(void *_this);
-
#ifdef __cplusplus
}
#endif
diff --git a/cx/include/cx_vm_def.h b/cx/include/cx_vm_def.h
index 852422e3..9f12b0cf 100644
--- a/cx/include/cx_vm_def.h
+++ b/cx/include/cx_vm_def.h
@@ -94,7 +94,7 @@ extern "C" {
OP2_EXP(expand##2, ELEMM, W, R, PQRV, typeAction, opAction)\
OP2_EXP(expand##2, ELEMMX, W, R, PQRV, typeAction, opAction)\
OP2_EXP(expand##2, ITER_SET, W, PQR, PQRV, typeAction, opAction)\
- OP3_EXP(expand##3, ITER_NEXT, W, PQR, PQR, PQRV, typeAction, opAction)\
+ OP2_EXP(expand##2, ITER_NEXT, W, PQR, PQRV, typeAction, opAction)\
OP1_EXP(expand##1, PUSH, BSLD, PQRV, typeAction, opAction) /* Regular push */\
OP1_EXP(expand##1, PUSHX, BSLD, R, typeAction, opAction) /* Push address of a register */\
OP1_EXP(expand##1, PUSHANY, W, PQRV, typeAction, opAction) /* Push any value */\
diff --git a/cx/src/cx_iterator.c b/cx/src/cx_iterator.c
index 1a345a82..c6980f24 100644
--- a/cx/src/cx_iterator.c
+++ b/cx/src/cx_iterator.c
@@ -10,146 +10,92 @@
#include "cx__meta.h"
/* $header() */
-
-cx_int16 cx_iterator_set(void* _this, void* collection, cx_collection collectionType) {
- CX_ITERATOR(IteratorType);
- IteratorType *iter = _this;
- iter->type = collectionType;
-
- switch (collectionType->kind) {
- case CX_ARRAY:
- case CX_SEQUENCE:
- iter->is.array.array = collection;
- iter->is.array.element = collection;
- break;
- case CX_LIST:
- iter->is.ll.ll = collection;
- iter->is.ll.iter = cx_llIter(collection);
- break;
- case CX_MAP:
- break;
+CX_ITERATOR(iteratorType);
+CX_SEQUENCE(seqType, cx_object, );
+
+/* Combined hasNext and next */
+static cx_bool cx_iterator_next_array(void* iterator) {
+ iteratorType *iter = iterator;
+ cx_uint32 elementSize = iter->is.array.elementSize;
+ void *current = iter->current;
+ cx_bool result = FALSE;
+ current = CX_OFFSET(current, elementSize);
+ if (current < iter->is.array.max) {
+ iter->current = current;
+ result = TRUE;
}
- return 0;
+ return result;
}
-static cx_bool cx_iterator_hasNext_array(void* iterator) {
- CX_ITERATOR(IteratorType);
- IteratorType *iter = iterator;
- cx_collection collection = iter->type;
- cx_void *array = iter->is.array.array;
- void *element = iter->is.array.element;
- cx_bool hasNext = FALSE;
- cx_type elementType = collection->elementType;
- cx_uint32 elementSize = cx_type_sizeof(elementType);
- cx_uint32 length = collection->max;
- if (element < CX_OFFSET(array, elementSize * length)) {
- hasNext = TRUE;
+static cx_bool cx_iterator_next_listPtr(void* iterator) {
+ iteratorType *iter = iterator;
+ cx_bool result = FALSE;
+ if ((result = cx_iterHasNext(&iter->is.ll.iter))) {
+ iter->current = cx_iterNextPtr(&iter->is.ll.iter);
+ result = TRUE;
}
- return hasNext;
+ return result;
}
-static int cx_iterator_next_array(void* iterator, void** nextElement) {
- CX_ITERATOR(IteratorType);
- IteratorType *iter;
- cx_collection collection;
- cx_void *array;
- void *element;
- cx_type elementType;
- cx_uint32 elementSize;
- cx_uint32 length;
- int error;
-
- error = 1;
- iter = iterator;
- collection = iter->type;
- array = iter->is.array.array;
- element = iter->is.array.element;
- elementType = collection->elementType;
- elementSize = cx_type_sizeof(elementType);
- length = collection->max;
- if (element < CX_OFFSET(array, elementSize * length)) {
- *nextElement = CX_OFFSET(element, elementSize);
- iter->is.array.element = *nextElement;
- error = 0;
+static cx_bool cx_iterator_next_list(void* iterator) {
+ iteratorType *iter = iterator;
+ cx_bool result = FALSE;
+ if ((result = cx_iterHasNext(&iter->is.ll.iter))) {
+ iter->current = cx_iterNext(&iter->is.ll.iter);
+ result = TRUE;
}
- return error;
-}
-
-static cx_bool cx_iterator_hasNext_ll(void* iterator) {
- CX_ITERATOR(IteratorType);
- IteratorType *iter = iterator;
- cx_bool result = cx_iterHasNext(&(iter->is.ll.iter));
return result;
}
-static int cx_iterator_next_ll(void* iterator, void** nextElement) {
- CX_ITERATOR(IteratorType);
- IteratorType *iter = iterator;
- *nextElement = cx_iterNext(&iter->is.ll.iter);
- return 0;
-}
-
-static cx_bool cx_iterator_hasNext_map(void* iterator) {
- // CX_ITERATOR(IteratorType);
+static cx_bool cx_iterator_next_map(void* iterator) {
CX_UNUSED(iterator);
// TODO implement
- return 0;
-}
-
-static int cx_iterator_next_map(void* iterator, void** nextElement) {
- // CX_ITERATOR(IteratorType);
- CX_UNUSED(iterator);
- CX_UNUSED(nextElement);
- // TODO implement
return 1;
}
-cx_bool cx_iterator_hasNext(void* _this) {
+cx_bool cx_iterator_next(void* _this) {
CX_ITERATOR(iteratorType);
iteratorType *iterator = _this;
cx_bool result = FALSE;
- switch (iterator->type->kind) {
- case CX_ARRAY:
- case CX_SEQUENCE:
- result = cx_iterator_hasNext_array(iterator);
- break;
- case CX_LIST:
- result = cx_iterator_hasNext_ll(iterator);
- break;
- case CX_MAP:
- result = cx_iterator_hasNext_map(iterator);
- break;
- default:
- break;
- }
+
+ result = iterator->next(iterator);
+
return result;
}
-void* cx_iterator_next(void* _this) {
- CX_ITERATOR(iteratorType);
- iteratorType *iterator = _this;
- int error = 0;
- void *result = NULL;
+cx_int16 cx_iterator_set(void* _this, void* collection, cx_collection collectionType) {
+ iteratorType *iter = _this;
+ iter->type = collectionType;
- switch (iterator->type->kind) {
+ switch (collectionType->kind) {
case CX_ARRAY:
- case CX_SEQUENCE:
- error = cx_iterator_next_array(iterator, &result);
+ iter->is.array.array = collection;
+ iter->is.array.elementSize = cx_type_sizeof(collectionType->elementType);
+ iter->is.array.max = CX_OFFSET(iter->is.array.array, collectionType->max * iter->is.array.elementSize);
+ iter->current = CX_OFFSET(collection, -iter->is.array.elementSize);
+ iter->next = cx_iterator_next_array;
break;
+ case CX_SEQUENCE:
+ iter->is.array.array = ((seqType*)collection)->buffer;
+ iter->is.array.elementSize = cx_type_sizeof(collectionType->elementType);
+ iter->is.array.max = CX_OFFSET(iter->is.array.array, ((seqType*)collection)->length * iter->is.array.elementSize);
+ iter->current = CX_OFFSET(iter->is.array.array, -iter->is.array.elementSize);
+ iter->next = cx_iterator_next_array;
break;
case CX_LIST:
- error = cx_iterator_next_ll(iterator, &result);
+ iter->is.ll.iter = cx_llIter(*(cx_ll*)collection);
+ if (cx_collection_elementRequiresAlloc(collectionType)) {
+ iter->next = cx_iterator_next_list;
+ } else {
+ iter->next = cx_iterator_next_listPtr;
+ }
+
break;
case CX_MAP:
- error = cx_iterator_next_map(iterator, &result);
- break;
- default:
+ iter->next = cx_iterator_next_map;
break;
}
- if (error || result == NULL) {
- cx_critical("error retrieving next element from collection");
- }
- return result;
+ return 0;
}
/* $end */
diff --git a/cx/src/cx_vm.c b/cx/src/cx_vm.c
index 4f949c84..dda7a577 100644
--- a/cx/src/cx_vm.c
+++ b/cx/src/cx_vm.c
@@ -730,10 +730,8 @@ typedef union Di2f_t {
/* op1 is hasNext, op2 is the result of next and op3 is the iterator */
#define ITER_NEXT(type,code)\
ITER_NEXT_##code:\
- fetchOp3(ITER_NEXT, code);\
- if ((op1_##code = (W_t)cx_iterator_hasNext((void*)op3_##code))) {\
- op2_##code = (W_t)cx_iterator_next((void*)op3_##code);\
- }\
+ fetchOp2(ITER_NEXT, code);\
+ op1_##code = (W_t)cx_iterator_next((void*)op2_##code);\
next();\
#define JUMP(type, code)\
@@ -1070,13 +1068,20 @@ int32_t cx_vm_run(cx_vmProgram program, void *result) {
/* This function converts a single instruction to a string */
#ifdef CX_IC_TRACING
-char * cx_vmOp_toString(char * string, cx_vmOp *instr, const char *op, const char *type, const char *lvalue, const char *rvalue, const char* fetch) {
+char * cx_vmOp_toString(
+ char * string, cx_vmOp *instr, const char *op, const char *type, const char *lvalue, const char *rvalue, const char* fetch) {
char *result = string;
if (fetch && strlen(fetch)) {
- result = strappend(result, "%s_%s%s%s_%s %u %u %u %u\n", op, type, lvalue, rvalue, fetch, instr->ic.b._1, instr->ic.b._2, instr->lo.w, instr->hi.w);
+ result = strappend(
+ result,
+ "%s_%s%s%s_%s %u %u %u %u\n",
+ op, type, lvalue, rvalue, fetch, instr->ic.b._1, instr->ic.b._2, instr->lo.w, instr->hi.w);
} else {
- result = strappend(result, "%s_%s%s%s %hu %hu %u %u\n", op, type, lvalue, rvalue, instr->ic.b._1, instr->ic.b._2, instr->lo.w, instr->hi.w);
+ result = strappend(
+ result,
+ "%s_%s%s%s %hu %hu %u %u\n",
+ op, type, lvalue, rvalue, instr->ic.b._1, instr->ic.b._2, instr->lo.w, instr->hi.w);
}
return result;
diff --git a/dev/src/cx_generatorDepWalk.c b/dev/src/cx_generatorDepWalk.c
index 5b2c010b..562daf2e 100644
--- a/dev/src/cx_generatorDepWalk.c
+++ b/dev/src/cx_generatorDepWalk.c
@@ -380,6 +380,7 @@ int cx_genDepBuildAction(cx_object o, void* userData) {
g_itemDepend(dependee, CX_DECLARED, type, CX_DEFINED);
}
+ /* TODO: this is not nice */
if (cx_class_instanceof(cx_procedure_o, cx_typeof(o))) {
/* Insert base-dependency: methods may only be declared after the base of a class has been defined. */
if (cx_typeof(o) != cx_type(cx_function_o)) {
@@ -412,7 +413,7 @@ int cx_genDepBuildAction(cx_object o, void* userData) {
g_itemDepend(dependee, CX_DECLARED, parent, CX_DECLARED);
/* If child must be declared when parent is declared, parent may only be defined after
- * all such childs are defined. */
+ * all such children are defined. */
g_itemDepend(parent, CX_DEFINED, dependee, CX_DEFINED);
break;
case CX_DEFINED:
diff --git a/dev/src/cx_ic.c b/dev/src/cx_ic.c
index b633eac6..af1c444b 100644
--- a/dev/src/cx_ic.c
+++ b/dev/src/cx_ic.c
@@ -539,7 +539,8 @@ cx_icObject cx_icObject__create(cx_icProgram program, cx_uint32 line, cx_object
return result;
}
-cx_icLocal cx_icLocal__create(cx_icProgram program, cx_uint32 line, cx_string name, cx_type type, cx_bool isParameter, cx_bool isReturn, cx_bool declare) {
+cx_icLocal cx_icLocal__create(
+ cx_icProgram program, cx_uint32 line, cx_string name, cx_type type, cx_bool isParameter, cx_bool isReturn, cx_bool declare) {
cx_icLocal result;
if (!(result = (cx_icLocal)cx_icProgram_lookupStorage(program, name, !declare))) {
@@ -569,12 +570,14 @@ cx_icAccumulator cx_icAccumulator__create(cx_icProgram program, cx_uint32 line,
cx_icMember cx_icMember__create(cx_icProgram program, cx_uint32 line, cx_icStorage base, cx_member member) {
cx_icMember result;
cx_id name;
+ cx_type t;
sprintf(name, "%s.%s", base->name, cx_nameof(member));
+ t = member->type;
if (!(result = (cx_icMember)cx_icProgram_lookupStorage(program, name, TRUE))) {
result = cx_calloc(sizeof(cx_icMember_s));
- cx_icStorage_init((cx_icStorage)result, program, line, CX_STORAGE_MEMBER, name, member->type);
+ cx_icStorage_init((cx_icStorage)result, program, line, CX_STORAGE_MEMBER, name, t);
result->base = base;
result->member = member;
cx_llAppend(program->scope->storages, result);
@@ -588,9 +591,13 @@ cx_icElement cx_icElement__create(cx_icProgram program, cx_uint32 line, cx_type
cx_id name;
cx_string elemStr;
- elemStr = cx_icValue_toString(index, NULL);
- sprintf(name, "%s[%s]", base->name, elemStr);
- cx_dealloc(elemStr);
+ if (index) {
+ elemStr = cx_icValue_toString(index, NULL);
+ sprintf(name, "%s[%s]", base->name, elemStr);
+ cx_dealloc(elemStr);
+ } else {
+ sprintf(name, "*%s", base->name);
+ }
if (!(result = (cx_icElement)cx_icProgram_lookupStorage(program, name, TRUE))) {
result = cx_calloc(sizeof(cx_icElement_s));
@@ -598,7 +605,7 @@ cx_icElement cx_icElement__create(cx_icProgram program, cx_uint32 line, cx_type
result->base = base;
result->index = index;
result->collectionType = (cx_collection)base->type;
- result->dynamic = !(index->_parent.kind == CX_IC_LITERAL);
+ result->dynamic = !index || !(index->_parent.kind == CX_IC_LITERAL);
cx_llAppend(program->scope->storages, result);
}
@@ -769,7 +776,8 @@ void cx_icProgram__free(cx_icProgram _this) {
}
cx_icAccumulator cx_icProgram_accumulatorPush(cx_icProgram _this, cx_uint32 line, cx_type type, cx_bool isReference) {
- _this->accumulatorStack[_this->accumulatorId] = cx_icAccumulator__create(_this, line, type ? type : cx_void_o, _this->accumulatorId);
+ _this->accumulatorStack[_this->accumulatorId] =
+ cx_icAccumulator__create(_this, line, type ? type : cx_void_o, _this->accumulatorId);
((cx_icStorage)_this->accumulatorStack[_this->accumulatorId])->isReference = isReference;
_this->accumulatorId++;
return _this->accumulatorStack[_this->accumulatorId-1];
diff --git a/dev/src/cx_ic_assemble.c b/dev/src/cx_ic_assemble.c
index b3d0b5fe..f02c761b 100644
--- a/dev/src/cx_ic_assemble.c
+++ b/dev/src/cx_ic_assemble.c
@@ -444,8 +444,13 @@ static cx_ic_vmStorage *cx_ic_vmStorageNew(cx_ic_vmProgram *program, cx_icStorag
if (element->base) {
result->base = cx_ic_vmStorageGet(program, element->base);
+ /* Iterator elements are a special case throuhg which access to the current member
+ * is granted */
+ if (element->base->type->kind == CX_ITERATOR) {
+ result->dynamic = TRUE;
+
/* If element is an array and index-expression is a literal, offset is determined at compile-time. */
- if (element->index->_parent.kind == CX_IC_LITERAL) {
+ } else if (element->index->_parent.kind == CX_IC_LITERAL) {
if (element->collectionType->kind == CX_ARRAY) {
cx_uint32 index = ((cx_icLiteral)element->index)->value.is.literal.v._unsigned_integer;
result->offset = index * cx_type_sizeof(element->collectionType->elementType);
@@ -464,7 +469,7 @@ static cx_ic_vmStorage *cx_ic_vmStorageNew(cx_ic_vmProgram *program, cx_icStorag
result->offset += result->base->offset;
- if (!result->base->dynamic && result->base->base) {
+ if (!result->base->dynamic && result->base->base) {
result->base = result->base->base;
}
}
@@ -1154,45 +1159,53 @@ OPS_EXP_EXT(GETOP, TYPE,)
static cx_vmOp *cx_ic_vmStorageAssembleElement(cx_icStorage storage, cx_ic_vmProgram *program, cx_vmOp *vmOp, cx_icStorage topLevelStorage) {
- cx_ic_vmOperand indexKind;
- cx_icValue icElementSize;
- cx_collection type = cx_collection(((cx_icElement)storage)->base->type); /* Obtain collectiontype */
- cx_value elementSizeValue;
- cx_uint64 elementSize;
+ cx_type type = ((cx_icElement)storage)->base->type;
/* Obtain kind for index */
- indexKind = cx_ic_getVmOperand(program, CX_IC_DEREF_VALUE, ((cx_icElement)storage)->index);
-
- /* Create value for elementSize */
- elementSize = cx_type_sizeof(type->elementType);
- cx_valueLiteralInit(&elementSizeValue, CX_LITERAL_UNSIGNED_INTEGER, &elementSize);
- icElementSize = (cx_icValue)cx_icLiteral__create(program->icProgram, ((cx_ic)storage)->line, elementSizeValue, (cx_type)cx_uint32_o);
-
- switch(type->kind) {
- case CX_ARRAY:
- vmOp->op = cx_ic_getVmELEMA(cx_type(type), CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
- cx_ic_vmSetOp3Addr(program, vmOp, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, CX_IC_VMOPERAND_V, (cx_icValue)topLevelStorage, ((cx_icElement)storage)->index, icElementSize);
- break;
- case CX_SEQUENCE:
- vmOp->op = cx_ic_getVmELEMS(cx_type(type), CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
- cx_ic_vmSetOp3Addr(program, vmOp, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, CX_IC_VMOPERAND_V, (cx_icValue)topLevelStorage, ((cx_icElement)storage)->index, icElementSize);
- break;
- case CX_LIST:
- if (cx_collection_elementRequiresAlloc(type)) {
- vmOp->op = cx_ic_getVmELEML(cx_type(type), CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
- } else {
- vmOp->op = cx_ic_getVmELEMLX(cx_type(type), CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
- }
- cx_ic_vmSetOp2Addr(program, vmOp, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, (cx_icValue)topLevelStorage, ((cx_icElement)storage)->index);
- break;
- case CX_MAP:
- if (cx_collection_elementRequiresAlloc(type)) {
- vmOp->op = cx_ic_getVmELEMM(cx_type(type), CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
- } else {
- vmOp->op = cx_ic_getVmELEMMX(cx_type(type), CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
+ if (type->kind == CX_ITERATOR) {
+ cx_ic_vmOperand baseKind = cx_ic_getVmOperand(program, CX_IC_DEREF_VALUE, (cx_icValue)((cx_icElement)storage)->base);
+ vmOp->op = cx_ic_getVmSET(type, CX_IC_VMTYPE_D, CX_IC_VMOPERAND_R, baseKind, 0);
+ cx_ic_vmSetOp2Addr(program, vmOp, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, baseKind,
+ (cx_icValue)topLevelStorage, (cx_icValue)((cx_icElement)storage)->base);
+
+ }else if (type->kind == CX_COLLECTION) {
+ cx_icValue icElementSize;
+ cx_value elementSizeValue;
+ cx_uint64 elementSize;
+ cx_collection collection = cx_collection(type);
+ cx_ic_vmOperand indexKind = cx_ic_getVmOperand(program, CX_IC_DEREF_VALUE, ((cx_icElement)storage)->index);
+
+ /* Create value for elementSize */
+ elementSize = cx_type_sizeof(collection->elementType);
+ cx_valueLiteralInit(&elementSizeValue, CX_LITERAL_UNSIGNED_INTEGER, &elementSize);
+ icElementSize = (cx_icValue)cx_icLiteral__create(program->icProgram, ((cx_ic)storage)->line, elementSizeValue, (cx_type)cx_uint32_o);
+
+ switch(collection->kind) {
+ case CX_ARRAY:
+ vmOp->op = cx_ic_getVmELEMA(type, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
+ cx_ic_vmSetOp3Addr(program, vmOp, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, CX_IC_VMOPERAND_V, (cx_icValue)topLevelStorage, ((cx_icElement)storage)->index, icElementSize);
+ break;
+ case CX_SEQUENCE:
+ vmOp->op = cx_ic_getVmELEMS(type, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
+ cx_ic_vmSetOp3Addr(program, vmOp, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, CX_IC_VMOPERAND_V, (cx_icValue)topLevelStorage, ((cx_icElement)storage)->index, icElementSize);
+ break;
+ case CX_LIST:
+ if (cx_collection_elementRequiresAlloc(collection)) {
+ vmOp->op = cx_ic_getVmELEML(type, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
+ } else {
+ vmOp->op = cx_ic_getVmELEMLX(type, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
+ }
+ cx_ic_vmSetOp2Addr(program, vmOp, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, (cx_icValue)topLevelStorage, ((cx_icElement)storage)->index);
+ break;
+ case CX_MAP:
+ if (cx_collection_elementRequiresAlloc(collection)) {
+ vmOp->op = cx_ic_getVmELEMM(type, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
+ } else {
+ vmOp->op = cx_ic_getVmELEMMX(type, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, 0);
+ }
+ cx_ic_vmSetOp2Addr(program, vmOp, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, (cx_icValue)topLevelStorage, ((cx_icElement)storage)->index);
+ break;
}
- cx_ic_vmSetOp2Addr(program, vmOp, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, indexKind, (cx_icValue)topLevelStorage, ((cx_icElement)storage)->index);
- break;
}
return cx_vmProgram_addOp(program->program, ((cx_ic)storage)->line);
@@ -1257,30 +1270,32 @@ static cx_vmOp *cx_ic_vmStorageAssembleNested(cx_icStorage icStorage, cx_ic_vmPr
* is dynamic the address will be calculated at runtime. */
if (storage->dynamic || cx_ic_isReference(storage->base->accumulator)) {
/* If the base is an object store the address in the accumulator */
- if (base->kind == CX_STORAGE_OBJECT) {
- vmOp->op = sizeof(intptr_t) == 4 ? CX_VM_SET_LRV : CX_VM_SET_DRV;
- cx_ic_vmStorageAddReferee(program, topLevelStorage, &vmOp->ic.b._1);
- vmOp->lo.w = (intptr_t)((cx_icObject)base)->ptr;
- if (storage->offset) {
- vmOp->lo.w += storage->offset;
- }
- vmOp = cx_vmProgram_addOp(program->program, ((cx_ic)icStorage)->line);
-
- /* If the base is a local store the address of the local in the accumulator */
- } else if (base->kind == CX_STORAGE_LOCAL) {
- if (!cx_ic_isReference(storage->base->accumulator)) {
- vmOp->op = cx_ic_getVmSETX(NULL, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, CX_IC_VMOPERAND_R, 0);
+ if (base->type->kind != CX_ITERATOR) {
+ if (base->kind == CX_STORAGE_OBJECT) {
+ vmOp->op = sizeof(intptr_t) == 4 ? CX_VM_SET_LRV : CX_VM_SET_DRV;
cx_ic_vmStorageAddReferee(program, topLevelStorage, &vmOp->ic.b._1);
- vmOp->ic.b._2 = storage->base->addr;
+ vmOp->lo.w = (intptr_t)((cx_icObject)base)->ptr;
if (storage->offset) {
- vmOp->ic.b._2 += storage->offset;
+ vmOp->lo.w += storage->offset;
}
vmOp = cx_vmProgram_addOp(program->program, ((cx_ic)icStorage)->line);
- } else {
- vmOp->op = sizeof(intptr_t) == 4 ? CX_VM_SET_LRR : CX_VM_SET_DRR;
- cx_ic_vmStorageAddReferee(program, topLevelStorage, &vmOp->ic.b._1);
- vmOp->ic.b._2 = storage->base->addr;
- vmOp = cx_vmProgram_addOp(program->program, ((cx_ic)icStorage)->line);
+
+ /* If the base is a local store the address of the local in the accumulator */
+ } else if (base->kind == CX_STORAGE_LOCAL) {
+ if (!cx_ic_isReference(storage->base->accumulator)) {
+ vmOp->op = cx_ic_getVmSETX(NULL, CX_IC_VMTYPE_W, CX_IC_VMOPERAND_R, CX_IC_VMOPERAND_R, 0);
+ cx_ic_vmStorageAddReferee(program, topLevelStorage, &vmOp->ic.b._1);
+ vmOp->ic.b._2 = storage->base->addr;
+ if (storage->offset) {
+ vmOp->ic.b._2 += storage->offset;
+ }
+ vmOp = cx_vmProgram_addOp(program->program, ((cx_ic)icStorage)->line);
+ } else {
+ vmOp->op = sizeof(intptr_t) == 4 ? CX_VM_SET_LRR : CX_VM_SET_DRR;
+ cx_ic_vmStorageAddReferee(program, topLevelStorage, &vmOp->ic.b._1);
+ vmOp->ic.b._2 = storage->base->addr;
+ vmOp = cx_vmProgram_addOp(program->program, ((cx_ic)icStorage)->line);
+ }
}
}
@@ -1570,6 +1585,16 @@ static cx_vmOpKind cx_ic_getVmPush(cx_icOp op, cx_type t, cx_ic_vmType typeKind,
}\
}
+static cx_vmOpKind cx_ic_getVmInc(cx_icOp op, cx_type t, cx_ic_vmType typeKind, cx_ic_vmOperand op1, cx_ic_vmOperand op2) {
+ cx_vmOpKind result = CX_VM_STOP;
+
+ if (((cx_icStorage)op->s1)->type->kind == CX_ITERATOR) {
+ result = cx_ic_getVmITER_NEXT(t, CX_IC_VMTYPE_W, op2, op1, 0);
+ } else {
+ result = cx_ic_getVmINC(t, typeKind, op1, 0, 0);
+ }
+ return result;
+}
static cx_vmOpKind cx_ic_getVmOpKind(cx_ic_vmProgram *program, cx_icOp op, cx_icValue storage, cx_type t, cx_ic_vmType typeKind, cx_ic_vmOperand op1, cx_ic_vmOperand op2, cx_icDerefMode deref1, cx_icDerefMode deref2) {
cx_vmOpKind result = CX_VM_STOP;
@@ -1592,7 +1617,7 @@ static cx_vmOpKind cx_ic_getVmOpKind(cx_ic_vmProgram *program, cx_icOp op, cx_ic
case CX_IC_MUL: cx_ic_getVmArith(MUL, t, typeKind, op1, op2); break;
case CX_IC_DIV: cx_ic_getVmArith(DIV, t, typeKind, op1, op2); break;
case CX_IC_MOD: result = cx_ic_getVmMODI(t, typeKind, op1, op2, 0); break;
- case CX_IC_INC: result = cx_ic_getVmINC(t, typeKind, op1, 0, 0); break;
+ case CX_IC_INC: result = cx_ic_getVmInc(op, t, typeKind, op1, op2); break;
case CX_IC_DEC: result = cx_ic_getVmDEC(t, typeKind, op1, 0, 0); break;
case CX_IC_XOR: result = cx_ic_getVmXOR(t, typeKind, op1, op2, 0); break;
case CX_IC_OR: result = cx_ic_getVmOR(t, typeKind, op1, op2, 0); break;
@@ -1941,8 +1966,18 @@ static void cx_ic_getVmOp(cx_ic_vmProgram *program, cx_icOp op) {
opDeref2 = op->s2Deref;
}
/* no break */
+ case CX_IC_INC: {
+ cx_type t = ((cx_icStorage)op->s1)->type;
+ if (t->kind == CX_ITERATOR) {
+ op2 = op->s2;
+ op1 = op->s1;
+ opDeref2 = op->s2Deref;
+ opDeref1 = CX_IC_DEREF_ADDRESS;
+ storage = NULL;
+ break;
+ }
+ }
case CX_IC_DEFINE:
- case CX_IC_INC:
case CX_IC_DEC:
case CX_IC_RET:
case CX_IC_FREE:
@@ -2020,7 +2055,7 @@ static void cx_ic_getVmOp(cx_ic_vmProgram *program, cx_icOp op) {
op1 = op->s1;
storage = NULL;
vmOp->hi.w = (cx_word)((cx_icObject)op->s2)->ptr;
- opDeref1 = op->s1Deref;
+ opDeref1 = op->s1Deref;
}
break;
@@ -2056,7 +2091,6 @@ static void cx_ic_getVmOp(cx_ic_vmProgram *program, cx_icOp op) {
if (op1) {
/* Operation has two operands */
if (op2) {
-
if (op3) {
cx_vmOp3(program, vmOp, op, op1, op2, op3, opDeref1, opDeref2, opDeref3);
} else if (storage && (storage != op1)) {
diff --git a/interface/fast/Fast.xml b/interface/fast/Fast.xml
index 6f2498ad..4f54c715 100644
--- a/interface/fast/Fast.xml
+++ b/interface/fast/Fast.xml
@@ -181,7 +181,6 @@
-
@@ -206,13 +205,6 @@
-
-
-
-
-
-
-
@@ -239,13 +231,6 @@
-
-
-
-
-
-
-
diff --git a/interface/fast/include/Fast.h b/interface/fast/include/Fast.h
index fd040ee3..32a74041 100644
--- a/interface/fast/include/Fast.h
+++ b/interface/fast/include/Fast.h
@@ -66,8 +66,6 @@ Fast_valueKind Fast_valueKindFromType(cx_type type);
#include "Fast_InitializerVariable.h"
#include "Fast_InitOper.h"
#include "Fast_Integer.h"
-#include "Fast_IteratorLocal.h"
-#include "Fast_IteratorObject.h"
#include "Fast_Literal.h"
#include "Fast_Local.h"
#include "Fast_Lvalue.h"
diff --git a/interface/fast/include/Fast_IteratorLocal.h b/interface/fast/include/Fast_IteratorLocal.h
deleted file mode 100644
index a3fa6f54..00000000
--- a/interface/fast/include/Fast_IteratorLocal.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Fast_IteratorLocal.h
- *
- * This file contains generated code. Do not modify!
- */
-
-#ifndef Fast_IteratorLocal_H
-#define Fast_IteratorLocal_H
-
-#include "cortex.h"
-#include "Fast_Local.h"
-#include "Fast__type.h"
-
-#include "Fast__api.h"
-
-#include "Fast__meta.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* ::cortex::Fast::IteratorLocal::getBuddy() */
-Fast_Local Fast_IteratorLocal_getBuddy(Fast_IteratorLocal _this);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
diff --git a/interface/fast/include/Fast_IteratorObject.h b/interface/fast/include/Fast_IteratorObject.h
deleted file mode 100644
index 6dae6e58..00000000
--- a/interface/fast/include/Fast_IteratorObject.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Fast_IteratorObject.h
- *
- * This file contains generated code. Do not modify!
- */
-
-#ifndef Fast_IteratorObject_H
-#define Fast_IteratorObject_H
-
-#include "cortex.h"
-#include "Fast_Object.h"
-#include "Fast__type.h"
-
-#include "Fast__api.h"
-
-#include "Fast__meta.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* ::cortex::Fast::IteratorObject::getBuddy() */
-Fast_Local Fast_IteratorObject_getBuddy(Fast_IteratorObject _this);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
diff --git a/interface/fast/include/Fast_Variable.h b/interface/fast/include/Fast_Variable.h
index 346592c7..ca89870a 100644
--- a/interface/fast/include/Fast_Variable.h
+++ b/interface/fast/include/Fast_Variable.h
@@ -21,12 +21,6 @@ extern "C" {
/* ::cortex::Fast::Variable::construct() */
cx_int16 Fast_Variable_construct(Fast_Variable _this);
-/* virtual ::cortex::Fast::Variable::getBuddy() */
-Fast_Local Fast_Variable_getBuddy(Fast_Variable _this);
-
-/* ::cortex::Fast::Variable::getBuddy() */
-Fast_Local Fast_Variable_getBuddy_v(Fast_Variable _this);
-
#ifdef __cplusplus
}
#endif
diff --git a/interface/fast/include/Fast__type.h b/interface/fast/include/Fast__type.h
index 8a439f92..60352200 100644
--- a/interface/fast/include/Fast__type.h
+++ b/interface/fast/include/Fast__type.h
@@ -36,8 +36,6 @@ extern "C" {
#define Fast_Initializer(o) ((Fast_Initializer)o)
#define Fast_InitializerExpression(o) ((Fast_InitializerExpression)o)
#define Fast_Integer(o) ((Fast_Integer)o)
-#define Fast_IteratorLocal(o) ((Fast_IteratorLocal)o)
-#define Fast_IteratorObject(o) ((Fast_IteratorObject)o)
#define Fast_Literal(o) ((Fast_Literal)o)
#define Fast_Local(o) ((Fast_Local)o)
#define Fast_Member(o) ((Fast_Member)o)
@@ -412,37 +410,6 @@ typedef enum Fast_InitializerKind {
Fast_InitExpression = 2
} Fast_InitializerKind;
-/* ::cortex::Fast::IteratorLocal */
-CX_CLASS(Fast_IteratorLocal);
-
-CX_CLASS_DEF(Fast_IteratorLocal) {
- CX_EXTEND(Fast_Local);
- Fast_Local buddy;
-};
-
-/* ::cortex::Fast::ObjectBase */
-CX_CLASS(Fast_ObjectBase);
-
-CX_CLASS_DEF(Fast_ObjectBase) {
- CX_EXTEND(Fast_Variable);
- cx_object value;
-};
-
-/* ::cortex::Fast::Object */
-CX_CLASS(Fast_Object);
-
-CX_CLASS_DEF(Fast_Object) {
- CX_EXTEND(Fast_ObjectBase);
-};
-
-/* ::cortex::Fast::IteratorObject */
-CX_CLASS(Fast_IteratorObject);
-
-CX_CLASS_DEF(Fast_IteratorObject) {
- CX_EXTEND(Fast_Object);
- Fast_Local buddy;
-};
-
/* ::cortex::Fast::Lvalue */
typedef struct Fast_Lvalue Fast_Lvalue;
@@ -478,6 +445,21 @@ CX_CLASS_DEF(Fast_Null) {
CX_EXTEND(Fast_Literal);
};
+/* ::cortex::Fast::ObjectBase */
+CX_CLASS(Fast_ObjectBase);
+
+CX_CLASS_DEF(Fast_ObjectBase) {
+ CX_EXTEND(Fast_Variable);
+ cx_object value;
+};
+
+/* ::cortex::Fast::Object */
+CX_CLASS(Fast_Object);
+
+CX_CLASS_DEF(Fast_Object) {
+ CX_EXTEND(Fast_ObjectBase);
+};
+
CX_LIST(Fast_Binding_list);
CX_LIST(cx_word_list);
diff --git a/interface/fast/src/Fast_DynamicInitializer.c b/interface/fast/src/Fast_DynamicInitializer.c
index 486b7194..9da8a885 100644
--- a/interface/fast/src/Fast_DynamicInitializer.c
+++ b/interface/fast/src/Fast_DynamicInitializer.c
@@ -49,6 +49,9 @@ Fast_Expression Fast_Initializer_expr(Fast_DynamicInitializer _this, cx_uint8 va
case CX_PRIMITIVE:
result = base;
break;
+ case CX_ITERATOR:
+ result = base;
+ break;
case CX_COMPOSITE:
if (fp) {
Fast_String memberString = Fast_String__create(cx_nameof(thisFrame->member));
diff --git a/interface/fast/src/Fast_Initializer.c b/interface/fast/src/Fast_Initializer.c
index 15fce50a..558482fe 100644
--- a/interface/fast/src/Fast_Initializer.c
+++ b/interface/fast/src/Fast_Initializer.c
@@ -130,7 +130,8 @@ cx_type Fast_Parser_initGetType(Fast_Initializer _this, cx_member *m_out) {
} else {
if (m_out) {
cx_id id;
- Fast_Parser_error(yparser(), "too many elements for non-composite\\collection type '%s'", Fast_Parser_id(t, id));
+ Fast_Parser_error(yparser(),
+ "too many elements for non-composite\\collection type '%s'", Fast_Parser_id(t, id));
result = NULL;
}
}
@@ -181,7 +182,8 @@ cx_int16 Fast_Initializer_construct(Fast_Initializer _this) {
#ifdef CX_INIT_DEBUG
{
cx_id id, id2;
- printf("%*s%d[%s %p]: construct (type=%s)\n", indent, " ", yparser()->line, Fast_Parser_id(cx_typeof(_this), id), _this, Fast_Parser_id(t, id2));
+ printf("%*s%d[%s %p]: construct (type=%s)\n",
+ indent, " ", yparser()->line, Fast_Parser_id(cx_typeof(_this), id), _this, Fast_Parser_id(t, id2));
indent++;
}
#endif
@@ -319,7 +321,8 @@ cx_int16 Fast_Initializer_next_v(Fast_Initializer _this) {
{
cx_id id, id2;
printf("%*s%d[%s %p]: next(fp=%d, location=%d, type=%s, member=%s)\n",
- indent, " ", yparser()->line, Fast_Parser_id(cx_typeof(_this), id), _this, _this->fp, _this->frames[_this->fp].location,
+ indent, " ", yparser()->line, Fast_Parser_id(cx_typeof(_this), id), _this, _this->fp,
+ _this->frames[_this->fp].location,
_this->frames[_this->fp].type?Fast_Parser_id(_this->frames[_this->fp].type, id2):NULL,
_this->frames[_this->fp].member?cx_nameof(_this->frames[_this->fp].member):NULL);
}
@@ -340,7 +343,9 @@ cx_int8 Fast_Initializer_pop_v(Fast_Initializer _this) {
{
cx_id id;
indent--;
- printf("%*s%d[%s %p]: pop(fp=%d, location=%d)\n", indent, " ", yparser()->line, Fast_Parser_id(cx_typeof(_this), id), _this, _this->fp, _this->frames[_this->fp].location);
+ printf("%*s%d[%s %p]: pop(fp=%d, location=%d)\n",
+ indent, " ", yparser()->line,
+ Fast_Parser_id(cx_typeof(_this), id), _this, _this->fp, _this->frames[_this->fp].location);
}
#endif
Fast_Initializer_next(_this);
@@ -373,7 +378,8 @@ cx_int16 Fast_Initializer_push_v(Fast_Initializer _this) {
cx_id id, id2;
printf("%*s%d[%s %p]: push(fp=%d, location=%d, type=%s, member=%s)\n",
indent, " ", yparser()->line, Fast_Parser_id(cx_typeof(_this), id), _this, _this->fp,
- _this->frames[_this->fp].location, _this->frames[_this->fp].type?Fast_Parser_id(_this->frames[_this->fp].type, id2):NULL,
+ _this->frames[_this->fp].location,
+ _this->frames[_this->fp].type ? Fast_Parser_id(_this->frames[_this->fp].type, id2) : NULL,
_this->frames[_this->fp].member?cx_nameof(_this->frames[_this->fp].member):NULL);
indent++;
}
diff --git a/interface/fast/src/Fast_IteratorLocal.c b/interface/fast/src/Fast_IteratorLocal.c
deleted file mode 100644
index b0f91996..00000000
--- a/interface/fast/src/Fast_IteratorLocal.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Fast_IteratorLocal.c
- *
- * This file contains the implementation for the generated interface.
- *
- * Don't mess with the begin and end tags, since these will ensure that modified
- * code in interface functions isn't replaced when code is re-generated.
- */
-
-#include "Fast.h"
-#include "Fast__meta.h"
-
-/* ::cortex::Fast::IteratorLocal::getBuddy() */
-Fast_Local Fast_IteratorLocal_getBuddy(Fast_IteratorLocal _this) {
-/* $begin(::cortex::Fast::IteratorLocal::getBuddy) */
- return _this->buddy;
-/* $end */
-}
diff --git a/interface/fast/src/Fast_IteratorObject.c b/interface/fast/src/Fast_IteratorObject.c
deleted file mode 100644
index d2ab3733..00000000
--- a/interface/fast/src/Fast_IteratorObject.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Fast_IteratorObject.c
- *
- * This file contains the implementation for the generated interface.
- *
- * Don't mess with the begin and end tags, since these will ensure that modified
- * code in interface functions isn't replaced when code is re-generated.
- */
-
-#include "Fast.h"
-#include "Fast__meta.h"
-
-/* ::cortex::Fast::IteratorObject::getBuddy() */
-Fast_Local Fast_IteratorObject_getBuddy(Fast_IteratorObject _this) {
-/* $begin(::cortex::Fast::IteratorObject::getBuddy) */
- return _this->buddy;
-/* $end */
-}
diff --git a/interface/fast/src/Fast_Object.c b/interface/fast/src/Fast_Object.c
index 3027ecff..84f08ba0 100644
--- a/interface/fast/src/Fast_Object.c
+++ b/interface/fast/src/Fast_Object.c
@@ -66,7 +66,10 @@ cx_int16 Fast_Object_serialize(Fast_Object _this, cx_type dstType, cx_word dst)
dstIsDelegate = TRUE;
}
- if (dstIsDelegate) {
+ /* Handle iterators */
+ if ((dstType->kind == CX_ITERATOR) && (srcType->kind == CX_COLLECTION)) {
+ cx_iterator_set((void*)dst, obj, cx_collection(srcType));
+ } else if (dstIsDelegate) {
if (srcIsDelegate) {
cx_value vDst, vSrc;
cx_valueValueInit(&vDst, NULL, cx_type(dstType), (void *)dst);
diff --git a/interface/fast/src/Fast_Parser.c b/interface/fast/src/Fast_Parser.c
index fcd3d162..52f05cb7 100644
--- a/interface/fast/src/Fast_Parser.c
+++ b/interface/fast/src/Fast_Parser.c
@@ -1493,11 +1493,7 @@ Fast_Variable Fast_Parser_declaration(Fast_Parser _this, Fast_Variable type, cx_
cx_free_ext(_this, o, "Free object from resolve (2nd run)");
}
if (o) {
- if (cx_type(Fast_ObjectBase(type)->value)->kind == CX_ITERATOR) {
- result = Fast_Variable(Fast_IteratorObject__create(o));
- } else {
- result = Fast_Variable(Fast_Object__create(o));
- }
+ result = Fast_Variable(Fast_Object__create(o));
Fast_Parser_collect(_this, result);
_this->variables[_this->variableCount] = result;
_this->variableCount++;
diff --git a/interface/fast/src/Fast_PostFix.c b/interface/fast/src/Fast_PostFix.c
index c1978a80..e7e92a0e 100644
--- a/interface/fast/src/Fast_PostFix.c
+++ b/interface/fast/src/Fast_PostFix.c
@@ -32,6 +32,7 @@ cx_int16 Fast_PostFix_construct(Fast_PostFix _this) {
} else {
cx_id id;
switch(lvalueType->kind) {
+
case CX_PRIMITIVE:
switch(cx_primitive(lvalueType)->kind) {
case CX_INTEGER:
@@ -46,7 +47,19 @@ cx_int16 Fast_PostFix_construct(Fast_PostFix _this) {
goto error;
break;
}
+ Fast_Expression(_this)->type = Fast_Variable(Fast_Object__create(lvalueType));
+ break;
+
+ case CX_ITERATOR:
+ if (_this->operator == CX_INC) {
+ /* The result of an expression that increments an iterator is a boolean */
+ Fast_Expression(_this)->type = Fast_Variable(Fast_Object__create(cx_bool_o));
+ } else {
+ Fast_Parser_error(yparser(), "invalid operator for iterator");
+ goto error;
+ }
break;
+
default:
Fast_Parser_error(
yparser(), "invalid operator for type '%s'", Fast_Parser_id(lvalueType, id));
@@ -55,10 +68,8 @@ cx_int16 Fast_PostFix_construct(Fast_PostFix _this) {
}
}
-
Fast_Node(_this)->kind = Fast_PostfixExpr;
- Fast_Expression(_this)->type = Fast_Variable(Fast_Object__create(lvalueType));
-
+
return 0;
error:
return -1;
@@ -70,7 +81,8 @@ cx_ic Fast_PostFix_toIc_v(Fast_PostFix _this, cx_icProgram program, cx_icStorage
/* $begin(::cortex::Fast::PostFix::toIc) */
cx_icStorage result;
cx_ic lvalue;
- cx_icOp op;
+ cx_icOp op = NULL;
+ cx_type lvalueType = Fast_Expression_getType(_this->lvalue);
CX_UNUSED(stored);
if (storage) {
@@ -84,12 +96,13 @@ cx_ic Fast_PostFix_toIc_v(Fast_PostFix _this, cx_icProgram program, cx_icStorage
}
lvalue = Fast_Node_toIc(Fast_Node(_this->lvalue), program, result, TRUE);
-
- op = cx_icOp__create(program, Fast_Node(_this)->line, cx_icOpKindFromOperator(_this->operator), (cx_icValue)lvalue, NULL, NULL);
+ op = cx_icOp__create(program, Fast_Node(_this)->line, cx_icOpKindFromOperator(_this->operator), (cx_icValue)lvalue, (cx_icValue)result, NULL);
cx_icProgram_addIc(program, (cx_ic)op);
if (!storage) {
cx_icProgram_accumulatorPop(program, Fast_Node(_this)->line);
+ } else if ((lvalueType->kind == CX_ITERATOR) && (_this->operator == CX_INC)) {
+ lvalue = (cx_ic)storage;
}
return (cx_ic)lvalue;
diff --git a/interface/fast/src/Fast_StaticInitializer.c b/interface/fast/src/Fast_StaticInitializer.c
index c2bb3e5d..38b240cd 100644
--- a/interface/fast/src/Fast_StaticInitializer.c
+++ b/interface/fast/src/Fast_StaticInitializer.c
@@ -46,6 +46,9 @@ cx_word Fast_Initializer_offset(Fast_StaticInitializer _this, cx_uint32 variable
result = base;
}
break;
+ case CX_ITERATOR:
+ result = base;
+ break;
case CX_COLLECTION: {
if (fp) {
cx_uint32 elementSize = cx_type_sizeof(cx_collection(frame->type)->elementType);
diff --git a/interface/fast/src/Fast_Unary.c b/interface/fast/src/Fast_Unary.c
index 7e2d8ca3..aacf8151 100644
--- a/interface/fast/src/Fast_Unary.c
+++ b/interface/fast/src/Fast_Unary.c
@@ -24,13 +24,26 @@ cx_int16 Fast_Unary_construct(Fast_Unary _this) {
lvalueType = Fast_Expression_getType(_this->lvalue);
Fast_Node(_this)->kind = Fast_UnaryExpr;
- if (_this->operator == CX_COND_NOT) {
- Fast_Expression(_this)->type = Fast_Variable(Fast_Object__create(cx_bool_o));
+ if (lvalueType->kind != CX_ITERATOR) {
+ if (_this->operator == CX_COND_NOT) {
+ Fast_Expression(_this)->type = Fast_Variable(Fast_Object__create(cx_bool_o));
+ } else {
+ Fast_Expression(_this)->type = Fast_Variable(Fast_Object__create(lvalueType));
+ }
} else {
- Fast_Expression(_this)->type = Fast_Variable(Fast_Object__create(lvalueType));
+ if (_this->operator == CX_MUL) {
+ cx_type iterType = cx_iterator(lvalueType)->elementType;
+ Fast_Expression(_this)->type = Fast_Variable(Fast_Object__create(iterType));
+ Fast_Expression(_this)->isReference = TRUE;
+ } else {
+ Fast_Parser_error(yparser(), "invalid operator for iterator");
+ goto error;
+ }
}
return 0;
+error:
+ return -1;
/* $end */
}
@@ -49,6 +62,7 @@ cx_ic Fast_Unary_toIc_v(Fast_Unary _this, cx_icProgram program, cx_icStorage sto
cx_icStorage result;
cx_ic lvalue;
cx_icOp op;
+ cx_type lvalueType = Fast_Expression_getType(_this->lvalue);
CX_UNUSED(stored);
if (storage) {
@@ -66,12 +80,23 @@ cx_ic Fast_Unary_toIc_v(Fast_Unary _this, cx_icProgram program, cx_icStorage sto
switch(_this->operator) {
case CX_INC:
case CX_DEC:
- op = cx_icOp__create(program, Fast_Node(_this)->line, cx_icOpKindFromOperator(_this->operator), (cx_icValue)lvalue, NULL, NULL);
+ op = cx_icOp__create(
+ program, Fast_Node(_this)->line, cx_icOpKindFromOperator(_this->operator),
+ (cx_icValue)lvalue, NULL, NULL);
cx_icProgram_addIc(program, (cx_ic)op);
result = (cx_icStorage)lvalue;
break;
+ case CX_MUL: {
+ /* Create an element with the iterator as base */
+ result =
+ (cx_icStorage)cx_icElement__create(
+ program, Fast_Node(_this)->line, cx_iterator(lvalueType)->elementType, (cx_icStorage)lvalue, NULL);
+ break;
+ }
default:
- op = cx_icOp__create(program, Fast_Node(_this)->line, cx_icOpKindFromOperator(_this->operator), (cx_icValue)result, (cx_icValue)lvalue, NULL);
+ op = cx_icOp__create(
+ program, Fast_Node(_this)->line, cx_icOpKindFromOperator(_this->operator),
+ (cx_icValue)result, (cx_icValue)lvalue, NULL);
cx_icProgram_addIc(program, (cx_ic)op);
break;
}
diff --git a/interface/fast/src/Fast_Variable.c b/interface/fast/src/Fast_Variable.c
index 8d9bf75f..2b1dc839 100644
--- a/interface/fast/src/Fast_Variable.c
+++ b/interface/fast/src/Fast_Variable.c
@@ -18,11 +18,3 @@ cx_int16 Fast_Variable_construct(Fast_Variable _this) {
return 0;
/* $end */
}
-
-/* ::cortex::Fast::Variable::getBuddy() */
-Fast_Local Fast_Variable_getBuddy_v(Fast_Variable _this) {
-/* $begin(::cortex::Fast::Variable::getBuddy) */
- CX_UNUSED(_this);
- return NULL;
-/* $end */
-}
diff --git a/interface/fast/src/fast.y b/interface/fast/src/fast.y
index 3d4715a1..7c71ec2f 100644
--- a/interface/fast/src/fast.y
+++ b/interface/fast/src/fast.y
@@ -161,7 +161,7 @@ Fast_Expression Fast_declarationSeqDo(Fast_Variable type, Fast_ParserDeclaration
/* Syntax tree nodes */
%type
statement statements
- expr literal_expr primary_expr postfix_expr unary_expr multiplicative_expr additive_expr shift_expr
+ expr literal_expr primary_expr iter_expr postfix_expr unary_expr multiplicative_expr additive_expr shift_expr
boolean_expr equality_expr and_expr xor_expr or_expr logical_and_expr logical_or_expr assignment_expr
comma_expr bracket_expr conditional_expr wait_expr declaration declaration_expr declaration_ref
function_declaration
@@ -405,16 +405,21 @@ bracket_expr
primary_expr
: bracket_expr
- | literal_expr {$$=$1;}
- | identifier {$$=$1;}
+ | literal_expr {$$ = $1;}
+ | identifier {$$ = $1;}
;
-postfix_expr
+iter_expr
: primary_expr
+ | '*' iter_expr {$$ = Fast_Parser_unaryExpr(yparser(), $2, CX_MUL); fast_op;}
+ ;
+
+postfix_expr
+ : iter_expr
| postfix_expr {PUSHCOMPLEX($1)} '[' expr ']' {$$ = Fast_Parser_elementExpr(yparser(), $1, $4); fast_op; POPCOMPLEX()}
- | postfix_expr '(' ')' {$$ = Fast_Parser_callExpr(yparser(), $1, NULL); fast_op;}
- | postfix_expr bracket_expr {$$ = Fast_Parser_callExpr(yparser(), $1, $2); fast_op;}
- | postfix_expr '.' any_id {Fast_String str = Fast_String__create($3); if (!str) {YYERROR;} $$ = Fast_Parser_memberExpr(yparser(), $1, Fast_Expression(str)); cx_free(str); fast_op;}
+ | postfix_expr '(' ')' {$$ = Fast_Parser_callExpr(yparser(), $1, NULL); fast_op;}
+ | postfix_expr bracket_expr {$$ = Fast_Parser_callExpr(yparser(), $1, $2); fast_op;}
+ | postfix_expr '.' any_id {Fast_String str = Fast_String__create($3); if (!str) {YYERROR;} $$ = Fast_Parser_memberExpr(yparser(), $1, Fast_Expression(str)); cx_free(str); fast_op;}
| postfix_expr INC {$$ = Fast_Parser_postfixExpr(yparser(), $1, CX_INC); fast_op}
| postfix_expr DEC {$$ = Fast_Parser_postfixExpr(yparser(), $1, CX_DEC); fast_op}
;
diff --git a/test/language/tc_iterator01.cx b/test/language/tc_iterator01.cx
index 02edcc7d..06309067 100644
--- a/test/language/tc_iterator01.cx
+++ b/test/language/tc_iterator01.cx
@@ -1,17 +1,32 @@
-// Iterator assignments
-
-bool result : true
+bool result: true
void fail(string msg):
"tc_iterator01: FAIL: $msg"
result = false
-array sarray: string, 1
-sarray array1: "a"
+array{int32, 3} intArray: 1, 2, 3
+sequence{int32} intSeq: 2, 3, 4
+list{int32} intList: 3, 4, 5
+
+iterator{int32} a : intArray
+iterator{int32} b : intSeq
+iterator{int32} c : intList
+
+var int32 total
+while a++: total += *a
+if total != 6: fail("total != 6 (array)")
+
+total = 0
+while b++: total += *b
+if total != 9: fail("total != 9 (sequence)")
-iterator siter: string
-siter iter1
-iter1 = array1
+total = 0
+while c++: total += *c
+if total != 12: fail("total != 12 (list)")
-iter1++
+// Reassign iterator
+a = intSeq
+total = 0
+while a++: total += *a
+if total != 9: fail("total != 6 (sequence #2)")
-if result: "$testname: OK"
+if result: "tc_iterator01: OK"
diff --git a/test/language/tc_iterator02.cx b/test/language/tc_iterator02.cx
new file mode 100644
index 00000000..3a1ac603
--- /dev/null
+++ b/test/language/tc_iterator02.cx
@@ -0,0 +1,34 @@
+bool result: true
+void fail(string msg):
+ "tc_iterator02: FAIL: $msg"
+ result = false
+
+struct Point:: x, y: int32
+
+array{Point, 3} pArray: {1, 2}, {3, 4}, {5, 6}
+sequence{Point} pSeq: {3, 4}, {5, 6}, {7, 8}
+list{Point} pList: {5, 6}, {7, 8}, {9, 10}
+
+iterator{Point} a : pArray
+iterator{Point} b : pSeq
+iterator{Point} c : pList
+
+var Point total
+while a++: total[x, y] += *a[x, y]
+if total[x, y] != (9, 12): fail("total[x, y] != (9, 12) (array)")
+
+total = {0, 0}
+while b++: total[x, y] += *b[x, y]
+if total[x, y] != (15, 18): fail("total[x, y] != (15, 18) (sequence)")
+
+total = {0, 0}
+while c++: total[x, y] += *c[x, y]
+if total[x, y] != (21, 24): fail("total[x, y] != (21, 24) (list)")
+
+// Reassign iterator
+a = pSeq
+total = {0, 0}
+while a++: total[x, y] += *a[x, y]
+if total[x, y] != (15, 18): fail("total[x, y] != (15, 18) (sequence #2)")
+
+if result: "tc_iterator02: OK"