@@ -2296,23 +2296,35 @@ class State {
22962296 expr->computeFreeVars ();
22972297 expr->computeTail (false );
22982298 if (doPreAlloc) {
2299+ std::unordered_map<int , syntax::Location> integerLocationMap;
2300+ std::unordered_map<std::string, syntax::Location> stringLocationMap;
22992301 std::function<void (syntax::ExprNode*)> preAllocate =
2300- [this ](syntax::ExprNode* e) -> void {
2302+ [this , &integerLocationMap, &stringLocationMap]
2303+ (syntax::ExprNode* e) -> void {
23012304 if (auto inode = dynamic_cast <syntax::IntegerNode*>(e)) {
23022305 // TODO: exceptions
2303- inode->loc = this ->_new <runtime::Integer>(std::stoi (inode->val ));
2306+ int ival = std::stoi (inode->val );
2307+ if (integerLocationMap.contains (ival)) {
2308+ inode->loc = integerLocationMap.at (ival);
2309+ } else {
2310+ inode->loc = this ->_new <runtime::Integer>(ival);
2311+ integerLocationMap[ival] = inode->loc ;
2312+ }
23042313 }
23052314 else if (auto snode = dynamic_cast <syntax::StringNode*>(e)) {
2306- snode->loc = this ->_new <runtime::String>(syntax::unquote (snode->val ));
2315+ std::string sval = syntax::unquote (snode->val );
2316+ if (stringLocationMap.contains (sval)) {
2317+ snode->loc = stringLocationMap.at (sval);
2318+ } else {
2319+ snode->loc = this ->_new <runtime::String>(sval);
2320+ stringLocationMap[sval] = snode->loc ;
2321+ }
23072322 }
23082323 };
23092324 expr->traverse (syntax::TraversalMode::TOP_DOWN, preAllocate);
23102325 }
23112326 else {
2312- // it's ok to find any location with the same value
2313- // and this is the only known (unobservable) difference
2314- // between the original state and serialized-and-de-serialized state
2315- // TODO: change to unique values
2327+ // the location for every different value is unique
23162328 std::function<void (syntax::ExprNode*)> findPreAllocate =
23172329 [this ](syntax::ExprNode* e) -> void {
23182330 if (auto inode = dynamic_cast <syntax::IntegerNode*>(e)) {
0 commit comments