diff --git a/src/ast_printer.zig b/src/ast_printer.zig index b770f4e..2593619 100644 --- a/src/ast_printer.zig +++ b/src/ast_printer.zig @@ -9,28 +9,28 @@ const warn = std.debug.warn; fn printIdent(ident: usize) void { var i: usize = 0; while (i < ident) : (i += 1) { - std.debug.warn("\t"); + std.debug.warn("\t", .{}); } } -fn print(ident: usize, comptime fmt: []const u8, args: ...) void { +fn print(ident: usize, comptime fmt: []const u8, args: var) void { printIdent(ident); std.debug.warn(fmt, args); } fn printBlock(ident: usize, block: var, endNewline: bool) void { - std.debug.warn("(\n"); + std.debug.warn("(\n", .{}); for (block.toSlice()) |stmt| { printIdent(ident); printStmt(ident, stmt); - std.debug.warn("\n"); + std.debug.warn("\n", .{}); } if (endNewline) { - print(ident - 1, ")\n"); + print(ident - 1, ")\n", .{}); } else { - print(ident - 1, ")"); + print(ident - 1, ")", .{}); } } @@ -48,51 +48,47 @@ pub fn printNode(node: *Node, ident: usize) void { const typ = method.typ.lexeme; if (method.mutable) { - warn("(method mut {} {} {} {} ", vari, typ, name, ret_type); + warn("(method mut {} {} {} {} ", .{ vari, typ, name, ret_type }); } else { - warn("(method {} {} {} {} ", vari, typ, name, ret_type); + warn("(method {} {} {} {} ", .{ vari, typ, name, ret_type }); } } else { - warn("(fn {} {} (", name, ret_type); + warn("(fn {} {} (", .{ name, ret_type }); } for (decl.params.toSlice()) |param| { - warn("({} {}) ", param.name.lexeme, param.typ.lexeme); + warn("({} {}) ", .{ param.name.lexeme, param.typ.lexeme }); } printBlock(ident + 1, decl.body, false); - warn(")\n"); + warn(")\n", .{}); }, .ConstDecl => |consts| { - print(ident, "(const (\n"); + print(ident, "(const (\n", .{}); for (consts.toSlice()) |const_decl| { - print( - ident + 1, - "({} ", + print(ident + 1, "({} ", .{ const_decl.name.lexeme, - ); + }); printExpr(const_decl.expr); - std.debug.warn(")\n"); + std.debug.warn(")\n", .{}); } - print(ident, "))\n"); + print(ident, "))\n", .{}); }, .Enum => |decl| { - print(ident, "(enum {} (\n", decl.name.lexeme); + print(ident, "(enum {} (\n", .{decl.name.lexeme}); for (decl.fields.toSlice()) |field| { - print( - ident + 1, - "{}\n", + print(ident + 1, "{}\n", .{ field.lexeme, - ); + }); } - print(ident, "))\n"); + print(ident, "))\n", .{}); }, .Root => { @@ -104,129 +100,129 @@ pub fn printNode(node: *Node, ident: usize) void { .Stmt => |stmt| { printIdent(ident); printStmt(ident, stmt); - std.debug.warn("\n"); + std.debug.warn("\n", .{}); }, .Struct => |struc| { - print(ident, "(struct {} (\n", struc.name.lexeme); + print(ident, "(struct {} (\n", .{struc.name.lexeme}); for (struc.fields.toSlice()) |field| { printIdent(ident + 1); if (field.mutable) { - std.debug.warn("(mut "); + std.debug.warn("(mut ", .{}); } else { - std.debug.warn("("); + std.debug.warn("(", .{}); } if (field.public) { - std.debug.warn("pub "); + std.debug.warn("pub ", .{}); } if (field.mutable_outside) { - std.debug.warn("MUT_OUT "); + std.debug.warn("MUT_OUT ", .{}); } - std.debug.warn("{} {})\n", field.name.lexeme, field.typ.lexeme); + std.debug.warn("{} {})\n", .{ field.name.lexeme, field.typ.lexeme }); } - print(ident, "))\n"); + print(ident, "))\n", .{}); }, else => { - print(ident, "unknown node: {}\n", node); + print(ident, "unknown node: {}\n", .{node}); }, } } -fn parenthetize(name: []const u8, exprs: []*Expr) void { - std.debug.warn("({}", name); +fn parenthetize(name: []const u8, exprs: []*const Expr) void { + std.debug.warn("({}", .{name}); for (exprs) |expr| { - std.debug.warn(" "); + std.debug.warn(" ", .{}); printExpr(expr); } - std.debug.warn(")"); + std.debug.warn(")", .{}); } -pub fn printExpr(expr: *Expr) void { +pub fn printExpr(expr: *const Expr) void { switch (expr.*) { - .Binary => |binary| parenthetize(binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }), - .Logical => |binary| parenthetize(binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }), - .Unary => |unary| parenthetize(unary.op.lexeme, &[_]*Expr{unary.right}), - .Grouping => |expr_ptr| parenthetize("group", &[_]*Expr{expr_ptr}), + .Binary => |binary| parenthetize(binary.op.lexeme, &[_]*const Expr{ binary.left, binary.right }), + .Logical => |binary| parenthetize(binary.op.lexeme, &[_]*const Expr{ binary.left, binary.right }), + .Unary => |unary| parenthetize(unary.op.lexeme, &[_]*const Expr{unary.right}), + .Grouping => |expr_ptr| parenthetize("group", &[_]*const Expr{expr_ptr}), .Literal => |literal| { switch (literal) { - .Bool => |val| std.debug.warn("{}", val), - .Integer => |val| std.debug.warn("{}", val), - .Float => |val| std.debug.warn("{}", val), - .String => |val| std.debug.warn("'{}'", val), + .Bool => |val| std.debug.warn("{}", .{val}), + .Integer => |val| std.debug.warn("{}", .{val}), + .Float => |val| std.debug.warn("{}", .{val}), + .String => |val| std.debug.warn("'{}'", .{val}), .Array => |exprs| { parenthetize("array", exprs.toSlice()); }, - else => |typ| std.debug.warn("UnknownLiteral-{}", typ), + else => |typ| std.debug.warn("UnknownLiteral-{}", .{typ}), } }, - .Variable => |token| std.debug.warn("{}", token.lexeme), + .Variable => |token| std.debug.warn("{}", .{token.lexeme}), .VarDecl => |decl| { if (decl.mutable) { - std.debug.warn("(mut "); + std.debug.warn("(mut ", .{}); } else { - std.debug.warn("("); + std.debug.warn("(", .{}); } - std.debug.warn("let {} ", decl.assign.name.lexeme); + std.debug.warn("let {} ", .{decl.assign.name.lexeme}); printExpr(decl.assign.value); - std.debug.warn(")"); + std.debug.warn(")", .{}); }, .Assign => |assign| { - std.debug.warn("(set "); - std.debug.warn("{} ", assign.name.lexeme); + std.debug.warn("(set ", .{}); + std.debug.warn("{} ", .{assign.name.lexeme}); printExpr(assign.value); - std.debug.warn(")"); + std.debug.warn(")", .{}); }, .Call => |call| { - std.debug.warn("("); + std.debug.warn("(", .{}); printExpr(call.callee); for (call.arguments.toSlice()) |arg| { - std.debug.warn(" "); + std.debug.warn(" ", .{}); printExpr(arg); } - std.debug.warn(")"); + std.debug.warn(")", .{}); }, .Struct => |val| { - std.debug.warn("({} (", val.name.lexeme); + std.debug.warn("({} (", .{val.name.lexeme}); for (val.inits.toSlice()) |init| { - std.debug.warn(" ({} ", init.field.lexeme); + std.debug.warn(" ({} ", .{init.field.lexeme}); printExpr(init.expr); - std.debug.warn(")"); + std.debug.warn(")", .{}); } - std.debug.warn("))"); + std.debug.warn("))", .{}); }, .Get => |get| { - warn("("); + warn("(", .{}); printExpr(get.struc); - warn(".{})", get.name.lexeme); + warn("{}", .{get.name.lexeme}); }, .Set => |set| { - warn("(set "); + warn("(set ", .{}); printExpr(set.struc); - warn(" {} ", set.field.lexeme); + warn(" {} ", .{set.field.lexeme}); printExpr(set.value); - warn(")"); + warn(")", .{}); }, - else => std.debug.warn("UnknownExpr-{}", @tagName(expr.*)), + else => std.debug.warn("UnknownExpr-{}", .{@tagName(expr.*)}), } } @@ -236,53 +232,53 @@ pub fn printStmt(ident: usize, stmt: *Stmt) void { .Expr => |expr| printExpr(expr), .If => |ifstmt| { - std.debug.warn("(if "); + std.debug.warn("(if ", .{}); printExpr(ifstmt.condition); - std.debug.warn(" "); + std.debug.warn(" ", .{}); printBlock(ident + 1, ifstmt.then_branch, false); if (ifstmt.else_branch) |else_branch| { - std.debug.warn(" else "); + std.debug.warn(" else ", .{}); printBlock(ident + 1, else_branch, false); } - std.debug.warn(")\n"); + std.debug.warn(")\n", .{}); }, .Loop => |loop| { - std.debug.warn("(loop "); + std.debug.warn("(loop ", .{}); if (loop.condition) |cond| { printExpr(cond); } else { - std.debug.warn("true"); + std.debug.warn("true", .{}); } - std.debug.warn(" "); + std.debug.warn(" ", .{}); printBlock(ident + 1, loop.then_branch, false); - std.debug.warn(")\n"); + std.debug.warn(")\n", .{}); }, .For => |forstmt| { - std.debug.warn("(for "); + std.debug.warn("(for ", .{}); if (forstmt.index) |index| { - std.debug.warn("({} {}) ", index.lexeme, forstmt.value.lexeme); + std.debug.warn("({} {}) ", .{ index.lexeme, forstmt.value.lexeme }); } else { - std.debug.warn("{} ", forstmt.value.lexeme); + std.debug.warn("{} ", .{forstmt.value.lexeme}); } - std.debug.warn("{} ", forstmt.array.lexeme); + std.debug.warn("{} ", .{forstmt.array.lexeme}); printBlock(ident + 1, forstmt.block, false); - std.debug.warn(")\n"); + std.debug.warn(")\n", .{}); }, .Return => |ret| { - std.debug.warn("(return "); + std.debug.warn("(return ", .{}); printExpr(ret.value); - std.debug.warn(")\n"); + std.debug.warn(")\n", .{}); }, - else => std.debug.warn("UnknownStmt-{}", @tagName(stmt.*)), + else => std.debug.warn("UnknownStmt-{}", .{@tagName(stmt.*)}), } } diff --git a/src/errors.zig b/src/errors.zig index 201afb0..eb95d27 100644 --- a/src/errors.zig +++ b/src/errors.zig @@ -1,14 +1,14 @@ const std = @import("std"); pub fn report(line: usize, where: []const u8, message: []const u8) void { - std.debug.warn("[line {}] Error{}: {}", line, where, message); + std.debug.warn("[line {}] Error{}: {}", .{ line, where, message }); } pub fn reportN(line: usize, message: []const u8) void { report(line, "", message); } -pub fn reportFmt(line: usize, comptime fmt: []const u8, args: ...) void { - std.debug.warn("[line {}] Error", line); +pub fn reportFmt(line: usize, comptime fmt: []const u8, args: var) void { + std.debug.warn("[line {}] Error", .{line}); std.debug.warn(fmt, args); - std.debug.warn("\n"); + std.debug.warn("\n", .{}); } diff --git a/src/main.zig b/src/main.zig index 47e3a53..f2c6156 100644 --- a/src/main.zig +++ b/src/main.zig @@ -10,18 +10,16 @@ pub const Result = error{ CompileError, }; -pub const StdOut = *std.io.OutStream(std.fs.File.WriteError); - -fn run(allocator: *Allocator, data: []u8) !void { +fn run(allocator: *Allocator, data: []const u8) !void { var stdout_file = std.io.getStdOut(); - const stdout = &stdout_file.outStream().stream; + const stdout = stdout_file.outStream(); var runner = runners.Runner.init(allocator, stdout); return runner.execute(data); } fn runFile(allocator: *Allocator, path: []const u8) !void { - var file = try std.fs.File.openRead(path); + var file = try std.fs.cwd().openFile(path, .{}); defer file.close(); const total_bytes = try file.getEndPos(); @@ -40,25 +38,31 @@ fn runFile(allocator: *Allocator, path: []const u8) !void { fn runPrompt(allocator: *Allocator) !void { var stdout_file = std.io.getStdOut(); - const stdout = &stdout_file.outStream().stream; + const stdout = stdout_file.outStream(); + + var stdin_file = std.io.getStdIn(); + const stdin = stdin_file.inStream(); + + var line_buf: [1024]u8 = undefined; while (true) { - try stdout.print("> "); - var buffer = try std.Buffer.init(allocator, ""[0..]); + try stdout.print("> ", .{}); - var line = std.io.readLine(&buffer) catch |err| { - if (err == error.EndOfStream) return; - return err; - }; + const amt = try stdin.read(&line_buf); + if (amt == line_buf.len) { + try stdout.print("Input too long.\n", .{}); + continue; + } + const line = std.mem.trimRight(u8, line_buf[0..amt], "\r\n"); run(allocator, line) catch |err| { switch (err) { Result.Ok => {}, Result.ScannerError => blk: { - try stdout.print("scanner error.\n"); + try stdout.print("scanner error.\n", .{}); }, Result.CompileError => blk: { - try stdout.print("compile error.\n"); + try stdout.print("compile error.\n", .{}); }, else => return err, } @@ -67,12 +71,12 @@ fn runPrompt(allocator: *Allocator) !void { } pub fn main() anyerror!void { - var arena = std.heap.ArenaAllocator.init(std.heap.direct_allocator); + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); var allocator = &arena.allocator; var stdout_file = std.io.getStdOut(); - var stdout = &stdout_file.outStream().stream; + var stdout = stdout_file.outStream(); var args_it = std.process.args(); diff --git a/src/parser.zig b/src/parser.zig index 46976e2..818a540 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -43,27 +43,27 @@ pub const Parser = struct { self.tokens.deinit(); } - fn doError(self: *Parser, comptime fmt: []const u8, args: ...) void { + fn doError(self: *Parser, comptime fmt: []const u8, args: var) void { self.hadError = true; - std.debug.warn("parser error at line {}\n\t", self.scanner.line); + std.debug.warn("parser error at line {}\n\t", .{self.scanner.line}); std.debug.warn(fmt, args); - std.debug.warn("\n"); + std.debug.warn("\n", .{}); } fn peek(self: *Parser) Token { - return self.tokens.at(self.tokens.len - 1); + return self.tokens.items[self.tokens.items.len - 1]; } fn previous(self: *Parser) Token { - return self.tokens.at(self.tokens.len - 2); + return self.tokens.items[self.tokens.items.len - 2]; } fn tokenError(self: *Parser, token: Token, msg: []const u8) Result!void { if (token.ttype == .EOF) { err.report(token.line, " at end", msg); } else { - err.reportFmt(token.line, " at '{}': {}", token.lexeme, msg); + err.reportFmt(token.line, " at '{}': {}", .{ token.lexeme, msg }); } return Result.CompileError; @@ -90,7 +90,7 @@ pub const Parser = struct { } try self.tokens.append(token); - std.debug.warn("skip to {}\n", token); + std.debug.warn("skip to {}\n", .{token}); return token; } @@ -117,19 +117,17 @@ pub const Parser = struct { // TODO maybe this could be entirely comptime? var buf_main: [1000]u8 = undefined; - var buf = try std.fmt.bufPrint( - buf_main[0..], - "expected {}, got {}", + var buf = try std.fmt.bufPrint(buf_main[0..], "expected {}, got {}", .{ ttype, self.peek().ttype, - ); + }); try self.tokenError(self.peek(), buf); return Result.CompileError; } /// check() against multiple tokens - fn compareAnyOf(self: *@This(), ttypes: []TokenType) bool { + fn compareAnyOf(self: *@This(), ttypes: []const TokenType) bool { for (ttypes) |ttype| { if (self.check(ttype)) return true; } @@ -191,7 +189,7 @@ pub const Parser = struct { } fn mkUnary(self: *Parser, op: Token, right: *Expr) !*Expr { - std.debug.warn("Unary\n"); + std.debug.warn("Unary\n", .{}); var expr = try self.allocator.create(Expr); expr.* = Expr{ @@ -609,7 +607,7 @@ pub const Parser = struct { .Enum => try self.parseEnumDecl(), else => |ttype| blk: { - self.doError("expected Fn, Const, Struct, got {}\n", ttype); + self.doError("expected Fn, Const, Struct, got {}\n", .{ttype}); return Result.CompileError; }, }; @@ -839,7 +837,7 @@ pub const Parser = struct { .Get => |get| { switch (op.ttype) { .ColonEqual => { - self.doError("can not initialize struct field"); + self.doError("can not initialize struct field", .{}); return Result.CompileError; }, @@ -859,7 +857,7 @@ pub const Parser = struct { }, else => |expr_typ| { - self.doError("Invalid assignment target {}", expr_typ); + self.doError("Invalid assignment target {}", .{expr_typ}); return Result.CompileError; }, } @@ -1030,7 +1028,7 @@ pub const Parser = struct { // {a: 10 b: 10} // for this to work properly, must be Variable, since its a type. if (@as(ast.ExprType, expr.*) != .Variable) { - self.doError("Expected variable for struct type, got {}", @as(ast.ExprType, expr.*)); + self.doError("Expected variable for struct type, got {}", .{@as(ast.ExprType, expr.*)}); return Result.CompileError; } @@ -1095,7 +1093,7 @@ pub const Parser = struct { }, else => blk: { - self.doError("expected literal, got {}", curtype); + self.doError("expected literal, got {}", .{curtype}); return Result.CompileError; }, }; diff --git a/src/runner.zig b/src/runner.zig index 9c9f0f5..49b0dd4 100644 --- a/src/runner.zig +++ b/src/runner.zig @@ -13,32 +13,31 @@ const Parser = parsers.Parser; pub const Runner = struct { allocator: *Allocator, - stdout: main.StdOut, + stdout: std.fs.File.OutStream, - pub fn init(allocator: *Allocator, stdout: main.StdOut) Runner { - return Runner{ .allocator = allocator, .stdout = stdout }; + pub fn init(allocator: *Allocator, stdout: var) Runner { + return .{ .allocator = allocator, .stdout = stdout }; } fn testScanner(self: *Runner, scanner: *scanners.Scanner) !void { while (true) { var tok_opt = scanner.nextToken() catch |err| { - try self.stdout.print( - "error at '{}': {}\n", + try self.stdout.print("error at '{}': {}\n", .{ scanner.currentLexeme(), err, - ); + }); return Result.ScannerError; }; if (tok_opt) |tok| { if (tok.ttype == .EOF) break; - try self.stdout.print("{x}\n", tok); + try self.stdout.print("{x}\n", .{tok}); } } } - pub fn execute(self: *Runner, code: []u8) !void { + pub fn execute(self: *Runner, code: []const u8) !void { var scanner = scanners.Scanner.init(self.allocator, code); try self.testScanner(&scanner); @@ -46,9 +45,9 @@ pub const Runner = struct { var parser = Parser.init(self.allocator, &scanner); var root = try parser.parse(); - var it = root.Root.iterator(); + // var it = root.Root.iterator(); - std.debug.warn("parse tree\n"); + std.debug.warn("parse tree\n", .{}); printer.printNode(root, 0); return Result.Ok; diff --git a/src/scanner.zig b/src/scanner.zig index 0261a7a..907dd48 100644 --- a/src/scanner.zig +++ b/src/scanner.zig @@ -97,13 +97,13 @@ fn getKeyword(keyword: []const u8) ?TokenType { /// Scanner for vlang tokens. pub const Scanner = struct { allocator: *Allocator, - source: []u8, + source: []const u8, start: usize = 0, current: usize = 0, line: usize = 1, - pub fn init(allocator: *Allocator, source: []u8) Scanner { + pub fn init(allocator: *Allocator, source: []const u8) Scanner { return Scanner{ .allocator = allocator, .source = source }; }