mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Merge remote-tracking branch 'origin/main' into import-builtins
This commit is contained in:
commit
82c6562352
623 changed files with 37254 additions and 35279 deletions
|
|
@ -20,6 +20,12 @@ pub const Color = enum {
|
|||
punctuation,
|
||||
};
|
||||
|
||||
/// Controls whether line/column information is included in output
|
||||
pub const LineColMode = enum {
|
||||
skip_linecol,
|
||||
include_linecol,
|
||||
};
|
||||
|
||||
/// Helper function to escape HTML characters
|
||||
fn escapeHtmlChar(writer: anytype, char: u8) !void {
|
||||
switch (char) {
|
||||
|
|
@ -255,7 +261,7 @@ pub fn endNode(self: *SExprTree, begin: NodeBegin, attrsMarker: NodeBegin) std.m
|
|||
}
|
||||
|
||||
/// Internal method that writes the node using a writer implementation
|
||||
fn toStringImpl(self: *const SExprTree, node: Node, writer_impl: anytype, indent: usize) !void {
|
||||
fn toStringImpl(self: *const SExprTree, node: Node, writer_impl: anytype, indent: usize, linecol_mode: LineColMode) !void {
|
||||
switch (node) {
|
||||
.StaticAtom => |s| {
|
||||
try writer_impl.setColor(.node_name);
|
||||
|
|
@ -290,7 +296,6 @@ fn toStringImpl(self: *const SExprTree, node: Node, writer_impl: anytype, indent
|
|||
},
|
||||
.BytesRange => |range| {
|
||||
try writer_impl.beginSourceRange(range.begin, range.end);
|
||||
// try writer_impl.print("@{d}-{d}", .{ range.begin, range.end });
|
||||
try writer_impl.print("@{d}.{d}-{d}.{d}", .{
|
||||
// add one to display numbers instead of index
|
||||
range.region.start_line_idx + 1,
|
||||
|
|
@ -307,20 +312,36 @@ fn toStringImpl(self: *const SExprTree, node: Node, writer_impl: anytype, indent
|
|||
|
||||
var first = true;
|
||||
for (range.begin..range.attrs_marker) |i| {
|
||||
const child = self.children.items[i];
|
||||
|
||||
// Skip BytesRange nodes when linecol_mode is .skip_linecol
|
||||
// Note we do this check here to prevent trailing whitespace in the output
|
||||
if (child == .BytesRange and linecol_mode == .skip_linecol) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!first) {
|
||||
try writer_impl.print(" ", .{});
|
||||
}
|
||||
first = false;
|
||||
try self.toStringImpl(self.children.items[i], writer_impl, indent + 1);
|
||||
try self.toStringImpl(child, writer_impl, indent + 1, linecol_mode);
|
||||
}
|
||||
|
||||
for (range.attrs_marker..range.end) |i| {
|
||||
const child = self.children.items[i];
|
||||
|
||||
// Skip BytesRange nodes when linecol_mode is .skip_linecol
|
||||
// Note we do this check here to prevent extra newlines in the output
|
||||
if (child == .BytesRange and linecol_mode == .skip_linecol) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!first) {
|
||||
try writer_impl.print("\n", .{});
|
||||
try writer_impl.writeIndent(indent + 1);
|
||||
}
|
||||
first = false;
|
||||
try self.toStringImpl(self.children.items[i], writer_impl, indent + 1);
|
||||
try self.toStringImpl(child, writer_impl, indent + 1, linecol_mode);
|
||||
}
|
||||
|
||||
try writer_impl.setColor(.punctuation);
|
||||
|
|
@ -331,24 +352,24 @@ fn toStringImpl(self: *const SExprTree, node: Node, writer_impl: anytype, indent
|
|||
}
|
||||
|
||||
/// Pretty-print the root node (top of stack) to the writer
|
||||
pub fn printTree(self: *const SExprTree, writer: anytype) !void {
|
||||
pub fn printTree(self: *const SExprTree, writer: anytype, linecol_mode: LineColMode) !void {
|
||||
if (self.stack.items.len == 0) return;
|
||||
var plain_writer = PlainTextSExprWriter{ .writer = writer.any() };
|
||||
try self.toStringImpl(self.stack.items[self.stack.items.len - 1], &plain_writer, 0);
|
||||
try self.toStringImpl(self.stack.items[self.stack.items.len - 1], &plain_writer, 0, linecol_mode);
|
||||
}
|
||||
|
||||
/// Render this SExprTree to a writer with pleasing indentation.
|
||||
pub fn toStringPretty(self: *const SExprTree, writer: std.io.AnyWriter) !void {
|
||||
pub fn toStringPretty(self: *const SExprTree, writer: std.io.AnyWriter, linecol_mode: LineColMode) !void {
|
||||
if (self.stack.items.len == 0) return;
|
||||
var plain_writer = PlainTextSExprWriter{ .writer = writer };
|
||||
try self.toStringImpl(self.stack.items[self.stack.items.len - 1], &plain_writer, 0);
|
||||
try self.toStringImpl(self.stack.items[self.stack.items.len - 1], &plain_writer, 0, linecol_mode);
|
||||
}
|
||||
|
||||
/// Render this SExprTree to HTML with syntax highlighting.
|
||||
pub fn toHtml(self: *const SExprTree, writer: std.io.AnyWriter) !void {
|
||||
pub fn toHtml(self: *const SExprTree, writer: std.io.AnyWriter, linecol_mode: LineColMode) !void {
|
||||
if (self.stack.items.len == 0) return;
|
||||
var html_writer = HtmlSExprWriter.init(writer);
|
||||
try self.toStringImpl(self.stack.items[self.stack.items.len - 1], &html_writer, 0);
|
||||
try self.toStringImpl(self.stack.items[self.stack.items.len - 1], &html_writer, 0, linecol_mode);
|
||||
html_writer.deinit() catch {
|
||||
return error.ErrFinalizingHTMLWriter;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -97,6 +97,55 @@ pub const NumLiteral = union(enum) {
|
|||
Frac: FracLiteral,
|
||||
};
|
||||
|
||||
/// The core allocators for the lifetime of a roc program.
|
||||
///
|
||||
/// This structure should be used to pass allocators to most functions in Roc.
|
||||
/// Data structures should anchor to a generic allocator instead (alloc: Allocator).
|
||||
/// It is up to the instanciator of the data structure to pick what it will use.
|
||||
/// Generally speaking though, data structures can realloc and will use the gpa.
|
||||
///
|
||||
/// IMPORTANT: After initialization, Allocators must always be passed by pointer (*Allocators),
|
||||
/// never by value. Passing by value will invalidate the arena allocator pointer!
|
||||
pub const Allocators = struct {
|
||||
/// The gpa is the general purpose allocator. Anything allocated with the gpa must be freed.
|
||||
/// the gpa should generally be used for large allocations and things that might get reallocated.
|
||||
/// It is best to avoid allocating small or short lived things with the gpa.
|
||||
gpa: std.mem.Allocator,
|
||||
|
||||
/// The arena is an arena allocator that is around for the entire roc compilation.
|
||||
/// The arena should be used for small and miscellaneous allocations.
|
||||
/// Things allocated in arena are expected to never be freed individually.
|
||||
///
|
||||
/// IMPORTANT: This field contains a pointer to arena_impl. The struct must not be
|
||||
/// moved after initialization, or this pointer will be invalidated.
|
||||
arena: std.mem.Allocator,
|
||||
|
||||
/// The underlying arena allocator implementation (stored to enable deinit)
|
||||
arena_impl: std.heap.ArenaAllocator,
|
||||
|
||||
// TODO: consider if we want to add scratch. It would be an arena reset between each compilation phase.
|
||||
// scratch: ?std.mem.Allocator,
|
||||
|
||||
/// Initialize the Allocators in-place with a general purpose allocator.
|
||||
///
|
||||
/// IMPORTANT: This struct must be initialized in its final memory location.
|
||||
/// After calling initInPlace(), the struct must only be passed by pointer (*Allocators),
|
||||
/// never by value, or the arena allocator pointer will be invalidated.
|
||||
pub fn initInPlace(self: *Allocators, gpa: std.mem.Allocator) void {
|
||||
self.* = .{
|
||||
.gpa = gpa,
|
||||
.arena = undefined,
|
||||
.arena_impl = std.heap.ArenaAllocator.init(gpa),
|
||||
};
|
||||
self.arena = self.arena_impl.allocator();
|
||||
}
|
||||
|
||||
/// Deinitialize the arena allocator.
|
||||
pub fn deinit(self: *Allocators) void {
|
||||
self.arena_impl.deinit();
|
||||
}
|
||||
};
|
||||
|
||||
test "base tests" {
|
||||
std.testing.refAllDecls(@import("CommonEnv.zig"));
|
||||
std.testing.refAllDecls(@import("DataSpan.zig"));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue