diff --git a/dub.sdl b/dub.sdl index 8920a38..8248879 100644 --- a/dub.sdl +++ b/dub.sdl @@ -9,6 +9,10 @@ buildRequirements "requireBoundsCheck" "requireContracts" versions "LoxConcatNonStrings" "LoxExtraNativeFuncs" "LoxPrintMultiple" +sourcePaths +configuration "clox" { + sourcePaths "src/clox" "src/common" +} configuration "jlox" { sourcePaths "src/jlox" "src/common" } diff --git a/src/clox/chunk.d b/src/clox/chunk.d new file mode 100644 index 0000000..d6199eb --- /dev/null +++ b/src/clox/chunk.d @@ -0,0 +1,26 @@ +module clox.chunk; + +import std.container.array; +import std.stdio; + +import clox.value; + +enum OpCode : ubyte{ + OP_CONSTANT, + OP_RETURN, +} + +struct Chunk{ + Array!ubyte code; + Array!uint lines; + Array!Value constants; + ubyte addConstant(in Value value) @nogc nothrow { + constants ~= value; + return cast(ubyte)((constants.length) - 1); + } + void write(ubyte b, uint line = 0) @nogc nothrow { + code ~= b; + lines ~= line; + } +} + diff --git a/src/clox/dbg.d b/src/clox/dbg.d new file mode 100644 index 0000000..9895399 --- /dev/null +++ b/src/clox/dbg.d @@ -0,0 +1,42 @@ +module clox.dbg; + +import std.stdio; + +import clox.chunk; +import clox.value; + +private ulong simpleInstruction(string name, ulong offset){ + writeln(name); + return offset + 1; +} +private ulong constantInstruction(string name, in ref Chunk chunk, ulong offset){ + ubyte constant = chunk.code[offset + 1]; + writef("%-16s %4d '", name, constant); + printValue(chunk.constants[constant]); + writeln("'"); + return offset + 2; +} + +void disassembleChunk(in ref Chunk chunk, string name = "chunk"){ + writefln("== %s ==", name); + for(ulong offset = 0; offset < chunk.code.length;) + offset = disassembleInstruction(chunk, offset); +} +ulong disassembleInstruction(in ref Chunk chunk, const ulong offset){ + writef(" %04d ", offset); + if(offset > 0 && chunk.lines[offset] == chunk.lines[offset - 1]) + write(" | "); + else + writef(" %4d ", chunk.lines[offset]); + ubyte instruction = chunk.code[offset]; + with(OpCode) switch(instruction){ + case OP_CONSTANT: + return constantInstruction("OP_CONSTANT", chunk, offset); + case OP_RETURN: + return simpleInstruction("OP_RETURN", offset); + default: + writefln("Unknown opcode %d", instruction); + return offset + 1; + } +} + diff --git a/src/clox/main.d b/src/clox/main.d new file mode 100644 index 0000000..cc07501 --- /dev/null +++ b/src/clox/main.d @@ -0,0 +1,20 @@ +module clox.main; + +import std.stdio; + +import clox.chunk; +import clox.dbg; + +int main(string[] argv){ + Chunk chunk; + + ubyte constant = chunk.addConstant(1.2); + chunk.write(OpCode.OP_CONSTANT); + chunk.write(constant); + + chunk.write(OpCode.OP_RETURN); + + disassembleChunk(chunk); + return 0; +} + diff --git a/src/clox/value.d b/src/clox/value.d new file mode 100644 index 0000000..c9b298c --- /dev/null +++ b/src/clox/value.d @@ -0,0 +1,10 @@ +module clox.value; + +import std.stdio; + +alias Value = double; + +void printValue(Value value){ + writef("%g", value); +} +