79 lines
1.8 KiB
Hare
79 lines
1.8 KiB
Hare
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);
|
|
};
|