Skip to content

Commit 6c2f8a2

Browse files
committed
Add code for absint
1 parent 633363f commit 6c2f8a2

File tree

3 files changed

+186
-0
lines changed

3 files changed

+186
-0
lines changed

semantic/absint.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "metac_value_table.c"

semantic/metac_value_table.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#include "metac_value_table.h"
2+
3+
const metac_node_ptr_t empty_node = {~0u};
4+
5+
static inline bool IsFilled(metac_value_table_slot_t slot)
6+
{
7+
return slot.HashKey != 0;
8+
}
9+
10+
void ValueTable_Init_(metac_value_table_t* table, uint32_t slotCountLog2, metac_alloc_t* alloc,
11+
const char* file, uint32_t line)
12+
{
13+
table->SlotCount_Log2 = slotCountLog2;
14+
const uint32_t maxSlots = (1 << table->SlotCount_Log2);
15+
table->Slots = cast(metac_value_table_slot_t*)
16+
Allocator_Calloc_(alloc, sizeof(metac_value_table_slot_t), maxSlots, file, line);
17+
table->SlotsUsed = 0;
18+
19+
20+
void ValueTable_Free(metac_value_table_t* table)
21+
{
22+
static const metac_value_table_t zeroTable = {0};
23+
(*table) = zeroTable;
24+
}
25+
26+
metac_node_ptr_t GetOrAddValue(metac_value_table_t* table, metac_node_ptr_t keyNode, metac_node_ptr_t valueNode)
27+
{
28+
metac_node_ptr_t result = {0};
29+
30+
const uint32_t slotIndexMask = ((1 << table->SlotCount_Log2) - 1);
31+
const uint32_t initialSlotIndex = (keyNodeHash & slotIndexMask);
32+
uint32_t displacement = 0;
33+
34+
for (uint32_t slotIndex = initialSlotIndex; (++slotIndex & slotIndexMask) != initialSlotIndex;)
35+
{
36+
metac_value_table_slot_t* slot = &table->Slots[(slotIndex - 1) & slotIndexMask];
37+
38+
if (slot->HashKey == keyNodeHash)
39+
{
40+
if (slot->KeyNode.v == keyNode.v)
41+
{
42+
result = slot->ValueNode;
43+
#ifdef REFCOUNT
44+
slot->RefCount++;
45+
#endif
46+
break;
47+
}
48+
}
49+
else if (slot->HashKey == 0)
50+
{
51+
result = valueNode;
52+
slot->HashKey = keyNodeHash;
53+
slot->KeyNode = keyNode;
54+
slot->ValueNode = valueNode;
55+
#ifdef REFCOUNT
56+
slot->RefCount = 1;
57+
slot->Displacement = displacement;
58+
#endif
59+
table->SlotsUsed++;
60+
break;
61+
}
62+
displacement++;
63+
}
64+
return result;
65+
}
66+
67+
int32_t ValueTable_HasKey(metac_value_table_t* table, uint32_t keyNodeHash, metac_node_ptr_t keyNode)
68+
{
69+
int32_t result = -1;
70+
const uint32_t slotIndexMask = ((1 << table->SlotCount_Log2) - 1);
71+
const uint32_t initialSlotIndex = (keyNodeHash & slotIndexMask);
72+
73+
for (uint32_t slotIndex = initialSlotIndex; (++slotIndex & slotIndexMask) != initialSlotIndex;)
74+
{
75+
int32_t idx = (int32_t)((slotIndex - 1) & slotIndexMask);
76+
metac_value_table_slot_t slot = table->Slots[idx];
77+
78+
if (slot.HashKey == 0)
79+
break;
80+
if (slot.HashKey == keyNodeHash && slot.KeyNode.v == keyNode.v)
81+
{
82+
result = idx;
83+
break;
84+
}
85+
}
86+
87+
return result;
88+
}
89+
90+
metac_node_ptr_t IsValueInTable(metac_value_table_t* table, uint32_t keyNodeHash, metac_node_ptr_t keyNode)
91+
{
92+
metac_node_ptr_t result = {0};
93+
const uint32_t slotIndexMask = ((1 << table->SlotCount_Log2) - 1);
94+
const uint32_t initialSlotIndex = (keyNodeHash & slotIndexMask);
95+
96+
for (uint32_t slotIndex = initialSlotIndex; (++slotIndex & slotIndexMask) != initialSlotIndex;)
97+
{
98+
metac_value_table_slot_t slot = table->Slots[(slotIndex - 1) & slotIndexMask];
99+
100+
if (slot.HashKey == 0)
101+
return result;
102+
if (slot.HashKey == keyNodeHash && slot.KeyNode.v == keyNode.v)
103+
{
104+
result = slot.ValueNode;
105+
return result;
106+
}
107+
}
108+
109+
return result;
110+
}
111+
112+
metac_value_table_slot_t* ValueTableLookup(metac_value_table_t* table, uint32_t keyNodeHash, metac_node_ptr_t keyNode, metac_node_ptr_t valueNode)
113+
{
114+
const uint32_t slotIndexMask = ((1 << table->SlotCount_Log2) - 1);
115+
const uint32_t initialSlotIndex = (keyNodeHash & slotIndexMask);
116+
117+
for (uint32_t slotIndex = initialSlotIndex; (++slotIndex & slotIndexMask) != initialSlotIndex;)
118+
{
119+
uint32_t lookupIdx = (slotIndex - 1) & slotIndexMask;
120+
metac_value_table_slot_t slot = table->Slots[lookupIdx];
121+
122+
if (slot.HashKey == 0)
123+
return 0;
124+
if (slot.HashKey == keyNodeHash && slot.KeyNode.v == keyNode.v && slot.ValueNode.v == valueNode.v)
125+
return table->Slots + lookupIdx;
126+
}
127+
128+
return 0;
129+
}
130+
131+
bool IsInValueTable(metac_value_table_t* table, uint32_t keyNodeHash, metac_node_ptr_t keyNode, metac_node_ptr_t valueNode)
132+
{
133+
return ValueTableLookup(table, keyNodeHash, keyNode, valueNode) != 0;
134+
}

semantic/metac_value_table.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#ifndef _METAC_VALUE_TABLE_H_
2+
#define _METAC_VALUE_TABLE_H_
3+
#include "../parser/metac_node.h"
4+
5+
typedef struct metac_alloc_t metac_alloc_t;
6+
7+
// Define a generic metac_node_ptr_t structure to hold metac_node_t mappings
8+
typedef struct metac_node_ptr_t
9+
{
10+
uint32_t v;
11+
} metac_node_ptr_t;
12+
13+
extern const metac_node_ptr_t empty_node;
14+
15+
// The slot structure stores the mapping from one metac_node_t to another
16+
typedef struct metac_value_table_slot_t
17+
{
18+
metac_node_t KeyNode; // The key node in the mapping
19+
metac_node_t ValueNode; // The value node it maps to
20+
21+
#ifdef REFCOUNT
22+
uint32_t RefCount; // Optional reference counting
23+
uint32_t Displacement; // Displacement for handling hash collisions
24+
#endif
25+
} metac_value_table_slot_t;
26+
27+
// The main table structure that holds the slots and manages memory
28+
typedef struct metac_value_table_t
29+
{
30+
metac_value_table_slot_t* Slots; // Array of slots for storing mappings
31+
uint32_t SlotCount_Log2; // Log2 of the number of slots (for hashing)
32+
uint32_t SlotsUsed; // Number of slots currently used
33+
34+
metac_alloc_t* Allocator; // Allocator used for managing table memory
35+
} metac_value_table_t;
36+
37+
#pragma pack(push, 1)
38+
// File header structure to represent the value table in a serialized form
39+
typedef struct value_table_file_header_t
40+
{
41+
uint32_t NumberOfSlots; // Total number of slots
42+
uint32_t SizeofSlot; // Size of each slot
43+
uint32_t OffsetSlots; // Offset to the slots in the file
44+
uint32_t OffsetValues; // Offset to the value nodes in the file
45+
46+
uint32_t Version; // Version of the serialized format
47+
uint32_t LengthShift; // Shift used to determine table growth
48+
uint32_t HeaderCommentSize; // Size of any comments or metadata in the header
49+
} value_table_file_header_t;
50+
#pragma pack(pop)
51+
#endif

0 commit comments

Comments
 (0)