Hash Tables 20

This commit is contained in:
nazrin 2025-06-07 04:09:48 +00:00
parent 3b234814fa
commit a7b7348f61
20 changed files with 868 additions and 837 deletions

View file

@ -1,83 +1,68 @@
module clox.chunk;
import std.container.array;
import std.stdio;
import std.algorithm;
import clox.memory;
import clox.value;
import clox.object;
import clox.container.rle;
import clox.container.int24;
enum SimpleOp;
enum LogicOp;
enum ValueOp;
enum ArithOp;
enum CompOp;
enum OpCode : ubyte{
Constant,
@ValueOp Nil,
@ValueOp True,
@ValueOp False,
@(SimpleOp, CompOp) Equal,
@(SimpleOp, CompOp) Greater,
@(SimpleOp, CompOp) Less,
@(SimpleOp, CompOp) NotEqual,
@(SimpleOp, CompOp) GreaterEqual,
@(SimpleOp, CompOp) LessEqual,
@(SimpleOp, ArithOp) Add,
@(SimpleOp, ArithOp) Subtract,
@(SimpleOp, ArithOp) Multiply,
@(SimpleOp, ArithOp) Divide,
@(SimpleOp, LogicOp) Not,
@(SimpleOp, LogicOp) Negate,
@(SimpleOp) Return,
struct OpColour{
string r, g, b;
}
enum OpCode : ubyte{
@(OpColour("200", "200", "100")) Constant,
@(OpColour("255", "200", "100")) Nil,
@(OpColour("255", "200", "100")) True,
@(OpColour("255", "200", "100")) False,
@(OpColour("255", "100", "100")) Equal,
@(OpColour("255", "100", "100")) Greater,
@(OpColour("255", "100", "100")) Less,
@(OpColour("255", "100", "100")) NotEqual,
@(OpColour("255", "100", "100")) GreaterEqual,
@(OpColour("255", "100", "100")) LessEqual,
@(OpColour("100", "100", "255")) Add,
@(OpColour("100", "100", "255")) Subtract,
@(OpColour("100", "100", "255")) Multiply,
@(OpColour("100", "100", "255")) Divide,
@(OpColour("200", "100", "100")) Not,
@(OpColour("100", "100", "200")) Negate,
@(OpColour("000", "200", "100")) Return,
}
import std.traits: hasUDA;
bool isSimpleOp(alias op)() => hasUDA!(op, SimpleOp);
bool isValueOp(alias op)() => hasUDA!(op, ValueOp);
bool isLogicOp(alias op)() => hasUDA!(op, LogicOp);
bool isCompOp(alias op)() => hasUDA!(op, CompOp);
bool isArithOp(alias op)() => hasUDA!(op, ArithOp);
bool isSize1Op(alias op)() => isSimpleOp!op || isValueOp!op;
static assert( isSimpleOp!(OpCode.Equal) );
static assert( !isSimpleOp!(OpCode.Constant) );
struct Chunk{
Array!ubyte code;
Rle!(Uint24, ubyte) lines;
Array!Value constants;
string name;
~this(){
stderr.writeln("Deallocing chunk ", name);
foreach(value; constants[].filter!isObj)
value.getObj.freeObject();
uint count;
uint capacity;
ubyte* code;
uint* lines;
ValueArray constants;
void initialise(){
count = 0;
capacity = 0;
code = null;
lines = null;
constants.initialise();
}
uint addConstant(in Value value) @nogc nothrow {
long index;
switch(value.type){
case Value.Type.Str:
index = constants[].countUntil!(v => v.isStr && v.getStr.data == value.getStr.data);
break;
default:
index = constants[].countUntil(value);
void write(ubyte b, uint line = 0){
if(capacity < count + 1){
uint oldCapacity = capacity;
capacity = GROW_CAPACITY(oldCapacity);
code = GROW_ARRAY!ubyte(code, oldCapacity, capacity);
lines = GROW_ARRAY!uint(lines, oldCapacity, capacity);
}
if(index >= 0)
return cast(uint)index;
constants ~= value;
return cast(uint)((constants.length) - 1);
code[count] = b;
lines[count] = line;
count++;
}
void write(ubyte b, uint line = 0) @nogc nothrow {
ubyte[1] data = [ b ];
this.write(data, line);
int addConstant(Value value){
constants.write(value);
return constants.count - 1;
}
void write(ubyte[] b, uint line = 0) @nogc nothrow {
code ~= b;
foreach(i; 0 .. b.length)
lines ~= Uint24(line); // TODO could be done without a loop
void free(){
FREE_ARRAY!ubyte(code, capacity);
FREE_ARRAY!uint(lines, capacity);
constants.free();
initialise();
}
}