Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .zigversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.14.1
0.15.2
15 changes: 5 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,19 @@ main source of knowledge: https://matklad.github.io/2020/04/13/simple-but-powerf

### Run locally
```bash
zig run parser.zig
zig build run -- --help
```

### Run tests
```bash
zig test parser.zig
zig build test
```

### Build WASM and run web interface
```bash
zig build wasm
cp zig-out/bin/parser.wasm .
python -m http.server 8081
cd assets
cp ../zig-out/bin/parser.wasm .
python3 -m http.server 8081
```
Then open `http://localhost:8081`

## Files

- `parser.zig` - Main parser with stdout
- `wasm.zig` - Same as the previous one, but this is the WASM version with JSON output
- `index.html`, `style.css`, `script.js` - Web interface
File renamed without changes.
Binary file added assets/parser.wasm
Binary file not shown.
File renamed without changes.
File renamed without changes.
124 changes: 115 additions & 9 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
const std = @import("std");

pub fn build(b: *std.Build) void {
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const tex_mod = b.addModule("tex", .{
.root_source_file = b.path("src/root.zig"),
.target = target,
.optimize = optimize,
});

const tex_lib = b.addLibrary(.{
.name = "tex",
.root_module = tex_mod,
.linkage = .static,
});
b.installArtifact(tex_lib);

const exe_mod = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
exe_mod.addImport("tex", tex_mod);

// Create the executable
const exe = b.addExecutable(.{
.name = "parser",
.root_module = b.createModule(.{
.root_source_file = b.path("parser.zig"),
.target = target,
.optimize = optimize,
}),
.name = "zig-tex",
.root_module = exe_mod,
});

b.installArtifact(exe);
Expand All @@ -25,7 +41,7 @@ pub fn build(b: *std.Build) void {
const wasm_lib = b.addExecutable(.{
.name = "parser",
.root_module = b.createModule(.{
.root_source_file = b.path("wasm.zig"),
.root_source_file = b.path("src/wasm.zig"),
.target = wasm_target,
.optimize = optimize,
}),
Expand All @@ -50,7 +66,7 @@ pub fn build(b: *std.Build) void {
// Create the test executable
const exe_unit_tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("parser.zig"),
.root_source_file = b.path("src/parser.zig"),
.target = target,
.optimize = optimize,
}),
Expand All @@ -60,4 +76,94 @@ pub fn build(b: *std.Build) void {

const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_exe_unit_tests.step);
try setupSnapshotTesting(b, target, exe);
}

fn setupSnapshotTesting(
b: *std.Build,
target: std.Build.ResolvedTarget,
zemml_exe: *std.Build.Step.Compile,
) !void {
var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_allocator.deinit();

const test_step = b.step("test-snapshots", "build snapshot tests and diff the results");

const camera = b.addExecutable(.{
.name = "camera",
.root_module = b.createModule(.{
.root_source_file = b.path("src/build/camera.zig"),
.target = target,
.optimize = .ReleaseFast,
}),
});

const diff = b.addSystemCommand(&.{
"git",
"diff",
"--cached",
"--exit-code",
});
diff.addDirectoryArg(b.path("tests"));
diff.setName("git diff tests/");
test_step.dependOn(&diff.step);

// We need to stage all of tests/ in order for untracked files to show up in
// the diff. It's also not a bad automatism since it avoids the problem of
// forgetting to stage new snapshot files.
const git_add = b.addSystemCommand(&.{ "git", "add" });
git_add.addDirectoryArg(b.path("tests/"));
git_add.setName("git add tests/");
diff.step.dependOn(&git_add.step);

try setupSnapshotTestFolder(
&arena_allocator,
b,
camera,
zemml_exe,
git_add,
"tests/parse_ast",
"--format=ast",
);
}

fn setupSnapshotTestFolder(
arena: *std.heap.ArenaAllocator,
b: *std.Build,
camera: *std.Build.Step.Compile,
zemml_exe: *std.Build.Step.Compile,
git_add: *std.Build.Step.Run,
test_path: []const u8,
format_arg: []const u8,
) !void {
const tests_dir = try b.build_root.handle.openDir(test_path, .{
.iterate = true,
});

var it = tests_dir.iterateAssumeFirstIteration();
while (try it.next()) |entry| {
if (entry.kind != .file) continue;
const src_path = b.pathJoin(&.{ test_path, entry.name });

_ = arena.reset(.retain_capacity);

const snap_name = try std.fmt.allocPrint(arena.allocator(), "{s}.snapshot.txt", .{entry.name});
const snap_path = b.pathJoin(&.{ test_path, "snapshots", snap_name });
const input_arg = try std.fmt.allocPrint(arena.allocator(), "--input={s}", .{src_path});
// const output_arg = try std.fmt.allocPrint(arena.allocator(), "--output={s}", .{snap_path});

const run_camera = b.addRunArtifact(camera);
run_camera.addArtifactArg(zemml_exe);
run_camera.addArg(input_arg);
run_camera.addArg(format_arg);
// run_camera.addArg(output_arg);
run_camera.has_side_effects = true;

const stdout = run_camera.captureStdErr();
const update_snap = b.addUpdateSourceFiles();
update_snap.addCopyFileToSource(stdout, snap_path);

update_snap.step.dependOn(&run_camera.step);
git_add.step.dependOn(&update_snap.step);
}
}
24 changes: 24 additions & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.{
// This is the default name used by packages depending on this one. For
// example, when a user runs `zig fetch --save <url>`, this field is used
// as the key in the `dependencies` table. Although the user can choose a
// different name, most users will stick with this provided value.
//
// It is redundant to include "zig" in this name because it is already
// within the Zig package namespace.
.name = .tex,
// This is a [Semantic Version](https://semver.org/).
// In a future version of Zig it will be used for package deduplication.
.version = "0.0.0",
.fingerprint = 0xeaed7f72a51b943e, // Changing this has security and trust implications.
.minimum_zig_version = "0.15.2",
.dependencies = .{},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
// For example...
//"LICENSE",
//"README.md",
},
}
Binary file removed parser.wasm
Binary file not shown.
Loading