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"