diff options
author | Adrian Thurston <thurston@complang.org> | 2015-01-17 14:38:11 -0500 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2015-01-17 14:38:11 -0500 |
commit | 62ac1f337497046fa0f46a41eaee36e23c0e8fcc (patch) | |
tree | c333aa566fa4ffce2d2f6896a2c447232b402e8a | |
parent | ffe2843d882b5f6fc606a6ee09f15a3196840c7b (diff) | |
download | colm-62ac1f337497046fa0f46a41eaee36e23c0e8fcc.tar.gz |
more of map implemented: can now traverse map elements
-rw-r--r-- | src/bytecode.c | 172 | ||||
-rw-r--r-- | src/bytecode.h | 8 | ||||
-rw-r--r-- | src/compiler.h | 2 | ||||
-rw-r--r-- | src/declare.cc | 65 | ||||
-rw-r--r-- | src/map.c | 29 | ||||
-rw-r--r-- | src/struct.h | 2 |
6 files changed, 162 insertions, 116 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index af08beb2..942088dc 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -3275,6 +3275,7 @@ again: vm_push( res ); break; } +#if 0 case IN_SET_LIST_MEM_WC: { Half field; read_half( field ); @@ -3323,6 +3324,7 @@ again: treeDownref( prg, sp, undid ); break; } +#endif case IN_GET_PARSER_MEM_R: { short field; read_half( field ); @@ -3339,20 +3341,6 @@ again: vm_push( val ); break; } -// short genId; -// read_half( genId ); -// -// debug( prg, REALM_BYTECODE, "IN_LIST_PUSH_TAIL_WC\n" ); -// -// List *list = vm_pop_list(); -// Struct *s = vm_pop_struct(); -// -// ListEl *listEl = colm_struct_to_list_el( prg, s, genId ); -// colm_list_append( list, listEl ); -// -// treeUpref( prg->trueVal ); -// vm_push( prg->trueVal ); -// break; case IN_GET_MAP_EL_MEM_R: { short genId, field; @@ -3436,84 +3424,7 @@ again: treeDownref( prg, sp, key ); break; } -// case IN_MAP_STORE_WC: { -// debug( prg, REALM_BYTECODE, "IN_MAP_STORE_WC\n" ); -// -// Tree *obj = vm_pop(); -// Tree *element = vm_pop(); -// Tree *key = vm_pop(); -// -// Tree *existing = mapStore( prg, (Map*)obj, key, element ); -// Tree *result = existing == 0 ? prg->trueVal : prg->falseVal; -// treeUpref( result ); -// vm_push( result ); -// -// treeDownref( prg, sp, obj ); -// if ( existing != 0 ) { -// treeDownref( prg, sp, key ); -// treeDownref( prg, sp, existing ); -// } -// break; -// } -// case IN_MAP_STORE_WV: { -// debug( prg, REALM_BYTECODE, "IN_MAP_STORE_WV\n" ); -// -// Tree *obj = vm_pop(); -// Tree *element = vm_pop(); -// Tree *key = vm_pop(); -// -// Tree *existing = mapStore( prg, (Map*)obj, key, element ); -// Tree *result = existing == 0 ? prg->trueVal : prg->falseVal; -// treeUpref( result ); -// vm_push( result ); -// -// /* Set up the reverse instruction. */ -// treeUpref( key ); -// treeUpref( existing ); -// rcodeCode( exec, IN_MAP_STORE_BKT ); -// rcodeWord( exec, (Word)key ); -// rcodeWord( exec, (Word)existing ); -// rcodeUnitTerm( exec ); -// -// treeDownref( prg, sp, obj ); -// if ( existing != 0 ) { -// treeDownref( prg, sp, key ); -// treeDownref( prg, sp, existing ); -// } -// break; -// } -// case IN_MAP_STORE_BKT: { -// Tree *key, *val; -// read_tree( key ); -// read_tree( val ); -// -// debug( prg, REALM_BYTECODE, "IN_MAP_STORE_BKT\n" ); -// -// Tree *obj = vm_pop(); -// Tree *stored = mapUnstore( prg, (Map*)obj, key, val ); -// -// treeDownref( prg, sp, stored ); -// if ( val == 0 ) -// treeDownref( prg, sp, key ); -// -// treeDownref( prg, sp, obj ); -// treeDownref( prg, sp, key ); -// break; -// } case IN_MAP_DETACH_WC: { -// debug( prg, REALM_BYTECODE, "IN_MAP_DETACH_WC\n" ); -// -// Tree *obj = vm_pop(); -// Tree *key = vm_pop(); -// TreePair pair = mapRemove( prg, (Map*)obj, key ); -// -// vm_push( pair.val ); -// -// treeDownref( prg, sp, obj ); -// treeDownref( prg, sp, key ); -// treeDownref( prg, sp, pair.key ); -// break; - short genId; read_half( genId ); @@ -3596,6 +3507,65 @@ again: vm_push_struct( strct ); break; } + case IN_GET_MAP_MEM_R: { + short genId, field; + read_half( genId ); + read_half( field ); + + debug( prg, REALM_BYTECODE, + "IN_GET_MAP_MEM_R %hd %hd\n", genId, field ); + + Map *map = vm_pop_map(); + Struct *val = colm_map_get( prg, map, genId, field ); + vm_push_struct( val ); + break; + } + case IN_GET_MAP_MEM_WC: { + short field; + read_half( field ); + + debug( prg, REALM_BYTECODE, "IN_GET_MAP_MEM_WC\n" ); + + Tree *obj = vm_pop(); + treeDownref( prg, sp, obj ); + + Tree *val = getListMemSplit( prg, (List*)obj, field ); + treeUpref( val ); + vm_push( val ); + break; + } + case IN_GET_MAP_MEM_WV: { + short field; + read_half( field ); + + debug( prg, REALM_BYTECODE, "IN_GET_MAP_MEM_WV\n" ); + + Tree *obj = vm_pop(); + treeDownref( prg, sp, obj ); + + Tree *val = getListMemSplit( prg, (List*)obj, field ); + treeUpref( val ); + vm_push( val ); + + /* Set up the reverse instruction. */ + rcodeCode( exec, IN_GET_MAP_MEM_BKT ); + rcodeHalf( exec, field ); + break; + } + case IN_GET_MAP_MEM_BKT: { + short field; + read_half( field ); + + debug( prg, REALM_BYTECODE, "IN_GET_MAP_MEM_BKT\n" ); + + Tree *obj = vm_pop(); + treeDownref( prg, sp, obj ); + + Tree *res = getListMemSplit( prg, (List*)obj, field ); + treeUpref( res ); + vm_push( res ); + break; + } case IN_CONTIGUOUS: { Half size; read_half( size ); @@ -4205,6 +4175,7 @@ again: debug( prg, REALM_BYTECODE, "IN_GET_LIST_MEM_BKT %hd\n", field ); break; } +#if 0 case IN_SET_LIST_MEM_BKT: { Half field; Tree *val; @@ -4216,6 +4187,7 @@ again: treeDownref( prg, sp, val ); break; } +#endif case IN_MAP_INSERT_BKT: { /* uchar inserted; */ Tree *key; @@ -4227,17 +4199,6 @@ again: treeDownref( prg, sp, key ); break; } -// case IN_MAP_STORE_BKT: { -// Tree *key, *val; -// read_tree( key ); -// read_tree( val ); -// -// debug( prg, REALM_BYTECODE,"IN_MAP_STORE_BKT\n" ); -// -// treeDownref( prg, sp, key ); -// treeDownref( prg, sp, val ); -// break; -// } case IN_MAP_DETACH_BKT: { Tree *key, *val; read_tree( key ); @@ -4249,6 +4210,13 @@ again: treeDownref( prg, sp, val ); break; } + case IN_GET_MAP_MEM_BKT: { + short field; + read_half( field ); + + debug( prg, REALM_BYTECODE, "IN_GET_MAP_MEM_BKT %hd\n", field ); + break; + } case IN_STOP: { return; } diff --git a/src/bytecode.h b/src/bytecode.h index f2f5acd1..11c0eef6 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -174,12 +174,14 @@ typedef unsigned char uchar; #define IN_GET_LIST_MEM_WC 0x7a #define IN_GET_LIST_MEM_WV 0x7b #define IN_GET_LIST_MEM_BKT 0x7c -#define IN_SET_LIST_MEM_WV 0x7d -#define IN_SET_LIST_MEM_WC 0x7e -#define IN_SET_LIST_MEM_BKT 0x7f #define IN_GET_LIST_EL_MEM_R 0xf5 +#define IN_GET_MAP_MEM_R 0x6d +#define IN_GET_MAP_MEM_WV 0x7d +#define IN_GET_MAP_MEM_WC 0x7e +#define IN_GET_MAP_MEM_BKT 0x7f + #define IN_VECTOR_LENGTH 0x80 #define IN_VECTOR_APPEND_WV 0x81 #define IN_VECTOR_APPEND_WC 0x82 diff --git a/src/compiler.h b/src/compiler.h index 4e500099..6a9cf271 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -736,7 +736,9 @@ struct Compiler void verifyParseStopGrammar( LangEl *langEl, PdaGraph *pdaGraph ); void computeAdvanceReductions( LangEl *langEl, PdaGraph *pdaGraph ); + void initMapElKey( GenericType *gen, const char *name, int offset ); void initMapElField( GenericType *gen, const char *name, int offset ); + void initMapField( GenericType *gen, const char *name, int offset ); void initMapFunctions( GenericType *gen ); void initMapFields( GenericType *gen ); diff --git a/src/declare.cc b/src/declare.cc index 5e927622..083693b5 100644 --- a/src/declare.cc +++ b/src/declare.cc @@ -938,13 +938,40 @@ void Compiler::initMapFunctions( GenericType *gen ) IN_MAP_DETACH_WV, IN_MAP_DETACH_WC, gen->utArg, false, false, gen ); } +void Compiler::initMapField( GenericType *gen, const char *name, int offset ) +{ + /* Make the type ref and create the field. */ + ObjectField *el = ObjectField::cons( internal, + ObjectField::InbuiltOffType, gen->typeArg, name ); + + el->inGetR = IN_GET_MAP_MEM_R; + el->inGetWC = IN_GET_MAP_MEM_WC; + el->inGetWV = IN_GET_MAP_MEM_WV; +// el->inSetWC = IN_SET_MAP_MEM_WC; +// el->inSetWV = IN_SET_MAP_MEM_WV; + + el->inGetValR = IN_GET_MAP_MEM_R; + el->inGetValWC = IN_GET_MAP_MEM_WC; + el->inGetValWV = IN_GET_MAP_MEM_WV; + + gen->objDef->rootScope->insertField( el->name, el ); + + el->useGenericId = true; + el->generic = gen; + + /* Zero for head, One for tail. */ + el->offset = offset; +} + void Compiler::initMapFields( GenericType *gen ) { addLengthField( gen->objDef, IN_MAP_LENGTH ); -} + initMapField( gen, "head", 0 ); + initMapField( gen, "tail", 1 ); +} -void Compiler::initMapElField( GenericType *gen, const char *name, int offset ) +void Compiler::initMapElKey( GenericType *gen, const char *name, int offset ) { /* Make the type ref and create the field. */ ObjectField *el = ObjectField::cons( internal, @@ -958,14 +985,38 @@ void Compiler::initMapElField( GenericType *gen, const char *name, int offset ) gen->utArg->structEl->structDef->objectDef->rootScope->insertField( el->name, el ); } +void Compiler::initMapElField( GenericType *gen, const char *name, int offset ) +{ + /* Make the type ref and create the field. */ + ObjectField *el = ObjectField::cons( internal, + ObjectField::InbuiltOffType, gen->typeArg, name ); + + el->inGetR = IN_GET_MAP_EL_MEM_R; + el->inGetValR = IN_GET_MAP_EL_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; + + el->useGenericId = true; + el->generic = gen; + + /* Zero for head, One for tail. */ + el->offset = offset; + + gen->utArg->structEl->structDef->objectDef->rootScope->insertField( el->name, el ); +} + void Compiler::initMapElFields( GenericType *gen ) { - initMapElField( gen, "key", 0 ); + initMapElKey( gen, "key", 0 ); + + initMapElField( gen, "prev", 0 ); + initMapElField( gen, "next", 1 ); } void Compiler::initListFunctions( 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, false, gen ); @@ -1011,6 +1062,8 @@ void Compiler::initListElField( GenericType *gen, const char *name, int offset ) void Compiler::initListElFields( GenericType *gen ) { + addLengthField( gen->objDef, IN_LIST_LENGTH ); + initListElField( gen, "prev", 0 ); initListElField( gen, "next", 1 ); } @@ -1024,8 +1077,8 @@ void Compiler::initListField( GenericType *gen, const char *name, int offset ) el->inGetR = IN_GET_LIST_MEM_R; el->inGetWC = IN_GET_LIST_MEM_WC; el->inGetWV = IN_GET_LIST_MEM_WV; - el->inSetWC = IN_SET_LIST_MEM_WC; - el->inSetWV = IN_SET_LIST_MEM_WV; +// el->inSetWC = IN_SET_LIST_MEM_WC; +// el->inSetWV = IN_SET_LIST_MEM_WV; el->inGetValR = IN_GET_LIST_MEM_R; el->inGetValWC = IN_GET_LIST_MEM_WC; @@ -15,16 +15,35 @@ struct colm_struct *colm_map_el_get( struct colm_program *prg, MapEl *mapEl, Word genId, Word field ) { GenericInfo *gi = &prg->rtd->genericInfo[genId]; - ListEl *result = 0; + MapEl *result = 0; switch ( field ) { case 0: -// result = listEl->list_prev; + result = mapEl->prev; break; case 1: -// result = listEl->list_next; + result = mapEl->next; break; - case 2: -// result = listEl->list_next; + default: + assert( 0 ); + break; + } + + struct colm_struct *s = result != 0 ? + colm_struct_container( result, gi->elOffset ) : 0; + return s; +} + +struct colm_struct *colm_map_get( struct colm_program *prg, + Map *map, Word genId, Word field ) +{ + GenericInfo *gi = &prg->rtd->genericInfo[genId]; + MapEl *result = 0; + switch ( field ) { + case 0: + result = map->head; + break; + case 1: + result = map->tail; break; default: assert( 0 ); diff --git a/src/struct.h b/src/struct.h index 7ff8256b..086e479e 100644 --- a/src/struct.h +++ b/src/struct.h @@ -143,6 +143,8 @@ long colm_list_length( List *list ); Map *colm_map_new( struct colm_program *prg ); struct colm_struct *colm_map_el_get( struct colm_program *prg, MapEl *mapEl, Word genId, Word field ); +struct colm_struct *colm_map_get( struct colm_program *prg, Map *map, + Word genId, Word field ); #define STRUCT_INBUILT_ID -1 |