guid/src/parser_test.zig

119 lines
3.6 KiB
Zig

const std = @import("std");
const mem = std.mem;
const warn = std.debug.warn;
const io = std.io;
const maxInt = std.math.maxInt;
const process = std.process;
const fs = std.fs;
const ast = @import("ast.zig");
const own_parser = @import("./parse.zig");
fn testParse(source: []const u8, allocator: *mem.Allocator) !void {
const stderr = io.getStdErr().outStream();
var tree = try own_parser.parse(allocator, source);
defer tree.deinit();
// for (tree.errors) |*parse_error| {
// const token = tree.token_locs[parse_error.loc()];
// const loc = tree.tokenLocation(0, parse_error.loc());
// try stderr.print("(memory buffer):{}:{}: error: ", .{ loc.line + 1, loc.column + 1 });
// try tree.renderError(parse_error, stderr);
// try stderr.print("\n{}\n", .{source[loc.line_start..loc.line_end]});
// {
// var i: usize = 0;
// while (i < loc.column) : (i += 1) {
// try stderr.writeAll(" ");
// }
// }
// {
// const caret_count = token.end - token.start;
// var i: usize = 0;
// while (i < caret_count) : (i += 1) {
// try stderr.writeAll("~");
// }
// }
// try stderr.writeAll("\n");
// }
// if (tree.errors.len != 0) {
// return error.ParseError;
// }
}
const Error = @TagType(ast.Error);
fn testError(source: []const u8, expected_errors: []const Error) !void {
const tree = try own_parser.parse(std.testing.allocator, source);
defer tree.deinit();
std.testing.expect(tree.errors.len == expected_errors.len);
for (expected_errors) |expected, i| {
std.testing.expect(expected == tree.errors[i]);
}
}
fn nextArg(args: [][]const u8, idx: *usize) ?[]const u8 {
if (idx.* >= args.len) return null;
defer idx.* += 1;
return args[idx.*];
}
pub fn get_file_size(path: []const u8) !u64 {
var file = try fs.cwd().openFile(path, .{});
defer file.close();
// Find the size of the file and create a buffer with this size.
var file_stat = try file.stat();
return file_stat.size;
}
pub fn parser_analyze() !void {
// 1. get an allocator.
// 2. get the file path.
// 3. get the file size, and allocate file_size+1 bytes.
// 4. get the content of the file.
// 5. perform the analyze, and print each element.
// Create an allocator, for the arguments and the file.
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = &arena.allocator;
var args = try process.argsAlloc(allocator);
defer process.argsFree(allocator, args);
// Get the file path.
var arg_idx: usize = 1; // Skipping the executable binary name.
const gui_file_path = nextArg(args, &arg_idx) orelse {
warn("Expected first argument to be path to gui file\n", .{});
return error.InvalidArgs;
};
// Get the file size.
const file_size = try get_file_size(gui_file_path);
// Get the file size and allocate memory.
const buffer = try allocator.alloc(u8, file_size + 1); // Last value will be a null-byte.
buffer[file_size] = 0;
const content = try fs.cwd().readFile(gui_file_path, buffer);
// print("file content is: {}", .{content}); // Working.
// Get the file size and allocate memory.
// const tokens = try getAllTokens(allocator, content);
// for(tokens.items) |token| {
// print("{s:20} => {}\n", .{@tagName(token.id), buffer[token.loc.start..token.loc.end]});
// }
try testParse(content, allocator);
}
pub fn main() !void {
try parser_analyze();
}