diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4dbc5a97..2d808b30 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -56,6 +56,8 @@ jobs: uses: actions/checkout@v3.0.0 - name: Checkout submodules run: git submodule update --init --recursive + - name: Configure pcre2 + run: cp vendors/pcre2/src/pcre2_chartables.c.dist vendors/pcre2/src/pcre2_chartables.c && cd vendors/pcre2 && ./autogen.sh && ./configure && cd ../.. - name: Setup nightly Zig uses: mlugg/setup-zig@v1 with: @@ -96,6 +98,8 @@ jobs: uses: actions/checkout@v3.0.0 - name: Checkout submodules run: git submodule update --init --recursive + - name: Configure pcre2 + run: cp vendors/pcre2/src/pcre2_chartables.c.dist vendors/pcre2/src/pcre2_chartables.c && cd vendors/pcre2 && ./autogen.sh && ./configure && cd ../.. - name: Setup nightly Zig uses: mlugg/setup-zig@v1 with: diff --git a/README.md b/README.md index ab3ec90b..ff7acefe 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ A small/lightweight statically typed scripting language written in Zig ## How to build and install -_Latest zig version supported: 0.14.0-dev.121+ab4c461b7 (https://github.com/ziglang/zig/issues/20847 prevents us from upgrading further)_ +_Latest zig version supported: 0.14.0-dev.1588+2111f4c38_ ### Requirements - Since this is built with Zig, you should be able to build buzz on a wide variety of architectures even though this has only been tested on x86/M1. @@ -42,13 +42,18 @@ _Latest zig version supported: 0.14.0-dev.121+ab4c461b7 (https://github.com/zigl ### Build 1. Clone the project: `git clone https://github.com/buzz-language/buzz ` 2. Checkout submodules: `git submodule update --init` -3. Run configure for pcre2: +3. Copy `pcre2_chartables`: +```bash +ln -s vendors/pcre2/src/pcre2_chartables.c.dist vendors/pcre2/src/pcre2_chartables.c +``` +3. Configure pcre2: ```bash cd vendors/pcre2 +./autogen.sh ./configure cd ../.. ``` -4. Have fun: `zig build run -- ` +4. Have fun: `zig build run -- ` to run a script or `zig build run` to start the REPL ### Install diff --git a/build.zig b/build.zig index 432eda63..0623f07c 100644 --- a/build.zig +++ b/build.zig @@ -2,7 +2,7 @@ const std = @import("std"); const builtin = @import("builtin"); const Build = std.Build; -const BuzzDebugOptions = struct { +const DebugOptions = struct { debug: bool, stack: bool, current_instruction: bool, @@ -10,7 +10,7 @@ const BuzzDebugOptions = struct { stop_on_report: bool, placeholders: bool, - pub fn step(self: BuzzDebugOptions, options: *Build.Step.Options) void { + pub fn step(self: DebugOptions, options: *Build.Step.Options) void { options.addOption(@TypeOf(self.debug), "debug", self.debug); options.addOption(@TypeOf(self.stack), "debug_stack", self.stack); options.addOption(@TypeOf(self.current_instruction), "debug_current_instruction", self.current_instruction); @@ -20,14 +20,14 @@ const BuzzDebugOptions = struct { } }; -const BuzzJITOptions = struct { +const JITOptions = struct { on: bool, always_on: bool, hotspot_always_on: bool, debug: bool, prof_threshold: f128 = 0.05, - pub fn step(self: BuzzJITOptions, options: *Build.Step.Options) void { + pub fn step(self: JITOptions, options: *Build.Step.Options) void { options.addOption(@TypeOf(self.debug), "jit_debug", self.debug); options.addOption(@TypeOf(self.always_on), "jit_always_on", self.always_on); options.addOption(@TypeOf(self.hotspot_always_on), "jit_hotspot_always_on", self.hotspot_always_on); @@ -36,7 +36,7 @@ const BuzzJITOptions = struct { } }; -const BuzzGCOptions = struct { +const GCOptions = struct { debug: bool, debug_light: bool, debug_access: bool, @@ -46,7 +46,7 @@ const BuzzGCOptions = struct { next_full_gc_ratio: usize, memory_limit: ?usize, - pub fn step(self: BuzzGCOptions, options: *Build.Step.Options) void { + pub fn step(self: GCOptions, options: *Build.Step.Options) void { options.addOption(@TypeOf(self.debug), "gc_debug", self.debug); options.addOption(@TypeOf(self.debug_light), "gc_debug_light", self.debug_light); options.addOption(@TypeOf(self.debug_access), "gc_debug_access", self.debug_access); @@ -58,13 +58,13 @@ const BuzzGCOptions = struct { } }; -const BuzzBuildOptions = struct { +const BuildOptions = struct { version: std.SemanticVersion, sha: []const u8, mimalloc: bool, - debug: BuzzDebugOptions, - gc: BuzzGCOptions, - jit: BuzzJITOptions, + debug: DebugOptions, + gc: GCOptions, + jit: JITOptions, target: Build.ResolvedTarget, cycle_limit: ?u128, recursive_call_limit: ?u32, @@ -98,7 +98,7 @@ fn getBuzzPrefix(b: *Build) ![]const u8 { pub fn build(b: *Build) !void { // Check minimum zig version const current_zig = builtin.zig_version; - const min_zig = std.SemanticVersion.parse("0.14.0-dev.121+ab4c461b7") catch return; + const min_zig = std.SemanticVersion.parse("0.14.0-dev.1588+2111f4c38") catch return; if (current_zig.order(min_zig).compare(.lt)) { @panic(b.fmt("Your Zig version v{} does not meet the minimum build requirement of v{}", .{ current_zig, min_zig })); } @@ -108,9 +108,8 @@ pub fn build(b: *Build) !void { const is_wasm = target.result.cpu.arch.isWasm(); const install_step = b.getInstallStep(); - var build_options = BuzzBuildOptions{ + var build_options = BuildOptions{ .target = target, - // Version is latest tag or empty string .version = std.SemanticVersion{ .major = 0, .minor = 5, .patch = 0 }, // Current commit sha .sha = std.posix.getenv("GIT_SHA") orelse @@ -413,7 +412,7 @@ pub fn build(b: *Build) !void { // Building std libraries const Lib = struct { - path: ?[]const u8, + path: ?[]const u8 = null, name: []const u8, wasm_compatible: bool = true, }; @@ -431,8 +430,8 @@ pub fn build(b: *Build) !void { .{ .name = "http", .path = "src/lib/buzz_http.zig", .wasm_compatible = false }, .{ .name = "ffi", .path = "src/lib/buzz_ffi.zig", .wasm_compatible = false }, .{ .name = "serialize", .path = "src/lib/buzz_serialize.zig" }, - .{ .name = "testing", .path = null }, - .{ .name = "errors", .path = null }, + .{ .name = "testing" }, + .{ .name = "errors" }, }; var library_steps = std.ArrayList(*std.Build.Step.Compile).init(b.allocator); @@ -546,15 +545,15 @@ pub fn build(b: *Build) !void { pub fn buildPcre2(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) !*Build.Step.Compile { const copyFiles = b.addWriteFiles(); - copyFiles.addCopyFileToSource( + _ = copyFiles.addCopyFile( b.path("vendors/pcre2/src/config.h.generic"), "vendors/pcre2/src/config.h", ); - copyFiles.addCopyFileToSource( + _ = copyFiles.addCopyFile( b.path("vendors/pcre2/src/pcre2.h.generic"), "vendors/pcre2/src/pcre2.h", ); - copyFiles.addCopyFileToSource( + _ = copyFiles.addCopyFile( b.path("vendors/pcre2/src/pcre2_chartables.c.dist"), "vendors/pcre2/src/pcre2_chartables.c", ); @@ -726,6 +725,8 @@ pub fn buildMir(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.O lib.addIncludePath(b.path("./vendors/mir")); + lib.linkLibC(); + lib.addCSourceFiles( .{ .files = &.{ diff --git a/src/Codegen.zig b/src/Codegen.zig index 6742a37d..682f4ead 100644 --- a/src/Codegen.zig +++ b/src/Codegen.zig @@ -307,7 +307,7 @@ pub fn identifierConstant(self: *Self, name: []const u8) !u24 { // Unlocated error, should not be used fn reportError(self: *Self, error_type: Reporter.Error, message: []const u8) void { - @setCold(true); + @branchHint(.cold); if (self.reporter.panic_mode) { return; diff --git a/src/FFI.zig b/src/FFI.zig index 4948e2d9..7ad105dc 100644 --- a/src/FFI.zig +++ b/src/FFI.zig @@ -810,8 +810,8 @@ fn fnProto(self: *Self, tag: Ast.Node.Tag, decl_index: Ast.Node.Index) anyerror! .generic_types = std.AutoArrayHashMap(*o.ObjString, *o.ObjTypeDef).init(self.gc.allocator), }; - var parameters_zig_types = std.ArrayList(ZigType.Fn.Param).init(self.gc.allocator); - var zig_fn_type = ZigType.Fn{ + var parameters_zig_types = std.ArrayList(ZigType.FnType.Param).init(self.gc.allocator); + var zig_fn_type = ZigType.FnType{ .calling_convention = .C, // How could it be something else? .alignment = 4, diff --git a/src/Parser.zig b/src/Parser.zig index 1a386095..c36c97e4 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -559,7 +559,7 @@ pub fn deinit(self: *Self) void { } fn reportErrorAtCurrent(self: *Self, error_type: Reporter.Error, message: []const u8) void { - @setCold(true); + @branchHint(.cold); self.reporter.reportErrorAt( error_type, self.ast.tokens.get(self.current_token.?), @@ -568,7 +568,7 @@ fn reportErrorAtCurrent(self: *Self, error_type: Reporter.Error, message: []cons } pub fn reportError(self: *Self, error_type: Reporter.Error, message: []const u8) void { - @setCold(true); + @branchHint(.cold); self.reporter.reportErrorAt( error_type, self.ast.tokens.get(if (self.current_token.? > 0) self.current_token.? - 1 else 0), @@ -577,7 +577,7 @@ pub fn reportError(self: *Self, error_type: Reporter.Error, message: []const u8) } fn reportErrorFmt(self: *Self, error_type: Reporter.Error, comptime fmt: []const u8, args: anytype) void { - @setCold(true); + @branchHint(.cold); self.reporter.reportErrorFmt( error_type, self.ast.tokens.get(if (self.current_token.? > 0) self.current_token.? - 1 else 0), diff --git a/src/Scanner.zig b/src/Scanner.zig index 2488be5f..d2b58fc4 100644 --- a/src/Scanner.zig +++ b/src/Scanner.zig @@ -51,7 +51,7 @@ pub fn scanToken(self: *Self) !Token { const char: u8 = self.advance(); return try switch (char) { - 'a'...'z', 'A'...'Z' => self.identifier(), + 'a'...'z', 'A'...'Z' => try self.identifier(), '_' => self.makeToken( .Identifier, self.source[self.current.start..self.current.offset], @@ -101,7 +101,7 @@ pub fn scanToken(self: *Self) !Token { '&' => self.makeToken(.Ampersand, null, null, null), '*' => self.makeToken(.Star, null, null, null), '/' => if (self.match('/')) - self.docblock() + try self.docblock() else self.makeToken(.Slash, null, null, null), '%' => self.makeToken(.Percent, null, null, null), @@ -130,11 +130,11 @@ pub fn scanToken(self: *Self) !Token { null, null, ), - '"' => self.string(false), - '`' => self.string(true), + '"' => try self.string(false), + '`' => try self.string(true), '\'' => self.byte(), - '@' => self.atIdentifier(), - '$' => self.pattern(), + '@' => try self.atIdentifier(), + '$' => try self.pattern(), '\\' => self.makeToken(.AntiSlash, null, null, null), else => self.makeToken( diff --git a/src/ext/clap b/src/ext/clap index c0193e92..70036783 160000 --- a/src/ext/clap +++ b/src/ext/clap @@ -1 +1 @@ -Subproject commit c0193e9247335a6c1688b946325060289405de2a +Subproject commit 7003678307b72bc25869308d7435a79114d1ac42 diff --git a/src/lib/buzz_io.zig b/src/lib/buzz_io.zig index 97044c37..3e8a0e93 100644 --- a/src/lib/buzz_io.zig +++ b/src/lib/buzz_io.zig @@ -121,6 +121,9 @@ fn handleFileReadWriteError(ctx: *api.NativeCtx, err: anytype) void { error.SocketNotConnected, => ctx.vm.pushErrorEnum("errors.FileSystemError", @errorName(err)), + error.Canceled, + => ctx.vm.pushErrorEnum("errors.SocketError", @errorName(err)), + error.OperationAborted, error.BrokenPipe, error.ConnectionResetByPeer, @@ -180,6 +183,9 @@ fn handleFileReadLineError(ctx: *api.NativeCtx, err: anytype) void { error.SocketNotConnected, => ctx.vm.pushErrorEnum("errors.FileSystemError", @errorName(err)), + error.Canceled, + => ctx.vm.pushErrorEnum("errors.SocketError", @errorName(err)), + error.BrokenPipe, error.ConnectionResetByPeer, error.ConnectionTimedOut, @@ -244,6 +250,9 @@ fn handleFileReadAllError(ctx: *api.NativeCtx, err: anytype) void { error.SocketNotConnected, => ctx.vm.pushErrorEnum("errors.FileSystemError", @errorName(err)), + error.Canceled, + => ctx.vm.pushErrorEnum("errors.SocketError", @errorName(err)), + error.OperationAborted, error.BrokenPipe, error.ConnectionResetByPeer, diff --git a/src/lib/buzz_os.zig b/src/lib/buzz_os.zig index d4815f43..65422ddb 100644 --- a/src/lib/buzz_os.zig +++ b/src/lib/buzz_os.zig @@ -159,6 +159,9 @@ fn handleSpawnError(ctx: *api.NativeCtx, err: anytype) void { error.ResourceLimitReached, error.WaitAbandoned, error.WaitTimeOut, + error.ProcessAlreadyExec, + error.InvalidProcessGroupId, + error.ProcessNotFound, => ctx.vm.pushErrorEnum("errors.ExecError", @errorName(err)), error.OutOfMemory => { @@ -249,6 +252,7 @@ fn handleConnectError(ctx: *api.NativeCtx, err: anytype) void { error.TimeoutTooBig, error.UnknownHostName, error.WouldBlock, + error.Canceled, => ctx.vm.pushErrorEnum("errors.SocketError", @errorName(err)), error.BadPathName, @@ -461,6 +465,9 @@ fn handleReadLineError(ctx: *api.NativeCtx, err: anytype) void { error.SocketNotConnected, => ctx.vm.pushErrorEnum("errors.FileSystemError", @errorName(err)), + error.Canceled, + => ctx.vm.pushErrorEnum("errors.SocketError", @errorName(err)), + error.BrokenPipe, error.ConnectionResetByPeer, error.ConnectionTimedOut, diff --git a/src/lib/errors.buzz b/src/lib/errors.buzz index f1873ff7..9f50a3ca 100644 --- a/src/lib/errors.buzz +++ b/src/lib/errors.buzz @@ -52,6 +52,9 @@ export enum ExecError { TooBig, WaitAbandoned, WaitTimeOut, + ProcessAlreadyExec, + InvalidProcessGroupId, + ProcessNotFound, } export enum SocketError { @@ -67,6 +70,7 @@ export enum SocketError { ConnectionRefused, ConnectionResetByPeer, ConnectionTimedOut, + Canceled, FileDescriptorNotASocket, HostLacksNetworkAddresses, Incomplete, diff --git a/src/vm.zig b/src/vm.zig index 0a2c30a0..2c8a2cde 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -876,7 +876,7 @@ pub const VM = struct { } pub fn panic(self: *Self, msg: []const u8) void { - @setCold(true); + @branchHint(.cold); self.reportRuntimeErrorWithCurrentStack(msg); diff --git a/src/zigtypes.zig b/src/zigtypes.zig index 06195d19..dd26e3dd 100644 --- a/src/zigtypes.zig +++ b/src/zigtypes.zig @@ -8,25 +8,25 @@ pub const Type = union(enum) { Void: void, Bool: void, NoReturn: void, - Int: Int, - Float: Float, - Pointer: Pointer, - Array: Array, - Struct: Struct, + Int: IntType, + Float: FloatType, + Pointer: PointerType, + Array: ArrayType, + Struct: StructType, ComptimeFloat: void, ComptimeInt: void, Undefined: void, Null: void, - Optional: Optional, - ErrorUnion: ErrorUnion, - ErrorSet: ErrorSet, - Enum: Enum, - Union: Union, - Fn: Fn, - Opaque: Opaque, - Frame: Frame, - AnyFrame: AnyFrame, - Vector: Vector, + Optional: OptionalType, + ErrorUnion: ErrorUnionType, + ErrorSet: ErrorSetType, + Enum: EnumType, + Union: UnionType, + Fn: FnType, + Opaque: OpaqueType, + Frame: FrameType, + AnyFrame: AnyFrameType, + Vector: VectorType, EnumLiteral: void, // FIXME: should be expressed in bits, because alignment and shit @@ -121,20 +121,20 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Int = struct { + pub const IntType = struct { signedness: std.builtin.Signedness, bits: u16, }; /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Float = struct { + pub const FloatType = struct { bits: u16, }; /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Pointer = struct { + pub const PointerType = struct { size: std.builtin.Type.Pointer.Size, is_const: bool, is_volatile: bool, @@ -151,7 +151,7 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Array = struct { + pub const ArrayType = struct { len: usize, child: *const Type, @@ -173,7 +173,7 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Struct = struct { + pub const StructType = struct { layout: std.builtin.Type.ContainerLayout, /// Only valid if layout is .Packed backing_integer: ?*const Type = null, @@ -184,13 +184,13 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Optional = struct { + pub const OptionalType = struct { child: *const Type, }; /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const ErrorUnion = struct { + pub const ErrorUnionType = struct { error_set: *const Type, payload: *const Type, }; @@ -203,7 +203,7 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const ErrorSet = ?[]const Error; + pub const ErrorSetType = ?[]const Error; /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. @@ -214,7 +214,7 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Enum = struct { + pub const EnumType = struct { tag_type: *const Type, fields: []const EnumField, decls: []const Declaration, @@ -231,7 +231,7 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Union = struct { + pub const UnionType = struct { layout: std.builtin.Type.ContainerLayout, tag_type: ?*const Type, fields: []const UnionField, @@ -240,7 +240,7 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Fn = struct { + pub const FnType = struct { calling_convention: std.builtin.CallingConvention, alignment: u16, is_generic: bool, @@ -260,25 +260,25 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Opaque = struct { + pub const OpaqueType = struct { decls: []const Declaration, }; /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Frame = struct { + pub const FrameType = struct { function: *const anyopaque, }; /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const AnyFrame = struct { + pub const AnyFrameType = struct { child: ?*const Type, }; /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Vector = struct { + pub const VectorType = struct { len: usize, child: *const Type, };