summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2015-01-17 14:38:11 -0500
committerAdrian Thurston <thurston@complang.org>2015-01-17 14:38:11 -0500
commit62ac1f337497046fa0f46a41eaee36e23c0e8fcc (patch)
treec333aa566fa4ffce2d2f6896a2c447232b402e8a
parentffe2843d882b5f6fc606a6ee09f15a3196840c7b (diff)
downloadcolm-62ac1f337497046fa0f46a41eaee36e23c0e8fcc.tar.gz
more of map implemented: can now traverse map elements
-rw-r--r--src/bytecode.c172
-rw-r--r--src/bytecode.h8
-rw-r--r--src/compiler.h2
-rw-r--r--src/declare.cc65
-rw-r--r--src/map.c29
-rw-r--r--src/struct.h2
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;
diff --git a/src/map.c b/src/map.c
index bdbf9f65..2d617e21 100644
--- a/src/map.c
+++ b/src/map.c
@@ -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