@@ -117,7 +117,7 @@ void pvm::start_thread() {
117
117
void pvm::step () {
118
118
next_inst:
119
119
if (!this ->queue ) return ;
120
- object* next_type = car ( cdr ( this ->curr_thread () ));
120
+ object* next_type = cadr ( this ->curr_thread ());
121
121
object* op = this ->pop_inst ();
122
122
if (!op) {
123
123
object* last = this ->queue ;
@@ -133,12 +133,12 @@ void pvm::step() {
133
133
}
134
134
object* type = car (op);
135
135
if (eqcmp (type, next_type) != 0 ) goto next_inst;
136
- object* inst_name = car ( cdr (op) );
137
- object* cookie = cdr ( cdr (op) );
136
+ object* inst_name = cadr (op );
137
+ object* cookie = cddr (op );
138
138
object* pair = assoc (this ->function_registry , inst_name);
139
139
ASSERT (pair, " Unknown instruction %s" , this ->stringof (inst_name));
140
140
next_type = this ->fptr (cdr (pair))(this , cookie, next_type);
141
- car ( cdr ( this ->curr_thread () )) = next_type;
141
+ cadr ( this ->curr_thread ()) = next_type;
142
142
this ->queue = cdr (this ->queue );
143
143
}
144
144
@@ -416,8 +416,9 @@ object* parse(pvm* vm, object* cookie, object* inst_type) {
416
416
// ------------------------- HASHMAPS (OBJECTS) -------------------------------
417
417
418
418
// Returns the found node or nil if the hash is not found.
419
- static object* hashmap_find (pvm* vm, object* map, uint64_t hash) {
419
+ static object* hashmap_get (pvm* vm, object* map, uint64_t hash) {
420
420
// Each hashmap node is a 4-cons tree ((hash . (key . value)) . (left . right))
421
+ // but this gets printed as ((hash key . value) left . right) when the map is printed as-is
421
422
uint64_t hh = hash;
422
423
DBG (" Searching hashmap for hash %" PRId64 " {" , hash);
423
424
recurse:
@@ -427,13 +428,10 @@ static object* hashmap_find(pvm* vm, object* map, uint64_t hash) {
427
428
}
428
429
object* hash_pair = car (map);
429
430
if (hash_pair) {
430
- printf (" hash_pair = " );
431
- vm->dump (hash_pair);
432
- putchar (' ' );
433
- vm->dump (car (hash_pair));
434
431
int64_t this_hash = vm->intof (car (hash_pair));
432
+ DBG (" this_hash=%" PRId64, this_hash);
435
433
if (this_hash == hash) {
436
- DBG (" Found matching key for hash %" PRId64, hash);
434
+ DBG (" Found matching key for hash %" PRId64 " } " , hash);
437
435
return map;
438
436
}
439
437
}
@@ -454,6 +452,7 @@ static object* hashmap_find(pvm* vm, object* map, uint64_t hash) {
454
452
static object* hashmap_set (pvm* vm, object** map, object* key, uint64_t hash, object* val) {
455
453
DBG (" Setting hash %" PRId64 " on hashmap. {" , hash);
456
454
uint64_t hh = hash;
455
+ object* newnode = nil;
457
456
recurse:
458
457
if (*map == nil) {
459
458
DBG (" Tree is terminated -- add new node. }" );
@@ -467,15 +466,17 @@ static object* hashmap_set(pvm* vm, object** map, object* key, uint64_t hash, ob
467
466
if (!hash_pair) {
468
467
DBG (" Found tombstoned node. Inserting key." );
469
468
car (*map) = vm->cons (vm->integer (hash), vm->cons (key, val));
469
+ newnode = *map;
470
+ if (!children) return newnode; // No children to search and kill
470
471
goto killshadow;
471
472
} else {
472
473
// Check if the hashes match
473
474
int64_t z = vm->intof (car (hash_pair));
474
475
if (z == hash) {
475
476
DBG (" Found matching node. Re-setting it. }" );
476
477
if (!cdr (hash_pair)) cdr (hash_pair) = vm->cons (nil, nil);
477
- car ( cdr ( hash_pair) ) = key;
478
- cdr ( cdr ( hash_pair) ) = val;
478
+ cadr ( hash_pair) = key;
479
+ cddr ( hash_pair) = val;
479
480
return *map;
480
481
}
481
482
}
@@ -495,6 +496,11 @@ static object* hashmap_set(pvm* vm, object** map, object* key, uint64_t hash, ob
495
496
else map = &cdr (children);
496
497
hh >>= 1 ;
497
498
DBG (" Continuing on %s" , ll ? " LEFT" : " RIGHT" );
499
+ killagain:
500
+ if ((*map) == nil) {
501
+ DBG (" Reached end of hash path. Done killing. }" );
502
+ return newnode;
503
+ }
498
504
hash_pair = car (*map);
499
505
ll = hh & 1 ;
500
506
children = cdr (*map);
@@ -505,15 +511,15 @@ static object* hashmap_set(pvm* vm, object** map, object* key, uint64_t hash, ob
505
511
car (*map) = nil;
506
512
}
507
513
}
508
- if (! children) {
514
+ if (children == nil ) {
509
515
DBG (" Reached node with no children. Stopping }" );
510
- return *map ;
516
+ return newnode ;
511
517
}
512
518
if (ll) map = &car (children);
513
519
else map = &cdr (children);
514
520
hh >>= 1 ;
515
521
DBG (" Shadow recursing on %s" , ll ? " LEFT" : " RIGHT" );
516
- goto killshadow ;
522
+ goto killagain ;
517
523
}
518
524
519
525
object* pvm::get_property (object* obj, uint64_t hash, bool recurse) {
@@ -534,17 +540,17 @@ object* pvm::get_property(object* obj, uint64_t hash, bool recurse) {
534
540
if (obj->type != &obj_type) return nil;
535
541
// Search the hashmap.
536
542
object* hashmap = cdr (obj);
537
- object* node = hashmap_find (this , obj , hash);
538
- if (node) return cdr ( car ( node) );
543
+ object* node = hashmap_get (this , hashmap , hash);
544
+ if (node) return cddar ( node);
539
545
return nil;
540
546
}
541
547
542
- bool pvm::set_property (object* obj, object* val , uint64_t hash, object* value) {
548
+ bool pvm::set_property (object* obj, object* key , uint64_t hash, object* value) {
543
549
// Nil has no properties
544
550
if (!obj) return false ;
545
551
// Check if it is an object-object (primitives have no own properties)
546
552
if (obj->type != &obj_type) return false ;
547
- hashmap_set (this , &cdr (obj), val , hash, value);
553
+ hashmap_set (this , &cdr (obj), key , hash, value);
548
554
return true ;
549
555
}
550
556
@@ -553,7 +559,7 @@ bool pvm::remove_property(object* obj, uint64_t hash) {
553
559
if (!obj) return false ;
554
560
// Check if it is an object-object (primitives have no own properties)
555
561
if (obj->type != &obj_type) return false ;
556
- bool had = hashmap_find (this , cdr (obj), hash) != nil;
562
+ bool had = hashmap_get (this , cdr (obj), hash) != nil;
557
563
// Try to set the node to nil, which will kill the shadow references
558
564
object* node = hashmap_set (this , &cdr (obj), nil, hash, nil);
559
565
// Then kill this node too
@@ -619,8 +625,7 @@ static void make_refs_list(pvm* vm, object* obj, object** alist) {
619
625
return ;
620
626
}
621
627
vm->push (vm->cons (obj, vm->integer (1 )), *alist);
622
- if (obj->type == &obj_type) return ; // hashmaps are guaranteed non disjoint, i guess
623
- make_refs_list (vm, car (obj), alist);
628
+ if (obj->type != &obj_type) make_refs_list (vm, car (obj), alist); // hashmaps are guaranteed non disjoint, i guess
624
629
obj = cdr (obj);
625
630
goto again;
626
631
}
@@ -652,13 +657,16 @@ static void print_with_refs(pvm*, object*, object*, int64_t*);
652
657
static void print_hashmap (pvm* vm, object* node, object* alist, int64_t * counter) {
653
658
recur:
654
659
if (node) {
655
- print_with_refs (vm, car (cdr (car (node))), alist, counter);
656
- printf (" : " );
657
- print_with_refs (vm, cdr (cdr (car (node))), alist, counter);
658
- printf (" , " );
660
+ if (car (node)) {
661
+ object* hinfo = car (node);
662
+ print_with_refs (vm, cadr (hinfo), alist, counter);
663
+ printf (" -> " );
664
+ print_with_refs (vm, cddr (hinfo), alist, counter);
665
+ printf (" ;[hash=%" PRId64 " ] " , vm->intof (car (hinfo)));
666
+ }
659
667
if (!cdr (node)) return ;
660
- print_hashmap (vm, car ( cdr ( node) ), alist, counter);
661
- node = cdr ( cdr ( node) );
668
+ print_hashmap (vm, cadr ( node), alist, counter);
669
+ node = cddr ( node);
662
670
goto recur;
663
671
}
664
672
}
@@ -668,8 +676,17 @@ static void print_with_refs(pvm* vm, object* obj, object* alist, int64_t* counte
668
676
printf (" NIL" );
669
677
return ;
670
678
}
679
+ // test if it's in the table
680
+ int64_t ref = reffed (vm, obj, alist, counter);
681
+ if (ref < 0 ) {
682
+ printf (" #%" PRId64 " #" , -ref);
683
+ return ;
684
+ }
685
+ if (ref) {
686
+ printf (" #%" PRId64 " =" , ref);
687
+ }
671
688
#define PRINTTYPE (t, f, fmt ) else if (obj->type == t) printf(fmt, obj->f)
672
- else if (obj->type == &string_type) {
689
+ if (obj->type == &string_type) {
673
690
putchar (' "' );
674
691
for (char * c = obj->as_chars ; *c; c++) {
675
692
char e = escape (*c);
@@ -688,16 +705,7 @@ static void print_with_refs(pvm* vm, object* obj, object* alist, int64_t* counte
688
705
PRINTTYPE (NULL , as_ptr, " <garbage %p>" );
689
706
#undef PRINTTYPE
690
707
else if (obj->type == &cons_type) {
691
- // it's a cons
692
- // test if it's in the table
693
- int64_t ref = reffed (vm, obj, alist, counter);
694
- if (ref < 0 ) {
695
- printf (" #%" PRId64 " #" , -ref);
696
- return ;
697
- }
698
- if (ref) {
699
- printf (" #%" PRId64 " =" , ref);
700
- }
708
+ // it's a cons and unreffed
701
709
// now print the object
702
710
putchar (' (' );
703
711
for (;;) {
@@ -723,14 +731,14 @@ static void print_with_refs(pvm* vm, object* obj, object* alist, int64_t* counte
723
731
}
724
732
else if (obj->type == &obj_type) {
725
733
// Try to find the class name
726
- // TODO: String/symbol/int hash.
734
+ // TODO: String/symbol/int static hash.
727
735
const char * nm = " object" ;
728
- // if (car(obj) && !cdr(car(obj)) && car(car(obj))) {
736
+ // if (car(obj) && car(car(obj))) {
729
737
// object* super = car(car(obj));
730
- // object* name = vm->get_property(obj , vm->static_hash(vm->string("__name__")));
738
+ // object* name = vm->get_property(super , vm->static_hash(vm->string("__name__")));
731
739
// if (name->type == &symbol_type) nm = vm->stringof(name);
732
740
// }
733
- printf (" %s { " , nm);
741
+ printf (" %s{ " , nm);
734
742
print_hashmap (vm, cdr (obj), alist, counter);
735
743
putchar (' }' );
736
744
}
0 commit comments