done with chapter one

This commit is contained in:
William Ball 2026-03-16 22:20:18 -04:00
commit da3a5e5275
Signed by: wball
SSH key fingerprint: SHA256:3K3IvjUp1U5HwsIRYy/vosnG8l/A84LPUSAKQ6oCGKI
5 changed files with 159 additions and 0 deletions

79
chunk/chunk.ha Normal file
View file

@ -0,0 +1,79 @@
use value;
use log;
export type opcode = enum u8 {
RETURN,
CONSTANT,
CONSTANT_LONG,
};
export type line_code = struct {
line: size,
num: size,
};
export type chunk = struct {
code: []u8,
constants: []value::value,
lines: []line_code,
};
export fn new_chunk() chunk = {
return chunk {
code = [],
constants = [],
lines = [],
};
};
export fn get_line(this_chunk: *chunk, idx: size) size = {
let total = 0z;
for (let line .. this_chunk.lines) {
total += line.num;
if (total >= idx) {
return line.line;
};
};
log::fatalf("{} out of bounds", idx);
};
export fn write_chunk(this_chunk: *chunk, byte: u8, line: size) void = {
append(this_chunk.code, byte)!;
const num_lines = len(this_chunk.lines);
if (num_lines == 0 ||
line != this_chunk.lines[num_lines - 1].line)
{
append(this_chunk.lines, line_code {
line = line,
num = 1,
})!;
} else {
this_chunk.lines[num_lines - 1].num += 1;
};
};
export fn add_constant(this_chunk: *chunk, value: value::value) size = {
append(this_chunk.constants, value)!;
return len(this_chunk.constants) - 1;
};
export fn write_constant(this_chunk: *chunk, value: value::value, line: size) void = {
const constant = add_constant(this_chunk, value);
if (constant <= 1 << 8) {
write_chunk(this_chunk, opcode::CONSTANT, line);
write_chunk(this_chunk, constant : u8, line);
} else if (constant <= 1 << 24) {
write_chunk(this_chunk, opcode::CONSTANT_LONG, line);
write_chunk(this_chunk, (constant & 0xFF) : u8, line);
write_chunk(this_chunk, ((constant >> 8) & 0xFF) : u8, line);
write_chunk(this_chunk, ((constant >> 16) & 0xFF) : u8, line);
} else {
log::fatalf("Maximum of {} constants surpassed!", 1 << 24);
};
};
export fn free_chunk(this_chunk: *chunk) void = {
free(this_chunk.code);
free(this_chunk.constants);
free(this_chunk.lines);
};

57
debug/debug.ha Normal file
View file

@ -0,0 +1,57 @@
use chunk;
use fmt;
use value;
export fn disassemble_chunk(chunk: *chunk::chunk, name: str) void = {
fmt::printf("== {} ==\n", name)!;
for (let idx = 0z; idx < len(chunk.code)) {
idx = dissassemble_instruction(chunk, idx);
};
};
export fn dissassemble_instruction(chunk: *chunk::chunk, idx: size) size = {
fmt::printf("{:4_0} ", idx)!;
const line = chunk::get_line(chunk, idx);
if (idx > 0 && line == chunk::get_line(chunk, idx - 1)) {
fmt::print(" | ")!;
} else {
fmt::printf("{:4} ", line)!;
};
let instruction = chunk.code[idx];
switch (instruction) {
case chunk::opcode::RETURN =>
return simple_instruction("RETURN", idx);
case chunk::opcode::CONSTANT =>
return constant_instruction("CONSTANT", chunk, idx);
case chunk::opcode::CONSTANT_LONG =>
return long_constant_instruction("CONSTANT_LONG", chunk, idx);
case =>
fmt::printf("Unknown opcode: {}\n", instruction)!;
return idx + 1;
};
};
fn simple_instruction(name: str, idx: size) size = {
fmt::printf("{}\n", name)!;
return idx + 1;
};
fn constant_instruction(name: str, chunk: *chunk::chunk, idx: size) size = {
const constant = chunk.code[idx + 1];
fmt::printf("{:-16} {:4} '", name, constant)!;
value::print_value(chunk.constants[constant]);
fmt::print("'\n")!;
return idx + 2;
};
fn long_constant_instruction(name: str, chunk: *chunk::chunk, idx: size) size = {
const constant1: size = chunk.code[idx + 1];
const constant2: size = chunk.code[idx + 2];
const constant3: size = chunk.code[idx + 3];
const constant = (constant3 << 16) + (constant2 << 8) + constant1;
fmt::printf("{:-16} {} '", name, constant)!;
value::print_value(chunk.constants[constant]);
fmt::print("'\n")!;
return idx + 4;
};

BIN
hlox Executable file

Binary file not shown.

16
main.ha Normal file
View file

@ -0,0 +1,16 @@
use chunk;
use debug;
use fmt;
use os;
export fn main() void = {
let chunk = chunk::new_chunk();
defer chunk::free_chunk(&chunk);
chunk::write_constant(&chunk, 1.2, 123);
chunk::write_chunk(&chunk, chunk::opcode::RETURN, 123);
debug::disassemble_chunk(&chunk, "test chunk");
os::exit(0);
};

7
value/value.ha Normal file
View file

@ -0,0 +1,7 @@
use fmt;
export type value = f64;
export fn print_value(val: value) void = {
fmt::printf("{}", val)!;
};