diff options
author | Adrian Thurston <thurston@complang.org> | 2014-12-07 16:50:49 -0500 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2014-12-07 16:50:49 -0500 |
commit | 1de6249aa3c481e5ff582b95dac49c8fbf04f8c9 (patch) | |
tree | 0fc1a8509c7d8e42dbbb4e83bff619e4870acb2b | |
parent | e1b207d6d2642d545f151429d9ffd662d6a82494 (diff) | |
download | colm-1de6249aa3c481e5ff582b95dac49c8fbf04f8c9.tar.gz |
start on the object-based list implementation (list2)
-rw-r--r-- | src/bytecode.c | 42 | ||||
-rw-r--r-- | src/bytecode.h | 12 | ||||
-rw-r--r-- | src/colm.lm | 10 | ||||
-rw-r--r-- | src/declare.cc | 107 | ||||
-rw-r--r-- | src/loadcolm.cc | 23 | ||||
-rw-r--r-- | src/parsedata.h | 12 | ||||
-rw-r--r-- | src/parsetree.cc | 40 | ||||
-rw-r--r-- | src/parsetree.h | 100 | ||||
-rw-r--r-- | src/resolve.cc | 163 | ||||
-rw-r--r-- | src/tree.c | 81 | ||||
-rw-r--r-- | src/tree.h | 1 |
11 files changed, 587 insertions, 4 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index fefcdc97..76a88b6d 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -3096,6 +3096,34 @@ again: treeDownref( prg, sp, tree ); break; } + case IN_LIST2_PUSH_TAIL_WC: { + debug( prg, REALM_BYTECODE, "IN_LIST2_PUSH_TAIL_WC\n" ); + + Tree *obj = vm_pop(); + Tree *val = vm_pop(); + + treeDownref( prg, sp, obj ); + list2PushTail( prg, sp, (List*)obj, val ); + + treeUpref( prg->trueVal ); + vm_push( prg->trueVal ); + break; + } + case IN_GET_LIST2EL_MEM_R: { + short field; + read_half( field ); + + debug( prg, REALM_BYTECODE, "IN_GET_LIST2EL_MEM_R\n" ); + + Tree *obj = vm_pop(); + + Tree *val = colm_get_attr( obj, 1 ); + + treeUpref( val ); + vm_push( val ); + break; + + } case IN_LIST_POP_TAIL_WC: { debug( prg, REALM_BYTECODE, "IN_LIST_POP_TAIL_WC\n" ); @@ -3228,6 +3256,20 @@ again: vm_push( val ); break; } + case IN_GET_LIST2_MEM_R: { + short field; + read_half( field ); + + debug( prg, REALM_BYTECODE, "IN_GET_LIST2_MEM_R\n" ); + + Tree *obj = vm_pop(); + treeDownref( prg, sp, obj ); + + Tree *val = (Tree*)((List*)obj)->head; + treeUpref( val ); + vm_push( val ); + break; + } case IN_GET_LIST_MEM_WC: { short field; read_half( field ); diff --git a/src/bytecode.h b/src/bytecode.h index 1fe56846..a7f27782 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -171,6 +171,12 @@ typedef unsigned char uchar; #define IN_LIST_POP_HEAD_WC 0xeb #define IN_LIST_POP_HEAD_BKT 0xec +#define IN_LIST2_PUSH_TAIL_WV 0xf2 +#define IN_LIST2_PUSH_TAIL_WC 0xf3 +#define IN_LIST2_PUSH_TAIL_BKT 0xf4 +#define IN_GET_LIST2EL_MEM_R 0xf5 +#define IN_GET_LIST2_MEM_R 0xf6 + #define IN_GET_LIST_MEM_R 0x79 #define IN_GET_LIST_MEM_WC 0x7a #define IN_GET_LIST_MEM_WV 0x7b @@ -332,7 +338,11 @@ enum TYPE enum GEN { GEN_LIST = 0x10, GEN_MAP = 0x11, - GEN_PARSER = 0x13 + GEN_PARSER = 0x13, + GEN_LIST2EL = 0x14, + GEN_LIST2 = 0x15, + GEN_MAP2EL = 0x16, + GEN_MAP2 = 0x17, }; /* Known language element ids. */ diff --git a/src/colm.lm b/src/colm.lm index d916e0a4..a821abeb 100644 --- a/src/colm.lm +++ b/src/colm.lm @@ -28,7 +28,11 @@ lex token IN / 'in' / token PARSER / 'parser' | 'accum' / token LIST / 'list' / + token LIST2 / 'list2' / + token LIST2EL / 'list2el' / token MAP / 'map' / + token MAP2 / 'map2' / + token MAP2EL / 'map2el' / token PTR / 'ptr' / token ITER / 'iter' / token REF / 'ref' / @@ -553,9 +557,13 @@ def code_factor def type_ref [region_qual id opt_repeat] :Id | [PTR LT region_qual id opt_repeat GT] :Ptr -| [MAP LT MapKeyType: type_ref MapValueType: type_ref GT] :Map | [LIST LT type_ref GT] :List +| [MAP LT MapKeyType: type_ref MapValueType: type_ref GT] :Map | [PARSER LT type_ref GT] :Parser +| [LIST2EL LT type_ref GT] :List2El +| [LIST2 LT type_ref GT] :List2 +| [MAP2EL LT type_ref GT] :Map2El +| [MAP2 LT type_ref GT] :Map2 def region_qual [region_qual id DOUBLE_COLON] :Qual diff --git a/src/declare.cc b/src/declare.cc index ce05de86..22815ca0 100644 --- a/src/declare.cc +++ b/src/declare.cc @@ -384,6 +384,18 @@ void GenericType::declare( Compiler *pd, Namespace *nspace ) pd->initParserFunctions( this ); pd->initParserFields( this ); break; + case GEN_LIST2EL: + pd->initList2ElFields( this ); + break; + case GEN_LIST2: + pd->initList2Functions( this ); + pd->initList2Fields( this ); + break; + case GEN_MAP2EL: + break; + case GEN_MAP2: + pd->initMap2Functions( this ); + break; } langEl->objectDef = objDef; @@ -1115,6 +1127,101 @@ void Compiler::initListFunctions( GenericType *gen ) IN_LIST_POP_HEAD_WV, IN_LIST_POP_HEAD_WC, false ); } +void Compiler::initList2Functions( GenericType *gen ) +{ +// addLengthField( gen->objDef, IN_LIST_LENGTH ); +// +// initFunction( uniqueTypeInt, gen->objDef, "push_head", +// IN_LIST_PUSH_HEAD_WV, IN_LIST_PUSH_HEAD_WC, gen->utArg, false ); + + initFunction( uniqueTypeInt, gen->objDef, "push_tail", + IN_LIST2_PUSH_TAIL_WV, IN_LIST2_PUSH_TAIL_WC, gen->utArg, false ); + +// initFunction( uniqueTypeInt, gen->objDef, "push", +// IN_LIST_PUSH_HEAD_WV, IN_LIST_PUSH_HEAD_WC, gen->utArg, false ); +// +// initFunction( gen->utArg, gen->objDef, "pop_head", +// IN_LIST_POP_HEAD_WV, IN_LIST_POP_HEAD_WC, false ); +// +// initFunction( gen->utArg, gen->objDef, "pop_tail", +// IN_LIST_POP_TAIL_WV, IN_LIST_POP_TAIL_WC, false ); +// +// initFunction( gen->utArg, gen->objDef, "pop", +// IN_LIST_POP_HEAD_WV, IN_LIST_POP_HEAD_WC, false ); +} + +void Compiler::initList2Field( GenericType *gen, const char *name, int offset ) +{ + /* Make the type ref and create the field. */ + TypeRef *typeRef = TypeRef::cons( internal, gen->utArg ); + ObjectField *el = ObjectField::cons( internal, typeRef, name ); + + el->inGetR = IN_GET_LIST2_MEM_R; +// el->inGetWC = IN_GET_LIST2_MEM_WC; +// el->inGetWV = IN_GET_LIST2_MEM_WV; +// el->inSetWC = IN_SET_LIST2_MEM_WC; +// el->inSetWV = IN_SET_LIST2_MEM_WV; + + gen->objDef->rootScope->insertField( el->name, el ); + + el->useOffset = true; + el->beenReferenced = true; + el->beenInitialized = true; + + /* Zero for head, One for tail. */ + el->offset = offset; +} + + +void Compiler::initList2Fields( GenericType *gen ) +{ + initList2Field( gen, "head", 0 ); +// initListField( gen, "tail", 1 ); +// initListField( gen, "top", 0 ); +} + +void Compiler::initList2ElField( GenericType *gen, const char *name, int offset ) +{ + /* Make the type ref and create the field. */ + TypeRef *typeRef = TypeRef::cons( internal, gen->utArg ); + ObjectField *el = ObjectField::cons( internal, typeRef, name ); + + el->inGetR = IN_GET_LIST2EL_MEM_R; +// el->inGetWC = IN_GET_LIST2EL_MEM_WC; +// el->inGetWV = IN_GET_LIST2EL_MEM_WV; +// el->inSetWC = IN_SET_LIST2EL_MEM_WC; +// el->inSetWV = IN_SET_LIST2EL_MEM_WV; + + gen->objDef->rootScope->insertField( el->name, el ); + + el->useOffset = true; + el->beenReferenced = true; + el->beenInitialized = true; + + /* Zero for head, One for tail. */ + el->offset = offset; +} + + +void Compiler::initList2ElFields( GenericType *gen ) +{ + initList2ElField( gen, "next", 0 ); +} + +void Compiler::initMap2Functions( GenericType *gen ) +{ +// addLengthField( gen->objDef, IN_MAP_LENGTH ); +// +// initFunction( gen->utArg, gen->objDef, "find", +// IN_MAP_FIND, IN_MAP_FIND, gen->keyUT, true ); +// initFunction( uniqueTypeInt, gen->objDef, "insert", +// IN_MAP_INSERT_WV, IN_MAP_INSERT_WC, gen->keyUT, gen->utArg, false ); +// initFunction( uniqueTypeInt, gen->objDef, "store", +// IN_MAP_STORE_WV, IN_MAP_STORE_WC, gen->keyUT, gen->utArg, false ); +// initFunction( gen->utArg, gen->objDef, "remove", +// IN_MAP_REMOVE_WV, IN_MAP_REMOVE_WC, gen->keyUT, false ); +} + void Compiler::initListField( GenericType *gen, const char *name, int offset ) { /* Make the type ref and create the field. */ diff --git a/src/loadcolm.cc b/src/loadcolm.cc index a7aecf20..bafd9eca 100644 --- a/src/loadcolm.cc +++ b/src/loadcolm.cc @@ -831,7 +831,28 @@ struct LoadColm TypeRef *type = walkTypeRef( typeRef._type_ref() ); tr = TypeRef::cons( typeRef.loc(), TypeRef::Parser, 0, type, 0 ); break; - }} + } + case type_ref::List2El: { + TypeRef *type = walkTypeRef( typeRef._type_ref() ); + tr = TypeRef::cons( typeRef.loc(), TypeRef::List2El, 0, type, 0 ); + break; + } + case type_ref::List2: { + TypeRef *type = walkTypeRef( typeRef._type_ref() ); + tr = TypeRef::cons( typeRef.loc(), TypeRef::List2, 0, type, 0 ); + break; + } + case type_ref::Map2El: { + TypeRef *type = walkTypeRef( typeRef._type_ref() ); + tr = TypeRef::cons( typeRef.loc(), TypeRef::Map2El, 0, type, 0 ); + break; + } + case type_ref::Map2: { + TypeRef *type = walkTypeRef( typeRef._type_ref() ); + tr = TypeRef::cons( typeRef.loc(), TypeRef::Map2, 0, type, 0 ); + break; + } + } return tr; } diff --git a/src/parsedata.h b/src/parsedata.h index d1bc27e1..411a2c9e 100644 --- a/src/parsedata.h +++ b/src/parsedata.h @@ -746,6 +746,13 @@ struct Compiler void initParserFields( GenericType *gen ); void initCtxField( GenericType *gen ); + void initList2Field( GenericType *gen, const char *name, int offset ); + void initList2ElFields( GenericType *gen ); + void initList2ElField( GenericType *gen, const char *name, int offset ); + void initList2Functions( GenericType *gen ); + void initList2Fields( GenericType *gen ); + void initMap2Functions( GenericType *gen ); + void addStdin(); void addStdout(); void addStderr(); @@ -893,6 +900,11 @@ struct Compiler UniqueVectorMap uniqueVectorMap; UniqueParserMap uniqueParserMap; + UniqueList2ElMap uniqueList2ElMap; + UniqueList2Map uniqueList2Map; + UniqueMap2ElMap uniqueMap2ElMap; + UniqueMap2Map uniqueMap2Map; + void initStrObject(); void initStreamObject(); void initIntObject(); diff --git a/src/parsetree.cc b/src/parsetree.cc index 037e6c2b..acb482d1 100644 --- a/src/parsetree.cc +++ b/src/parsetree.cc @@ -154,6 +154,46 @@ int CmpUniqueList::compare( const UniqueList &ut1, const UniqueList &ut2 ) return 0; } +int CmpUniqueList2El::compare( const UniqueList2El &ut1, const UniqueList2El &ut2 ) +{ + if ( ut1.value < ut2.value ) + return -1; + else if ( ut1.value > ut2.value ) + return 1; + + return 0; +} + +int CmpUniqueList2::compare( const UniqueList2 &ut1, const UniqueList2 &ut2 ) +{ + if ( ut1.value < ut2.value ) + return -1; + else if ( ut1.value > ut2.value ) + return 1; + + return 0; +} + +int CmpUniqueMap2El::compare( const UniqueMap2El &ut1, const UniqueMap2El &ut2 ) +{ + if ( ut1.value < ut2.value ) + return -1; + else if ( ut1.value > ut2.value ) + return 1; + + return 0; +} + +int CmpUniqueMap2::compare( const UniqueMap2 &ut1, const UniqueMap2 &ut2 ) +{ + if ( ut1.value < ut2.value ) + return -1; + else if ( ut1.value > ut2.value ) + return 1; + + return 0; +} + int CmpUniqueVector::compare( const UniqueVector &ut1, const UniqueVector &ut2 ) { if ( ut1.value < ut2.value ) diff --git a/src/parsetree.h b/src/parsetree.h index 034f8620..d1d78a6f 100644 --- a/src/parsetree.h +++ b/src/parsetree.h @@ -1941,6 +1941,91 @@ struct CmpUniqueParser typedef AvlBasic< UniqueParser, CmpUniqueParser > UniqueParserMap; +/* + * Unique List2El Types + */ + +struct UniqueList2El + : public AvlTreeEl<UniqueList2El> +{ + UniqueList2El( UniqueType *value ) : + value(value), generic(0) {} + + UniqueType *value; + GenericType *generic; +}; + +struct CmpUniqueList2El +{ + static int compare( const UniqueList2El &ut1, const UniqueList2El &ut2 ); +}; + +typedef AvlBasic< UniqueList2El, CmpUniqueList2El > UniqueList2ElMap; + +/* + * Unique List2 Types + */ + +struct UniqueList2 + : public AvlTreeEl<UniqueList2> +{ + UniqueList2( UniqueType *value ) : + value(value), generic(0) {} + + UniqueType *value; + GenericType *generic; +}; + +struct CmpUniqueList2 +{ + static int compare( const UniqueList2 &ut1, const UniqueList2 &ut2 ); +}; + +typedef AvlBasic< UniqueList2, CmpUniqueList2 > UniqueList2Map; + + +/* + * Unique Map2El Types + */ + +struct UniqueMap2El + : public AvlTreeEl<UniqueMap2El> +{ + UniqueMap2El( UniqueType *value ) : + value(value), generic(0) {} + + UniqueType *value; + GenericType *generic; +}; + +struct CmpUniqueMap2El +{ + static int compare( const UniqueMap2El &ut1, const UniqueMap2El &ut2 ); +}; + +typedef AvlBasic< UniqueMap2El, CmpUniqueMap2El > UniqueMap2ElMap; + +/* + * Unique Map2 Types + */ + +struct UniqueMap2 + : public AvlTreeEl<UniqueMap2> +{ + UniqueMap2( UniqueType *value ) : + value(value), generic(0) {} + + UniqueType *value; + GenericType *generic; +}; + +struct CmpUniqueMap2 +{ + static int compare( const UniqueMap2 &ut1, const UniqueMap2 &ut2 ); +}; + +typedef AvlBasic< UniqueMap2, CmpUniqueMap2 > UniqueMap2Map; + /* * */ @@ -1958,11 +2043,15 @@ struct TypeRef Name, Literal, Iterator, - Map, List, + Map, Parser, Ref, Ptr, + List2El, + List2, + Map2El, + Map2, }; TypeRef() @@ -2138,6 +2227,15 @@ struct TypeRef UniqueType *resolveTypePtr( Compiler *pd ); UniqueType *resolveTypeRef( Compiler *pd ); + UniqueType *resolveTypeList2ElObj( Compiler *pd ); + UniqueType *resolveTypeList2El( Compiler *pd ); + UniqueType *resolveTypeList2Obj( Compiler *pd ); + UniqueType *resolveTypeList2( Compiler *pd ); + UniqueType *resolveTypeMap2ElObj( Compiler *pd ); + UniqueType *resolveTypeMap2El( Compiler *pd ); + UniqueType *resolveTypeMap2Obj( Compiler *pd ); + UniqueType *resolveTypeMap2( Compiler *pd ); + Type type; InputLoc loc; NamespaceQual *nspaceQual; diff --git a/src/resolve.cc b/src/resolve.cc index f1c34872..aa545e0d 100644 --- a/src/resolve.cc +++ b/src/resolve.cc @@ -210,6 +210,157 @@ UniqueType *TypeRef::resolveTypeParser( Compiler *pd ) return pd->findUniqueType( TYPE_PTR, parserUt->langEl ); } +/* + * Object-based list/map + */ +UniqueType *TypeRef::resolveTypeList2ElObj( Compiler *pd ) +{ + nspace = pd->rootNamespace; + + UniqueType *utValue = typeRef1->resolveType( pd ); + + UniqueList2El searchKey( utValue ); + UniqueList2El *inMap = pd->uniqueList2ElMap.find( &searchKey ); + if ( inMap == 0 ) { + inMap = new UniqueList2El( utValue ); + pd->uniqueList2ElMap.insert( inMap ); + + /* FIXME: Need uniqe name allocator for types. */ + static int listId = 0; + String name( 36, "__list2el%d", listId++ ); + + GenericType *generic = new GenericType( name, GEN_LIST2EL, + pd->nextGenericId++, 0/*langEl*/, typeRef1 ); + + nspace->genericList.append( generic ); + + generic->declare( pd, nspace ); + + inMap->generic = generic; + } + + generic = inMap->generic; + return pd->findUniqueType( TYPE_TREE, inMap->generic->langEl ); +} + +UniqueType *TypeRef::resolveTypeList2El( Compiler *pd ) +{ + UniqueType *listUt = resolveTypeList2ElObj( pd ); + return pd->findUniqueType( TYPE_PTR, listUt->langEl ); +} + +UniqueType *TypeRef::resolveTypeList2Obj( Compiler *pd ) +{ + nspace = pd->rootNamespace; + + UniqueType *utValue = typeRef1->resolveType( pd ); + + UniqueList2 searchKey( utValue ); + UniqueList2 *inMap = pd->uniqueList2Map.find( &searchKey ); + if ( inMap == 0 ) { + inMap = new UniqueList2( utValue ); + pd->uniqueList2Map.insert( inMap ); + + /* FIXME: Need uniqe name allocator for types. */ + static int listId = 0; + String name( 36, "__list2%d", listId++ ); + + GenericType *generic = new GenericType( name, GEN_LIST2, + pd->nextGenericId++, 0/*langEl*/, typeRef1 ); + + nspace->genericList.append( generic ); + + generic->declare( pd, nspace ); + + inMap->generic = generic; + } + + generic = inMap->generic; + return pd->findUniqueType( TYPE_TREE, inMap->generic->langEl ); +} + +UniqueType *TypeRef::resolveTypeList2( Compiler *pd ) +{ + UniqueType *listUt = resolveTypeList2Obj( pd ); + return pd->findUniqueType( TYPE_PTR, listUt->langEl ); +} + +UniqueType *TypeRef::resolveTypeMap2ElObj( Compiler *pd ) +{ + nspace = pd->rootNamespace; + + UniqueType *utValue = typeRef1->resolveType( pd ); + + UniqueMap2El searchKey( utValue ); + UniqueMap2El *inMap = pd->uniqueMap2ElMap.find( &searchKey ); + if ( inMap == 0 ) { + inMap = new UniqueMap2El( utValue ); + pd->uniqueMap2ElMap.insert( inMap ); + + /* FIXME: Need uniqe name allocator for types. */ + static int listId = 0; + String name( 36, "__map2el%d", listId++ ); + + GenericType *generic = new GenericType( name, GEN_MAP2EL, + pd->nextGenericId++, 0/*langEl*/, typeRef1 ); + + nspace->genericList.append( generic ); + + generic->declare( pd, nspace ); + + inMap->generic = generic; + } + + generic = inMap->generic; + return pd->findUniqueType( TYPE_TREE, inMap->generic->langEl ); +} + +UniqueType *TypeRef::resolveTypeMap2El( Compiler *pd ) +{ + UniqueType *listUt = resolveTypeMap2ElObj( pd ); + return pd->findUniqueType( TYPE_PTR, listUt->langEl ); +} + +UniqueType *TypeRef::resolveTypeMap2Obj( Compiler *pd ) +{ + nspace = pd->rootNamespace; + + UniqueType *utValue = typeRef1->resolveType( pd ); + + UniqueMap2 searchKey( utValue ); + UniqueMap2 *inMap = pd->uniqueMap2Map.find( &searchKey ); + if ( inMap == 0 ) { + inMap = new UniqueMap2( utValue ); + pd->uniqueMap2Map.insert( inMap ); + + /* FIXME: Need uniqe name allocator for types. */ + static int listId = 0; + String name( 36, "__map2%d", listId++ ); + + GenericType *generic = new GenericType( name, GEN_MAP2, + pd->nextGenericId++, 0/*langEl*/, typeRef1 ); + + nspace->genericList.append( generic ); + + generic->declare( pd, nspace ); + + inMap->generic = generic; + } + + generic = inMap->generic; + return pd->findUniqueType( TYPE_TREE, inMap->generic->langEl ); +} + +UniqueType *TypeRef::resolveTypeMap2( Compiler *pd ) +{ + UniqueType *listUt = resolveTypeMap2Obj( pd ); + return pd->findUniqueType( TYPE_PTR, listUt->langEl ); +} + +/* + * End object based list/map + */ + UniqueType *TypeRef::resolveTypePtr( Compiler *pd ) { typeRef1->resolveType( pd ); @@ -322,6 +473,18 @@ UniqueType *TypeRef::resolveType( Compiler *pd ) case Iterator: uniqueType = resolveIterator( pd ); break; + case List2El: + uniqueType = resolveTypeList2El( pd ); + break; + case List2: + uniqueType = resolveTypeList2( pd ); + break; + case Map2El: + uniqueType = resolveTypeMap2El( pd ); + break; + case Map2: + uniqueType = resolveTypeMap2( pd ); + break; case Unspecified: /* No lookup needed, unique type(s) set when constructed. */ break; @@ -1039,6 +1039,22 @@ Tree *constructGeneric( Program *prg, long genericId ) newGeneric = (Tree*) parser; break; } + case GEN_LIST2EL: { + break; + } + case GEN_LIST2: { + List *list = (List*)mapElAllocate( prg ); + list->id = genericInfo->langElId; + list->genericInfo = genericInfo; + newGeneric = (Tree*) list; + break; + } + case GEN_MAP2EL: { + break; + } + case GEN_MAP2: { + break; + } default: assert(false); return 0; @@ -1163,6 +1179,26 @@ free_tree: treeDownref( prg, sp, (Tree*)parser->input ); mapElFree( prg, (MapEl*)parser ); } + else if ( generic->type == GEN_LIST2EL ) { + + } + else if ( generic->type == GEN_LIST2 ) { + List *list = (List*) tree; +// ListEl *el = list->head; +// while ( el != 0 ) { +// ListEl *next = el->next; +// vm_push( el->value ); +// listElFree( prg, el ); +// el = next; +// } + mapElFree( prg, (MapEl*)list ); + } + else if ( generic->type == GEN_MAP2EL ) { + + } + else if ( generic->type == GEN_MAP2 ) { + + } else { assert(false); } @@ -1658,6 +1694,51 @@ void listPushTail( Program *prg, List *list, Tree *val ) listAppend( list, listEl ); } +void list2PushTail( Program *prg, Tree **sp, List *list, Tree *val ) +{ + /* Deref the object we are pushing. */ + val = ((Pointer*)val)->value->tree; + + /* Make sure val has an element tree. */ + Tree *el = colm_get_attr( val, 0 ); + if ( el == 0 ) { + el = treeAllocate( prg ); + el->id = 0; + el->refs = 1; + el->child = allocAttrs( prg, 2 ); + setAttr( val, 0, constructPointer( prg, el ) ); + } + else { + /* Deref the list element (must be a pointer too for time being) */ + el = ((Pointer*)el)->value->tree; + } + + /* val->prev = list->tail */ + /* val->next = 0 */ + setAttr( el, 0, (Tree*)list->tail ); + setAttr( el, 1, 0 ); + +// if list->tail == 0 +// list->tail = list->tail = val +// else +// list->tail->next = val +// list->tail = val + + Tree *pval = constructPointer( prg, val ); + + pval->refs += 100; + val->refs += 100; + + if ( list->tail == 0 ) { + list->head = list->tail = (ListEl*)pval; + } + else { + Tree *tel = colm_get_attr( ((Pointer*)list->tail)->value->tree, 0 ); + setAttr( ((Pointer*)tel)->value->tree, 1, pval ); + list->tail = (ListEl*)pval; + } +} + void listPushHead( Program *prg, List *list, Tree *val ) { assert( list->refs == 1 ); @@ -300,6 +300,7 @@ Tree *setListMem( List *list, Half field, Tree *value ); void listPushTail( struct colm_program *prg, List *list, Tree *val ); void listPushHead( struct colm_program *prg, List *list, Tree *val ); +void list2PushTail( struct colm_program *prg, Tree **sp, List *list, Tree *val ); Tree *listRemoveEnd( struct colm_program *prg, List *list ); Tree *listRemoveHead( struct colm_program *prg, List *list ); Tree *getListMem( List *list, Word field ); |