ComputeValue

original_code:
double ComputeValue(IncrementListNode *incNodePtr, Substructure *sub,
                    LabelList *labelList, ULONG *numPosInstances,
                    ULONG *numNegInstances, ULONG *graphPosSize,
                    ULONG *graphNegSize, Parameters *parameters)
{
   Increment *increment;
   IncrementListNode *incrementNode;
   SubListNode *subListNode;
   Substructure *incrementSub;
   BOOLEAN found = 0;
   ULONG totalPosInstances = 0;
   ULONG totalNegInstances = 0;
   ULONG totalPosEgs = 0;
   ULONG totalNegEgs = 0;
   ULONG startIncrement;
   double totalPosGraphSize = 0;
   double totalNegGraphSize = 0;
   double compressedPosGraphSize = 0;
   double compressedNegGraphSize = 0;
   double subValue;
   if (incNodePtr == ((void *)0))
      printf("ComputeValue Error: incNodePtr is null\n");
   if (parameters->evalMethod != 3)
   {
      startIncrement = incNodePtr->increment->incrementNum;
      if (startIncrement !=
          parameters->incrementList->head->increment->incrementNum)
      {
         incrementNode = parameters->incrementList->head;
         while (incrementNode->increment->incrementNum < startIncrement)
         {
            increment = incrementNode->increment;
            totalPosGraphSize += increment->numPosVertices +
                                 increment->numPosEdges;
            totalNegGraphSize += increment->numNegVertices +
                                 increment->numNegEdges;
            incrementNode = incrementNode->next;
         }
         compressedPosGraphSize = totalPosGraphSize;
         compressedNegGraphSize = totalNegGraphSize;
      }
   }
   while (incNodePtr != ((void *)0))
   {
      increment = incNodePtr->increment;
      if (parameters->evalMethod != 3)
      {
         totalPosGraphSize += increment->numPosVertices +
                              increment->numPosEdges;
         totalNegGraphSize += increment->numNegVertices +
                              increment->numNegEdges;
      }
      subListNode = increment->subList->head;
      found = 0;
      while (subListNode != ((void *)0))
      {
         incrementSub = subListNode->sub;
         if (GraphMatch(incrementSub->definition, sub->definition, labelList,
                        0.0, ((void *)0), ((void *)0)))
         {
            if (parameters->evalMethod == 3)
            {
               totalPosEgs += (ULONG) incrementSub->posIncrementValue;
               totalNegEgs += (ULONG) incrementSub->negIncrementValue;
            }
            else
            {
               compressedPosGraphSize += incrementSub->posIncrementValue;
               compressedNegGraphSize += incrementSub->negIncrementValue;
            }
            totalPosInstances += incrementSub->numInstances;
            totalNegInstances += incrementSub->numNegInstances;
            found = 1;
            break;
         }
         subListNode = subListNode->next;
      }
      if (!found && parameters->evalMethod != 3)
      {
         compressedPosGraphSize += increment->numPosVertices +
                                   increment->numPosEdges;
         compressedNegGraphSize += increment->numNegVertices +
                                   increment->numNegEdges;
      }
      incNodePtr = incNodePtr->next;
   }
   *numPosInstances = totalPosInstances;
   *numNegInstances = totalNegInstances;
   *graphPosSize = totalPosGraphSize;
   *graphNegSize = totalNegGraphSize;
   if (parameters->evalMethod == 3)
   {
      subValue = ((double) (totalPosEgs +
                            (parameters->numPosEgs - totalNegEgs))) /
          ((double) (parameters->numPosEgs + parameters->numNegEgs));
   }
   else
   {
      if (totalNegGraphSize == 0)
         subValue = totalPosGraphSize /
                    ((double) GraphSize(sub->definition) +
                     compressedPosGraphSize);
      else
         subValue = (totalPosGraphSize + totalNegGraphSize) /
                    ((double) GraphSize(sub->definition) +
                     compressedPosGraphSize + totalNegGraphSize -
                     compressedNegGraphSize);
   }
   return(subValue);
}

canonical_original_code:
double ComputeValue(struct _increment_list_node *incNodePtr, struct Substructure *sub, struct LabelList *labelList, unsigned long *numPosInstances, unsigned long *numNegInstances, unsigned long *graphPosSize, unsigned long *graphNegSize, struct Parameters *parameters)
{
   struct _increment *increment;
   struct _increment_list_node *incrementNode;
   struct _sub_list_node *subListNode;
   struct Substructure *incrementSub;
   unsigned char found = 0;
   unsigned long totalPosInstances = 0;
   unsigned long totalNegInstances = 0;
   unsigned long totalPosEgs = 0;
   unsigned long totalNegEgs = 0;
   unsigned long startIncrement;
   double totalPosGraphSize = 0;
   double totalNegGraphSize = 0;
   double compressedPosGraphSize = 0;
   double compressedNegGraphSize = 0;
   double subValue;
   if (incNodePtr == ((void *)0))
      printf("ComputeValue Error: incNodePtr is null\n");
   if (parameters->evalMethod != 3)
   {
      startIncrement = incNodePtr->increment->incrementNum;
      if (startIncrement !=
          parameters->incrementList->head->increment->incrementNum)
      {
         incrementNode = parameters->incrementList->head;
         while (incrementNode->increment->incrementNum < startIncrement)
         {
            increment = incrementNode->increment;
            totalPosGraphSize += increment->numPosVertices +
                                 increment->numPosEdges;
            totalNegGraphSize += increment->numNegVertices +
                                 increment->numNegEdges;
            incrementNode = incrementNode->next;
         }
         compressedPosGraphSize = totalPosGraphSize;
         compressedNegGraphSize = totalNegGraphSize;
      }
   }
   while (incNodePtr != ((void *)0))
   {
      increment = incNodePtr->increment;
      if (parameters->evalMethod != 3)
      {
         totalPosGraphSize += increment->numPosVertices +
                              increment->numPosEdges;
         totalNegGraphSize += increment->numNegVertices +
                              increment->numNegEdges;
      }
      subListNode = increment->subList->head;
      found = 0;
      while (subListNode != ((void *)0))
      {
         incrementSub = subListNode->sub;
         if (GraphMatch(incrementSub->definition, sub->definition, labelList,
                        0.0, ((void *)0), ((void *)0)))
         {
            if (parameters->evalMethod == 3)
            {
               totalPosEgs += (unsigned long) incrementSub->posIncrementValue;
               totalNegEgs += (unsigned long) incrementSub->negIncrementValue;
            }
            else
            {
               compressedPosGraphSize += incrementSub->posIncrementValue;
               compressedNegGraphSize += incrementSub->negIncrementValue;
            }
            totalPosInstances += incrementSub->numInstances;
            totalNegInstances += incrementSub->numNegInstances;
            found = 1;
            break;
         }
         subListNode = subListNode->next;
      }
      if (!found && parameters->evalMethod != 3)
      {
         compressedPosGraphSize += increment->numPosVertices +
                                   increment->numPosEdges;
         compressedNegGraphSize += increment->numNegVertices +
                                   increment->numNegEdges;
      }
      incNodePtr = incNodePtr->next;
   }
   *numPosInstances = totalPosInstances;
   *numNegInstances = totalNegInstances;
   *graphPosSize = totalPosGraphSize;
   *graphNegSize = totalNegGraphSize;
   if (parameters->evalMethod == 3)
   {
      subValue = ((double) (totalPosEgs +
                            (parameters->numPosEgs - totalNegEgs))) /
          ((double) (parameters->numPosEgs + parameters->numNegEgs));
   }
   else
   {
      if (totalNegGraphSize == 0)
         subValue = totalPosGraphSize /
                    ((double) GraphSize(sub->definition) +
                     compressedPosGraphSize);
      else
         subValue = (totalPosGraphSize + totalNegGraphSize) /
                    ((double) GraphSize(sub->definition) +
                     compressedPosGraphSize + totalNegGraphSize -
                     compressedNegGraphSize);
   }
   return(subValue);
}

variable_types: struct _increment_list_node { struct _increment { struct SubList { struct _sub_list_node { struct Substructure { struct Graph { unsigned long numVertices; unsigned long numEdges; struct Vertex { unsigned long label; unsigned long numEdges; unsigned long *edges; unsigned long map; unsigned char used; } *vertices; struct Edge { unsigned long vertex1; unsigned long vertex2; unsigned long label; unsigned char directed; unsigned char used; unsigned char spansIncrement; unsigned char validPath; } *edges; unsigned long vertexListSize; unsigned long edgeListSize; } *definition; unsigned long numInstances; unsigned long numExamples; struct InstanceList { struct _instance_list_node { struct _instance { unsigned long numVertices; unsigned long numEdges; unsigned long *vertices; unsigned long *edges; double minMatchCost; unsigned long newVertex; unsigned long newEdge; unsigned long refCount; struct VertexMap { unsigned long v1; unsigned long v2; } *mapping; unsigned long mappingIndex1; unsigned long mappingIndex2; unsigned char used; struct _instance *parentInstance; } *instance; struct _instance_list_node *next; } *head; } *instances; unsigned long numNegInstances; unsigned long numNegExamples; struct InstanceList *negInstances; double value; unsigned char recursive; unsigned long recursiveEdgeLabel; double posIncrementValue; double negIncrementValue; } *sub; struct _sub_list_node *next; } *head; } *subList; unsigned long incrementNum; unsigned long numPosVertices; unsigned long numPosEdges; unsigned long numNegVertices; unsigned long numNegEdges; unsigned long startPosVertexIndex; unsigned long startPosEdgeIndex; unsigned long startNegVertexIndex; unsigned long startNegEdgeIndex; double numPosEgs; double numNegEgs; } *increment; struct _increment_list_node *next; } *

variable_types:
sub
struct Substructure *

variable_types: struct LabelList { unsigned long size; unsigned long numLabels; struct Label { unsigned char labelType; union { char *stringLabel; double numericLabel; } labelValue; unsigned char used; } *labels; } *

variable_types:
numPosInstances
unsigned long *

variable_types:
numNegInstances
unsigned long *

variable_types:
graphPosSize
unsigned long *

variable_types:
graphNegSize
unsigned long *

variable_types: struct Parameters { char inputFileName[512]; char psInputFileName[512]; char outFileName[512]; struct Graph *posGraph; struct Graph *negGraph; double posGraphDL; double negGraphDL; unsigned long numPosEgs; unsigned long numNegEgs; unsigned long *posEgsVertexIndices; unsigned long *negEgsVertexIndices; struct LabelList *labelList; struct Graph **preSubs; unsigned long numPreSubs; unsigned char predefinedSubs; unsigned char outputToFile; unsigned char directed; unsigned long beamWidth; unsigned long limit; unsigned long maxVertices; unsigned long minVertices; unsigned long numBestSubs; unsigned char valueBased; unsigned char prune; unsigned long outputLevel; unsigned char allowInstanceOverlap; unsigned long evalMethod; double threshold; unsigned long iterations; double *log2Factorial; unsigned long log2FactorialSize; unsigned long numPartitions; unsigned char recursion; unsigned char variables; unsigned char relations; unsigned char incremental; unsigned char compress; struct IncrementList { struct _increment_list_node *head; } *incrementList; struct InstanceVertexList { struct AvlTreeList { struct _avltablenode { struct avl_table { struct avl_node { struct avl_node *avl_link[2]; void *avl_data; char avl_balance; } *avl_root; int (*avl_compare)(void *avl_a, void *avl_b, void *avl_param); void *avl_param; struct libavl_allocator { void *(*libavl_malloc)(struct libavl_allocator *, unsigned long libavl_size); void (*libavl_free)(struct libavl_allocator *, void *libavl_block); } *avl_alloc; unsigned long avl_count; unsigned long avl_generation; } *vertexTree; struct Substructure *sub; struct _avltablenode *next; } *head; } *avlTreeList; } *vertexList; unsigned long posGraphSize; unsigned long negGraphSize; } *

variable_types:
found
unsigned char

variable_types:
totalPosInstances
unsigned long

variable_types:
totalNegInstances
unsigned long

variable_types:
totalPosEgs
unsigned long

variable_types:
totalNegEgs
unsigned long

variable_types:
startIncrement
unsigned long

variable_types: totalPosGraphSize double

variable_types: totalNegGraphSize double

variable_types: compressedPosGraphSize double

variable_types: compressedNegGraphSize double

variable_types: subValue double

user_defined_types: struct _increment_list_node { struct _increment *increment; struct _increment_list_node *next; }

user_defined_types: struct Substructure { struct Graph *definition; unsigned long numInstances; unsigned long numExamples; struct InstanceList *instances; unsigned long numNegInstances; unsigned long numNegExamples; struct InstanceList *negInstances; double value; unsigned char recursive; unsigned long recursiveEdgeLabel; double posIncrementValue; double negIncrementValue; }

user_defined_types: struct InstanceList { struct _instance_list_node *head; }

user_defined_types: struct AvlTreeList { struct _avltablenode *head; }


PruneGraph

repo: gromgull/subdue

original_code:
void PruneGraph(Graph *g, char *labelStr, LabelList *labelList)
{
   ULONG v, e;
   char *endptr;
   Label label;
   ULONG labelIndex;
   BOOLEAN hangingVertex;
   ULONG vertexCounter;
   for (v = 0; v < g->numVertices; v++)
   {
      g->vertices[v].used = 1;
      g->vertices[v].map = v;
   }
   for (e = 0; e < g->numEdges; e++)
      g->edges[e].used = 1;
   label.labelType = 1;
   label.labelValue.numericLabel = strtod(labelStr, &endptr);
   if (*endptr != '\0')
   {
      label.labelType = 0;
      label.labelValue.stringLabel = labelStr;
   }
   labelIndex = GetLabelIndex(&label, labelList);
   for (v = 0; v < g->numVertices; v++)
   {
      if (g->vertices[v].label == labelIndex)
      {
         g->vertices[v].used = 0;
         for (e = 0; e < g->vertices[v].numEdges; e++)
            g->edges[g->vertices[v].edges[e]].used = 0;
      }
   }
   for (e = 0; e < g->numEdges; e++)
      if (g->edges[e].label == labelIndex)
         g->edges[e].used = 0;
   for (v = 0; v < g->numVertices; v++)
   {
      hangingVertex = 1;
      for (e = 0; e < g->vertices[v].numEdges; e++)
         if (g->edges[g->vertices[v].edges[e]].used == 1)
      hangingVertex = 0;
      if (hangingVertex == 1)
         g->vertices[v].used = 0;
   }
   vertexCounter = 0;
   for (v = 0; v < g->numVertices; v++)
      if (g->vertices[v].used == 1)
      {
         g->vertices[v].map = vertexCounter;
         vertexCounter++;
      }
}

canonical_original_code:
void PruneGraph(struct Graph *g, char *labelStr, struct LabelList *labelList)
{
   unsigned long v; unsigned long e;
   char *endptr;
   struct Label label;
   unsigned long labelIndex;
   unsigned char hangingVertex;
   unsigned long vertexCounter;
   for (v = 0; v < g->numVertices; v++)
   {
      g->vertices[v].used = 1;
      g->vertices[v].map = v;
   }
   for (e = 0; e < g->numEdges; e++)
      g->edges[e].used = 1;
   label.labelType = 1;
   label.labelValue.numericLabel = strtod(labelStr, &endptr);
   if (*endptr != '\0')
   {
      label.labelType = 0;
      label.labelValue.stringLabel = labelStr;
   }
   labelIndex = GetLabelIndex(&label, labelList);
   for (v = 0; v < g->numVertices; v++)
   {
      if (g->vertices[v].label == labelIndex)
      {
         g->vertices[v].used = 0;
         for (e = 0; e < g->vertices[v].numEdges; e++)
            g->edges[g->vertices[v].edges[e]].used = 0;
      }
   }
   for (e = 0; e < g->numEdges; e++)
      if (g->edges[e].label == labelIndex)
         g->edges[e].used = 0;
   for (v = 0; v < g->numVertices; v++)
   {
      hangingVertex = 1;
      for (e = 0; e < g->vertices[v].numEdges; e++)
         if (g->edges[g->vertices[v].edges[e]].used == 1)
      hangingVertex = 0;
      if (hangingVertex == 1)
         g->vertices[v].used = 0;
   }
   vertexCounter = 0;
   for (v = 0; v < g->numVertices; v++)
      if (g->vertices[v].used == 1)
      {
         g->vertices[v].map = vertexCounter;
         vertexCounter++;
      }
}

variable_types: struct Graph { unsigned long numVertices; unsigned long numEdges; struct Vertex { unsigned long label; unsigned long numEdges; unsigned long *edges; unsigned long map; unsigned char used; } *vertices; struct Edge { unsigned long vertex1; unsigned long vertex2; unsigned long label; unsigned char directed; unsigned char used; unsigned char spansIncrement; unsigned char validPath; } *edges; unsigned long vertexListSize; unsigned long edgeListSize; } *

variable_types:
labelStr
char *

variable_types: struct LabelList { unsigned long size; unsigned long numLabels; struct Label { unsigned char labelType; union { char *stringLabel; double numericLabel; } labelValue; unsigned char used; } *labels; } *

variable_types:
v
unsigned long

variable_types:
e
unsigned long

variable_types:
endptr
char *

variable_types:
labelIndex
unsigned long

variable_types:
hangingVertex
unsigned char

variable_types:
vertexCounter
unsigned long

return_type: void

user_defined_types: struct Graph { unsigned long numVertices; unsigned long numEdges; struct Vertex *vertices; struct Edge *edges; unsigned long vertexListSize; unsigned long edgeListSize; }

user_defined_types: struct LabelList { unsigned long size; unsigned long numLabels; struct Label *labels; }


PositiveExample

decompiled_code:
bool __fastcall PositiveExample(__int64 a1, __int64 a2, unsigned __int64 a3, __int64 a4)
{
unsigned __int64 v7; // rbx
__int64 v8; // rdi
__int64 *v9; // rax
__int64 v10; // r14

if ( !a3 )
return 0;
v7 = 0LL;
do
{
v8 = *(_QWORD *)(a2 + 8 * v7++);
v9 = (__int64 *)FindInstances(v8, a1, a4);
v10 = *v9;
FreeInstanceList(v9);
}
while ( a3 > v7 && !v10 );
return v10 != 0;
}

canonical_decompiled_code:
bool __fastcall func0(__int64 a1, __int64 a2, unsigned __int64 a3, __int64 a4)
{
unsigned __int64 v7; // rbx
__int64 v8; // rdi
__int64 *v9; // rax
__int64 v10; // r14

if ( !a3 )
return 0;
v7 = 0LL;
do
{
v8 = *(_QWORD *)(a2 + 8 * v7++);
v9 = (__int64 *)FindInstances(v8, a1, a4);
v10 = *v9;
FreeInstanceList(v9);
}
while ( a3 > v7 && !v10 );
return v10 != 0;
}

original_code:
BOOLEAN PositiveExample(Graph *graph, Graph **subGraphs,
                        ULONG numSubGraphs, Parameters *parameters)
{
   ULONG i = 0;
   BOOLEAN found = 0;
   InstanceList *instanceList = ((void *)0);
   while ((i < numSubGraphs) && (! found))
   {
      instanceList = FindInstances(subGraphs[i], graph, parameters);
      if (instanceList->head != ((void *)0))
         found = 1;
      FreeInstanceList(instanceList);
      i++;
   }
   return found;
}

canonical_original_code:
unsigned char PositiveExample(struct Graph *graph, struct Graph **subGraphs, unsigned long numSubGraphs, struct Parameters *parameters)
{
   unsigned long i = 0;
   unsigned char found = 0;
   struct InstanceList *instanceList = ((void *)0);
   while ((i < numSubGraphs) && (! found))
   {
      instanceList = FindInstances(subGraphs[i], graph, parameters);
      if (instanceList->head != ((void *)0))
         found = 1;
      FreeInstanceList(instanceList);
      i++;
   }
   return found;
}

variable_types:
subGraphs
struct Graph **

variable_types:
numSubGraphs
unsigned long

variable_types: struct Parameters { char inputFileName[512]; char psInputFileName[512]; char outFileName[512]; struct Graph *posGraph; struct Graph *negGraph; double posGraphDL; double negGraphDL; unsigned long numPosEgs; unsigned long numNegEgs; unsigned long *posEgsVertexIndices; unsigned long *negEgsVertexIndices; struct LabelList { unsigned long size; unsigned long numLabels; struct Label { unsigned char labelType; union { char *stringLabel; double numericLabel; } labelValue; unsigned char used; } *labels; } *labelList; struct Graph **preSubs; unsigned long numPreSubs; unsigned char predefinedSubs; unsigned char outputToFile; unsigned char directed; unsigned long beamWidth; unsigned long limit; unsigned long maxVertices; unsigned long minVertices; unsigned long numBestSubs; unsigned char valueBased; unsigned char prune; unsigned long outputLevel; unsigned char allowInstanceOverlap; unsigned long evalMethod; double threshold; unsigned long iterations; double *log2Factorial; unsigned long log2FactorialSize; unsigned long numPartitions; unsigned char recursion; unsigned char variables; unsigned char relations; unsigned char incremental; unsigned char compress; struct IncrementList { struct _increment_list_node { struct _increment { struct SubList { struct _sub_list_node { struct Substructure { struct Graph *definition; unsigned long numInstances; unsigned long numExamples; struct InstanceList { struct _instance_list_node { struct _instance { unsigned long numVertices; unsigned long numEdges; unsigned long *vertices; unsigned long *edges; double minMatchCost; unsigned long newVertex; unsigned long newEdge; unsigned long refCount; struct VertexMap { unsigned long v1; unsigned long v2; } *mapping; unsigned long mappingIndex1; unsigned long mappingIndex2; unsigned char used; struct _instance *parentInstance; } *instance; struct _instance_list_node *next; } *head; } *instances; unsigned long numNegInstances; unsigned long numNegExamples; struct InstanceList *negInstances; double value; unsigned char recursive; unsigned long recursiveEdgeLabel; double posIncrementValue; double negIncrementValue; } *sub; struct _sub_list_node *next; } *head; } *subList; unsigned long incrementNum; unsigned long numPosVertices; unsigned long numPosEdges; unsigned long numNegVertices; unsigned long numNegEdges; unsigned long startPosVertexIndex; unsigned long startPosEdgeIndex; unsigned long startNegVertexIndex; unsigned long startNegEdgeIndex; double numPosEgs; double numNegEgs; } *increment; struct _increment_list_node *next; } *head; } *incrementList; struct InstanceVertexList { struct AvlTreeList { struct _avltablenode { struct avl_table { struct avl_node { struct avl_node *avl_link[2]; void *avl_data; char avl_balance; } *avl_root; int (*avl_compare)(void *avl_a, void *avl_b, void *avl_param); void *avl_param; struct libavl_allocator { void *(*libavl_malloc)(struct libavl_allocator *, unsigned long libavl_size); void (*libavl_free)(struct libavl_allocator *, void *libavl_block); } *avl_alloc; unsigned long avl_count; unsigned long avl_generation; } *vertexTree; struct Substructure *sub; struct _avltablenode *next; } *head; } *avlTreeList; } *vertexList; unsigned long posGraphSize; unsigned long negGraphSize; } *

variable_types:
i
unsigned long

variable_types:
found
unsigned char

return_type: unsigned char

user_defined_types: struct Parameters { char inputFileName[512]; char psInputFileName[512]; char outFileName[512]; struct Graph *posGraph; struct Graph *negGraph; double posGraphDL; double negGraphDL; unsigned long numPosEgs; unsigned long numNegEgs; unsigned long *posEgsVertexIndices; unsigned long *negEgsVertexIndices; struct LabelList *labelList; struct Graph **preSubs; unsigned long numPreSubs; unsigned char predefinedSubs; unsigned char outputToFile; unsigned char directed; unsigned long beamWidth; unsigned long limit; unsigned long maxVertices; unsigned long minVertices; unsigned long numBestSubs; unsigned char valueBased; unsigned char prune; unsigned long outputLevel; unsigned char allowInstanceOverlap; unsigned long evalMethod; double threshold; unsigned long iterations; double *log2Factorial; unsigned long log2FactorialSize; unsigned long numPartitions; unsigned char recursion; unsigned char variables; unsigned char relations; unsigned char incremental; unsigned char compress; struct IncrementList *incrementList; struct InstanceVertexList *vertexList; unsigned long posGraphSize; unsigned long negGraphSize; }

user_defined_types: struct Vertex { unsigned long label; unsigned long numEdges; unsigned long *edges; unsigned long map; unsigned char used; }

user_defined_types: struct Edge { unsigned long vertex1; unsigned long vertex2; unsigned long label; unsigned char directed; unsigned char used; unsigned char spansIncrement; unsigned char validPath; }

user_defined_types: struct IncrementList { struct _increment_list_node *head; }

user_defined_types: struct InstanceVertexList { struct AvlTreeList *avlTreeList; }

user_defined_types: struct _instance_list_node { struct _instance *instance; struct _instance_list_node *next; }

user_defined_types: struct _instance { unsigned long numVertices; unsigned long numEdges; unsigned long *vertices; unsigned long *edges; double minMatchCost; unsigned long newVertex; unsigned long newEdge; unsigned long refCount; struct VertexMap *mapping; unsigned long mappingIndex1; unsigned long mappingIndex2; unsigned char used; struct _instance *parentInstance; }

user_defined_types: struct _increment { struct SubList *subList; unsigned long incrementNum; unsigned long numPosVertices; unsigned long numPosEdges; unsigned long numNegVertices; unsigned long numNegEdges; unsigned long startPosVertexIndex; unsigned long startPosEdgeIndex; unsigned long startNegVertexIndex; unsigned long startNegEdgeIndex; double numPosEgs; double numNegEgs; }

user_defined_types: struct _avltablenode { struct avl_table *vertexTree; struct Substructure *sub; struct _avltablenode *next; }

user_defined_types: struct SubList { struct _sub_list_node *head; }

user_defined_types: struct avl_table { struct avl_node *avl_root; int (*avl_compare)(void *avl_a, void *avl_b, void *avl_param); void *avl_param; struct libavl_allocator *avl_alloc; unsigned long avl_count; unsigned long avl_generation; }

user_defined_types: struct _sub_list_node { struct Substructure *sub; struct _sub_list_node *next; }


ExtendConstrainedInstance

original_code:
InstanceList *ExtendConstrainedInstance(Instance *instance,
                                        Substructure *bestSub,
                                        ReferenceGraph *refGraph,
                                        Graph *fullGraph,
                                        Parameters *parameters)
{
   InstanceList *newInstanceList;
   Instance *newInstance;
   ULONG v;
   ULONG e;
   ULONG v2;
   ReferenceVertex *vertex;
   ReferenceVertex *vertex2;
   ReferenceEdge *edge;
   BOOLEAN listEmpty = 1;
   newInstanceList = ((void *)0);
   MarkRefGraphInstanceEdges(instance, refGraph, 1);
   for (v = 0; v < instance->numVertices; v++)
   {
      vertex = &refGraph->vertices[instance->vertices[v]];
      if (vertex->vertexValid)
      {
         for (e = 0; e < vertex->numEdges; e++)
         {
            edge = &refGraph->edges[vertex->edges[e]];
            if (!edge->used && !edge->failed)
            {
               if (edge->vertex1 == instance->vertices[v])
                  v2 = edge->vertex2;
               else
                  v2 = edge->vertex1;
               vertex2 = &refGraph->vertices[v2];
               if (VertexInSub(bestSub->definition,
                               &fullGraph->vertices[vertex2->map]) &&
                   !CheckVertexForOverlap(vertex2->map, bestSub, parameters))
               {
                  newInstance =
                     CreateConstrainedExtendedInstance(instance,
                        instance->vertices[v], v2, vertex->edges[e], refGraph);
                  if (listEmpty)
                  {
                     newInstanceList = AllocateInstanceList();
                     listEmpty = 0;
                  }
                  InstanceListInsert(newInstance, newInstanceList, 1);
               }
            }
         }
      }
   }
   MarkRefGraphInstanceEdges(instance, refGraph, 0);
   return newInstanceList;
}

canonical_original_code:
struct InstanceList *ExtendConstrainedInstance(struct _instance *instance, struct Substructure *bestSub, struct ReferenceGraph *refGraph, struct Graph *fullGraph, struct Parameters *parameters)
{
   struct InstanceList *newInstanceList;
   struct _instance *newInstance;
   unsigned long v;
   unsigned long e;
   unsigned long v2;
   struct ReferenceVertex *vertex;
   struct ReferenceVertex *vertex2;
   struct ReferenceEdge *edge;
   unsigned char listEmpty = 1;
   newInstanceList = ((void *)0);
   MarkRefGraphInstanceEdges(instance, refGraph, 1);
   for (v = 0; v < instance->numVertices; v++)
   {
      vertex = &refGraph->vertices[instance->vertices[v]];
      if (vertex->vertexValid)
      {
         for (e = 0; e < vertex->numEdges; e++)
         {
            edge = &refGraph->edges[vertex->edges[e]];
            if (!edge->used && !edge->failed)
            {
               if (edge->vertex1 == instance->vertices[v])
                  v2 = edge->vertex2;
               else
                  v2 = edge->vertex1;
               vertex2 = &refGraph->vertices[v2];
               if (VertexInSub(bestSub->definition,
                               &fullGraph->vertices[vertex2->map]) &&
                   !CheckVertexForOverlap(vertex2->map, bestSub, parameters))
               {
                  newInstance =
                     CreateConstrainedExtendedInstance(instance,
                        instance->vertices[v], v2, vertex->edges[e], refGraph);
                  if (listEmpty)
                  {
                     newInstanceList = AllocateInstanceList();
                     listEmpty = 0;
                  }
                  InstanceListInsert(newInstance, newInstanceList, 1);
               }
            }
         }
      }
   }
   MarkRefGraphInstanceEdges(instance, refGraph, 0);
   return newInstanceList;
}

variable_types:
instance
struct _instance *

variable_types: struct Substructure { struct Graph { unsigned long numVertices; unsigned long numEdges; struct Vertex { unsigned long label; unsigned long numEdges; unsigned long *edges; unsigned long map; unsigned char used; } *vertices; struct Edge { unsigned long vertex1; unsigned long vertex2; unsigned long label; unsigned char directed; unsigned char used; unsigned char spansIncrement; unsigned char validPath; } *edges; unsigned long vertexListSize; unsigned long edgeListSize; } *definition; unsigned long numInstances; unsigned long numExamples; struct InstanceList *instances; unsigned long numNegInstances; unsigned long numNegExamples; struct InstanceList *negInstances; double value; unsigned char recursive; unsigned long recursiveEdgeLabel; double posIncrementValue; double negIncrementValue; } *

variable_types: struct ReferenceGraph { unsigned long numVertices; unsigned long numEdges; struct ReferenceVertex { unsigned long label; unsigned long numEdges; unsigned long *edges; unsigned long map; unsigned char used; unsigned char vertexValid; } *vertices; struct ReferenceEdge { unsigned long vertex1; unsigned long vertex2; unsigned char spansIncrement; unsigned long label; unsigned char directed; unsigned char used; unsigned char failed; unsigned long map; } *edges; unsigned long vertexListSize; unsigned long edgeListSize; } *

variable_types:
fullGraph
struct Graph *

variable_types: struct Parameters { char inputFileName[512]; char psInputFileName[512]; char outFileName[512]; struct Graph *posGraph; struct Graph *negGraph; double posGraphDL; double negGraphDL; unsigned long numPosEgs; unsigned long numNegEgs; unsigned long *posEgsVertexIndices; unsigned long *negEgsVertexIndices; struct LabelList { unsigned long size; unsigned long numLabels; struct Label { unsigned char labelType; union { char *stringLabel; double numericLabel; } labelValue; unsigned char used; } *labels; } *labelList; struct Graph **preSubs; unsigned long numPreSubs; unsigned char predefinedSubs; unsigned char outputToFile; unsigned char directed; unsigned long beamWidth; unsigned long limit; unsigned long maxVertices; unsigned long minVertices; unsigned long numBestSubs; unsigned char valueBased; unsigned char prune; unsigned long outputLevel; unsigned char allowInstanceOverlap; unsigned long evalMethod; double threshold; unsigned long iterations; double *log2Factorial; unsigned long log2FactorialSize; unsigned long numPartitions; unsigned char recursion; unsigned char variables; unsigned char relations; unsigned char incremental; unsigned char compress; struct IncrementList { struct _increment_list_node { struct _increment { struct SubList { struct _sub_list_node { struct Substructure *sub; struct _sub_list_node *next; } *head; } *subList; unsigned long incrementNum; unsigned long numPosVertices; unsigned long numPosEdges; unsigned long numNegVertices; unsigned long numNegEdges; unsigned long startPosVertexIndex; unsigned long startPosEdgeIndex; unsigned long startNegVertexIndex; unsigned long startNegEdgeIndex; double numPosEgs; double numNegEgs; } *increment; struct _increment_list_node *next; } *head; } *incrementList; struct InstanceVertexList { struct AvlTreeList { struct _avltablenode { struct avl_table { struct avl_node { struct avl_node *avl_link[2]; void *avl_data; char avl_balance; } *avl_root; int (*avl_compare)(void *avl_a, void *avl_b, void *avl_param); void *avl_param; struct libavl_allocator { void *(*libavl_malloc)(struct libavl_allocator *, unsigned long libavl_size); void (*libavl_free)(struct libavl_allocator *, void *libavl_block); } *avl_alloc; unsigned long avl_count; unsigned long avl_generation; } *vertexTree; struct Substructure *sub; struct _avltablenode *next; } *head; } *avlTreeList; } *vertexList; unsigned long posGraphSize; unsigned long negGraphSize; } *

variable_types: struct InstanceList { struct _instance_list_node { struct _instance { unsigned long numVertices; unsigned long numEdges; unsigned long *vertices; unsigned long *edges; double minMatchCost; unsigned long newVertex; unsigned long newEdge; unsigned long refCount; struct VertexMap { unsigned long v1; unsigned long v2; } *mapping; unsigned long mappingIndex1; unsigned long mappingIndex2; unsigned char used; struct _instance *parentInstance; } *instance; struct _instance_list_node *next; } *head; } *

variable_types:
listEmpty
unsigned char

user_defined_types: struct Substructure { struct Graph *definition; unsigned long numInstances; unsigned long numExamples; struct InstanceList *instances; unsigned long numNegInstances; unsigned long numNegExamples; struct InstanceList *negInstances; double value; unsigned char recursive; unsigned long recursiveEdgeLabel; double posIncrementValue; double negIncrementValue; }

user_defined_types: struct ReferenceGraph { unsigned long numVertices; unsigned long numEdges; struct ReferenceVertex *vertices; struct ReferenceEdge *edges; unsigned long vertexListSize; unsigned long edgeListSize; }

user_defined_types: struct _increment_list_node { struct _increment *increment; struct _increment_list_node *next; }


usage

repo: grouzen/fflisp

decompiled_code:
int usage()
{
puts("Usage: fflisp [--load filename] [--help].");
puts(" --load eval code from file.");
return puts(" --help print help message.");
}

canonical_decompiled_code:
int func0()
{
puts("Usage: fflisp [--load filename] [--help].");
puts(" --load eval code from file.");
return puts(" --help print help message.");
}

original_code:
static void usage(void)
{
    printf("Usage: fflisp [--load filename] [--help].\n");
    printf("       --load eval code from file.\n");
    printf("       --help print help message.\n");
    return;
}

canonical_original_code:
static void usage()
{
    printf("Usage: fflisp [--load filename] [--help].\n");
    printf("       --load eval code from file.\n");
    printf("       --help print help message.\n");
    return;
}


decompiled_code:
void __noreturn sigint_handler()
{
heap_clean();
puts("\nBye Bye!");
exit(0);
}

canonical_decompiled_code:
void __noreturn func1()
{
heap_clean();
puts("\nBye Bye!");
exit(0);
}

original_code:
void sigint_handler(int signum)
{
    heap_clean();
    printf("\nBye Bye!\n");
    exit(0);
    return;
}

variable_types: signum int


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
__int64 v4; // rax
__int64 v5; // rax
int v6; // eax

signal(2, (__sighandler_t)sigint_handler);
heap = heap_init();
v3 = object_create(2LL, "T");
v4 = heap_grab(v3);
nil = 0LL;
t = v4;
v5 = env_init();
environment = heap_grab(v5);
welcome();
while ( 1 )
{
v6 = getopt_long_only(argc, (char *const *)argv, &shortopts, &long_options_0, 0LL);
if ( v6 == -1 )
break;
if ( v6 != 108 )
{
usage();
heap_clean();
exit(1);
}
load(optarg);
}
repl(stdin);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
__int64 v4; // rax
__int64 v5; // rax
int v6; // eax

signal(2, (__sighandler_t)sigint_handler);
heap = heap_init();
v3 = object_create(2LL, "T");
v4 = heap_grab(v3);
nil = 0LL;
t = v4;
v5 = env_init();
environment = heap_grab(v5);
func2();
while ( 1 )
{
v6 = getopt_long_only(argc, (char *const *)argv, &shortopts, &long_options_0, 0LL);
if ( v6 == -1 )
break;
if ( v6 != 108 )
{
func0();
heap_clean();
exit(1);
}
load(optarg);
}
repl(stdin);
return 0;
}

original_code:
int main(int argc, char *argv[])
{
    int opt;
    static struct option long_options[] = {
        {"load", 1, ((void *)0), 'l'},
        {"help", 0, ((void *)0), 'h'},
        {0, 0, 0, 0}
    };
    signal(2, sigint_handler);
    heap = heap_init();
    t = heap_grab((object_create(SYMBOL, ("T"))));
    nil = ((void *)0);
    environment = heap_grab(env_init());
    welcome();
    while((opt = getopt_long_only(argc, argv, "", long_options, ((void *)0))) != -1) {
        switch(opt) {
        case 'l':
            load(optarg);
            break;
        case 'h':
        default:
            usage();
            heap_clean();
            exit(1);
        }
    }
    repl(stdin);
    return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: opt int

variable_types: struct option { char *name; int has_arg; int *flag; int val; } []

return_type: int


decompiled_code:
__int64 __fastcall env_var_lookup(__int64 a1, __int64 a2)
{
__int64 *v2; // rcx
__int64 v3; // rax
__int64 *v4; // rax
__int64 result; // rax
char v6[72]; // [rsp-48h] [rbp-48h] BYREF

if ( a2 )
{
while ( 1 )
{
v2 = *(__int64 **)(a2 + 8);
v3 = *v2;
if ( *v2 )
break;
LABEL_7:
a2 = v2[1];
if ( !a2 )
goto LABEL_8;
}
while ( 1 )
{
v4 = *(__int64 **)(v3 + 8);
if ( **(_QWORD **)(*v4 + 8) == a1 )
break;
v3 = v4[1];
if ( !v3 )
goto LABEL_7;
}
result = *v4;
}
else
{
LABEL_8:
snprintf(v6, 0x40uLL, "Unbound variable: %s.\n", *(const char **)(a1 + 8));
result = object_create(4LL, v6);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2)
{
__int64 *v2; // rcx
__int64 v3; // rax
__int64 *v4; // rax
__int64 result; // rax
char v6[72]; // [rsp-48h] [rbp-48h] BYREF

if ( a2 )
{
while ( 1 )
{
v2 = *(__int64 **)(a2 + 8);
v3 = *v2;
if ( *v2 )
break;
LABEL_7:
a2 = v2[1];
if ( !a2 )
goto LABEL_8;
}
while ( 1 )
{
v4 = *(__int64 **)(v3 + 8);
if ( **(_QWORD **)(*v4 + 8) == a1 )
break;
v3 = v4[1];
if ( !v3 )
goto LABEL_7;
}
result = *v4;
}
else
{
LABEL_8:
snprintf(v6, 0x40uLL, "Unbound variable: %s.\n", *(const char **)(a1 + 8));
result = object_create(4LL, v6);
}
return result;
}

original_code:
struct lispobj *env_var_lookup(struct lispobj *var, struct lispobj *env)
{
    struct lispobj *frame, *cell;
    char error[64];
    while(env != ((void *)0)) {
        frame = ((((((env)))->value.cons)->car));
        while(frame != ((void *)0)) {
            cell = ((((frame))->value.cons)->car);
            if(((((cell))->value.cons)->car) == var) {
                return cell;
            }
            frame = ((((frame))->value.cons)->cdr);
        }
        env = ((((((env)))->value.cons)->cdr));
    }
    snprintf(error, 64, "Unbound variable: %s.\n", ((var)->value.symbol));
    return (object_create(ERROR, (error)));
}

canonical_original_code:
struct lispobj *env_var_lookup(struct lispobj *var, struct lispobj *env)
{
    struct lispobj *frame; struct lispobj *cell;
    char error[64];
    while(env != ((void *)0)) {
        frame = ((((((env)))->value.cons)->car));
        while(frame != ((void *)0)) {
            cell = ((((frame))->value.cons)->car);
            if(((((cell))->value.cons)->car) == var) {
                return cell;
            }
            frame = ((((frame))->value.cons)->cdr);
        }
        env = ((((((env)))->value.cons)->cdr));
    }
    snprintf(error, 64, "Unbound variable: %s.\n", ((var)->value.symbol));
    return (object_create(ERROR, (error)));
}

variable_types:
var
struct lispobj *

variable_types:
env
struct lispobj *

variable_types: struct lispobj { int refs; int type; union { int number; char *symbol; char *string; char *error; struct cons { struct lispobj *car; struct lispobj *cdr; } *cons; } value; } *

variable_types:
error
char [64]

user_defined_types: struct lispobj { int refs; int type; union { int number; char *symbol; char *string; char *error; struct cons *cons; } value; }


decompiled_code:
__int64 __fastcall env_var_assign(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v4; // rax
__int64 v5; // r12
__int64 v6; // r12

if ( !a1 || *(_DWORD *)(a1 + 4) != 2 )
return object_create(4LL, "Variable name is not a symbol.\n");
v4 = env_var_lookup(a1, a3);
v5 = v4;
if ( *(_DWORD *)(v4 + 4) != 4 )
{
heap_release(*(_QWORD *)(*(_QWORD *)(v4 + 8) + 8LL));
v6 = *(_QWORD *)(v5 + 8);
*(_QWORD *)(v6 + 8) = heap_grab(a2);
v5 = a2;
}
return v5;
}

original_code:
struct lispobj *env_var_assign(struct lispobj *var, struct lispobj *val, struct lispobj *env)
{
    struct lispobj *cell;
    if(var == ((void *)0) || ((var)->type) != SYMBOL) {
        return (object_create(ERROR, ("Variable name is not a symbol.\n")));
    }
    cell = env_var_lookup(var, env);
    if(((cell)->type) == ERROR) {
        return cell;
    }
    heap_release(((((cell))->value.cons)->cdr));
    ((((cell))->value.cons)->cdr) = heap_grab(val);
    return val;
}

variable_types:
val
struct lispobj *

return_type: struct lispobj { int refs; int type; union { int number; char *symbol; char *string; char *error; struct cons { struct lispobj *car; struct lispobj *cdr; } *cons; } value; } *


decompiled_code:
__int64 __fastcall env_var_define(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v4; // rax
__int64 result; // rax
__int64 v6; // r13
__int64 v7; // rax
__int64 v8; // rax
char v9[104]; // [rsp+0h] [rbp-68h] BYREF

v4 = env_var_lookup(a1, a3);
if ( *(_DWORD *)(v4 + 4) == 4 )
{
heap_release(v4);
v6 = **(_QWORD **)(a3 + 8);
v7 = cons(a1, a2);
v8 = cons(v7, v6);
**(_QWORD **)(a3 + 8) = heap_grab(v8);
result = a2;
}
else
{
snprintf(v9, 0x40uLL, "Variable already exists: %s.\n", *(const char **)(a1 + 8));
result = object_create(4LL, v9);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v4; // rax
__int64 result; // rax
__int64 v6; // r13
__int64 v7; // rax
__int64 v8; // rax
char v9[104]; // [rsp+0h] [rbp-68h] BYREF

v4 = func1(a1, a3);
if ( *(_DWORD *)(v4 + 4) == 4 )
{
heap_release(v4);
v6 = **(_QWORD **)(a3 + 8);
v7 = cons(a1, a2);
v8 = cons(v7, v6);
**(_QWORD **)(a3 + 8) = heap_grab(v8);
result = a2;
}
else
{
snprintf(v9, 0x40uLL, "Variable already exists: %s.\n", *(const char **)(a1 + 8));
result = object_create(4LL, v9);
}
return result;
}

original_code:
struct lispobj *env_var_define(struct lispobj *var, struct lispobj *val, struct lispobj *env)
{
    struct lispobj *frame, *pair, *cell, *lookup;
    lookup = env_var_lookup(var, env);
    if(((lookup)->type) != ERROR) {
        char error[64];
        snprintf(error, 64, "Variable already exists: %s.\n", ((var)->value.symbol));
        return (object_create(ERROR, (error)));
    }
    heap_release(lookup);
    frame = ((((((env)))->value.cons)->car));
    cell = (cons((var), (val)));
    pair = (cons((cell), (frame)));
    frame = heap_grab(pair);
    ((((env))->value.cons)->car) = frame;
    return val;
}

canonical_original_code:
struct lispobj *env_var_define(struct lispobj *var, struct lispobj *val, struct lispobj *env)
{
    struct lispobj *frame; struct lispobj *pair; struct lispobj *cell; struct lispobj *lookup;
    lookup = env_var_lookup(var, env);
    if(((lookup)->type) != ERROR) {
        char error[64];
        snprintf(error, 64, "Variable already exists: %s.\n", ((var)->value.symbol));
        return (object_create(ERROR, (error)));
    }
    heap_release(lookup);
    frame = ((((((env)))->value.cons)->car));
    cell = (cons((var), (val)));
    pair = (cons((cell), (frame)));
    frame = heap_grab(pair);
    ((((env))->value.cons)->car) = frame;
    return val;
}

user_defined_types: struct cons { struct lispobj *car; struct lispobj *cdr; }


original_code:
struct lispobj *env_val_list(struct lispobj *vars, struct lispobj *env)
{
    if(vars != ((void *)0)) {
        struct lispobj *vals, *car, *cdr;
        car = eval(((((vars))->value.cons)->car), env);
        if(car != ((void *)0) && ((car)->type) == ERROR) {
            return car;
        }
        vals = (cons((((void *)0)), (((void *)0))));
        ((((vals))->value.cons)->car) = car;
        cdr = env_val_list(((((vars))->value.cons)->cdr), env);
        if(cdr != ((void *)0) && ((cdr)->type) == ERROR) {
            heap_release(vals);
            return cdr;
        }
        ((((vals))->value.cons)->cdr) = heap_grab(cdr);
        return vals;
    }
    return ((void *)0);
}

canonical_original_code:
struct lispobj *env_val_list(struct lispobj *vars, struct lispobj *env)
{
    if(vars != ((void *)0)) {
        struct lispobj *vals; struct lispobj *car; struct lispobj *cdr;
        car = eval(((((vars))->value.cons)->car), env);
        if(car != ((void *)0) && ((car)->type) == ERROR) {
            return car;
        }
        vals = (cons((((void *)0)), (((void *)0))));
        ((((vals))->value.cons)->car) = car;
        cdr = env_val_list(((((vars))->value.cons)->cdr), env);
        if(cdr != ((void *)0) && ((cdr)->type) == ERROR) {
            heap_release(vals);
            return cdr;
        }
        ((((vals))->value.cons)->cdr) = heap_grab(cdr);
        return vals;
    }
    return ((void *)0);
}

variable_types:
vars
struct lispobj *


decompiled_code:
__int64 __fastcall env_proc_make(__int64 a1)
{
__int64 v1; // rax

v1 = object_create(2LL, "PROC");
return list(4LL, v1, a1);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
__int64 v1; // rax

v1 = object_create(2LL, "PROC");
return list(4LL, v1, a1);
}

original_code:
struct lispobj *env_proc_make(struct lispobj *params, struct lispobj *body, struct lispobj *env)
{
    return list(4, (object_create(SYMBOL, ("PROC"))), params, body, env);
}

variable_types:
params
struct lispobj *

variable_types:
body
struct lispobj *


original_code:
struct lispobj *env_frame_make(struct lispobj *vars, struct lispobj *vals)
{
    struct lispobj *frame, *tmp;
    frame = (cons((((void *)0)), (((void *)0))));
    tmp = frame;
    while(vars != ((void *)0)) {
        struct lispobj *cell;
        cell = (cons((((((vars))->value.cons)->car)), (((((vals))->value.cons)->car))));
        ((((tmp))->value.cons)->car) = heap_grab(cell);
        vars = ((((vars))->value.cons)->cdr);
        vals = ((((vals))->value.cons)->cdr);
        if(vars != ((void *)0)) {
            ((((tmp))->value.cons)->cdr) = heap_grab((cons((((void *)0)), (((void *)0)))));
            tmp = ((((tmp))->value.cons)->cdr);
        }
    }
    ((((tmp))->value.cons)->cdr) = ((void *)0);
    return frame;
}

canonical_original_code:
struct lispobj *env_frame_make(struct lispobj *vars, struct lispobj *vals)
{
    struct lispobj *frame; struct lispobj *tmp;
    frame = (cons((((void *)0)), (((void *)0))));
    tmp = frame;
    while(vars != ((void *)0)) {
        struct lispobj *cell;
        cell = (cons((((((vars))->value.cons)->car)), (((((vals))->value.cons)->car))));
        ((((tmp))->value.cons)->car) = heap_grab(cell);
        vars = ((((vars))->value.cons)->cdr);
        vals = ((((vals))->value.cons)->cdr);
        if(vars != ((void *)0)) {
            ((((tmp))->value.cons)->cdr) = heap_grab((cons((((void *)0)), (((void *)0)))));
            tmp = ((((tmp))->value.cons)->cdr);
        }
    }
    ((((tmp))->value.cons)->cdr) = ((void *)0);
    return frame;
}

variable_types:
vals
struct lispobj *


decompiled_code:
__int64 env_init()
{
__int64 v0; // rax
__int64 v1; // rax
__int64 v2; // r12
__int64 v3; // rbp
__int64 v4; // rax
__int64 v5; // rax

v0 = env_subr_init_constprop_0(0);
v1 = heap_grab(v0);
v2 = cons(v1, 0LL);
v3 = object_create(2LL, "T");
v4 = object_create(2LL, "T");
env_var_define(v4, v3, v2);
v5 = object_create(2LL, "NIL");
env_var_define(v5, 0LL, v2);
return v2;
}

canonical_decompiled_code:
__int64 func7()
{
__int64 v0; // rax
__int64 v1; // rax
__int64 v2; // r12
__int64 v3; // rbp
__int64 v4; // rax
__int64 v5; // rax

v0 = func0(0);
v1 = heap_grab(v0);
v2 = cons(v1, 0LL);
v3 = object_create(2LL, "T");
v4 = object_create(2LL, "T");
func3(v4, v3, v2);
v5 = object_create(2LL, "NIL");
func3(v5, 0LL, v2);
return v2;
}

original_code:
struct lispobj *env_init(void)
{
    struct lispobj *frame, *cell, *tmp, *env = ((void *)0);
    static struct subrs s[] = {{"CAR", subr_car},
                               {"CDR", subr_cdr},
                               {"CONS", subr_cons},
                               {"PAIR", subr_pair},
                               {"STRING", subr_string},
                               {"NUMBER", subr_number},
                               {"SYMBOL", subr_symbol},
                               {"ATOM", subr_atom},
                               {"NULL", subr_null},
                               {"NOT", subr_not},
                               {"OR", subr_or},
                               {"AND", subr_and},
                               {"EQ", subr_eq},
                               {"EQL", subr_eql},
                               {"LIST", subr_list},
                               {"+", subr_plus},
                               {"-", subr_minus},
                               {"*", subr_multi},
                               {"=", subr_compar},
                               {">", subr_greatthan},
                               {"<", subr_lessthan},
                               {"/", subr_divide},
                               {"MOD", subr_mod},
                               {"HEAP", subr_heap},
                               {"HEAP-OBJECT", subr_heap_object},
                               {"LOAD", subr_load},
                               {"READ", subr_read},
                               {"EVAL", subr_eval},
                               {"ERROR", subr_error},
                               {"APPLY", subr_apply},
                               {"DISPLAY", subr_display},
                               {"NEWLINE", subr_newline},
                               {"RPLACA", subr_rplaca},
                               {"RPLACD", subr_rplacd},
                               {"EQUAL", subr_equal}};
    frame = heap_grab(env_subr_init(s, sizeof(s) / sizeof(struct subrs), 0));
    env = (cons((frame), (((void *)0))));
    env_var_define((object_create(SYMBOL, ("T"))), (object_create(SYMBOL, ("T"))), env);
    env_var_define((object_create(SYMBOL, ("NIL"))), ((void *)0), env);
    return env;
}

canonical_original_code:
struct lispobj *env_init()
{
    struct lispobj *frame; struct lispobj *cell; struct lispobj *tmp; struct lispobj *env = ((void *)0);
    static struct subrs s[] = {{"CAR", subr_car},
                               {"CDR", subr_cdr},
                               {"CONS", subr_cons},
                               {"PAIR", subr_pair},
                               {"STRING", subr_string},
                               {"NUMBER", subr_number},
                               {"SYMBOL", subr_symbol},
                               {"ATOM", subr_atom},
                               {"NULL", subr_null},
                               {"NOT", subr_not},
                               {"OR", subr_or},
                               {"AND", subr_and},
                               {"EQ", subr_eq},
                               {"EQL", subr_eql},
                               {"LIST", subr_list},
                               {"+", subr_plus},
                               {"-", subr_minus},
                               {"*", subr_multi},
                               {"=", subr_compar},
                               {">", subr_greatthan},
                               {"<", subr_lessthan},
                               {"/", subr_divide},
                               {"MOD", subr_mod},
                               {"HEAP", subr_heap},
                               {"HEAP-OBJECT", subr_heap_object},
                               {"LOAD", subr_load},
                               {"READ", subr_read},
                               {"EVAL", subr_eval},
                               {"ERROR", subr_error},
                               {"APPLY", subr_apply},
                               {"DISPLAY", subr_display},
                               {"NEWLINE", subr_newline},
                               {"RPLACA", subr_rplaca},
                               {"RPLACD", subr_rplacd},
                               {"EQUAL", subr_equal}};
    frame = heap_grab(env_subr_init(s, sizeof(s) / sizeof(struct subrs), 0));
    env = (cons((frame), (((void *)0))));
    env_var_define((object_create(SYMBOL, ("T"))), (object_create(SYMBOL, ("T"))), env);
    env_var_define((object_create(SYMBOL, ("NIL"))), ((void *)0), env);
    return env;
}

variable_types: struct subrs { char *var; struct lispobj { int refs; int type; union { int number; char *symbol; char *string; char *error; struct cons { struct lispobj *car; struct lispobj *cdr; } *cons; } value; } *(*val)(struct lispobj *); } []

user_defined_types: struct subrs { char *var; struct lispobj *(*val)(struct lispobj *); }


eval

original_code:
struct lispobj *eval(struct lispobj *obj, struct lispobj *env)
{
    struct lispobj *ret;
    if(obj == ((void *)0) || ((obj)->type) == NUMBER ||
       ((obj)->type) == ERROR || ((obj)->type) == STRING) {
        ret = heap_grab(obj);
    } else if(((obj)->type) == SYMBOL) {
        struct lispobj *val;
        val = env_var_lookup(obj, env);
        if(((val)->type) == ERROR) {
            ret = heap_grab(val);
        } else {
            ret = heap_grab(((((val))->value.cons)->cdr));
        }
    } else if((object_create(SYMBOL, ("QUOTE"))) == ((((obj))->value.cons)->car)) {
        if(length(obj) != 2) {
            ret = heap_grab(object_create(ERROR, "Recieve wrong number of arguments.\n"));
        } else {
            ret = heap_grab(((((((((((obj)))->value.cons)->cdr)))->value.cons)->car)));
        }
    } else if((object_create(SYMBOL, ("SETQ"))) == ((((obj))->value.cons)->car)) {
        if(length(obj) != 3) {
            ret = heap_grab(object_create(ERROR, "Recieve wrong number of arguments.\n"));
        } else {
            struct lispobj *val;
            val = eval(((((((((((((((obj)))->value.cons)->cdr)))->value.cons)->cdr)))->value.cons)->car)), env);
            if(val != ((void *)0) && ((val)->type) == ERROR) {
                ret = val;
            } else {
                ret = heap_grab(env_var_assign(((((((((((obj)))->value.cons)->cdr)))->value.cons)->car)), val, env));
                heap_release(val);
            }
        }
    } else if((object_create(SYMBOL, ("LABEL"))) == ((((obj))->value.cons)->car)) {
        if(length(obj) != 3) {
            ret = heap_grab(object_create(ERROR, "Recieve wrong number of arguments.\n"));
        } else {
            struct lispobj *val;
            val = eval(((((((((((((((obj)))->value.cons)->cdr)))->value.cons)->cdr)))->value.cons)->car)), env);
            if(val != ((void *)0) && ((val)->type) == ERROR) {
                ret = val;
            } else {
                ret = heap_grab(env_var_define(((((((((((obj)))->value.cons)->cdr)))->value.cons)->car)), val, env));
                heap_release(val);
            }
        }
    } else if((object_create(SYMBOL, ("IF"))) == ((((obj))->value.cons)->car)) {
        if(length(obj) != 4) {
            ret = heap_grab(object_create(ERROR, "Recieve wrong number of arguments.\n"));
        } else {
            struct lispobj *pred;
            pred = eval(((((((((((obj)))->value.cons)->cdr)))->value.cons)->car)), env);
            if(pred != ((void *)0) && ((pred)->type) == ERROR) {
                ret = pred;
            } else {
                if(pred) {
                    ret = eval(((((((((((((((obj)))->value.cons)->cdr)))->value.cons)->cdr)))->value.cons)->car)), env);
                } else {
                    ret = eval(((((((((((((((((((obj)))->value.cons)->cdr)))->value.cons)->cdr)))->value.cons)->cdr)))->value.cons)->car)), env);
                }
                heap_release(pred);
            }
        }
    } else if((object_create(SYMBOL, ("COND"))) == ((((obj))->value.cons)->car)) {
        if(length(obj) < 2) {
            ret = heap_grab(object_create(ERROR, "Recieve wrong number of arguments.\n"));
        } else {
            ret = eval_cond(((((obj))->value.cons)->cdr), env);
        }
    }
    else if((object_create(SYMBOL, ("LET"))) == ((((obj))->value.cons)->car)) {
        if(length(obj) < 3) {
            ret = heap_grab(object_create(ERROR, "Recieve wrong number of arguments.\n"));
        } else {
            ret = eval_let(((((obj))->value.cons)->cdr), env);
        }
    } else if((object_create(SYMBOL, ("PROGN"))) == ((((obj))->value.cons)->car)) {
        ret = eval_progn(((((obj))->value.cons)->cdr), env);
    } else if((object_create(SYMBOL, ("LAMBDA"))) == ((((obj))->value.cons)->car)) {
        if(length(obj) < 3) {
            ret = heap_grab(object_create(ERROR, "Recieve wrong number of arguments.\n"));
        } else {
            ret = heap_grab(env_proc_make(((((((((((obj)))->value.cons)->cdr)))->value.cons)->car)), ((((((((((obj)))->value.cons)->cdr)))->value.cons)->cdr)), env));
        }
    } else {
        struct lispobj *proc = eval(((((obj))->value.cons)->car), env);
        if(proc != ((void *)0) && ((proc)->type) == ERROR) {
            ret = proc;
        } else {
            struct lispobj *args = heap_grab(env_val_list(((((obj))->value.cons)->cdr), env));
            if(args != ((void *)0) && ((args)->type) == ERROR) {
                ret = args;
            } else {
                ret = apply(proc, args);
                heap_release(args);
            }
            heap_release(proc);
        }
    }
    return ret;
}

variable_types:
obj
struct lispobj *


original_code:
static struct lispobj* eval_cond(struct lispobj *exps, struct lispobj *env)
{
    struct lispobj *ret = nil;
    if(exps != ((void *)0)) {
        struct lispobj *cond;
        cond = ((((exps))->value.cons)->car);
        if(cond != ((void *)0) && ((cond)->type) == CONS) {
            struct lispobj *pred;
            pred = eval(((((cond))->value.cons)->car), env);
            if(pred != ((void *)0) && ((pred)->type) == ERROR) {
                ret = pred;
            } else {
                if(pred) {
                    if(length(cond) == 1) {
                        ret = t;
                    } else {
                        ret = eval(((((((((((cond)))->value.cons)->cdr)))->value.cons)->car)), env);
                    }
                } else {
                    ret = eval_cond(((((exps))->value.cons)->cdr), env);
                }
                heap_release(pred);
            }
        } else {
            ret = (object_create(ERROR, ("Bad cond clause.\n")));
        }
    }
    return ret;
}

canonical_original_code:
static struct lispobj *eval_cond(struct lispobj *exps, struct lispobj *env)
{
    struct lispobj *ret = nil;
    if(exps != ((void *)0)) {
        struct lispobj *cond;
        cond = ((((exps))->value.cons)->car);
        if(cond != ((void *)0) && ((cond)->type) == CONS) {
            struct lispobj *pred;
            pred = eval(((((cond))->value.cons)->car), env);
            if(pred != ((void *)0) && ((pred)->type) == ERROR) {
                ret = pred;
            } else {
                if(pred) {
                    if(length(cond) == 1) {
                        ret = t;
                    } else {
                        ret = eval(((((((((((cond)))->value.cons)->cdr)))->value.cons)->car)), env);
                    }
                } else {
                    ret = eval_cond(((((exps))->value.cons)->cdr), env);
                }
                heap_release(pred);
            }
        } else {
            ret = (object_create(ERROR, ("Bad cond clause.\n")));
        }
    }
    return ret;
}

variable_types:
exps
struct lispobj *


original_code:
static struct lispobj *eval_progn(struct lispobj *exps, struct lispobj *env)
{
    if(exps == ((void *)0)) {
        return exps;
    } else if(((((exps))->value.cons)->cdr) == ((void *)0)) {
        return eval(((((exps))->value.cons)->car), env);
    } else {
        eval(((((exps))->value.cons)->car), env);
        return eval_progn(((((exps))->value.cons)->cdr), env);
    }
}


decompiled_code:
void __fastcall object_delete(void *ptr)
{
_QWORD *v2; // rdi

heap_remove();
switch ( *((_DWORD *)ptr + 1) )
{
case 0:
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
if ( *v2 )
{
heap_release(*v2);
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
}
if ( v2[1] )
{
heap_release(v2[1]);
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
}
goto LABEL_3;
case 1:
goto LABEL_4;
case 2:
case 3:
case 4:
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
LABEL_3:
free(v2);
LABEL_4:
free(ptr);
break;
default:
return;
}
}

canonical_decompiled_code:
void __fastcall func0(void *ptr)
{
_QWORD *v2; // rdi

heap_remove();
switch ( *((_DWORD *)ptr + 1) )
{
case 0:
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
if ( *v2 )
{
heap_release(*v2);
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
}
if ( v2[1] )
{
heap_release(v2[1]);
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
}
goto LABEL_3;
case 1:
goto LABEL_4;
case 2:
case 3:
case 4:
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
LABEL_3:
free(v2);
LABEL_4:
free(ptr);
break;
default:
return;
}
}

original_code:
void object_delete(struct lispobj *obj)
{
    heap_remove(obj);
    switch(((obj)->type)) {
    case SYMBOL:
        free(((obj)->value.symbol));
        free(obj);
        break;
    case NUMBER:
        free(obj);
        break;
    case CONS:
        if(((((obj))->value.cons)->car) != ((void *)0))
            heap_release(((((obj))->value.cons)->car));
        if(((((obj))->value.cons)->cdr) != ((void *)0))
            heap_release(((((obj))->value.cons)->cdr));
        free(((obj)->value.cons));
        free(obj);
        break;
    case STRING:
        free(((obj)->value.string));
        free(obj);
        break;
    case ERROR:
        free(((obj)->value.error));
        free(obj);
        break;
    default:
        break;
    }
    return;
}


original_code:
static void heap_grow(void)
{
    struct heap *new_heap = malloc(sizeof(struct heap));
    new_heap->data = malloc(sizeof(struct lispobj *) * (heap->size * 2));
    memset(new_heap->data, 0, sizeof(struct lispobj *) * (heap->size * 2));
    new_heap->size = heap->size * 2;
    new_heap->index = 0;
    while(new_heap->index < heap->index) {
        new_heap->data[new_heap->index] = heap->data[new_heap->index];
        new_heap->index++;
    }
    free(heap->data);
    free(heap);
    heap = new_heap;
    return;
}

canonical_original_code:
static void heap_grow()
{
    struct heap *new_heap = malloc(sizeof(struct heap));
    new_heap->data = malloc(sizeof(struct lispobj *) * (heap->size * 2));
    memset(new_heap->data, 0, sizeof(struct lispobj *) * (heap->size * 2));
    new_heap->size = heap->size * 2;
    new_heap->index = 0;
    while(new_heap->index < heap->index) {
        new_heap->data[new_heap->index] = heap->data[new_heap->index];
        new_heap->index++;
    }
    free(heap->data);
    free(heap);
    heap = new_heap;
    return;
}

variable_types: struct heap { struct lispobj { int refs; int type; union { int number; char *symbol; char *string; char *error; struct cons { struct lispobj *car; struct lispobj *cdr; } *cons; } value; } **data; int index; int size; } *

user_defined_types: struct heap { struct lispobj **data; int index; int size; }


decompiled_code:
void __fastcall symbol_table_delete(__int64 a1)
{
__int64 v2; // rdi
__int64 v3; // rsi
_QWORD *v4; // rax
__int64 v5; // rdx

v2 = symbol_table;
if ( symbol_table )
{
v3 = 0LL;
while ( 1 )
{
v4 = *(_QWORD **)(v2 + 8);
v5 = v4[1];
if ( *v4 == a1 )
break;
v3 = v2;
if ( !v5 )
return;
v2 = v4[1];
}
if ( v3 )
*(_QWORD *)(*(_QWORD *)(v3 + 8) + 8LL) = v5;
else
symbol_table = v4[1];
*v4 = 0LL;
v4[1] = 0LL;
object_delete();
}
}

canonical_decompiled_code:
void __fastcall func1(__int64 a1)
{
__int64 v2; // rdi
__int64 v3; // rsi
_QWORD *v4; // rax
__int64 v5; // rdx

v2 = symbol_table;
if ( symbol_table )
{
v3 = 0LL;
while ( 1 )
{
v4 = *(_QWORD **)(v2 + 8);
v5 = v4[1];
if ( *v4 == a1 )
break;
v3 = v2;
if ( !v5 )
return;
v2 = v4[1];
}
if ( v3 )
*(_QWORD *)(*(_QWORD *)(v3 + 8) + 8LL) = v5;
else
symbol_table = v4[1];
*v4 = 0LL;
v4[1] = 0LL;
object_delete();
}
}

original_code:
static void symbol_table_delete(struct lispobj *symbol)
{
    struct lispobj *tmp_symt, *prev_cons;
    tmp_symt = symbol_table;
    prev_cons = ((void *)0);
    while(tmp_symt != ((void *)0)) {
        struct lispobj *curs = ((((tmp_symt))->value.cons)->car);
        if(curs == symbol) {
            if(prev_cons != ((void *)0)) {
                ((((prev_cons))->value.cons)->cdr) = ((((tmp_symt))->value.cons)->cdr);
            } else {
                symbol_table = ((((tmp_symt))->value.cons)->cdr);
            }
            ((((tmp_symt))->value.cons)->car) = ((void *)0);
            ((((tmp_symt))->value.cons)->cdr) = ((void *)0);
            object_delete(tmp_symt);
            return;
        }
        prev_cons = tmp_symt;
        tmp_symt = ((((tmp_symt))->value.cons)->cdr);
    }
    return;
}

canonical_original_code:
static void symbol_table_delete(struct lispobj *symbol)
{
    struct lispobj *tmp_symt; struct lispobj *prev_cons;
    tmp_symt = symbol_table;
    prev_cons = ((void *)0);
    while(tmp_symt != ((void *)0)) {
        struct lispobj *curs = ((((tmp_symt))->value.cons)->car);
        if(curs == symbol) {
            if(prev_cons != ((void *)0)) {
                ((((prev_cons))->value.cons)->cdr) = ((((tmp_symt))->value.cons)->cdr);
            } else {
                symbol_table = ((((tmp_symt))->value.cons)->cdr);
            }
            ((((tmp_symt))->value.cons)->car) = ((void *)0);
            ((((tmp_symt))->value.cons)->cdr) = ((void *)0);
            object_delete(tmp_symt);
            return;
        }
        prev_cons = tmp_symt;
        tmp_symt = ((((tmp_symt))->value.cons)->cdr);
    }
    return;
}


decompiled_code:
int __fastcall heap_debug_object(unsigned int *a1)
{
unsigned int v1; // eax
int result; // eax

if ( !a1 )
return printf(" null pointer");
printf(" [%p ", a1);
v1 = a1[1];
if ( v1 == 2 )
{
printf("(symbol %s) ", *((const char **)a1 + 1));
result = printf("%d] ", *a1);
}
else if ( v1 == 1 )
{
printf("(number %d) ", a1[2]);
result = printf("%d] ", *a1);
}
else
{
if ( v1 == 3 )
printf("(string %s) ", *((const char **)a1 + 1));
else
printf("(cons) ");
result = printf("%d] ", *a1);
}
return result;
}

canonical_decompiled_code:
int __fastcall func2(unsigned int *a1)
{
unsigned int v1; // eax
int result; // eax

if ( !a1 )
return printf(" null pointer");
printf(" [%p ", a1);
v1 = a1[1];
if ( v1 == 2 )
{
printf("(symbol %s) ", *((const char **)a1 + 1));
result = printf("%d] ", *a1);
}
else if ( v1 == 1 )
{
printf("(number %d) ", a1[2]);
result = printf("%d] ", *a1);
}
else
{
if ( v1 == 3 )
printf("(string %s) ", *((const char **)a1 + 1));
else
printf("(cons) ");
result = printf("%d] ", *a1);
}
return result;
}

original_code:
void heap_debug_object(struct lispobj *obj)
{
    if(obj == ((void *)0)) {
        printf(" null pointer");
    } else {
        printf(" [%p ", obj);
        if(((obj)->type) == SYMBOL) {
            printf("(symbol %s) ", ((obj)->value.symbol));
        } else if(((obj)->type) == NUMBER) {
            printf("(number %d) ", ((obj)->value.number));
        } else if(((obj)->type) == STRING) {
            printf("(string %s) ", ((obj)->value.string));
        } else {
            printf("(cons) ");
        }
        printf("%d] ", ((obj)->refs));
    }
}


decompiled_code:
int heap_debug()
{
_QWORD *v0; // rax
__int64 v1; // rbx
__int64 v2; // rsi

v0 = heap;
if ( *((int *)heap + 2) <= 0 )
return printf("\nTotal: %d objects (%z bytes).\n", 0LL, 0LL);
v1 = 0LL;
do
{
heap_debug_object(*(unsigned int **)(*v0 + 8 * v1));
v0 = heap;
v2 = (unsigned int)++v1;
}
while ( *((_DWORD *)heap + 2) > (int)v1 );
return printf("\nTotal: %d objects (%z bytes).\n", v2, 16LL * (int)v2);
}

canonical_decompiled_code:
int func3()
{
_QWORD *v0; // rax
__int64 v1; // rbx
__int64 v2; // rsi

v0 = heap;
if ( *((int *)heap + 2) <= 0 )
return printf("\nTotal: %d objects (%z bytes).\n", 0LL, 0LL);
v1 = 0LL;
do
{
func2(*(unsigned int **)(*v0 + 8 * v1));
v0 = heap;
v2 = (unsigned int)++v1;
}
while ( *((_DWORD *)heap + 2) > (int)v1 );
return printf("\nTotal: %d objects (%z bytes).\n", v2, 16LL * (int)v2);
}

original_code:
void heap_debug(void)
{
    int i = 0;
    while(i < heap->index) {
        heap_debug_object(heap->data[i]);
        i++;
    }
    printf("\nTotal: %d objects (%z bytes).\n",
           i,
           i * sizeof(struct lispobj));
    return;
}

canonical_original_code:
void heap_debug()
{
    int i = 0;
    while(i < heap->index) {
        heap_debug_object(heap->data[i]);
        i++;
    }
    printf("\nTotal: %d objects (%z bytes).\n",
           i,
           i * sizeof(struct lispobj));
    return;
}

variable_types: i int


decompiled_code:
_QWORD *heap_init()
{
_QWORD *v0; // r12

v0 = malloc(0x10uLL);
*v0 = calloc(0x4000uLL, 1uLL);
v0[1] = 0x80000000000LL;
return v0;
}

original_code:
struct heap *heap_init(void)
{
    struct heap *h;
    h = malloc(sizeof(struct heap));
    h->data = malloc(sizeof(struct lispobj *) * (2 << 10));
    memset(h->data, 0, sizeof(struct lispobj *) * (2 << 10));
    h->index = 0;
    h->size = (2 << 10);
    return h;
}

canonical_original_code:
struct heap *heap_init()
{
    struct heap *h;
    h = malloc(sizeof(struct heap));
    h->data = malloc(sizeof(struct lispobj *) * (2 << 10));
    memset(h->data, 0, sizeof(struct lispobj *) * (2 << 10));
    h->index = 0;
    h->size = (2 << 10);
    return h;
}

return_type: struct heap { struct lispobj { int refs; int type; union { int number; char *symbol; char *string; char *error; struct cons { struct lispobj *car; struct lispobj *cdr; } *cons; } value; } **data; int index; int size; } *


decompiled_code:
__int64 __fastcall heap_add(__int64 a1)
{
_DWORD *v1; // rdx
int v2; // eax

v1 = heap;
v2 = *((_DWORD *)heap + 2);
if ( v2 >= *((_DWORD *)heap + 3) )
{
heap_grow();
v1 = heap;
v2 = *((_DWORD *)heap + 2);
}
*(_QWORD *)(*(_QWORD *)v1 + 8LL * v2) = a1;
v1[2] = v2 + 1;
return a1;
}

original_code:
struct lispobj *heap_add(struct lispobj *obj)
{
    if(heap->index >= heap->size) {
        heap_grow();
    }
    heap->data[heap->index] = obj;
    heap->index++;
    return obj;
}


decompiled_code:
void __fastcall heap_remove(__int64 a1)
{
_DWORD *v1; // rcx
int v2; // edx
_QWORD *v3; // rax
__int64 v4; // rdx
_QWORD *v5; // rsi
int v6; // edx

v1 = heap;
v2 = *((_DWORD *)heap + 3);
if ( v2 > 0 )
{
v3 = *(_QWORD **)heap;
v4 = *(_QWORD *)heap + 8LL * (unsigned int)(v2 - 1) + 8;
while ( *v3 != a1 )
{
if ( ++v3 == (_QWORD *)v4 )
return;
}
v5 = (_QWORD *)(*(_QWORD *)heap + 8LL * *((int *)heap + 2) - 8);
v6 = *((_DWORD *)heap + 2) - 1;
*v3 = *v5;
*v5 = 0LL;
v1[2] = v6;
}
}

canonical_decompiled_code:
void __fastcall func6(__int64 a1)
{
_DWORD *v1; // rcx
int v2; // edx
_QWORD *v3; // rax
__int64 v4; // rdx
_QWORD *v5; // rsi
int v6; // edx

v1 = heap;
v2 = *((_DWORD *)heap + 3);
if ( v2 > 0 )
{
v3 = *(_QWORD **)heap;
v4 = *(_QWORD *)heap + 8LL * (unsigned int)(v2 - 1) + 8;
while ( *v3 != a1 )
{
if ( ++v3 == (_QWORD *)v4 )
return;
}
v5 = (_QWORD *)(*(_QWORD *)heap + 8LL * *((int *)heap + 2) - 8);
v6 = *((_DWORD *)heap + 2) - 1;
*v3 = *v5;
*v5 = 0LL;
v1[2] = v6;
}
}

original_code:
void heap_remove(struct lispobj *obj)
{
    int i = 0;
    while(i < heap->size) {
        if(obj == heap->data[i]) {
            heap->data[i] = heap->data[heap->index - 1];
            heap->data[heap->index - 1] = ((void *)0);
            heap->index--;
            return;
        }
        i++;
    }
    return;
}


decompiled_code:
_QWORD **heap_clean()
{
_QWORD **result; // rax

for ( result = (_QWORD **)heap; *((int *)heap + 2) > 0; result = (_QWORD **)heap )
object_delete(**result);
return result;
}

canonical_decompiled_code:
_QWORD **func7()
{
_QWORD **result; // rax

for ( result = (_QWORD **)heap; *((int *)heap + 2) > 0; result = (_QWORD **)heap )
object_delete(**result);
return result;
}

original_code:
void heap_clean(void)
{
    while(heap->index > 0) {
        object_delete(heap->data[0]);
    }
    return;
}

canonical_original_code:
void heap_clean()
{
    while(heap->index > 0) {
        object_delete(heap->data[0]);
    }
    return;
}


decompiled_code:
__int64 __fastcall heap_release(_DWORD *a1)
{
__int64 result; // rax

if ( a1 )
{
result = (unsigned int)(*a1 - 1);
*a1 = result;
if ( (int)result <= 0 )
{
if ( a1[1] == 2 )
symbol_table_delete((__int64)a1);
result = object_delete(a1);
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(_DWORD *a1)
{
__int64 result; // rax

if ( a1 )
{
result = (unsigned int)(*a1 - 1);
*a1 = result;
if ( (int)result <= 0 )
{
if ( a1[1] == 2 )
func1((__int64)a1);
result = object_delete(a1);
}
}
return result;
}

original_code:
void heap_release(struct lispobj *obj)
{
    if(obj != ((void *)0)) {
        ((obj)->refs)--;
        if(((obj)->refs) <= 0) {
            if(((obj)->type) == SYMBOL)
                symbol_table_delete(obj);
            object_delete(obj);
        }
    }
    return;
}


decompiled_code:
__int64 __fastcall symbol_table_intern(__int64 a1)
{
_DWORD *v1; // rax

v1 = (_DWORD *)cons(a1, symbol_table);
symbol_table = heap_grab(v1);
return a1;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
_DWORD *v1; // rax

v1 = (_DWORD *)cons(a1, symbol_table);
symbol_table = heap_grab(v1);
return a1;
}

original_code:
struct lispobj *symbol_table_intern(struct lispobj *symbol)
{
    struct lispobj *pair;
    pair = (cons((symbol), (symbol_table)));
    symbol_table = heap_grab(pair);
    return symbol;
}

variable_types:
symbol
struct lispobj *


decompiled_code:
__int64 __fastcall symbol_table_lookup(char *s2)
{
__int64 i; // r12
_QWORD *v2; // rbx

for ( i = symbol_table; i; i = v2[1] )
{
v2 = *(_QWORD **)(i + 8);
i = *v2;
if ( !strcmp(*(const char **)(*v2 + 8LL), s2) )
break;
}
return i;
}

canonical_decompiled_code:
__int64 __fastcall func10(char *s2)
{
__int64 i; // r12
_QWORD *v2; // rbx

for ( i = symbol_table; i; i = v2[1] )
{
v2 = *(_QWORD **)(i + 8);
i = *v2;
if ( !strcmp(*(const char **)(*v2 + 8LL), s2) )
break;
}
return i;
}

original_code:
struct lispobj *symbol_table_lookup(char *symbol)
{
    struct lispobj *tmp = symbol_table;
    while(tmp != ((void *)0)) {
        if(!strcmp(((((((tmp))->value.cons)->car))->value.symbol), symbol)) {
            return ((((tmp))->value.cons)->car);
        }
        tmp = ((((tmp))->value.cons)->cdr);
    }
    return ((void *)0);
}

variable_types:
symbol
char *


print

decompiled_code:
int __fastcall print(__int64 a1)
{
int v2; // eax
__int64 *v3; // rsi
const char *v4; // rdi
__int64 v5; // rbx
__int64 v6; // rbx
int result; // eax
__int64 v8; // rbx

if ( !a1 )
return printf("NIL");
v2 = *(_DWORD *)(a1 + 4);
switch ( v2 )
{
case 4:
v3 = *(__int64 **)(a1 + 8);
v4 = "Error: %s";
return printf(v4, v3);
case 2:
return printf("%s", *(const char **)(a1 + 8));
case 1:
return printf("%d", *(unsigned int *)(a1 + 8));
}
v3 = *(__int64 **)(a1 + 8);
v4 = "\"%s\"";
if ( v2 == 3 )
return printf(v4, v3);
v5 = *v3;
if ( v5 == object_create(2LL, "PROC") )
{
printf("<procedure ");
v8 = **(_QWORD **)(*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) + 8LL);
if ( v8 == object_create(2LL, "NIL") )
printf("()");
else
print_list(**(_QWORD **)(*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) + 8LL));
result = printf(
" %p>",
**(_QWORD **)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) + 8LL)
+ 8LL)
+ 8LL)
+ 8LL)
+ 8LL));
}
else
{
v6 = **(_QWORD **)(a1 + 8);
if ( v6 == object_create(2LL, "SUBR") )
result = printf("<primitive-procedure %p>", **(_QWORD **)(*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) + 8LL));
else
result = print_list(a1);
}
return result;
}

canonical_decompiled_code:
int __fastcall func0(__int64 a1)
{
int v2; // eax
__int64 *v3; // rsi
const char *v4; // rdi
__int64 v5; // rbx
__int64 v6; // rbx
int result; // eax
__int64 v8; // rbx

if ( !a1 )
return printf("NIL");
v2 = *(_DWORD *)(a1 + 4);
switch ( v2 )
{
case 4:
v3 = *(__int64 **)(a1 + 8);
v4 = "Error: %s";
return printf(v4, v3);
case 2:
return printf("%s", *(const char **)(a1 + 8));
case 1:
return printf("%d", *(unsigned int *)(a1 + 8));
}
v3 = *(__int64 **)(a1 + 8);
v4 = "\"%s\"";
if ( v2 == 3 )
return printf(v4, v3);
v5 = *v3;
if ( v5 == object_create(2LL, "PROC") )
{
printf("<procedure ");
v8 = **(_QWORD **)(*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) + 8LL);
if ( v8 == object_create(2LL, "NIL") )
printf("()");
else
func1(**(_QWORD **)(*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) + 8LL));
result = printf(
" %p>",
**(_QWORD **)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) + 8LL)
+ 8LL)
+ 8LL)
+ 8LL)
+ 8LL));
}
else
{
v6 = **(_QWORD **)(a1 + 8);
if ( v6 == object_create(2LL, "SUBR") )
result = printf("<primitive-procedure %p>", **(_QWORD **)(*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) + 8LL));
else
result = func1(a1);
}
return result;
}

original_code:
void print(struct lispobj *obj)
{
    if(obj == ((void *)0)) {
        printf("NIL");
    } else if(((obj)->type) == ERROR) {
        printf("Error: %s", ((obj)->value.error));
    } else if(((obj)->type) == SYMBOL) {
        printf("%s", ((obj)->value.symbol));
    } else if(((obj)->type) == NUMBER) {
        printf("%d", ((obj)->value.number));
    } else if(((obj)->type) == STRING) {
        printf("\"%s\"", ((obj)->value.string));
    } else {
        if(((((obj))->value.cons)->car) == (object_create(SYMBOL, ("PROC")))) {
            printf("<procedure ");
            if(((((((((((obj)))->value.cons)->cdr)))->value.cons)->car)) != (object_create(SYMBOL, ("NIL")))) {
                print_list(((((((((((obj)))->value.cons)->cdr)))->value.cons)->car)));
            } else {
                printf("()");
            }
            printf(" %p>", ((((((((((((((((((obj)))->value.cons)->cdr)))->value.cons)->cdr)))->value.cons)->cdr)))->value.cons)->car)));
        } else if(((((obj))->value.cons)->car) == (object_create(SYMBOL, ("SUBR")))) {
            printf("<primitive-procedure %p>", ((((((((((obj)))->value.cons)->cdr)))->value.cons)->car)));
        } else {
            print_list(obj);
        }
    }
    return;
}


decompiled_code:
int __fastcall print_list(__int64 a1)
{
__int64 v2; // rdi
__int64 v3; // rax
int result; // eax

if ( print_bracket )
putchar(40);
print_bracket = 0;
v2 = **(_QWORD **)(a1 + 8);
if ( v2 && !*(_DWORD *)(v2 + 4) )
{
putchar(40);
v2 = **(_QWORD **)(a1 + 8);
}
print(v2);
v3 = *(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL);
if ( v3
&& (!*(_DWORD *)(v3 + 4) ? putchar(32) : printf(" . "),
print_bracket = 0,
print(*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL)),
(result = print_bracket) != 0) )
{
print_bracket = 1;
}
else
{
result = putchar(41);
print_bracket = 1;
}
return result;
}

canonical_decompiled_code:
int __fastcall func1(__int64 a1)
{
__int64 v2; // rdi
__int64 v3; // rax
int result; // eax

if ( print_bracket )
putchar(40);
print_bracket = 0;
v2 = **(_QWORD **)(a1 + 8);
if ( v2 && !*(_DWORD *)(v2 + 4) )
{
putchar(40);
v2 = **(_QWORD **)(a1 + 8);
}
func0(v2);
v3 = *(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL);
if ( v3
&& (!*(_DWORD *)(v3 + 4) ? putchar(32) : printf(" . "),
print_bracket = 0,
func0(*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL)),
(result = print_bracket) != 0) )
{
print_bracket = 1;
}
else
{
result = putchar(41);
print_bracket = 1;
}
return result;
}

original_code:
static void print_list(struct lispobj *obj)
{
    if(print_bracket) {
        printf("(");
    }
    print_bracket = 0;
    if(((((obj))->value.cons)->car) != ((void *)0) && ((((((obj))->value.cons)->car))->type) == CONS) {
        printf("(");
    }
    print(((((obj))->value.cons)->car));
    if(((((obj))->value.cons)->cdr) == ((void *)0)) {
        printf(")");
        print_bracket = 1;
        return;
    }
    if(((((((obj))->value.cons)->cdr))->type) == CONS) {
        printf(" ");
    } else {
        printf(" . ");
    }
    print_bracket = 0;
    print(((((obj))->value.cons)->cdr));
    if(!print_bracket) {
        printf(")");
    }
    print_bracket = 1;
    return;
}


decompiled_code:
__int64 __fastcall token_to_upper_case(_BYTE *a1)
{
__int64 result; // rax

while ( 1 )
{
result = (unsigned __int8)*a1;
if ( !(_BYTE)result )
break;
if ( (unsigned __int8)(result - 97) <= 0x19u )
*a1 = result - 32;
++a1;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(_BYTE *a1)
{
__int64 result; // rax

while ( 1 )
{
result = (unsigned __int8)*a1;
if ( !(_BYTE)result )
break;
if ( (unsigned __int8)(result - 97) <= 0x19u )
*a1 = result - 32;
++a1;
}
return result;
}

original_code:
static void token_to_upper_case(char *token)
{
    int i = 0;
    while(token[i] != '\0') {
        if(token[i] >= 'a' && token[i] <= 'z') {
            token[i] -= 0x20;
        }
        i++;
    }
    return;
}

variable_types:
token
char *


main

repo: growian/words

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__int64 v3; // r14
__int64 v4; // rbx
__int64 v5; // rbp
unsigned int v6; // er14
unsigned int v7; // er15
__int64 v8; // r13
const char **v9; // r12
__int64 v10; // rax
__int64 v11; // rdi
const char **v12; // r13
__int64 v13; // rbx
__int64 v14; // rbp
__int64 v15; // rdi
__int64 v16; // rax
__int64 v17; // rbx
__int64 v18; // rbp
__int64 v19; // rax
int v20; // [rsp+Ch] [rbp-21Ch]
char s[64]; // [rsp+10h] [rbp-218h] BYREF
__int64 v22[26]; // [rsp+50h] [rbp-1D8h] BYREF
__int64 v23[33]; // [rsp+120h] [rbp-108h] BYREF

memset(v22, 0, sizeof(v22));
memset(v23, 0, 0xD0uLL);
v3 = (unsigned int)read_file(v22, v23, envp);
printf("%i words left\n", v3);
while ( 1 )
{
while ( 1 )
{
printf("Next word: ");
fgets(s, 64, stdin);
chomp(s);
if ( s[0] )
break;
print_array(v22);
putchar(10);
}
v4 = (int)index_first(s);
v5 = find_word_in_list(v22[v4], s);
if ( v5 )
break;
puts("Word not in index");
}
v6 = v3 - 1;
v7 = 1;
v8 = (int)index_last(s);
v9 = (const char **)create_word(v5);
v10 = delete_word(v22[v4], v5);
v11 = v23[v8];
v22[v4] = v10;
v23[v8] = delete_word(v11, v5);
v12 = v9;
while ( 1 )
{
while ( 1 )
{
v13 = (int)index_first(*v9);
v14 = (int)index_last(*v12);
printf("%i words left\n", v6);
printf("Current chain of %i words: %s ... %s\n", v7, *v9, *v12);
printf("Next word: ");
fgets(s, 64, stdin);
chomp(s);
v15 = v23[v13];
if ( s[0] )
break;
print_list(v15);
print_list(v22[v14]);
putchar(10);
}
v16 = find_word_in_list(v15, s);
v17 = v16;
if ( v16 )
break;
v19 = find_word_in_list(v22[v14], s);
v17 = v19;
if ( v19 )
{
v12 = (const char **)append_word(v12, v19);
LABEL_9:
--v6;
++v7;
v20 = index_first(v17);
v18 = (int)index_last(v17);
v23[v18] = delete_word(v23[v18], v17);
v22[v20] = delete_word(v22[v20], v17);
}
else
{
puts("Word not in index or not matching or already used");
}
}
v9 = (const char **)prefix_word(v9, v16);
goto LABEL_9;
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__int64 v3; // r14
__int64 v4; // rbx
__int64 v5; // rbp
unsigned int v6; // er14
unsigned int v7; // er15
__int64 v8; // r13
const char **v9; // r12
__int64 v10; // rax
__int64 v11; // rdi
const char **v12; // r13
__int64 v13; // rbx
__int64 v14; // rbp
__int64 v15; // rdi
__int64 v16; // rax
__int64 v17; // rbx
__int64 v18; // rbp
__int64 v19; // rax
int v20; // [rsp+Ch] [rbp-21Ch]
char s[64]; // [rsp+10h] [rbp-218h] BYREF
__int64 v22[26]; // [rsp+50h] [rbp-1D8h] BYREF
__int64 v23[33]; // [rsp+120h] [rbp-108h] BYREF

memset(v22, 0, sizeof(v22));
memset(v23, 0, 0xD0uLL);
v3 = (unsigned int)func12(v22, v23, envp);
printf("%i words left\n", v3);
while ( 1 )
{
while ( 1 )
{
printf("Next word: ");
fgets(s, 64, stdin);
func7(s);
if ( s[0] )
break;
func15(v22);
putchar(10);
}
v4 = (int)func8(s);
v5 = func13(v22[v4], s);
if ( v5 )
break;
puts("Word not in index");
}
v6 = v3 - 1;
v7 = 1;
v8 = (int)func9(s);
v9 = (const char **)create_word(v5);
v10 = func10(v22[v4], v5);
v11 = v23[v8];
v22[v4] = v10;
v23[v8] = func10(v11, v5);
v12 = v9;
while ( 1 )
{
while ( 1 )
{
v13 = (int)func8(*v9);
v14 = (int)func9(*v12);
printf("%i words left\n", v6);
printf("Current chain of %i words: %s ... %s\n", v7, *v9, *v12);
printf("Next word: ");
fgets(s, 64, stdin);
func7(s);
v15 = v23[v13];
if ( s[0] )
break;
func14(v15);
func14(v22[v14]);
putchar(10);
}
v16 = func13(v15, s);
v17 = v16;
if ( v16 )
break;
v19 = func13(v22[v14], s);
v17 = v19;
if ( v19 )
{
v12 = (const char **)append_word(v12, v19);
LABEL_9:
--v6;
++v7;
v20 = func8(v17);
v18 = (int)func9(v17);
v23[v18] = func10(v23[v18], v17);
v22[v20] = func10(v22[v20], v17);
}
else
{
puts("Word not in index or not matching or already used");
}
}
v9 = (const char **)prefix_word(v9, v16);
goto LABEL_9;
}

original_code:
int main() {
   word* chainbegin = ((void *)0);
   word* chainend = ((void *)0);
   word* first[26] = {0};
   word* last[26] = {0};
   int words_left = read_file(first, last);
   printf("%i words left\n", words_left);
   char input[64];
   while (1) {
      int ifi, ila, len_chain = 0;
      char* ps;
      while (1) {
         printf("Next word: ");
         fgets(input, 64, stdin);
         chomp(input);
         if (strlen(input) == 0) {
            print_array(first);
            printf("\n");
            continue;
         } else {
            ifi = index_first(input);
            ila = index_last(input);
            ps = find_word_in_list(first[ifi], input);
            if (ps != ((void *)0)) {
               chainbegin = create_word(ps);
               len_chain++;
               chainend = chainbegin;
               first[ifi] = delete_word(first[ifi], ps);
               last[ila] = delete_word(last[ila], ps);
               words_left--;
               break;
            } else {
               printf("Word not in index\n");
               continue;
            }
         }
      }
      while (1) {
         ifi = index_first(chainbegin->val);
         ila = index_last(chainend->val);
         printf("%i words left\n", words_left);
         printf("Current chain of %i words: %s ... %s\n",len_chain ,chainbegin->val, chainend->val);
         printf("Next word: ");
         fgets(input, 64, stdin);
         chomp(input);
         if (strlen(input) == 0) {
            print_list(last[ifi]);
            print_list(first[ila]);
            printf("\n");
            continue;
         } else {
            ps = find_word_in_list(last[ifi], input);
            if (ps != ((void *)0)) {
               chainbegin = prefix_word(chainbegin, ps);
            } else {
               ps = find_word_in_list(first[ila], input);
               if (ps != ((void *)0)) {
                  chainend = append_word(chainend, ps);
               } else {
                  printf("Word not in index or not matching or already used\n");
                  continue;
               }
            }
            ifi = index_first(ps);
            ila = index_last(ps);
            last[ila] = delete_word(last[ila], ps);
            first[ifi] = delete_word(first[ifi], ps);
            words_left--;
            len_chain++;
         }
      }
   }
   return 0;
}

canonical_original_code:
int main() {
   struct word *chainbegin = ((void *)0);
   struct word *chainend = ((void *)0);
   struct word *first[26] = {0};
   struct word *last[26] = {0};
   int words_left = read_file(first, last);
   printf("%i words left\n", words_left);
   char input[64];
   while (1) {
      int ifi; int ila; int len_chain = 0;
      char *ps;
      while (1) {
         printf("Next word: ");
         fgets(input, 64, stdin);
         chomp(input);
         if (strlen(input) == 0) {
            print_array(first);
            printf("\n");
            continue;
         } else {
            ifi = index_first(input);
            ila = index_last(input);
            ps = find_word_in_list(first[ifi], input);
            if (ps != ((void *)0)) {
               chainbegin = create_word(ps);
               len_chain++;
               chainend = chainbegin;
               first[ifi] = delete_word(first[ifi], ps);
               last[ila] = delete_word(last[ila], ps);
               words_left--;
               break;
            } else {
               printf("Word not in index\n");
               continue;
            }
         }
      }
      while (1) {
         ifi = index_first(chainbegin->val);
         ila = index_last(chainend->val);
         printf("%i words left\n", words_left);
         printf("Current chain of %i words: %s ... %s\n",len_chain ,chainbegin->val, chainend->val);
         printf("Next word: ");
         fgets(input, 64, stdin);
         chomp(input);
         if (strlen(input) == 0) {
            print_list(last[ifi]);
            print_list(first[ila]);
            printf("\n");
            continue;
         } else {
            ps = find_word_in_list(last[ifi], input);
            if (ps != ((void *)0)) {
               chainbegin = prefix_word(chainbegin, ps);
            } else {
               ps = find_word_in_list(first[ila], input);
               if (ps != ((void *)0)) {
                  chainend = append_word(chainend, ps);
               } else {
                  printf("Word not in index or not matching or already used\n");
                  continue;
               }
            }
            ifi = index_first(ps);
            ila = index_last(ps);
            last[ila] = delete_word(last[ila], ps);
            first[ifi] = delete_word(first[ifi], ps);
            words_left--;
            len_chain++;
         }
      }
   }
   return 0;
}

variable_types: struct word { char *val; struct word *next; } *[26]

variable_types:
input
char [64]

variable_types: ifi int

variable_types: ila int

variable_types:
ps
char *


chomp

decompiled_code:
size_t __fastcall chomp(const char *a1)
{
size_t result; // rax

result = strlen(a1);
a1[result - 1] = 0;
return result;
}

canonical_decompiled_code:
size_t __fastcall func7(const char *a1)
{
size_t result; // rax

result = strlen(a1);
a1[result - 1] = 0;
return result;
}

original_code:
void chomp(char* str) {
   size_t l = strlen(str);
   str[l-1] = '\0';
}

canonical_original_code:
void chomp(char *str) {
   unsigned long l = strlen(str);
   str[l-1] = '\0';
}

variable_types:
str
char *

variable_types:
l
unsigned long


decompiled_code:
__int64 __fastcall index_first(char *a1)
{
return (unsigned int)((*__ctype_toupper_loc())[*a1] - 65);
}

canonical_decompiled_code:
__int64 __fastcall func8(char *a1)
{
return (unsigned int)((*__ctype_toupper_loc())[*a1] - 65);
}

original_code:
int index_first(char* str) {
   return toupper(str[0]) - 65;
}

canonical_original_code:
int index_first(char *str) {
   return toupper(str[0]) - 65;
}


decompiled_code:
__int64 __fastcall index_last(const char *a1)
{
int v1; // ebx

v1 = strlen(a1);
return (unsigned int)((*__ctype_toupper_loc())[a1[v1 - 1]] - 65);
}

canonical_decompiled_code:
__int64 __fastcall func9(const char *a1)
{
int v1; // ebx

v1 = strlen(a1);
return (unsigned int)((*__ctype_toupper_loc())[a1[v1 - 1]] - 65);
}

original_code:
int index_last(char *str) {
   int last_char = strlen(str) - 1;
   return toupper(str[last_char]) - 65;
}


decompiled_code:
__int64 __fastcall delete_word(__int64 a1, const char *a2)
{
__int64 v2; // rbx
__int64 v3; // r13
__int64 v5; // rax

v2 = a1;
if ( !strcmp(a2, *(const char **)a1) )
return *(_QWORD *)(a1 + 8);
do
{
v3 = v2;
v2 = *(_QWORD *)(v2 + 8);
if ( !v2 )
return a1;
}
while ( strcmp(a2, *(const char **)v2) );
v5 = *(_QWORD *)(v2 + 8);
if ( v5 )
*(_QWORD *)(v3 + 8) = v5;
else
*(_QWORD *)(v3 + 8) = 0LL;
return a1;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1, const char *a2)
{
__int64 v2; // rbx
__int64 v3; // r13
__int64 v5; // rax

v2 = a1;
if ( !strcmp(a2, *(const char **)a1) )
return *(_QWORD *)(a1 + 8);
do
{
v3 = v2;
v2 = *(_QWORD *)(v2 + 8);
if ( !v2 )
return a1;
}
while ( strcmp(a2, *(const char **)v2) );
v5 = *(_QWORD *)(v2 + 8);
if ( v5 )
*(_QWORD *)(v3 + 8) = v5;
else
*(_QWORD *)(v3 + 8) = 0LL;
return a1;
}

original_code:
word* delete_word(word* w, char* str) {
   if (strcmp(str, w->val) == 0) {
      return w->next;
   } else {
      word *curr = w;
      word *pre;
      while (curr->next != ((void *)0)) {
         pre = curr;
         curr = curr->next;
         if (strcmp(str, curr->val) == 0) {
            if (curr->next != ((void *)0)) {
               pre->next = curr->next;
            } else {
               pre->next = ((void *)0);
            }
            break;
         }
      }
   }
   return w;
}

canonical_original_code:
struct word *delete_word(struct word *w, char *str) {
   if (strcmp(str, w->val) == 0) {
      return w->next;
   } else {
      struct word *curr = w;
      struct word *pre;
      while (curr->next != ((void *)0)) {
         pre = curr;
         curr = curr->next;
         if (strcmp(str, curr->val) == 0) {
            if (curr->next != ((void *)0)) {
               pre->next = curr->next;
            } else {
               pre->next = ((void *)0);
            }
            break;
         }
      }
   }
   return w;
}

variable_types:
w
struct word *

variable_types: struct word { char *val; struct word *next; } *


decompiled_code:
int __fastcall add_to_list(__int64 a1, __int64 a2)
{
__int64 v2; // r8

if ( !a1 )
return (unsigned int)create_word(a2);
do
{
v2 = a1;
a1 = *(_QWORD *)(a1 + 8);
}
while ( a1 );
append_word(v2, a2);
return printf("new word added");
}

canonical_decompiled_code:
int __fastcall func11(__int64 a1, __int64 a2)
{
__int64 v2; // r8

if ( !a1 )
return (unsigned int)create_word(a2);
do
{
v2 = a1;
a1 = *(_QWORD *)(a1 + 8);
}
while ( a1 );
append_word(v2, a2);
return printf("new word added");
}

original_code:
void add_to_list(word* w, char* str) {
   if (w == ((void *)0)) {
      w = create_word(str);
   } else {
      while (w->next != ((void *)0))
         w = w->next;
      append_word(w, str);
      printf("new  word added");
   }
}

canonical_original_code:
void add_to_list(struct word *w, char *str) {
   if (w == ((void *)0)) {
      w = create_word(str);
   } else {
      while (w->next != ((void *)0))
         w = w->next;
      append_word(w, str);
      printf("new  word added");
   }
}

user_defined_types: struct word { char *val; struct word *next; }


decompiled_code:
const char *__fastcall find_word_in_list(__int64 a1, const char *a2)
{
__int64 v2; // rbx
const char *v3; // r12

if ( !a1 )
return 0LL;
v2 = a1;
while ( 1 )
{
v3 = *(const char **)v2;
if ( !strcmp(a2, *(const char **)v2) )
break;
v2 = *(_QWORD *)(v2 + 8);
if ( !v2 )
return 0LL;
}
return v3;
}

canonical_decompiled_code:
const char *__fastcall func13(__int64 a1, const char *a2)
{
__int64 v2; // rbx
const char *v3; // r12

if ( !a1 )
return 0LL;
v2 = a1;
while ( 1 )
{
v3 = *(const char **)v2;
if ( !strcmp(a2, *(const char **)v2) )
break;
v2 = *(_QWORD *)(v2 + 8);
if ( !v2 )
return 0LL;
}
return v3;
}

original_code:
char *find_word_in_list(word *w, char *str) {
   word *tmp = w;
   while (tmp != ((void *)0)) {
      if (strcmp(str, tmp->val) == 0)
         return tmp->val;
      tmp = tmp->next;
   }
   return ((void *)0);
}

canonical_original_code:
char *find_word_in_list(struct word *w, char *str) {
   struct word *tmp = w;
   while (tmp != ((void *)0)) {
      if (strcmp(str, tmp->val) == 0)
         return tmp->val;
      tmp = tmp->next;
   }
   return ((void *)0);
}

return_type: char *


decompiled_code:
int __fastcall print_list(__int64 a1)
{
__int64 v1; // rbx
int result; // eax

if ( a1 )
{
v1 = a1;
do
{
result = printf("%s, ", *(const char **)v1);
v1 = *(_QWORD *)(v1 + 8);
}
while ( v1 );
}
return result;
}

canonical_decompiled_code:
int __fastcall func14(__int64 a1)
{
__int64 v1; // rbx
int result; // eax

if ( a1 )
{
v1 = a1;
do
{
result = printf("%s, ", *(const char **)v1);
v1 = *(_QWORD *)(v1 + 8);
}
while ( v1 );
}
return result;
}

original_code:
void print_list(word *w) {
   word *tmp = w;
   while (tmp != ((void *)0)) {
      printf("%s, ", tmp->val);
      tmp = tmp->next;
   }
}

canonical_original_code:
void print_list(struct word *w) {
   struct word *tmp = w;
   while (tmp != ((void *)0)) {
      printf("%s, ", tmp->val);
      tmp = tmp->next;
   }
}


decompiled_code:
int __fastcall print_array(__int64 *a1)
{
__int64 *v1; // rbp
__int64 *v2; // rbx
__int64 v3; // rdi
int result; // eax

v1 = a1 + 26;
v2 = a1;
do
{
v3 = *v2++;
result = print_list(v3);
}
while ( v2 != v1 );
return result;
}

canonical_decompiled_code:
int __fastcall func15(__int64 *a1)
{
__int64 *v1; // rbp
__int64 *v2; // rbx
__int64 v3; // rdi
int result; // eax

v1 = a1 + 26;
v2 = a1;
do
{
v3 = *v2++;
result = func14(v3);
}
while ( v2 != v1 );
return result;
}

original_code:
void print_array(word *w[]) {
   for (int i = 0; i < 26; i++) {
      print_list(w[i]);
   }
}

canonical_original_code:
void print_array(struct word *w[]) {
   for (int i = 0; i < 26; i++) {
      print_list(w[i]);
   }
}

variable_types: struct word { char *val; struct word *next; } *[]


repo: grtkachenko/OS

decompiled_code:
void __fastcall free_arr_of_arr(void *ptr, int a2)
{
void *v2; // r12
void **v3; // rbx
void **v4; // rbp
void *v5; // rdi

v2 = ptr;
if ( a2 > 0 )
{
v3 = (void **)ptr;
v4 = (void **)((char *)ptr + 8 * (unsigned int)(a2 - 1) + 8);
do
{
v5 = *v3++;
free(v5);
}
while ( v3 != v4 );
}
free(v2);
}

canonical_decompiled_code:
void __fastcall func7(void *ptr, int a2)
{
void *v2; // r12
void **v3; // rbx
void **v4; // rbp
void *v5; // rdi

v2 = ptr;
if ( a2 > 0 )
{
v3 = (void **)ptr;
v4 = (void **)((char *)ptr + 8 * (unsigned int)(a2 - 1) + 8);
do
{
v5 = *v3++;
free(v5);
}
while ( v3 != v4 );
}
free(v2);
}

original_code:
void free_arr_of_arr(char ** arr, int num_files) {
    int i;
    for (i = 0; i < num_files; i++) {
        free(arr[i]);
    }
    free(arr);
}

canonical_original_code:
void free_arr_of_arr(char **arr, int num_files) {
    int i;
    for (i = 0; i < num_files; i++) {
        free(arr[i]);
    }
    free(arr);
}

variable_types:
arr
char **