aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/jq/compile.zig
blob: a28c10a2fb9b437bdeed4c16bd86fbdb8ea476a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
const std = @import("std");
const jv = @import("../jv.zig");
const Ast = @import("./parse.zig").Ast;

pub const Opcode = enum {
    nop,
    array_index,
    literal,
};

pub const Instr = union(Opcode) {
    nop,
    array_index,
    literal: *jv.Value,

    pub fn op(self: @This()) Opcode {
        return self;
    }
};

pub fn compile(allocator: std.mem.Allocator, compile_allocator: std.mem.Allocator, ast: *const Ast) ![]Instr {
    var instrs = try std.array_list.Aligned(Instr, null).initCapacity(allocator, 16);

    switch (ast.*) {
        .identity => try instrs.append(allocator, .nop),
        .array_index => |index| {
            const index_instrs = try compile(allocator, compile_allocator, index);
            defer allocator.free(index_instrs);
            try instrs.appendSlice(allocator, index_instrs);
            try instrs.append(allocator, .array_index);
        },
        .literal => |value| try instrs.append(allocator, .{ .literal = value }),
    }

    return instrs.toOwnedSlice(allocator);
}