diff --git a/examples/hello.ry b/examples/hello.ry index 8c6d510..1bf8dba 100644 --- a/examples/hello.ry +++ b/examples/hello.ry @@ -1,4 +1,4 @@ -// import std; +import std; fn add(a: i32, b: i32) i32 { return a + b; diff --git a/src/errors.zig b/src/errors.zig index 9043f2e..c7e9c2b 100644 --- a/src/errors.zig +++ b/src/errors.zig @@ -1,24 +1,15 @@ const std = @import("std"); -pub fn report(line: usize, where: []const u8, ctx_opt: ?[]const u8, message: []const u8) void { - if (ctx_opt) |ctx| { - std.debug.warn("[line {}] Error{} on {}: {}", line, where, ctx, message); - } else { - std.debug.warn("[line {}] Error{}: {}", line, where, message); - } +pub fn report(line: usize, where: []const u8, message: []const u8) void { + 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, ctx_opt: ?[]const u8, comptime fmt: []const u8, args: ...) void { - if (ctx_opt) |ctx| { - std.debug.warn("[line {}] Error on {}", line, ctx); - } else { - std.debug.warn("[line {}] Error", line); - } - +pub fn reportFmt(line: usize, comptime fmt: []const u8, args: ...) void { + std.debug.warn("[line {}] Error", line); std.debug.warn(fmt, args); std.debug.warn("\n"); } diff --git a/src/main.zig b/src/main.zig index cf09d7c..f17f242 100644 --- a/src/main.zig +++ b/src/main.zig @@ -38,12 +38,10 @@ pub fn run(allocator: *std.mem.Allocator, slice: []const u8) !Result { var parser = parsers.Parser.init(allocator, &scan); var root = try parser.parse(); - if (root == null) { - return Result.ParseError; - } + var it = root.Root.iterator(); std.debug.warn("parse tree\n"); - printer.printNode(root.?, 0); + //printer.printNode(root, 0); return Result.Ok; } diff --git a/src/parsers.zig b/src/parsers.zig index bb8e873..1b25957 100644 --- a/src/parsers.zig +++ b/src/parsers.zig @@ -3,7 +3,7 @@ const scanners = @import("scanners.zig"); const main = @import("main.zig"); const ast = @import("ast.zig"); const tokens = @import("tokens.zig"); -const ereport = @import("errors.zig"); +const err = @import("errors.zig"); const printer = @import("ast_printer.zig"); const Allocator = std.mem.Allocator; @@ -31,7 +31,6 @@ pub const Parser = struct { tokens: TokenList, hadError: bool = false, - err_ctx: ?[]const u8 = null, pub fn init(allocator: *Allocator, scanner: *Scanner) Parser { return Parser{ @@ -45,47 +44,12 @@ pub const Parser = struct { self.tokens.deinit(); } - fn setErrContext(self: *Parser, comptime fmt: ?[]const u8, args: ...) void { - if (fmt == null) { - self.err_ctx = null; - return; - } - - var buf = self.allocator.alloc(u8, 256) catch unreachable; - self.err_ctx = std.fmt.bufPrint(buf, fmt.?, args) catch unreachable; - } - - fn doError(self: *Parser, comptime fmt: []const u8, args: ...) ParseError { + fn doError(self: *Parser, comptime fmt: []const u8, args: ...) void { self.hadError = true; - std.debug.warn("parser error at line {}", self.scanner.line); - if (self.err_ctx) |ctx| { - std.debug.warn(" on {}", ctx); - } - - std.debug.warn("\n\t"); - + std.debug.warn("parser error at line {}\n\t", self.scanner.line); std.debug.warn(fmt, args); std.debug.warn("\n"); - - return ParseError.CompileError; - } - - fn synchronize(self: *Parser) !void { - // TODO is it nextToken()? - _ = try self.nextToken(); - - while (!self.isAtEnd()) { - if (self.previous().typ == .Semicolon) return; - - // TODO add more "stmt"-"starting" tokens here - switch (self.peek().typ) { - .Fn => return, - else => {}, - } - - _ = try self.nextToken(); - } } fn peek(self: *Parser) Token { @@ -96,12 +60,11 @@ pub const Parser = struct { return self.tokens.at(self.tokens.len - 2); } - fn tokenError(self: *Parser, token: Token, msg: []const u8) ParseError { - std.debug.warn("ctx: '{}'\n", self.err_ctx); + fn tokenError(self: *Parser, token: Token, msg: []const u8) ParseError!void { if (token.typ == .EOF) { - ereport.report(token.line, " at end", self.err_ctx, msg); + err.report(token.line, " at end", msg); } else { - ereport.reportFmt(token.line, self.err_ctx, " at '{}': {}", token.lexeme, msg); + err.reportFmt(token.line, " at '{}': {}", token.lexeme, msg); } return ParseError.CompileError; @@ -141,7 +104,8 @@ pub const Parser = struct { return tok; } - return self.tokenError(self.peek(), msg); + try self.tokenError(self.peek(), msg); + return ParseError.CompileError; } /// Consume the current token. Gives default error messages @@ -161,7 +125,8 @@ pub const Parser = struct { self.peek().typ, ); - return self.tokenError(self.peek(), buf); + try self.tokenError(self.peek(), buf); + return ParseError.CompileError; } /// check() against multiple tokens @@ -404,7 +369,7 @@ pub const Parser = struct { return expr; } - pub fn parse(self: *Parser) !?*ast.Node { + pub fn parse(self: *Parser) !*ast.Node { var root = try Node.mkRoot(self.allocator); var token_opt: ?Token = null; @@ -419,10 +384,7 @@ pub const Parser = struct { var token = token_opt.?; if (token.typ == .EOF) break; - var node = self.parseTopDecl() catch |err| { - if (err == ParseError.CompileError) return null; - return err; - }; + var node = try self.parseTopDecl(); try root.Root.append(node.*); } @@ -457,8 +419,6 @@ pub const Parser = struct { const name = try self.consumeSingle(.Identifier); - self.setErrContext("function {}", name.lexeme); - _ = try self.consumeSingle(.LeftParen); while (self.peek().typ != .RightParen) { @@ -643,8 +603,6 @@ pub const Parser = struct { } fn parseTopDecl(self: *@This()) !*Node { - self.setErrContext(null); - return switch (self.peek().typ) { .Fn => try self.parseFnDecl(), .Const => try self.parseConstDecl(), @@ -652,7 +610,8 @@ pub const Parser = struct { .Enum => try self.parseEnumDecl(), else => |typ| blk: { - return self.doError("expected Fn, Const, Struct, got {}\n", typ); + self.doError("expected Fn, Const, Struct, got {}\n", typ); + return ParseError.CompileError; }, }; } @@ -881,7 +840,8 @@ pub const Parser = struct { .Get => |get| { switch (op.typ) { .ColonEqual => { - return self.doError("can not initialize struct field"); + self.doError("can not initialize struct field"); + return ParseError.CompileError; }, .Equal => return try self.mkSet(get.struc, get.name, value), @@ -900,7 +860,8 @@ pub const Parser = struct { }, else => |expr_typ| { - return self.doError("Invalid assignment target {}", expr_typ); + self.doError("Invalid assignment target {}", expr_typ); + return ParseError.CompileError; }, } } @@ -1036,7 +997,7 @@ pub const Parser = struct { expr = try self.mkGet(expr, name); } } else { - return self.tokenError(self.peek(), "Expect expression."); + break; } } @@ -1070,7 +1031,8 @@ pub const Parser = struct { // {a: 10 b: 10} // for this to work properly, must be Variable, since its a type. if (ast.ExprType(expr.*) != .Variable) { - return self.doError("Expected variable for struct type, got {}", ast.ExprType(expr.*)); + self.doError("Expected variable for struct type, got {}", ast.ExprType(expr.*)); + return ParseError.CompileError; } var inits = ast.StructInitList.init(self.allocator); @@ -1134,7 +1096,8 @@ pub const Parser = struct { }, else => blk: { - return self.doError("expected literal, got {}", curtype); + self.doError("expected literal, got {}", curtype); + return ParseError.CompileError; }, };