aboutsummaryrefslogtreecommitdiff
path: root/examples/snippets
diff options
context:
space:
mode:
Diffstat (limited to 'examples/snippets')
-rw-r--r--examples/snippets/.nova/Configuration.json4
-rw-r--r--examples/snippets/error-example.zig19
-rw-r--r--examples/snippets/fibonacci.zig41
-rw-r--r--examples/snippets/syntax-tour.zig283
4 files changed, 347 insertions, 0 deletions
diff --git a/examples/snippets/.nova/Configuration.json b/examples/snippets/.nova/Configuration.json
new file mode 100644
index 0000000..44cadf8
--- /dev/null
+++ b/examples/snippets/.nova/Configuration.json
@@ -0,0 +1,4 @@
+{
+ "zls.enable_build_on_save" : false,
+ "zls.zig_exe_path" : "\/opt\/homebrew\/bin\/zig"
+}
diff --git a/examples/snippets/error-example.zig b/examples/snippets/error-example.zig
new file mode 100644
index 0000000..f35c684
--- /dev/null
+++ b/examples/snippets/error-example.zig
@@ -0,0 +1,19 @@
+// INVALID FILE — used to test the Nova issue matcher.
+//
+// Open this file and run it with the "Current Zig File" task (zig run).
+// The compiler will report an error that the issue matcher captures:
+//
+// error-example.zig:16:23: error: type 'u8' cannot represent integer value '300'
+//
+// This verifies that the regexp ^(.+?):(\d+):(\d+):\s*(error|warning):\s*(.+)$
+// correctly extracts file, line, column, severity, and message.
+
+const std = @import("std");
+
+pub fn main() void {
+ // The literal 300 does not fit in a u8 (max 255). Zig catches
+ // this at compile time and reports an error at this line.
+ const value: u8 = 300;
+ _ = value;
+ _ = std.io.getStdOut();
+}
diff --git a/examples/snippets/fibonacci.zig b/examples/snippets/fibonacci.zig
new file mode 100644
index 0000000..327bbd3
--- /dev/null
+++ b/examples/snippets/fibonacci.zig
@@ -0,0 +1,41 @@
+const std = @import("std");
+
+/// Compute the nth Fibonacci number iteratively.
+pub fn fibonacci(n: u64) u64 {
+ if (n <= 1) return n;
+ var a: u64 = 0;
+ var b: u64 = 1;
+ var i: u64 = 2;
+ while (i <= n) : (i += 1) {
+ const next = a + b;
+ a = b;
+ b = next;
+ }
+ return b;
+}
+
+pub fn main(init: std.process.Init) !void {
+ const io = init.io;
+ var buf: [4096]u8 = undefined;
+ var fw: std.Io.File.Writer = .init(.stdout(), io, &buf);
+ defer fw.interface.flush() catch {};
+ const w = &fw.interface;
+
+ try w.print("Fibonacci sequence (first 12 terms):\n", .{});
+ for (0..12) |n| {
+ try w.print(" fib({d}) = {d}\n", .{ n, fibonacci(n) });
+ }
+}
+
+test "fibonacci base cases" {
+ try std.testing.expectEqual(@as(u64, 0), fibonacci(0));
+ try std.testing.expectEqual(@as(u64, 1), fibonacci(1));
+ try std.testing.expectEqual(@as(u64, 1), fibonacci(2));
+}
+
+test "fibonacci sequence" {
+ const expected = [_]u64{ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };
+ for (expected, 0..) |v, n| {
+ try std.testing.expectEqual(v, fibonacci(n));
+ }
+}
diff --git a/examples/snippets/syntax-tour.zig b/examples/snippets/syntax-tour.zig
new file mode 100644
index 0000000..4c29588
--- /dev/null
+++ b/examples/snippets/syntax-tour.zig
@@ -0,0 +1,283 @@
+//! Root-level doc comment (module doc).
+//! This file exercises every syntax category for highlighting verification.
+//! Open in Nova and check that all constructs colour correctly.
+
+const std = @import("std");
+
+// ── Keywords: pub, const, var, comptime, extern, export, inline, noinline ──────
+
+/// Doc comment on a public constant.
+pub const VERSION: []const u8 = "0.15.0";
+
+pub var mutable_counter: u32 = 0;
+
+// ── Enums ──────────────────────────────────────────────────────────────────────
+
+pub const Color = enum(u8) {
+ red = 0,
+ green = 1,
+ blue = 2,
+
+ pub fn toHex(self: Color) u24 {
+ return switch (self) {
+ .red => 0xFF0000,
+ .green => 0x00FF00,
+ .blue => 0x0000FF,
+ };
+ }
+};
+
+// ── Structs with default field values ─────────────────────────────────────────
+
+pub const Point = struct {
+ x: f64 = 0.0,
+ y: f64 = 0.0,
+
+ pub fn distanceTo(self: Point, other: Point) f64 {
+ const dx = self.x - other.x;
+ const dy = self.y - other.y;
+ return std.math.sqrt(dx * dx + dy * dy);
+ }
+
+ /// Generic format method — tests `anytype` keyword.
+ pub fn format(self: Point, comptime fmt: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
+ _ = fmt;
+ try writer.print("({d:.2}, {d:.2})", .{ self.x, self.y });
+ }
+};
+
+// ── Tagged union ───────────────────────────────────────────────────────────────
+
+pub const Number = union(enum) {
+ integer: i64,
+ float: f64,
+
+ pub fn isZero(self: Number) bool {
+ return switch (self) {
+ .integer => |v| v == 0,
+ .float => |v| v == 0.0,
+ };
+ }
+};
+
+// ── Opaque type ───────────────────────────────────────────────────────────────
+
+pub const Handle = opaque {};
+
+// ── Packed struct ─────────────────────────────────────────────────────────────
+
+pub const Flags = packed struct {
+ enabled: bool,
+ verbose: bool,
+ debug: bool,
+ _pad: u5 = 0,
+};
+
+// ── Comptime ──────────────────────────────────────────────────────────────────
+
+pub fn typeName(comptime T: type) []const u8 {
+ return @typeName(T);
+}
+
+/// Comptime block with labeled break.
+pub const BITS_IN_BYTE: comptime_int = blk: {
+ var n: u8 = 255;
+ var count: usize = 0;
+ while (n > 0) : (n >>= 1) count += 1;
+ break :blk count;
+};
+
+// ── Generics ──────────────────────────────────────────────────────────────────
+
+pub fn Stack(comptime T: type) type {
+ return struct {
+ items: std.ArrayList(T) = .empty,
+
+ pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
+ self.items.deinit(allocator);
+ }
+
+ pub fn push(self: *@This(), allocator: std.mem.Allocator, value: T) !void {
+ try self.items.append(allocator, value);
+ }
+
+ pub fn pop(self: *@This()) ?T {
+ return self.items.pop();
+ }
+ };
+}
+
+// ── Builtin functions ─────────────────────────────────────────────────────────
+
+pub fn builtinDemo(value: i32) u32 {
+ const as_u32: u32 = @intCast(value);
+ const as_f32: f32 = @floatFromInt(value);
+ _ = as_f32;
+ _ = @sizeOf(u64);
+ _ = @alignOf(*u8);
+ _ = @typeInfo(Color);
+ return as_u32;
+}
+
+// ── String literal variants ───────────────────────────────────────────────────
+
+pub const PLAIN: []const u8 = "hello, Nova!";
+
+pub const ESCAPE: []const u8 = "tab:\there\nnewline\x00null";
+
+/// Multiline string — each line starts with `\\`.
+pub const MULTILINE: []const u8 =
+ \\first line
+ \\second line
+ \\third line
+;
+
+pub const CHAR_LITERAL: u8 = 'Z';
+pub const UNICODE_ESCAPE: []const u8 = "\u{2744}"; // ❄
+pub const HEX_ESCAPE: u8 = '\xff';
+
+// ── Error sets and error union ─────────────────────────────────────────────────
+
+pub const ParseError = error{
+ UnexpectedToken,
+ EndOfStream,
+ Overflow,
+};
+
+pub fn parseU8(s: []const u8) ParseError!u8 {
+ if (s.len == 0) return error.EndOfStream;
+ return std.fmt.parseInt(u8, s, 10) catch error.UnexpectedToken;
+}
+
+// ── Optional / orelse / if capture ───────────────────────────────────────────
+
+pub fn firstByte(s: []const u8) ?u8 {
+ return if (s.len == 0) null else s[0];
+}
+
+pub fn firstByteOr(s: []const u8, fallback: u8) u8 {
+ return firstByte(s) orelse fallback;
+}
+
+// ── Switch with integer ranges ────────────────────────────────────────────────
+
+pub fn classify(n: i32) []const u8 {
+ return switch (n) {
+ std.math.minInt(i32)...-1 => "negative",
+ 0 => "zero",
+ 1...100 => "small positive",
+ else => "large positive",
+ };
+}
+
+// ── For with index, multi-sequence ────────────────────────────────────────────
+
+pub fn sumSlice(items: []const i32) i64 {
+ var total: i64 = 0;
+ for (items, 0..) |item, idx| {
+ _ = idx;
+ total += item;
+ }
+ return total;
+}
+
+// ── While with continue expression ───────────────────────────────────────────
+
+pub fn countDown(start: u32) u32 {
+ var i = start;
+ var steps: u32 = 0;
+ while (i > 0) : (i -= 1) steps += 1;
+ return steps;
+}
+
+// ── Defer / errdefer ─────────────────────────────────────────────────────────
+
+pub fn withDefer(allocator: std.mem.Allocator) ![]u8 {
+ const buf = try allocator.alloc(u8, 16);
+ errdefer allocator.free(buf);
+ @memset(buf, 0);
+ return buf;
+}
+
+// ── Pointer types, alignment ──────────────────────────────────────────────────
+
+pub fn ptrDemo(p: *align(8) u64) u64 {
+ return p.*;
+}
+
+// ── inline / noinline ─────────────────────────────────────────────────────────
+
+pub inline fn inlineAdd(a: u32, b: u32) u32 {
+ return a + b;
+}
+
+pub noinline fn noinlineAdd(a: u32, b: u32) u32 {
+ return a + b;
+}
+
+// ── threadlocal ───────────────────────────────────────────────────────────────
+
+threadlocal var tl_counter: u32 = 0;
+
+pub fn bumpCounter() void {
+ tl_counter += 1;
+}
+
+// ── extern ────────────────────────────────────────────────────────────────────
+
+extern fn c_strlen(ptr: [*:0]const u8) usize;
+
+// ── Inline assembly ───────────────────────────────────────────────────────────
+
+pub fn nop() void {
+ asm volatile ("nop");
+}
+
+// ── Tests ─────────────────────────────────────────────────────────────────────
+
+test "syntax-tour: classify" {
+ try std.testing.expectEqualStrings("zero", classify(0));
+ try std.testing.expectEqualStrings("negative", classify(-5));
+ try std.testing.expectEqualStrings("small positive", classify(42));
+ try std.testing.expectEqualStrings("large positive", classify(200));
+}
+
+test "syntax-tour: sumSlice" {
+ try std.testing.expectEqual(@as(i64, 15), sumSlice(&.{ 1, 2, 3, 4, 5 }));
+ try std.testing.expectEqual(@as(i64, 0), sumSlice(&.{}));
+}
+
+test "syntax-tour: parseU8 errors" {
+ try std.testing.expectError(error.EndOfStream, parseU8(""));
+ try std.testing.expectError(error.UnexpectedToken, parseU8("abc"));
+}
+
+test "syntax-tour: firstByte" {
+ try std.testing.expectEqual(@as(?u8, 'h'), firstByte("hello"));
+ try std.testing.expectEqual(@as(?u8, null), firstByte(""));
+}
+
+test "syntax-tour: Color.toHex" {
+ try std.testing.expectEqual(@as(u24, 0xFF0000), Color.red.toHex());
+ try std.testing.expectEqual(@as(u24, 0x0000FF), Color.blue.toHex());
+}
+
+test "syntax-tour: Number.isZero" {
+ try std.testing.expect((Number{ .integer = 0 }).isZero());
+ try std.testing.expect(!(Number{ .float = 3.14 }).isZero());
+}
+
+test "syntax-tour: Stack(i32)" {
+ const gpa = std.testing.allocator;
+ var s = Stack(i32){};
+ defer s.deinit(gpa);
+ try s.push(gpa, 10);
+ try s.push(gpa, 20);
+ try std.testing.expectEqual(@as(?i32, 20), s.pop());
+ try std.testing.expectEqual(@as(?i32, 10), s.pop());
+ try std.testing.expectEqual(@as(?i32, null), s.pop());
+}
+
+test "syntax-tour: BITS_IN_BYTE" {
+ try std.testing.expectEqual(@as(comptime_int, 8), BITS_IN_BYTE);
+}