Compare commits

..

4 commits

3 changed files with 129 additions and 56 deletions

View file

@ -16,12 +16,26 @@ const readline = @cImport({
@cInclude("readline/history.h"); @cInclude("readline/history.h");
}); });
fn wrapInCmdList(allocator: *std.mem.Allocator, cmd: langs.Command) !langs.CommandList { fn wrapInCmdList(allocator: *std.mem.Allocator, cmd: *langs.Command) !langs.CommandList {
var cmds = langs.CommandList.init(allocator); var cmds = langs.CommandList.init(allocator);
try cmds.append(cmd); try cmds.append(cmd);
return cmds; return cmds;
} }
fn copyCommandToHeap(allocator: *std.mem.Allocator, command: langs.Command, comptime tag: langs.Command.Tag) !*langs.Command {
const CommandStruct = langs.Command.tagToType(tag);
const casted = command.cast(CommandStruct).?;
var heap_cmd = try allocator.create(CommandStruct);
@memcpy(
@ptrCast([*]u8, &heap_cmd),
@ptrCast([*]const u8, &casted),
@sizeOf(CommandStruct),
);
return &heap_cmd.base;
}
pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void {
var stdout_file = std.io.getStdOut(); var stdout_file = std.io.getStdOut();
const stdout = &stdout_file.outStream(); const stdout = &stdout_file.outStream();
@ -104,11 +118,12 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void {
// run the load command // run the load command
try runner.runCommands(cmds, true); try runner.runCommands(cmds, true);
var runqs_args = langs.ArgList.init(allocator);
defer runqs_args.deinit();
const wanted_runner: []const u8 = std.os.getenv("SCRITCHER_RUNNER") orelse "ristretto"; const wanted_runner: []const u8 = std.os.getenv("SCRITCHER_RUNNER") orelse "ristretto";
try runqs_args.append(wanted_runner);
var runqs_cmd = langs.Command.RunQS{
.base = langs.Command{ .tag = langs.Command.Tag.runqs },
.program = wanted_runner,
};
while (true) { while (true) {
lang.reset(); lang.reset();
@ -124,11 +139,51 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void {
var line = rd_line[0..std.mem.len(rd_line)]; var line = rd_line[0..std.mem.len(rd_line)];
if (std.mem.eql(u8, line, "push")) { if (std.mem.eql(u8, line, "push")) {
try cmds.append(current); const heap_cmd = switch (current.tag) {
.noop => try copyCommandToHeap(allocator, current, .noop),
.load => try copyCommandToHeap(allocator, current, .load),
.quicksave => try copyCommandToHeap(allocator, current, .quicksave),
.runqs => try copyCommandToHeap(allocator, current, .runqs),
.amp => try copyCommandToHeap(allocator, current, .amp),
.rflanger => try copyCommandToHeap(allocator, current, .rflanger),
.eq => try copyCommandToHeap(allocator, current, .eq),
.phaser => try copyCommandToHeap(allocator, current, .phaser),
.mbeq => try copyCommandToHeap(allocator, current, .mbeq),
.chorus => try copyCommandToHeap(allocator, current, .chorus),
.pitchscaler => try copyCommandToHeap(allocator, current, .pitchscaler),
.reverb => try copyCommandToHeap(allocator, current, .reverb),
.highpass => try copyCommandToHeap(allocator, current, .highpass),
.delay => try copyCommandToHeap(allocator, current, .delay),
.vinyl => try copyCommandToHeap(allocator, current, .vinyl),
.revdelay => try copyCommandToHeap(allocator, current, .revdelay),
.gate => try copyCommandToHeap(allocator, current, .gate),
.detune => try copyCommandToHeap(allocator, current, .detune),
.overdrive => try copyCommandToHeap(allocator, current, .overdrive),
.degrade => try copyCommandToHeap(allocator, current, .degrade),
.repsycho => try copyCommandToHeap(allocator, current, .repsycho),
.talkbox => try copyCommandToHeap(allocator, current, .talkbox),
.dyncomp => try copyCommandToHeap(allocator, current, .dyncomp),
.thruzero => try copyCommandToHeap(allocator, current, .thruzero),
.foverdrive => try copyCommandToHeap(allocator, current, .foverdrive),
.gverb => try copyCommandToHeap(allocator, current, .gverb),
.invert => try copyCommandToHeap(allocator, current, .invert),
.tapedelay => try copyCommandToHeap(allocator, current, .tapedelay),
.moddelay => try copyCommandToHeap(allocator, current, .moddelay),
.multichorus => try copyCommandToHeap(allocator, current, .multichorus),
.saturator => try copyCommandToHeap(allocator, current, .saturator),
.vintagedelay => try copyCommandToHeap(allocator, current, .vintagedelay),
.noise => try copyCommandToHeap(allocator, current, .noise),
.wildnoise => try copyCommandToHeap(allocator, current, .wildnoise),
.write => try copyCommandToHeap(allocator, current, .write),
.embed => try copyCommandToHeap(allocator, current, .embed),
.rotate => try copyCommandToHeap(allocator, current, .rotate),
};
try cmds.append(heap_cmd);
// run the current added command to main cmds list // run the current added command to main cmds list
// with the main parent runner // with the main parent runner
var cmds_wrapped = try wrapInCmdList(allocator, current); var cmds_wrapped = try wrapInCmdList(allocator, heap_cmd);
defer cmds_wrapped.deinit(); defer cmds_wrapped.deinit();
try runner.runCommands(cmds_wrapped, true); try runner.runCommands(cmds_wrapped, true);
@ -153,7 +208,7 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void {
std.debug.warn("repl: error while parsing: {}\n", .{err}); std.debug.warn("repl: error while parsing: {}\n", .{err});
continue; continue;
}; };
current = cmds_parsed.items[0]; current = cmds_parsed.items[0].*;
// by cloning the parent runner, we can iteratively write // by cloning the parent runner, we can iteratively write
// whatever command we want and only commit the good results // whatever command we want and only commit the good results
@ -161,10 +216,9 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void {
var runner_clone = try runner.clone(); var runner_clone = try runner.clone();
defer runner_clone.deinit(); defer runner_clone.deinit();
try cmds_parsed.append(langs.Command{ // taking address is fine, because runqs_cmd lives in the lifetime
.command = .RunQS, // of this function.
.args = runqs_args, try cmds.append(&runqs_cmd.base);
});
try runner_clone.runCommands(cmds_parsed, true); try runner_clone.runCommands(cmds_parsed, true);
_ = try stdout.write("\n"); _ = try stdout.write("\n");

View file

@ -1,6 +1,18 @@
const std = @import("std");
const langs = @import("lang.zig"); const langs = @import("lang.zig");
pub fn printCommand(cmd: langs.Command, comptime tag: langs.Command.Tag) !void { fn printCommandWithParams(stream: var, command: var) !void {
const Parameters = @TypeOf(command.parameters);
inline for (@typeInfo(Parameters).Struct.fields) |field| {
if (field.field_type == f32 or field.field_type == f64) {
try stream.print(" {d}", .{@field(command.parameters, field.name)});
} else {
try stream.print(" {}", .{@field(command.parameters, field.name)});
}
}
}
fn printCommand(stream: var, cmd: *langs.Command, comptime tag: langs.Command.Tag) !void {
const CommandStruct = langs.Command.tagToType(tag); const CommandStruct = langs.Command.tagToType(tag);
const casted = cmd.cast(CommandStruct).?; const casted = cmd.cast(CommandStruct).?;
@ -10,10 +22,10 @@ pub fn printCommand(cmd: langs.Command, comptime tag: langs.Command.Tag) !void {
else => true, else => true,
}; };
const ctype = typ.command_type; const ctype = CommandStruct.command_type;
switch (ctype) { switch (ctype) {
.lv2_command => try printLV2Command(casted), .lv2_command => try printCommandWithParams(stream, casted),
.custom_command => try printCustomCommand(casted), .custom_command => try printCommandWithParams(stream, casted),
else => @panic("TODO support command type"), else => @panic("TODO support command type"),
} }
} }
@ -25,48 +37,52 @@ pub fn printList(list: langs.CommandList, stream: var) !void {
switch (cmd.tag) { switch (cmd.tag) {
.load => { .load => {
const load = command.cast(langs.Command.Load).?; const load = cmd.cast(langs.Command.Load).?;
try stream.print("{}", .{load.path}); try stream.print(" {}", .{load.path});
}, },
.quicksave => {}, .runqs => {
const runqs = cmd.cast(langs.Command.RunQS).?;
try stream.print(" {}", .{runqs.program});
},
.noop, .quicksave => {},
.rotate => { .rotate => {
const rotate = command.cast(langs.Command.Rotate).?; const rotate = cmd.cast(langs.Command.Rotate).?;
try stream.print("{} {}", .{ rotate.deg, rotate.bgfill }); try stream.print(" {d} {}", .{ rotate.deg, rotate.bgfill });
}, },
.amp => try printCommand(cmd, .amp), .amp => try printCommand(stream, cmd, .amp),
.rflanger => try printCommand(cmd, .rflanger), .rflanger => try printCommand(stream, cmd, .rflanger),
.eq => try printCommand(cmd, .eq), .eq => try printCommand(stream, cmd, .eq),
.phaser => try printCommand(cmd, .phaser), .phaser => try printCommand(stream, cmd, .phaser),
.mbeq => try printCommand(cmd, .mbeq), .mbeq => try printCommand(stream, cmd, .mbeq),
.chorus => try printCommand(cmd, .chorus), .chorus => try printCommand(stream, cmd, .chorus),
.pitchscaler => try printCommand(cmd, .pitchscaler), .pitchscaler => try printCommand(stream, cmd, .pitchscaler),
.reverb => try printCommand(cmd, .reverb), .reverb => try printCommand(stream, cmd, .reverb),
.highpass => try printCommand(cmd, .highpass), .highpass => try printCommand(stream, cmd, .highpass),
.delay => try printCommand(cmd, .delay), .delay => try printCommand(stream, cmd, .delay),
.vinyl => try printCommand(cmd, .vinyl), .vinyl => try printCommand(stream, cmd, .vinyl),
.revdelay => try printCommand(cmd, .revdelay), .revdelay => try printCommand(stream, cmd, .revdelay),
.gate => try printCommand(cmd, .gate), .gate => try printCommand(stream, cmd, .gate),
.detune => try printCommand(cmd, .detune), .detune => try printCommand(stream, cmd, .detune),
.overdrive => try printCommand(cmd, .overdrive), .overdrive => try printCommand(stream, cmd, .overdrive),
.degrade => try printCommand(cmd, .degrade), .degrade => try printCommand(stream, cmd, .degrade),
.repsycho => try printCommand(cmd, .repsycho), .repsycho => try printCommand(stream, cmd, .repsycho),
.talkbox => try printCommand(cmd, .talkbox), .talkbox => try printCommand(stream, cmd, .talkbox),
.dyncomp => try printCommand(cmd, .dyncomp), .dyncomp => try printCommand(stream, cmd, .dyncomp),
.thruzero => try printCommand(cmd, .thruzero), .thruzero => try printCommand(stream, cmd, .thruzero),
.foverdrive => try printCommand(cmd, .foverdrive), .foverdrive => try printCommand(stream, cmd, .foverdrive),
.gverb => try printCommand(cmd, .gverb), .gverb => try printCommand(stream, cmd, .gverb),
.invert => try printCommand(cmd, .invert), .invert => try printCommand(stream, cmd, .invert),
.tapedelay => try printCommand(cmd, .tapedelay), .tapedelay => try printCommand(stream, cmd, .tapedelay),
.moddelay => try printCommand(cmd, .moddelay), .moddelay => try printCommand(stream, cmd, .moddelay),
.multichorus => try printCommand(cmd, .multichorus), .multichorus => try printCommand(stream, cmd, .multichorus),
.saturator => try printCommand(cmd, .saturator), .saturator => try printCommand(stream, cmd, .saturator),
.vintagedelay => try printCommand(cmd, .vintagedelay), .vintagedelay => try printCommand(stream, cmd, .vintagedelay),
.noise => try printCommand(cmd, .noise), .noise => try printCommand(stream, cmd, .noise),
.wildnoise => try printCommand(cmd, .wildnoise), .wildnoise => try printCommand(stream, cmd, .wildnoise),
.write => try printCommand(cmd, .write), .write => try printCommand(stream, cmd, .write),
.embed => try printCommand(cmd, .embed), .embed => try printCommand(stream, cmd, .embed),
} }
_ = try stream.write(";\n"); _ = try stream.write(";\n");

View file

@ -175,18 +175,19 @@ pub const Runner = struct {
try image.saveTo(out_path); try image.saveTo(out_path);
} }
fn runQSCmd(self: *Runner, program: []const u8) !void { fn runQSCmd(self: *Runner, cmd: lang.Command) !void {
const runqs = cmd.cast(lang.Command.RunQS).?;
var image = try self.getImage(); var image = try self.getImage();
const out_path = try self.makeGlitchedPath(); const out_path = try self.makeGlitchedPath();
try image.saveTo(out_path); try image.saveTo(out_path);
var proc = try std.ChildProcess.init( var proc = try std.ChildProcess.init(
&[_][]const u8{ program, out_path }, &[_][]const u8{ runqs.program, out_path },
self.allocator, self.allocator,
); );
defer proc.deinit(); defer proc.deinit();
std.debug.warn("running '{} {}'\n", .{ program, out_path }); std.debug.warn("running '{} {}'\n", .{ runqs.program, out_path });
_ = try proc.spawnAndWait(); _ = try proc.spawnAndWait();
} }
@ -249,12 +250,14 @@ pub const Runner = struct {
fn runCommand(self: *@This(), cmd: lang.Command) !void { fn runCommand(self: *@This(), cmd: lang.Command) !void {
switch (cmd.tag) { switch (cmd.tag) {
.noop => {},
.load => { .load => {
const command = cmd.cast(lang.Command.Load).?; const command = cmd.cast(lang.Command.Load).?;
try self.loadCmd(command.path); try self.loadCmd(command.path);
}, },
.quicksave => try self.quicksaveCmd(), .quicksave => try self.quicksaveCmd(),
.rotate => try self.rotateCmd(cmd), .rotate => try self.rotateCmd(cmd),
.runqs => try self.runQSCmd(cmd),
.amp => try self.runSingleCommand(cmd, .amp), .amp => try self.runSingleCommand(cmd, .amp),
.rflanger => try self.runSingleCommand(cmd, .rflanger), .rflanger => try self.runSingleCommand(cmd, .rflanger),