diff --git a/src/analysis.zig b/src/analysis.zig index 1169761..bc35d32 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -25,7 +25,7 @@ pub const Analyzer = struct { }; } - fn setErrContext(self: *@This(), comptime fmt: ?[]const u8, args: anytype) void { + fn setErrContext(self: *@This(), comptime fmt: ?[]const u8, args: var) void { if (fmt == null) { self.err_ctx = null; return; @@ -42,7 +42,7 @@ pub const Analyzer = struct { self.err_tok = tok; } - fn doError(self: *@This(), comptime fmt: []const u8, args: anytype) void { + fn doError(self: *@This(), comptime fmt: []const u8, args: var) void { self.hadError = true; std.debug.warn("analysis error", .{}); @@ -80,14 +80,14 @@ pub const Analyzer = struct { return null; } - return switch (sym.?.*) { + return switch (sym.?.value.*) { .Struct => SymbolUnderlyingType{ .Struct = val }, .Enum => SymbolUnderlyingType{ .Enum = val }, else => blk: { self.doError("expected struct or enum for '{}', got {}", .{ val, - @tagName(@as(comp.SymbolType, sym.?.*)), + @tagName(@as(comp.SymbolType, sym.?.value.*)), }); break :blk null; }, @@ -257,8 +257,8 @@ pub const Analyzer = struct { var symbol = try ctx.fetchGlobalSymbol(func_name, .Function); var func_sym = symbol.Function; - for (call.arguments.items) |arg_expr, idx| { - var param_type = func_sym.parameter_list.items[idx]; + for (call.arguments.toSlice()) |arg_expr, idx| { + var param_type = func_sym.parameter_list.at(idx); var arg_type = try self.resolveExprType(ctx, &arg_expr); self.expectSymUnTypeEqual(arg_type, param_type) catch { @@ -314,7 +314,7 @@ pub const Analyzer = struct { .Enum => |enum_identifier| { // fetch an enum off symbol table, then we use the // identifier map to ensure get.name exists in the enum - var map = ctx.symbol_table.get(enum_identifier).?.Enum; + var map = ctx.symbol_table.get(enum_identifier).?.value.Enum; const name = get.name.lexeme; var kv = map.get(name); @@ -355,8 +355,8 @@ pub const Analyzer = struct { } var value_type = try self.resolveExprType(ctx, assign.value); - try self.expectSymUnTypeEqual(var_type.?, value_type); - return var_type.?; + try self.expectSymUnTypeEqual(var_type.?.value, value_type); + return var_type.?.value; }, .Set => @panic("TODO analysis of Set exprs"), @@ -411,7 +411,7 @@ pub const Analyzer = struct { try ctx.bumpScope("if_then"); - for (ifstmt.then_branch.items) |then_stmt| { + for (ifstmt.then_branch.toSlice()) |then_stmt| { try self.stmtPass(ctx, then_stmt); } @@ -421,7 +421,7 @@ pub const Analyzer = struct { try ctx.bumpScope("if_else"); defer ctx.dumpScope(); - for (else_branch.items) |else_stmt| { + for (else_branch.toSlice()) |else_stmt| { try self.stmtPass(ctx, else_stmt); } } @@ -437,7 +437,7 @@ pub const Analyzer = struct { try ctx.bumpScope("loop"); - for (loop.then_branch.items) |then_stmt| { + for (loop.then_branch.toSlice()) |then_stmt| { try self.stmtPass(ctx, then_stmt); } @@ -476,7 +476,7 @@ pub const Analyzer = struct { }); var parameters = comp.TypeList.init(self.allocator); - for (decl.params.items) |param| { + for (decl.params.toSlice()) |param| { var param_type = self.resolveGlobalType(ctx, param.typ.lexeme); if (param_type == null) continue; try parameters.append(param_type.?); @@ -490,14 +490,14 @@ pub const Analyzer = struct { // we intentionally insert the function so that: // - we can do return statement validation // - we have parameter types fully analyzed - if (ret_type != null and parameters.items.len == decl.params.items.len) { + if (ret_type != null and parameters.len == decl.params.len) { try ctx.insertFn(decl, ret_type.?, parameters, scope); } else { if (ret_type != null) self.doError("Return type was not fully resolved", .{}); - if (parameters.items.len != decl.params.items.len) - self.doError("Fully analyzed {} parameters, wanted {}", .{ parameters.items.len, decl.params.items.len }); + if (parameters.len != decl.params.len) + self.doError("Fully analyzed {} parameters, wanted {}", .{ parameters.len, decl.params.len }); return CompileError.TypeError; } @@ -507,7 +507,7 @@ pub const Analyzer = struct { std.debug.assert(ctx.current_scope == null); ctx.setScope(scope); - for (decl.body.items) |stmt| { + for (decl.body.toSlice()) |stmt| { try self.stmtPass(ctx, stmt); } @@ -522,7 +522,7 @@ pub const Analyzer = struct { var types = comp.TypeList.init(self.allocator); - for (struc.fields.items) |field| { + for (struc.fields.toSlice()) |field| { self.setErrToken(field.name); var field_type = self.resolveGlobalType(ctx, field.typ.lexeme); if (field_type == null) continue; @@ -534,7 +534,7 @@ pub const Analyzer = struct { // we don't return type errors from the main loop so we can // keep going and find more type errors - if (types.items.len == struc.fields.items.len) + if (types.len == struc.fields.len) try ctx.insertStruct(struc, types); }, @@ -547,7 +547,7 @@ pub const Analyzer = struct { }, .ConstDecl => |constlist| { - for (constlist.items) |constdecl| { + for (constlist.toSlice()) |constdecl| { self.setErrToken(constdecl.name); self.setErrContext("const {}", .{constdecl.name.lexeme}); @@ -566,7 +566,7 @@ pub const Analyzer = struct { pub fn pass(self: *@This(), root: *ast.Node) !comp.CompilationContext { var ctx = comp.CompilationContext.init(self.allocator); - var slice = root.Root.items; + var slice = root.Root.toSlice(); for (slice) |_, idx| { try self.nodePass(&ctx, &slice[idx]); } diff --git a/src/ast_printer.zig b/src/ast_printer.zig index 69d7629..328f880 100644 --- a/src/ast_printer.zig +++ b/src/ast_printer.zig @@ -14,15 +14,15 @@ fn printIdent(ident: usize) void { } } -fn print(ident: usize, comptime fmt: []const u8, args: anytype) void { +fn print(ident: usize, comptime fmt: []const u8, args: var) void { printIdent(ident); std.debug.warn(fmt, args); } -fn printBlock(ident: usize, block: anytype, endNewline: bool) void { +fn printBlock(ident: usize, block: var, endNewline: bool) void { std.debug.warn("(\n", .{}); - for (block.items) |stmt| { + for (block.toSlice()) |stmt| { printIdent(ident); printStmt(ident, &stmt); std.debug.warn("\n", .{}); @@ -53,7 +53,7 @@ pub fn printNode(node: *const Node, ident: usize) void { warn("(fn {} {} (", .{ name, ret_type }); } - for (decl.params.items) |param| { + for (decl.params.toSlice()) |param| { warn(" ({} {})", .{ param.name.lexeme, param.typ.lexeme }); } warn(") ", .{}); @@ -65,7 +65,7 @@ pub fn printNode(node: *const Node, ident: usize) void { .ConstDecl => |consts| { print(ident, "(const (\n", .{}); - for (consts.items) |const_decl| { + for (consts.toSlice()) |const_decl| { print(ident + 1, "({} ", .{ const_decl.name.lexeme, }); @@ -80,7 +80,7 @@ pub fn printNode(node: *const Node, ident: usize) void { .Enum => |decl| { print(ident, "(enum {} (\n", .{decl.name.lexeme}); - for (decl.fields.items) |field| { + for (decl.fields.toSlice()) |field| { print(ident + 1, "{}\n", .{ field.lexeme, }); @@ -90,14 +90,14 @@ pub fn printNode(node: *const Node, ident: usize) void { }, .Root => { - for (node.Root.items) |child| { + for (node.Root.toSlice()) |child| { printNode(&child, ident + 1); } }, .Struct => |struc| { print(ident, "(struct {} (\n", .{struc.name.lexeme}); - for (struc.fields.items) |field| { + for (struc.fields.toSlice()) |field| { print(ident + 1, "({} {})\n", .{ field.name.lexeme, field.typ.lexeme }); } print(ident, "))\n", .{}); @@ -156,7 +156,7 @@ fn binOpToStr(op: BinaryOperator) ?[]const u8 { return null; } -fn printBinOp(inner: anytype) void { +fn printBinOp(inner: var) void { std.debug.warn("({}", .{binOpToStr(inner.op)}); printTwoExprs(inner.left, inner.right); std.debug.warn(")", .{}); @@ -203,7 +203,7 @@ pub fn printExpr(expr: *const Expr) void { .Float => |val| std.debug.warn("{}", .{val}), .String => |val| std.debug.warn("'{}'", .{val}), .Array => |exprs| { - parenthetize("array", exprs.items); + parenthetize("array", exprs.toSlice()); }, else => |typ| std.debug.warn("UnknownLiteral-{}", .{typ}), } @@ -222,7 +222,7 @@ pub fn printExpr(expr: *const Expr) void { std.debug.warn("(", .{}); printExpr(call.callee); - for (call.arguments.items) |arg| { + for (call.arguments.toSlice()) |arg| { std.debug.warn(" ", .{}); printExpr(&arg); } @@ -233,7 +233,7 @@ pub fn printExpr(expr: *const Expr) void { .Struct => |val| { std.debug.warn("({} (", .{val.name.lexeme}); - for (val.inits.items) |init| { + for (val.inits.toSlice()) |init| { std.debug.warn(" ({} ", .{init.field.lexeme}); printExpr(init.expr); std.debug.warn(")", .{}); @@ -345,11 +345,12 @@ fn prettyType(typ: SymbolUnderlyingType) []const u8 { pub fn printScope(scope: *Scope, ident: usize) void { print(ident, "scope '{}' at addr {}\n", .{ scope.id, @ptrToInt(scope) }); - for (scope.env.items()) |entry| { - print(ident + 1, "sym: {}, typ: {}\n", .{ entry.key, prettyType(entry.value) }); + var it = scope.env.iterator(); + while (it.next()) |kv| { + print(ident + 1, "sym: {}, typ: {}\n", .{ kv.key, prettyType(kv.value) }); } - for (scope.children.items) |child| { + for (scope.children.toSlice()) |child| { printScope(child, ident + 1); } } @@ -365,11 +366,11 @@ pub fn printContext(ctx: CompilationContext) void { prettyType(fn_sym.return_type), }); - for (fn_sym.decl.params.items) |param| { - var actual_param = fn_sym.parameters.get(param.name.lexeme).?; + for (fn_sym.decl.params.toSlice()) |param| { + var param_kv = fn_sym.parameters.get(param.name.lexeme).?; std.debug.warn("\tparameter {} typ {}\n", .{ - param.name.lexeme, - prettyType(actual_param.typ), + param_kv.key, + prettyType(param_kv.value.typ), }); } diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index f0894fb..ff2d6f6 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -46,7 +46,7 @@ pub const Codegen = struct { }, .Struct, .Enum => |lex| blk: { - var sym_data = self.ctx.symbol_table.get(lex).?; + var sym_data = self.ctx.symbol_table.get(lex).?.value; break :blk switch (sym_data.*) { .Struct => unreachable, .Enum => llvm.LLVMInt32Type(), @@ -64,8 +64,8 @@ pub const Codegen = struct { }; } - fn emitForVariableType(self: *@This(), vari: anytype, get: anytype, kv: anytype) !llvm.LLVMValueRef { - var sym = kv; + fn emitForVariableType(self: *@This(), vari: var, get: var, kv: var) !llvm.LLVMValueRef { + var sym = kv.value; switch (sym.*) { .Enum => |map| { @@ -76,7 +76,7 @@ pub const Codegen = struct { get.name.lexeme, }); } - return llvm.LLVMConstInt(llvm.LLVMInt32Type(), val.?, 1); + return llvm.LLVMConstInt(llvm.LLVMInt32Type(), val.?.value, 1); }, .Struct => @panic("TODO handle struct"), @@ -89,7 +89,7 @@ pub const Codegen = struct { fn emitExpr( self: *Codegen, - builder: anytype, + builder: var, expr: *const ast.Expr, ) anyerror!llvm.LLVMValueRef { return switch (expr.*) { @@ -185,16 +185,16 @@ pub const Codegen = struct { var args = LLVMValueList.init(self.allocator); errdefer args.deinit(); - for (call.arguments.items) |arg_expr| { + for (call.arguments.toSlice()) |arg_expr| { var arg_val = try self.emitExpr(builder, &arg_expr); try args.append(arg_val); } - var args_slice = args.items; + var args_slice = args.toSlice(); return llvm.LLVMBuildCall( builder, - llvm_func.?, + llvm_func.?.value, args_slice.ptr, @intCast(c_uint, args_slice.len), "call", @@ -203,10 +203,10 @@ pub const Codegen = struct { .Assign => |assign| { const name = assign.name.lexeme; - var meta = self.ctx.current_scope.?.meta_map.get(name).?; + var meta = self.ctx.current_scope.?.meta_map.get(name).?.value; var assign_expr = try self.emitExpr(builder, assign.value); var llvm_alloca: llvm.LLVMValueRef = switch (meta.using) { - .Function => meta.from_function.?.parameters.get(name).?.llvm_alloca.?, + .Function => meta.from_function.?.parameters.get(name).?.value.llvm_alloca.?, .Scope => meta.llvm_alloca.?, }; @@ -224,7 +224,7 @@ pub const Codegen = struct { // we have metadata, which means we can check if the variable // is coming from the scope or from the function - var metadata = kv_opt.?; + var metadata = kv_opt.?.value; std.debug.warn("!! LOAD FROM VAR META {}\n", .{@ptrToInt(metadata)}); var buf = try self.allocator.alloc(u8, 512); @@ -237,13 +237,13 @@ pub const Codegen = struct { return switch (metadata.using) { .Function => blk: { - var param = metadata.from_function.?.parameters.get(vari.lexeme).?; + var param = metadata.from_function.?.parameters.get(vari.lexeme).?.value; break :blk llvm.LLVMBuildLoad(builder, param.llvm_alloca.?, load_cstr.ptr); }, .Scope => blk: { var llvm_alloca = metadata.llvm_alloca.?; - //var var_typ = metadata.from_scope.?.env.get(vari.lexeme).?; + //var var_typ = metadata.from_scope.?.env.get(vari.lexeme).?.value; break :blk llvm.LLVMBuildLoad(builder, llvm_alloca, load_cstr.ptr); }, }; @@ -260,7 +260,7 @@ pub const Codegen = struct { }; } - fn emitStmt(self: *Codegen, builder: anytype, stmt: *ast.Stmt) anyerror!void { + fn emitStmt(self: *Codegen, builder: var, stmt: *ast.Stmt) anyerror!void { std.debug.warn("cgen: emitting stmt {}\n", .{@as(ast.StmtType, stmt.*)}); switch (stmt.*) { @@ -294,7 +294,7 @@ pub const Codegen = struct { self.ctx.setScope(self.ctx.current_scope.?.nextChild()); - var then_branch = ifstmt.then_branch.items; + var then_branch = ifstmt.then_branch.toSlice(); for (then_branch) |_, idx| { // keep emitting until branch has ret var then_stmt = &then_branch[idx]; @@ -326,7 +326,7 @@ pub const Codegen = struct { if (ifstmt.else_branch) |else_block| { self.ctx.setScope(self.ctx.current_scope.?.nextChild()); - var else_slice = else_block.items; + var else_slice = else_block.toSlice(); for (else_slice) |_, idx| { // keep emitting until branch has ret var else_stmt = &else_slice[idx]; @@ -361,7 +361,7 @@ pub const Codegen = struct { // analyze pass and the current scope contains the variable's // type(hopefully), so we resolve it const name = vardecl.name.lexeme; - var var_metadata = self.ctx.current_scope.?.meta_map.get(name).?; + var var_metadata = self.ctx.current_scope.?.meta_map.get(name).?.value; var name_cstr = try std.cstr.addNullByte(self.allocator, name); errdefer self.allocator.free(name_cstr); @@ -392,7 +392,7 @@ pub const Codegen = struct { } fn getFnSymbol(self: *@This(), name: []const u8) *comp.FunctionSymbol { - var fn_sym_search = self.ctx.symbol_table.get(name).?; + var fn_sym_search = self.ctx.symbol_table.get(name).?.value; std.debug.assert(@as(comp.SymbolType, fn_sym_search.*) == .Function); return &fn_sym_search.Function; } @@ -418,16 +418,16 @@ pub const Codegen = struct { var param_types = llvm.LLVMTypeList.init(self.allocator); errdefer param_types.deinit(); - for (decl.params.items) |param| { + for (decl.params.toSlice()) |param| { try param_types.append(try self.typeToLLVM(fn_sym.parameters.get( param.name.lexeme, - ).?.typ)); + ).?.value.typ)); } var llvm_ret_type = llvm.LLVMFunctionType( try self.typeToLLVM(fn_sym.return_type), - param_types.items.ptr, - @intCast(c_uint, param_types.items.len), + param_types.toSlice().ptr, + @intCast(c_uint, param_types.len), 0, ); @@ -444,9 +444,9 @@ pub const Codegen = struct { // to have the ability to mutate parameters, we must allocate them on // the stack - var params_slice = decl.params.items; + var params_slice = decl.params.toSlice(); for (params_slice) |param_node, idx| { - var param = fn_sym.parameters.get(param_node.name.lexeme).?; + var param = fn_sym.parameters.get(param_node.name.lexeme).?.value; const param_name_cstr = try std.cstr.addNullByte(self.allocator, param_node.name.lexeme); errdefer self.allocator.free(param_name_cstr); @@ -467,7 +467,7 @@ pub const Codegen = struct { // TODO check if stmt is return and if we already // returned before - var body_slice = decl.body.items; + var body_slice = decl.body.toSlice(); for (body_slice) |_, idx| { try self.emitStmt(builder, &body_slice[idx]); } @@ -480,10 +480,10 @@ pub const Codegen = struct { .Enum => {}, .ConstDecl => |constdecls| { - for (constdecls.items) |constdecl| { + for (constdecls.toSlice()) |constdecl| { const name = constdecl.name.lexeme; - var const_type = self.ctx.symbol_table.get(name).?; + var const_type = self.ctx.symbol_table.get(name).?.value; var const_llvm_type = try self.typeToLLVM(const_type.Const); const const_name = try std.cstr.addNullByte(self.allocator, name); @@ -515,7 +515,7 @@ pub const Codegen = struct { var mod = llvm.LLVMModuleCreateWithName("awoo").?; defer llvm.LLVMDisposeModule(mod); - var root_slice = root.Root.items; + var root_slice = root.Root.toSlice(); for (root_slice) |_, idx| { try self.genNode(mod, &root_slice[idx]); } diff --git a/src/comp_ctx.zig b/src/comp_ctx.zig index 54ac03f..44f377b 100644 --- a/src/comp_ctx.zig +++ b/src/comp_ctx.zig @@ -70,14 +70,13 @@ pub const Scope = struct { } pub fn nextChild(self: *@This()) *Scope { - var child = self.children.items[self.cur_child_idx]; + var child = self.children.at(self.cur_child_idx); self.cur_child_idx += 1; return child; } pub fn deinit(self: *const @This()) void { - // XXX: fix this someday - // self.env.deinit(); + self.env.deinit(); } }; @@ -272,8 +271,8 @@ pub const CompilationContext = struct { pub fn insertStruct(self: *@This(), struc: ast.Struct, field_types: TypeList) !void { var type_map = UnderlyingTypeMap.init(self.allocator); - for (struc.fields.items) |field, idx| { - _ = try type_map.put(field.name.lexeme, field_types.items[idx]); + for (struc.fields.toSlice()) |field, idx| { + _ = try type_map.put(field.name.lexeme, field_types.at(idx)); } var symbol = try self.allocator.create(SymbolData); @@ -290,13 +289,13 @@ pub const CompilationContext = struct { ) !void { var param_map = ParameterMap.init(self.allocator); - for (decl.params.items) |param, idx| { + for (decl.params.toSlice()) |param, idx| { var param_sym = try self.allocator.create(Parameter); param_sym.* = Parameter{ .name = param.name.lexeme, .idx = idx, - .typ = param_types.items[idx], + .typ = param_types.at(idx), }; _ = try param_map.put(param.name.lexeme, param_sym); } @@ -319,7 +318,7 @@ pub const CompilationContext = struct { _ = try self.symbol_table.put(lex, symbol); var kv = self.symbol_table.get(lex); - self.cur_function = &kv.?.Function; + self.cur_function = &kv.?.value.Function; } pub fn insertEnum(self: *@This(), enu: ast.Enum) !void { @@ -327,7 +326,7 @@ pub const CompilationContext = struct { errdefer ident_map.deinit(); // TODO change this when enums get support for custom values - for (enu.fields.items) |token, idx| { + for (enu.fields.toSlice()) |token, idx| { _ = try ident_map.put(token.lexeme, @intCast(u32, idx)); } @@ -353,7 +352,7 @@ pub const CompilationContext = struct { return CompilationError.TypeError; } - var value = sym_kv.?; + var value = sym_kv.?.value; var sym_typ = @as(SymbolType, value.*); if (sym_typ != typ) { @@ -379,7 +378,7 @@ pub const CompilationContext = struct { return try VariableMetadata.withScope( self.allocator, scope, - kv, + kv.value, ); } else { return null; @@ -409,7 +408,7 @@ pub const CompilationContext = struct { return try VariableMetadata.withParam( self.allocator, cur_function, - kv.typ, + kv.value.typ, ); } else { return null; diff --git a/src/errors.zig b/src/errors.zig index 5eb089e..88c05f1 100644 --- a/src/errors.zig +++ b/src/errors.zig @@ -12,7 +12,7 @@ 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: anytype) void { +pub fn reportFmt(line: usize, ctx_opt: ?[]const u8, comptime fmt: []const u8, args: var) void { if (ctx_opt) |ctx| { std.debug.warn("[line {}] Error on {}", .{ line, ctx }); } else { diff --git a/src/parsers.zig b/src/parsers.zig index db41947..391b48e 100644 --- a/src/parsers.zig +++ b/src/parsers.zig @@ -94,7 +94,7 @@ pub const Parser = struct { self.tokens.deinit(); } - fn setErrContext(self: *Parser, comptime fmt: ?[]const u8, args: anytype) void { + fn setErrContext(self: *Parser, comptime fmt: ?[]const u8, args: var) void { if (fmt == null) { self.err_ctx = null; return; @@ -104,7 +104,7 @@ pub const Parser = struct { self.err_ctx = std.fmt.bufPrint(buf, fmt.?, args) catch unreachable; } - fn doError(self: *Parser, comptime fmt: []const u8, args: anytype) ParseError { + fn doError(self: *Parser, comptime fmt: []const u8, args: var) ParseError { self.hadError = true; std.debug.warn("parser error at line {}", .{self.scanner.line}); @@ -138,11 +138,11 @@ pub const Parser = struct { } fn peek(self: *Parser) Token { - return self.tokens.items[self.tokens.items.len - 1]; + return self.tokens.at(self.tokens.len - 1); } fn previous(self: *Parser) Token { - return self.tokens.items[self.tokens.items.len - 2]; + return self.tokens.at(self.tokens.len - 2); } fn tokenError(self: *Parser, token: Token, msg: []const u8) ParseError { @@ -215,7 +215,7 @@ pub const Parser = struct { } /// check() against multiple tokens - fn compareAnyOf(self: *@This(), ttypes: []const TokenType) bool { + fn compareAnyOf(self: *@This(), ttypes: []TokenType) bool { for (ttypes) |typ| { if (self.check(typ)) return true; }