From 1e63471ae533f2b1f4b7ff84f2f962abce059e73 Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez Date: Sun, 12 Sep 2021 18:42:16 +0200 Subject: [PATCH] zig: update to zig/0.8.1 Adapt *.zig to changes in the zig library, and Makefile/run to the new output path for executables. Build system: * avoid symbolic links to executables. They increase complexity, are not useful, their timestamps or existence confuse make. * Acknowledge that Makefile is unable to build each step separately. Step files: * Add commented instructions printing `ast` at the start of the EVAL loop. The state in this commit now crashes with: /lib/std/hash_map.zig:863:33: 0x20ea58 in std.hash_map.HashMap([]const u8,*types.MalType,std.hash_map.StringContext,80).get (step6_file) Build with release-safe until this segmentation fault is fixed The original author has been contacted and intends to investigate. --- impls/zig/Dockerfile | 15 ++-- impls/zig/Makefile | 14 ++-- impls/zig/core.zig | 128 ++++++++++++++++----------------- impls/zig/env.zig | 12 ++-- impls/zig/hmap.zig | 34 +++------ impls/zig/linked_list.zig | 10 +-- impls/zig/printer.zig | 43 +++++------ impls/zig/reader.zig | 2 +- impls/zig/readline.zig | 2 +- impls/zig/run | 2 +- impls/zig/step0_repl.zig | 6 +- impls/zig/step1_read_print.zig | 12 ++-- impls/zig/step2_eval.zig | 40 +++++------ impls/zig/step3_env.zig | 51 ++++++------- impls/zig/step4_if_fn_do.zig | 49 ++++++------- impls/zig/step5_tco.zig | 49 ++++++------- impls/zig/step6_file.zig | 55 +++++++------- impls/zig/step7_quote.zig | 61 ++++++++-------- impls/zig/step8_macros.zig | 71 +++++++++--------- impls/zig/step9_try.zig | 77 ++++++++++---------- impls/zig/stepA_mal.zig | 78 ++++++++++---------- impls/zig/types.zig | 24 +++---- 22 files changed, 413 insertions(+), 422 deletions(-) diff --git a/impls/zig/Dockerfile b/impls/zig/Dockerfile index 2e70fa9bd9..0c6a79ebbc 100644 --- a/impls/zig/Dockerfile +++ b/impls/zig/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:bionic +FROM ubuntu:20.04 MAINTAINER Joel Martin ########################################################## @@ -11,9 +11,6 @@ RUN apt-get -y update # Required for running tests RUN apt-get -y install make python -# Some typical implementation and test requirements -RUN apt-get -y install curl libreadline-dev libedit-dev libpcre3-dev - RUN mkdir -p /mal WORKDIR /mal @@ -21,13 +18,9 @@ WORKDIR /mal # Specific implementation requirements ########################################################## -RUN apt-get -y install gcc gdc ldc gpg wget +RUN apt-get -y install ca-certificates curl gcc libc-dev libpcre3-dev libreadline-dev xz-utils -RUN wget https://ziglang.org/download/0.5.0/zig-linux-x86_64-0.5.0.tar.xz && \ - echo `pwd` && \ - tar -xf zig-linux-x86_64-0.5.0.tar.xz && \ - cp -r zig-linux-x86_64-0.5.0 /usr/local/bin && \ - ln -sf /usr/local/bin/zig-linux-x86_64-0.5.0/zig /usr/local/bin/zig && \ - chmod +x /usr/local/bin/zig +RUN curl https://ziglang.org/download/0.8.1/zig-linux-x86_64-0.8.1.tar.xz | tar -xJC/mal +RUN ln -fst/usr/local/bin /mal/zig-linux-x86_64-0.8.1/zig ENV HOME /mal diff --git a/impls/zig/Makefile b/impls/zig/Makefile index acf99b11d8..04012980e8 100644 --- a/impls/zig/Makefile +++ b/impls/zig/Makefile @@ -1,16 +1,16 @@ STEPS = step0_repl step1_read_print step2_eval step3_env step4_if_fn_do step5_tco step6_file step7_quote step8_macros step9_try stepA_mal -all: $(STEPS) +# TODO: it would be nice to be able to rebuild only one step. -dist: mal +# safe until the segfault is fixed. +# make HARD=1 REGRESS=1 test^zig +# was absent from 1c76e857f8f40c46a9b08274a26a0cca7fb20c77 with zig/0.5.0 - -%: %.zig - zig build -Drelease-fast=true - ln -sf zig-cache/bin/$* . +all $(STEPS): + zig build -Drelease-safe=true .PHONY: clean clean: - rm -f $(STEPS) + rm -fr zig-cache zig-out diff --git a/impls/zig/core.zig b/impls/zig/core.zig index 6e8ccd521c..96d317292e 100644 --- a/impls/zig/core.zig +++ b/impls/zig/core.zig @@ -80,16 +80,13 @@ fn int_geq(a1: *MalType, a2: *MalType) MalError!*MalType { } fn _linked_list_equality(l1: MalLinkedList, l2: MalLinkedList) MalError!bool { - if(l1.count() != l2.count()) { + if(l1.items.len != l2.items.len) { return false; } - var it1 = l1.iterator(); - var it2 = l2.iterator(); - while(true) { - const m1 = it1.next() orelse return (it2.next() == null); - const m2 = it2.next() orelse return false; + for (l1.items) |m1, idx| { + const m2 = l2.items[idx]; const el_cmp = try equality(m1, m2); - if(MalTypeValue(el_cmp.data) == MalTypeValue.False) { + if(@as(MalTypeValue, el_cmp.data) == MalTypeValue.False) { el_cmp.delete(Allocator); return false; } @@ -106,10 +103,10 @@ fn _hashmap_equality(h1: MalHashMap, h2: MalHashMap) MalError!bool { var iterator = h1.iterator(); var optional_pair = iterator.next(); while(optional_pair) |pair| { - const optional_val = h2.getValue(pair.key); + const optional_val = h2.get(pair.key_ptr.*); if(optional_val) |val| { - const el_cmp = try equality(pair.value, val); - if(MalTypeValue(el_cmp.data) == MalTypeValue.False) { + const el_cmp = try equality(pair.value_ptr.*, val); + if(@as(MalTypeValue, el_cmp.data) == MalTypeValue.False) { el_cmp.delete(Allocator); return false; } @@ -125,10 +122,10 @@ fn _hashmap_equality(h1: MalHashMap, h2: MalHashMap) MalError!bool { // TODO: make _equality -> bool fn equality(a1: *MalType, a2: *MalType) MalError!*MalType { - const a1_is_sequential = (MalTypeValue(a1.data) == MalTypeValue.List) or - (MalTypeValue(a1.data) == MalTypeValue.Vector); - const a2_is_sequential = (MalTypeValue(a2.data) == MalTypeValue.List) or - (MalTypeValue(a2.data) == MalTypeValue.Vector); + const a1_is_sequential = (@as(MalTypeValue, a1.data) == MalTypeValue.List) or + (@as(MalTypeValue, a1.data) == MalTypeValue.Vector); + const a2_is_sequential = (@as(MalTypeValue, a2.data) == MalTypeValue.List) or + (@as(MalTypeValue, a2.data) == MalTypeValue.Vector); if(a1_is_sequential and a2_is_sequential) { const l1 = (try a1.sequence_linked_list()).*; @@ -136,7 +133,7 @@ fn equality(a1: *MalType, a2: *MalType) MalError!*MalType { return MalType.new_bool(Allocator, try _linked_list_equality(l1, l2)); } - if(MalTypeValue(a1.data) != MalTypeValue(a2.data)) { + if(@as(MalTypeValue, a1.data) != @as(MalTypeValue, a2.data)) { return MalType.new_bool(Allocator, false); } @@ -189,14 +186,13 @@ fn vector(args: MalLinkedList) MalError!*MalType { } fn map(args: MalLinkedList) MalError!*MalType { - if(args.count() < 2) return MalError.ArgError; - const func_mal = args.at(0); - var args_mal = args.at(1); + if(args.items.len < 2) return MalError.ArgError; + const func_mal = args.items[0]; + var args_mal = args.items[1]; var new_ll = MalLinkedList.init(Allocator); var to_map_ll = try args_mal.sequence_linked_list(); - var iterator = to_map_ll.iterator(); - while(iterator.next()) |mal| { + for (to_map_ll.items) |mal| { var args_ll = MalLinkedList.init(Allocator); // TODO: can be more efficient than this try linked_list.append_mal(Allocator, &args_ll, try func_mal.copy(Allocator)); @@ -211,19 +207,19 @@ fn map(args: MalLinkedList) MalError!*MalType { } fn is_list(a1: *MalType) MalError!*MalType { - return MalType.new_bool(Allocator, MalTypeValue(a1.data) == MalTypeValue.List); + return MalType.new_bool(Allocator, @as(MalTypeValue, a1.data) == MalTypeValue.List); } fn is_vector(a1: *MalType) MalError!*MalType { - return MalType.new_bool(Allocator, MalTypeValue(a1.data) == MalTypeValue.Vector); + return MalType.new_bool(Allocator, @as(MalTypeValue, a1.data) == MalTypeValue.Vector); } pub fn is_string(a1: *MalType) MalError!*MalType { - return MalType.new_bool(Allocator, MalTypeValue(a1.data) == MalTypeValue.String); + return MalType.new_bool(Allocator, @as(MalTypeValue, a1.data) == MalTypeValue.String); } pub fn is_number(a1: *MalType) MalError!*MalType { - return MalType.new_bool(Allocator, MalTypeValue(a1.data) == MalTypeValue.Int); + return MalType.new_bool(Allocator, @as(MalTypeValue, a1.data) == MalTypeValue.Int); } pub fn is_fn(a1: *MalType) MalError!*MalType { @@ -250,17 +246,17 @@ pub fn is_macro(a1: *MalType) MalError!*MalType { fn empty(a1: *MalType) MalError!*MalType { return switch(a1.data) { - .List => |l| MalType.new_bool(Allocator, l.len == 0), - .Vector => |v| MalType.new_bool(Allocator, v.len == 0), + .List => |l| MalType.new_bool(Allocator, l.items.len == 0), + .Vector => |v| MalType.new_bool(Allocator, v.items.len == 0), else => MalType.new_bool(Allocator, false), }; } fn prn(args: MalLinkedList) MalError!*MalType { const s = try printer.print_mal_to_string(args, true, true); - const stdout_file = std.io.getStdOut() catch return MalError.SystemError; - stdout_file.write(s) catch return MalError.SystemError; - stdout_file.write("\n") catch return MalError.SystemError; + const stdout_file = std.io.getStdOut(); + stdout_file.writeAll(s) catch return MalError.SystemError; + stdout_file.writeAll("\n") catch return MalError.SystemError; Allocator.free(s); const mal = try MalType.new_nil(Allocator); return mal; @@ -268,16 +264,16 @@ fn prn(args: MalLinkedList) MalError!*MalType { fn println(args: MalLinkedList) MalError!*MalType { const s = try printer.print_mal_to_string(args, false, true); - const stdout_file = std.io.getStdOut() catch return MalError.SystemError; - stdout_file.write(s) catch return MalError.SystemError; - stdout_file.write("\n") catch return MalError.SystemError; + const stdout_file = std.io.getStdOut(); + stdout_file.writeAll(s) catch return MalError.SystemError; + stdout_file.writeAll("\n") catch return MalError.SystemError; Allocator.free(s); const mal = try MalType.new_nil(Allocator); return mal; } fn str(args: MalLinkedList) MalError!*MalType { - if(args.count() == 0) { + if(args.items.len == 0) { const s: []u8 = ""; return MalType.new_string(Allocator, s); } @@ -286,7 +282,7 @@ fn str(args: MalLinkedList) MalError!*MalType { } fn pr_str(args: MalLinkedList) MalError!*MalType { - if(args.count() == 0) { + if(args.items.len == 0) { const s: []u8 = ""; return MalType.new_string(Allocator, s); } @@ -297,7 +293,8 @@ fn pr_str(args: MalLinkedList) MalError!*MalType { fn slurp(a1: *MalType) MalError!*MalType { switch(a1.data) { .String => |path| { - const file_contents = std.io.readFileAlloc(Allocator, path) + const dir = std.fs.cwd(); + const file_contents = dir.readFileAlloc(Allocator, path, 10000) catch |err| return MalError.SystemError; // TODO: change this error defer Allocator.free(file_contents); return MalType.new_string(Allocator, file_contents); @@ -314,7 +311,7 @@ fn atom(a1: *MalType) MalError!*MalType { } fn is_atom(a1: *MalType) MalError!*MalType { - return MalType.new_bool(Allocator, MalTypeValue(a1.data) == MalTypeValue.Atom); + return MalType.new_bool(Allocator, @as(MalTypeValue, a1.data) == MalTypeValue.Atom); } fn deref(a1: *MalType) MalError!*MalType { @@ -337,8 +334,8 @@ fn atom_reset(a1: *MalType, a2: *MalType) MalError!*MalType { } fn atom_swap(args: MalLinkedList) MalError!*MalType { - const args_arr = args.toSlice(); - const n = args.len; + const args_arr = args.items; + const n = args_arr.len; if(n < 2) return MalError.ArgError; var new_args = MalLinkedList.init(Allocator); defer linked_list.destroy(Allocator, &new_args, false); @@ -382,14 +379,13 @@ pub fn concat(args: MalLinkedList) MalError!*MalType { // First we make a new array with shallow copies var new_ll = MalLinkedList.init(Allocator); errdefer linked_list.destroy(Allocator, &new_ll, false); - var iterator = args.iterator(); - while(iterator.next()) |mal| { + for (args.items) |mal| { const mal_seq = try mal.sequence_linked_list(); - new_ll.appendSlice(mal_seq.toSlice()) catch return MalError.SystemError; + new_ll.appendSlice(mal_seq.items) catch return MalError.SystemError; } // Now we turn the shallow copies into deep copies - const new_arr = new_ll.toSlice(); + const new_arr = new_ll.items; var i: usize = 0; while(i < new_arr.len) { new_arr[i] = try new_arr[i].copy(Allocator); @@ -412,7 +408,7 @@ pub fn rest(a1: *const MalType) MalError!*MalType { var new_list = try linked_list.deepcopy(Allocator, old_list); errdefer linked_list.destroy(Allocator, &new_list, false); - if(new_list.count() > 0) { + if(new_list.items.len > 0) { const mal = try linked_list.pop_first(Allocator, &new_list); mal.delete(Allocator); } @@ -424,10 +420,10 @@ pub fn rest(a1: *const MalType) MalError!*MalType { pub fn _nth(mal_list: *const MalType, pos: i64) MalError!*MalType { // TODO: vectors? const l = try mal_list.const_sequence_linked_list(); - if(pos < 0 or pos >= @intCast(i64,l.count())) { + if(pos < 0 or pos >= @intCast(i64,l.items.len)) { return MalError.OutOfBounds; } - return l.at(@intCast(usize,pos)); + return l.items[@intCast(usize,pos)]; } pub fn nth(a1: *const MalType, a2: *const MalType) MalError!*MalType { @@ -444,14 +440,14 @@ pub fn first(a1: *const MalType) MalError!*MalType { .Nil => return MalType.new_nil(Allocator), else => return MalError.TypeError, }; - if(l.count() == 0) return MalType.new_nil(Allocator); - return l.at(0).copy(Allocator); + if(l.items.len == 0) return MalType.new_nil(Allocator); + return l.items[0].copy(Allocator); } fn check_type(mal: *const MalType, value_type: MalTypeValue) MalError!*MalType { // TODO: use this everywhere // TODO: do this more generically - return MalType.new_bool(Allocator, MalTypeValue(mal.data) == value_type); + return MalType.new_bool(Allocator, @as(MalTypeValue, mal.data) == value_type); } pub fn is_nil(a1: *const MalType) MalError!*MalType { @@ -479,8 +475,8 @@ pub fn is_map(a1: *const MalType) MalError!*MalType { } pub fn is_sequential(a1: *const MalType) MalError!*MalType { - const res = (MalTypeValue(a1.data) == MalTypeValue.Vector) or - (MalTypeValue(a1.data) == MalTypeValue.List); + const res = (@as(MalTypeValue, a1.data) == MalTypeValue.Vector) or + (@as(MalTypeValue, a1.data) == MalTypeValue.List); return MalType.new_bool(Allocator, res); } @@ -494,7 +490,7 @@ pub fn symbol(a1: *const MalType) MalError!*MalType { pub fn hash_map(args: MalLinkedList) MalError!*MalType { const new_mal = try MalType.new_hashmap(Allocator); - const args_arr = args.toSlice(); + const args_arr = args.items; const n = args_arr.len; if((n%2) != 0) return MalError.ArgError; var i: usize = 0; @@ -514,7 +510,7 @@ pub fn hash_map(args: MalLinkedList) MalError!*MalType { } pub fn hash_map_assoc(args: MalLinkedList) MalError!*MalType { - const args_arr = args.toSlice(); + const args_arr = args.items; if(args_arr.len < 1) return MalError.ArgError; const new_mal = try MalType.new_nil(Allocator); errdefer new_mal.delete(Allocator); @@ -543,7 +539,7 @@ pub fn hash_map_assoc(args: MalLinkedList) MalError!*MalType { } pub fn hash_map_dissoc(args: MalLinkedList) MalError!*MalType { - const args_arr = args.toSlice(); + const args_arr = args.items; if(args_arr.len < 1) return MalError.ArgError; const new_mal = try MalType.new_nil(Allocator); errdefer new_mal.delete(Allocator); @@ -602,7 +598,7 @@ pub fn hash_map_keys(a1: *MalType) MalError!*MalType { while(true) { const pair = optional_pair orelse break; - const key = string_copy(Allocator, pair.key) catch return MalError.SystemError; + const key = string_copy(Allocator, pair.key_ptr.*) catch return MalError.SystemError; var key_mal: *MalType = undefined; if(key.len > 1 and key[0] == 255) { @@ -630,7 +626,7 @@ pub fn hash_map_vals(a1: *MalType) MalError!*MalType { while(true) { const pair = optional_pair orelse break; - const val = try pair.value.copy(Allocator); + const val = try pair.value_ptr.*.copy(Allocator); try linked_list.append_mal(Allocator, &new_ll, val); optional_pair = iterator.next(); } @@ -641,8 +637,8 @@ pub fn hash_map_vals(a1: *MalType) MalError!*MalType { pub fn sequence_length(a1: *MalType) MalError!*MalType { const len = switch(a1.data) { - .List => |l| l.count(), - .Vector => |v| v.count(), + .List => |l| l.items.len, + .Vector => |v| v.items.len, .String => |s| s.len, .Nil => 0, else => return MalError.TypeError, @@ -694,11 +690,11 @@ pub fn with_meta(a1: *MalType, a2: *MalType) MalError!*MalType { pub fn seq(a1: *MalType) MalError!*MalType { switch(a1.data) { .List => |l| { - if(l.count() == 0) return MalType.new_nil(Allocator); + if(l.items.len == 0) return MalType.new_nil(Allocator); return a1.copy(Allocator); }, .Vector => |v| { - if(v.count() == 0) return MalType.new_nil(Allocator); + if(v.items.len == 0) return MalType.new_nil(Allocator); const mal_copy = try a1.copy(Allocator); const ll = mal_copy.data.Vector; mal_copy.data = MalData{.List = ll}; @@ -708,7 +704,8 @@ pub fn seq(a1: *MalType) MalError!*MalType { if(s.len == 0) return MalType.new_nil(Allocator); const new_list = try MalType.new_list_empty(Allocator); for(s) |letter| { - const new_char = try MalType.new_string(Allocator, [_]u8 {letter}); + const s0 = [_]u8{letter, 0}; + const new_char = try MalType.new_string(Allocator, &s0); try new_list.sequence_append(Allocator, new_char); } return new_list; @@ -724,8 +721,8 @@ pub fn seq(a1: *MalType) MalError!*MalType { } pub fn conj(args: MalLinkedList) MalError!*MalType { - var iterator = args.iterator(); - const container = iterator.next() orelse return MalError.ArgError; + if(args.items.len == 0) return MalError.ArgError; + const container = args.items[0]; const append = switch(container.data) { .List => false, .Vector => true, @@ -733,7 +730,10 @@ pub fn conj(args: MalLinkedList) MalError!*MalType { }; var return_mal = try container.copy(Allocator); - while(iterator.next()) |mal| { + var i: usize = 1; + while(i |val| { - try fmt.format(rb, MalError, appendToBuffer, "{0}", val); + try fmt.format(writer(rb), "{0}", .{val}); }, .Nil => { try appendToBuffer(rb, "nil"); @@ -167,27 +174,21 @@ fn print_to_buffer(mal: *const MalType, rb: *ResizeBuffer, readable: bool) MalEr }, .List => |l| { try appendToBuffer(rb, "("); - var iterator = l.iterator(); - var first_iteration = true; - while(iterator.next()) |next_mal| { - if(!first_iteration) { + for (l.items) |next_mal, i| { + if(0 |v| { try appendToBuffer(rb, "["); - var iterator = v.iterator(); - var first_iteration = true; - while(iterator.next()) |next_mal| { - if(!first_iteration) { + for (v.items) |next_mal, i| { + if(0 1 and pair.key[0] == 255) { + if(pair.key_ptr.len > 1 and pair.key_ptr.*[0] == 255) { try appendToBuffer(rb, ":"); - try appendToBuffer(rb, pair.key[1..pair.key.len]); + try appendToBuffer(rb, pair.key_ptr.*[1..pair.key_ptr.len]); } else { try appendToBuffer(rb, "\""); - try appendToBuffer(rb, pair.key); + try appendToBuffer(rb, pair.key_ptr.*); try appendToBuffer(rb, "\""); } try appendToBuffer(rb, " "); - try print_to_buffer(pair.value, rb, readable); + try print_to_buffer(pair.value_ptr.*, rb, readable); first = false; } try appendToBuffer(rb, "}"); diff --git a/impls/zig/reader.zig b/impls/zig/reader.zig index c9c7d779dd..c5a23938fa 100644 --- a/impls/zig/reader.zig +++ b/impls/zig/reader.zig @@ -17,7 +17,7 @@ const string_eql = @import("utils.zig").string_eql; const linked_list = @import("linked_list.zig"); const match: [*]const u8 = - c\\[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"?|;.*|[^\s\[\]{}('"`,;)]*) + \\[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"?|;.*|[^\s\[\]{}('"`,;)]*) ; var error_msg: [*c]const u8 = undefined; var erroroffset: c_int = 0; diff --git a/impls/zig/readline.zig b/impls/zig/readline.zig index ed15d83f83..43968474b1 100644 --- a/impls/zig/readline.zig +++ b/impls/zig/readline.zig @@ -26,7 +26,7 @@ pub fn slice_from_cstr(allocator: *Allocator, str: [*]const u8) ![]u8{ } pub fn getline(allocator: *Allocator) !?[] u8 { - var input: ?[*] u8 = readline.readline(c"user> "); + var input: ?[*] u8 = readline.readline("user> "); if(input) |actual| { const aslice = try slice_from_cstr(allocator, actual); rl_hist.add_history(actual); diff --git a/impls/zig/run b/impls/zig/run index 8ba68a5484..938c080c74 100755 --- a/impls/zig/run +++ b/impls/zig/run @@ -1,2 +1,2 @@ #!/bin/bash -exec $(dirname $0)/${STEP:-stepA_mal} "${@}" +exec $(dirname $0)/zig-out/bin/${STEP:-stepA_mal} "${@}" diff --git a/impls/zig/step0_repl.zig b/impls/zig/step0_repl.zig index 265db0ff67..1d3eb3e78e 100644 --- a/impls/zig/step0_repl.zig +++ b/impls/zig/step0_repl.zig @@ -25,12 +25,12 @@ fn rep(input: [] u8) [] u8 { } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); while(true) { var line = (try getline(Allocator)) orelse break; var output = rep(line); - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } diff --git a/impls/zig/step1_read_print.zig b/impls/zig/step1_read_print.zig index 0b0793d073..03adb7656d 100644 --- a/impls/zig/step1_read_print.zig +++ b/impls/zig/step1_read_print.zig @@ -10,7 +10,7 @@ const Allocator = @import("std").heap.c_allocator; const MalType = @import("types.zig").MalType; -fn READ(a: [] u8) !?*MalType { +fn READ(a: []const u8) !?*MalType { var read = try reader.read_str(a); var optional_mal = reader.read_form(&read); return optional_mal; @@ -20,11 +20,11 @@ fn EVAL(a: ?*MalType) ?*MalType { return a; } -fn PRINT(optional_mal: ?*MalType) ![] u8 { +fn PRINT(optional_mal: ?*MalType) ![]const u8 { return printer.print_str(optional_mal); } -fn rep(input: [] u8) ![] u8 { +fn rep(input: []const u8) ![]const u8 { var read_input = READ(input) catch null; var eval_input = EVAL(read_input); var print_input = PRINT(eval_input); @@ -35,12 +35,12 @@ fn rep(input: [] u8) ![] u8 { } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); while(true) { var line = (try getline(Allocator)) orelse break; var output = try rep(line); - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } diff --git a/impls/zig/step2_eval.zig b/impls/zig/step2_eval.zig index e71d3d37ba..dad5655a10 100644 --- a/impls/zig/step2_eval.zig +++ b/impls/zig/step2_eval.zig @@ -21,16 +21,22 @@ const MalHashMap = hash_map.MalHashMap; var repl_environment: *MalHashMap = undefined; -fn READ(a: [] u8) MalError!?*MalType { +fn READ(a: []const u8) MalError!?*MalType { var read = try reader.read_str(a); var optional_mal = reader.read_form(&read); return optional_mal; } fn EVAL(mal: *MalType) MalError!*MalType { + + // const stdout = std.io.getStdOut(); + // stdout.writeAll("EVAL: ") catch return MalError.ThrownError; + // stdout.writeAll(try PRINT(mal)) catch return MalError.ThrownError; + // stdout.writeAll("\n") catch return MalError.ThrownError; + switch(mal.data) { .List => |ll| { - if(ll.len == 0) { + if(ll.items.len == 0) { return mal; } var new_list = try eval_ast(mal); @@ -42,11 +48,11 @@ fn EVAL(mal: *MalType) MalError!*MalType { } } -fn PRINT(optional_mal: ?*MalType) MalError![] u8 { +fn PRINT(optional_mal: ?*MalType) MalError![]const u8 { return printer.print_str(optional_mal); } -fn rep(input: [] u8) MalError!?[] u8 { +fn rep(input: []const u8) MalError!?[]const u8 { var read_input = (try READ(input)) orelse return null; var eval_input = try EVAL(read_input); var print_input = try PRINT(eval_input); @@ -55,16 +61,12 @@ fn rep(input: [] u8) MalError!?[] u8 { } fn lookup(symbol: []const u8, do_warn: bool) MalError!*MalType { - var optional_mal = repl_environment.getValue(symbol); + var optional_mal = repl_environment.get(symbol); if(optional_mal) |mal| { return mal.copy(Allocator); } if(do_warn) { - const s1 = string_concat(Allocator, "'", symbol) catch return MalError.SystemError; - const s2 = string_concat(Allocator, s1, "' not found") catch return MalError.SystemError; - defer Allocator.free(s1); - defer Allocator.free(s2); - warn("'{}' not found.\n", symbol); + warn("'{s}' not found.\n", .{symbol}); } return MalError.KeyError; } @@ -77,8 +79,7 @@ fn eval_ast(mal: *MalType) MalError!*MalType { }, .List => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -89,8 +90,7 @@ fn eval_ast(mal: *MalType) MalError!*MalType { }, .Vector => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -99,14 +99,14 @@ fn eval_ast(mal: *MalType) MalError!*MalType { const ret_mal = MalType.new_vector(Allocator, new_ll); return ret_mal; }, - .HashMap => |hmap| { + .HashMap => |*hmap| { var new_hashmap = try MalType.new_hashmap(Allocator); var iterator = hmap.iterator(); var optional_pair = iterator.next(); while(true) { const pair = optional_pair orelse break; - const key = pair.key; - const value = pair.value; + const key = pair.key_ptr.*; + const value = pair.value_ptr.*; const evaled_value = try EVAL(value); try new_hashmap.hashmap_insert(key, evaled_value); optional_pair = iterator.next(); @@ -176,7 +176,7 @@ fn make_environment() MalError!void { } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); try make_environment(); while(true) { var line = (try getline(Allocator)) orelse break; @@ -188,9 +188,9 @@ pub fn main() !void { } }; if(optional_output) |output| { - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } } diff --git a/impls/zig/step3_env.zig b/impls/zig/step3_env.zig index 3d65470601..19b33d05fe 100644 --- a/impls/zig/step3_env.zig +++ b/impls/zig/step3_env.zig @@ -22,16 +22,22 @@ const Env = @import("env.zig").Env; var repl_environment: *Env = undefined; -fn READ(a: [] u8) MalError!?*MalType { +fn READ(a: []const u8) MalError!?*MalType { var read = try reader.read_str(a); var optional_mal = reader.read_form(&read); return optional_mal; } fn EVAL(mal: *MalType, env: *Env) MalError!*MalType { + + // const stdout = std.io.getStdOut(); + // stdout.writeAll("EVAL: ") catch return MalError.ThrownError; + // stdout.writeAll(try PRINT(mal)) catch return MalError.ThrownError; + // stdout.writeAll("\n") catch return MalError.ThrownError; + switch(mal.data) { .List => |ll| { - if(ll.len == 0) { + if(ll.items.len == 0) { return mal; } var first_mal = linked_list.first(&ll) orelse return MalError.ArgError; @@ -78,15 +84,16 @@ fn EVAL_let(mal: *MalType, env: *Env) MalError!*MalType { .Vector => |v| v, else => return MalError.TypeError, }; - var iterator = binding_ll.iterator(); - var optional_node = iterator.next(); - while(optional_node) |node| { - const key_mal = node; + if(binding_ll.items.len % 2 != 0) return MalError.ArgError; + var i: usize = 0; + while(i < binding_ll.items.len) { + const key_mal = binding_ll.items[i]; + i += 1; const key = try key_mal.as_symbol(); - const val_mal = iterator.next() orelse return MalError.ArgError; + const val_mal = binding_ll.items[i]; + i += 1; const evaled_mal = try EVAL(val_mal, new_env); try new_env.set(key, evaled_mal); - optional_node = iterator.next(); key_mal.delete(Allocator); } @@ -98,11 +105,11 @@ fn EVAL_let(mal: *MalType, env: *Env) MalError!*MalType { return EVAL(eval_arg_copy, new_env); } -fn PRINT(optional_mal: ?*MalType) MalError![] u8 { +fn PRINT(optional_mal: ?*MalType) MalError![]const u8 { return printer.print_str(optional_mal); } -fn rep(environment: *Env, input: [] u8) MalError!?[] u8 { +fn rep(environment: *Env, input: []const u8) MalError!?[]const u8 { var read_input = (try READ(input)) orelse return null; var eval_input = try EVAL(read_input, environment); var print_input = try PRINT(eval_input); @@ -113,11 +120,7 @@ fn rep(environment: *Env, input: [] u8) MalError!?[] u8 { fn lookup(environment: *Env, symbol: []const u8, do_warn: bool) MalError!*MalType { var mal = environment.get(symbol) catch |err| { if(do_warn) { - const s1 = string_concat(Allocator, "'", symbol) catch return MalError.SystemError; - const s2 = string_concat(Allocator, s1, "' not found") catch return MalError.SystemError; - defer Allocator.free(s1); - defer Allocator.free(s2); - warn("'{}' not found.\n", symbol); + warn("'{s}' not found.\n", .{symbol}); } return MalError.KeyError; }; @@ -133,8 +136,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .List => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -145,8 +147,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .Vector => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -155,14 +156,14 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { const ret_mal = MalType.new_vector(Allocator, new_ll); return ret_mal; }, - .HashMap => |hmap| { + .HashMap => |*hmap| { var new_hashmap = try MalType.new_hashmap(Allocator); var iterator = hmap.iterator(); var optional_pair = iterator.next(); while(true) { const pair = optional_pair orelse break; - const key = pair.key; - const value = pair.value; + const key = pair.key_ptr.*; + const value = pair.value_ptr.*; const evaled_value = try EVAL(value, try env.copy(Allocator)); try new_hashmap.hashmap_insert(key, evaled_value); optional_pair = iterator.next(); @@ -234,7 +235,7 @@ fn make_environment() MalError!*Env { } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); var environment = try make_environment(); while(true) { var line = (try getline(Allocator)) orelse break; @@ -246,9 +247,9 @@ pub fn main() !void { } }; if(optional_output) |output| { - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } } diff --git a/impls/zig/step4_if_fn_do.zig b/impls/zig/step4_if_fn_do.zig index cc4cb24542..cd085b9cb8 100644 --- a/impls/zig/step4_if_fn_do.zig +++ b/impls/zig/step4_if_fn_do.zig @@ -31,9 +31,15 @@ fn READ(a: []const u8) MalError!?*MalType { } fn EVAL(mal: *MalType, env: *Env) MalError!*MalType { + + // const stdout = std.io.getStdOut(); + // stdout.writeAll("EVAL: ") catch return MalError.ThrownError; + // stdout.writeAll(try PRINT(mal)) catch return MalError.ThrownError; + // stdout.writeAll("\n") catch return MalError.ThrownError; + switch(mal.data) { .List => |ll| { - if(ll.len == 0) { + if(ll.items.len == 0) { return mal; } var first_mal = linked_list.first(&ll) orelse return MalError.ArgError; @@ -89,15 +95,16 @@ fn EVAL_let(mal: *MalType, env: *Env) MalError!*MalType { .Vector => |v| v, else => return MalError.TypeError, }; - var iterator = binding_ll.iterator(); - var optional_node = iterator.next(); - while(optional_node) |node| { - const key_mal = node; + if(binding_ll.items.len % 2 != 0) return MalError.ArgError; + var i: usize = 0; + while(i < binding_ll.items.len) { + const key_mal = binding_ll.items[i]; + i += 1; const key = try key_mal.as_symbol(); - const val_mal = iterator.next() orelse return MalError.ArgError; + const val_mal = binding_ll.items[i]; + i += 1; const evaled_mal = try EVAL(val_mal, new_env); try new_env.set(key, evaled_mal); - optional_node = iterator.next(); key_mal.delete(Allocator); } @@ -157,11 +164,11 @@ fn EVAL_fn(mal: *MalType, env: *Env) MalError!*MalType { return new_func; } -fn PRINT(optional_mal: ?*MalType) MalError![] u8 { +fn PRINT(optional_mal: ?*MalType) MalError![]const u8 { return printer.print_str(optional_mal); } -fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { +fn rep(environment: *Env, input: []const u8) MalError!?[]const u8 { var read_input = (try READ(input)) orelse return null; var eval_input = try EVAL(read_input, try environment.copy(Allocator)); var print_input = try PRINT(eval_input); @@ -172,11 +179,7 @@ fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { fn lookup(environment: *Env, symbol: []const u8, do_warn: bool) MalError!*MalType { var mal = environment.get(symbol) catch |err| { if(do_warn) { - const s1 = string_concat(Allocator, "'", symbol) catch return MalError.SystemError; - const s2 = string_concat(Allocator, s1, "' not found") catch return MalError.SystemError; - defer Allocator.free(s1); - defer Allocator.free(s2); - warn("'{}' not found.\n", symbol); + warn("'{s}' not found.\n", .{symbol}); } return MalError.KeyError; }; @@ -192,8 +195,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .List => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -204,8 +206,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .Vector => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -214,14 +215,14 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { const ret_mal = MalType.new_vector(Allocator, new_ll); return ret_mal; }, - .HashMap => |hmap| { + .HashMap => |*hmap| { var new_hashmap = try MalType.new_hashmap(Allocator); var iterator = hmap.iterator(); var optional_pair = iterator.next(); while(true) { const pair = optional_pair orelse break; - const key = pair.key; - const value = pair.value; + const key = pair.key_ptr.*; + const value = pair.value_ptr.*; const evaled_value = try EVAL(value, try env.copy(Allocator)); try new_hashmap.hashmap_insert(key, evaled_value); optional_pair = iterator.next(); @@ -265,7 +266,7 @@ fn make_environment() MalError!*Env { } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); core.set_allocator(Allocator); var environment = try make_environment(); while(true) { @@ -278,10 +279,10 @@ pub fn main() !void { } }; if(optional_output) |output| { - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); Allocator.free(line); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } } diff --git a/impls/zig/step5_tco.zig b/impls/zig/step5_tco.zig index 0bece1b341..8432d1cffb 100644 --- a/impls/zig/step5_tco.zig +++ b/impls/zig/step5_tco.zig @@ -34,9 +34,15 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { var mal = mal_arg; var env = env_arg; while(true) { + + // const stdout = std.io.getStdOut(); + // stdout.writeAll("EVAL: ") catch return MalError.ThrownError; + // stdout.writeAll(try PRINT(mal)) catch return MalError.ThrownError; + // stdout.writeAll("\n") catch return MalError.ThrownError; + switch(mal.data) { .List => |ll| { - if(ll.len == 0) { + if(ll.items.len == 0) { return mal; } var first_mal = linked_list.first(&ll) orelse return MalError.ArgError; @@ -97,15 +103,16 @@ fn EVAL_let(mal_ptr: **MalType, env_ptr: **Env) MalError!void { .Vector => |v| v, else => return MalError.TypeError, }; - var iterator = binding_ll.iterator(); - var optional_node = iterator.next(); - while(optional_node) |node| { - const key_mal = node; + if(binding_ll.items.len % 2 != 0) return MalError.ArgError; + var i: usize = 0; + while(i < binding_ll.items.len) { + const key_mal = binding_ll.items[i]; + i += 1; const key = try key_mal.as_symbol(); - const val_mal = iterator.next() orelse return MalError.ArgError; + const val_mal = binding_ll.items[i]; + i += 1; const evaled_mal = try EVAL(val_mal, new_env); try new_env.set(key, evaled_mal); - optional_node = iterator.next(); key_mal.delete(Allocator); } @@ -172,11 +179,11 @@ fn EVAL_fn(mal: *MalType, env: *Env) MalError!*MalType { return new_func; } -fn PRINT(optional_mal: ?*MalType) MalError![] u8 { +fn PRINT(optional_mal: ?*MalType) MalError![]const u8 { return printer.print_str(optional_mal); } -fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { +fn rep(environment: *Env, input: []const u8) MalError!?[]const u8 { var read_input = (try READ(input)) orelse return null; var eval_input = try EVAL(read_input, environment); var print_input = try PRINT(eval_input); @@ -187,11 +194,7 @@ fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { fn lookup(environment: *Env, symbol: []const u8, do_warn: bool) MalError!*MalType { var mal = environment.get(symbol) catch |err| { if(do_warn) { - const s1 = string_concat(Allocator, "'", symbol) catch return MalError.SystemError; - const s2 = string_concat(Allocator, s1, "' not found") catch return MalError.SystemError; - defer Allocator.free(s1); - defer Allocator.free(s2); - warn("'{}' not found.\n", symbol); + warn("'{s}' not found.\n", .{symbol}); } return MalError.KeyError; }; @@ -207,8 +210,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .List => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -219,8 +221,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .Vector => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -229,14 +230,14 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { const ret_mal = MalType.new_vector(Allocator, new_ll); return ret_mal; }, - .HashMap => |hmap| { + .HashMap => |*hmap| { var new_hashmap = try MalType.new_hashmap(Allocator); var iterator = hmap.iterator(); var optional_pair = iterator.next(); while(true) { const pair = optional_pair orelse break; - const key = pair.key; - const value = pair.value; + const key = pair.key_ptr.*; + const value = pair.value_ptr.*; const evaled_value = try EVAL(value, try env.copy(Allocator)); try new_hashmap.hashmap_insert(key, evaled_value); optional_pair = iterator.next(); @@ -280,7 +281,7 @@ fn make_environment() MalError!*Env { } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); core.set_allocator(Allocator); var environment = try make_environment(); while(true) { @@ -293,10 +294,10 @@ pub fn main() !void { } }; if(optional_output) |output| { - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); Allocator.free(line); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } } diff --git a/impls/zig/step6_file.zig b/impls/zig/step6_file.zig index ca897bd160..6651eadb9d 100644 --- a/impls/zig/step6_file.zig +++ b/impls/zig/step6_file.zig @@ -35,9 +35,15 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { var mal = mal_arg; var env = env_arg; while(true) { + + // const stdout = std.io.getStdOut(); + // stdout.writeAll("EVAL: ") catch return MalError.ThrownError; + // stdout.writeAll(try PRINT(mal)) catch return MalError.ThrownError; + // stdout.writeAll("\n") catch return MalError.ThrownError; + switch(mal.data) { .List => |ll| { - if(ll.len == 0) { + if(ll.items.len == 0) { return mal; } var first_mal = linked_list.first(&ll) orelse return MalError.ArgError; @@ -66,7 +72,7 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { else { var new_list = try eval_ast(mal, try env.copy(Allocator)); - if(MalTypeValue((try new_list.sequence_nth(0)).data) == MalTypeValue.Func) { + if(@as(MalTypeValue, (try new_list.sequence_nth(0)).data) == MalTypeValue.Func) { try do_user_func(try new_list.sequence_linked_list(), &mal, &env); new_list.shallow_destroy(Allocator); continue; @@ -113,15 +119,16 @@ fn EVAL_let(mal_ptr: **MalType, env_ptr: **Env) MalError!void { .Vector => |v| v, else => return MalError.TypeError, }; - var iterator = binding_ll.iterator(); - var optional_node = iterator.next(); - while(optional_node) |node| { - const key_mal = node; + if(binding_ll.items.len % 2 != 0) return MalError.ArgError; + var i: usize = 0; + while(i < binding_ll.items.len) { + const key_mal = binding_ll.items[i]; + i += 1; const key = try key_mal.as_symbol(); - const val_mal = iterator.next() orelse return MalError.ArgError; - const evaled_mal = try EVAL(val_mal, try new_env.copy(Allocator)); + const val_mal = binding_ll.items[i]; + i += 1; + const evaled_mal = try EVAL(val_mal, new_env); try new_env.set(key, evaled_mal); - optional_node = iterator.next(); key_mal.delete(Allocator); } @@ -190,11 +197,11 @@ fn EVAL_fn(mal: *MalType, env: *Env) MalError!*MalType { return new_func; } -fn PRINT(optional_mal: ?*MalType) MalError![] u8 { +fn PRINT(optional_mal: ?*MalType) MalError![]const u8 { return printer.print_str(optional_mal); } -fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { +fn rep(environment: *Env, input: []const u8) MalError!?[]const u8 { var read_input = (try READ(input)) orelse return null; var eval_input = try EVAL(read_input, try environment.copy(Allocator)); var print_input = try PRINT(eval_input); @@ -205,11 +212,7 @@ fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { fn lookup(environment: *Env, symbol: []const u8, do_warn: bool) MalError!*MalType { var mal = environment.get(symbol) catch |err| { if(do_warn) { - const s1 = string_concat(Allocator, "'", symbol) catch return MalError.SystemError; - const s2 = string_concat(Allocator, s1, "' not found") catch return MalError.SystemError; - defer Allocator.free(s1); - defer Allocator.free(s2); - warn("'{}' not found.\n", symbol); + warn("'{s}' not found.\n", .{symbol}); } return MalError.KeyError; }; @@ -226,8 +229,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .List => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -238,8 +240,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .Vector => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -248,14 +249,14 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { const ret_mal = MalType.new_vector(Allocator, new_ll); return ret_mal; }, - .HashMap => |hmap| { + .HashMap => |*hmap| { var new_hashmap = try MalType.new_hashmap(Allocator); var iterator = hmap.iterator(); var optional_pair = iterator.next(); while(true) { const pair = optional_pair orelse break; - const key = pair.key; - const value = pair.value; + const key = pair.key_ptr.*; + const value = pair.value_ptr.*; const evaled_value = try EVAL(value, try env.copy(Allocator)); try new_hashmap.hashmap_insert(key, evaled_value); optional_pair = iterator.next(); @@ -314,7 +315,7 @@ fn do_user_func(args: *MalLinkedList, mal_ptr: **MalType, env_ptr: **Env) MalErr const mal_func = try linked_list.pop_first(Allocator, args); const env = env_ptr.*; // First check if it is a user-defined Mal function - if(MalTypeValue(mal_func.data) == MalTypeValue.Func) { + if(@as(MalTypeValue, mal_func.data) == MalTypeValue.Func) { const func_data = mal_func.data.Func; const args_ll = try func_data.arg_list.sequence_linked_list(); const func_env = func_data.environment; @@ -333,7 +334,7 @@ fn do_user_func(args: *MalLinkedList, mal_ptr: **MalType, env_ptr: **Env) MalErr } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); core.set_allocator(Allocator); var environment = try make_environment(); @@ -362,10 +363,10 @@ pub fn main() !void { } }; if(optional_output) |output| { - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); Allocator.free(line); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } } diff --git a/impls/zig/step7_quote.zig b/impls/zig/step7_quote.zig index 0b26ed2583..72b1b3e230 100644 --- a/impls/zig/step7_quote.zig +++ b/impls/zig/step7_quote.zig @@ -35,9 +35,15 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { var mal = mal_arg; var env = env_arg; while(true) { + + // const stdout = std.io.getStdOut(); + // stdout.writeAll("EVAL: ") catch return MalError.ThrownError; + // stdout.writeAll(try PRINT(mal)) catch return MalError.ThrownError; + // stdout.writeAll("\n") catch return MalError.ThrownError; + switch(mal.data) { .List => |ll| { - if(ll.len == 0) { + if(ll.items.len == 0) { return mal; } var first_mal = linked_list.first(&ll) orelse return MalError.ArgError; @@ -83,7 +89,7 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { else { var new_list = try eval_ast(mal, try env.copy(Allocator)); - if(MalTypeValue((try new_list.sequence_nth(0)).data) == MalTypeValue.Func) { + if(@as(MalTypeValue, (try new_list.sequence_nth(0)).data) == MalTypeValue.Func) { try do_user_func(try new_list.sequence_linked_list(), &mal, &env); new_list.shallow_destroy(Allocator); continue; @@ -110,10 +116,10 @@ fn starts_with(ast: *MalType, sym: []const u8) bool { .List => |l| l, else => return false, }; - if(ll.count() < 2) { + if(ll.items.len < 2) { return false; } - const ss = switch(ll.at(0).data) { + const ss = switch(ll.items[0].data) { .Generic => |s| s, else => return false, }; @@ -145,15 +151,16 @@ fn EVAL_let(mal_ptr: **MalType, env_ptr: **Env) MalError!void { .Vector => |v| v, else => return MalError.TypeError, }; - var iterator = binding_ll.iterator(); - var optional_node = iterator.next(); - while(optional_node) |node| { - const key_mal = node; + if(binding_ll.items.len % 2 != 0) return MalError.ArgError; + var i: usize = 0; + while(i < binding_ll.items.len) { + const key_mal = binding_ll.items[i]; + i += 1; const key = try key_mal.as_symbol(); - const val_mal = iterator.next() orelse return MalError.ArgError; - const evaled_mal = try EVAL(val_mal, try new_env.copy(Allocator)); + const val_mal = binding_ll.items[i]; + i += 1; + const evaled_mal = try EVAL(val_mal, new_env); try new_env.set(key, evaled_mal); - optional_node = iterator.next(); key_mal.delete(Allocator); } @@ -230,7 +237,7 @@ fn EVAL_quote(mal: *MalType, env: *Env) MalError!*MalType { } fn quasiquote(ast: *MalType) MalError!*MalType { - const kind = MalTypeValue(ast.data); + const kind = @as(MalTypeValue, ast.data); if(kind == MalTypeValue.Generic or kind == MalTypeValue.HashMap) { const new_list = try MalType.new_list_empty(Allocator); try new_list.sequence_append(Allocator, try MalType.new_generic(Allocator, "quote")); @@ -275,11 +282,11 @@ fn quasiquote(ast: *MalType) MalError!*MalType { return result; } -fn PRINT(optional_mal: ?*MalType) MalError![] u8 { +fn PRINT(optional_mal: ?*MalType) MalError![]const u8 { return printer.print_str(optional_mal); } -fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { +fn rep(environment: *Env, input: []const u8) MalError!?[]const u8 { var read_input = (try READ(input)) orelse return null; var eval_input = try EVAL(read_input, try environment.copy(Allocator)); var print_input = try PRINT(eval_input); @@ -290,11 +297,7 @@ fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { fn lookup(environment: *Env, symbol: []const u8, do_warn: bool) MalError!*MalType { var mal = environment.get(symbol) catch |err| { if(do_warn) { - const s1 = string_concat(Allocator, "'", symbol) catch return MalError.SystemError; - const s2 = string_concat(Allocator, s1, "' not found") catch return MalError.SystemError; - defer Allocator.free(s1); - defer Allocator.free(s2); - warn("'{}' not found.\n", symbol); + warn("'{s}' not found.\n", .{symbol}); } return MalError.KeyError; }; @@ -311,8 +314,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .List => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -323,8 +325,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .Vector => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -333,14 +334,14 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { const ret_mal = MalType.new_vector(Allocator, new_ll); return ret_mal; }, - .HashMap => |hmap| { + .HashMap => |*hmap| { var new_hashmap = try MalType.new_hashmap(Allocator); var iterator = hmap.iterator(); var optional_pair = iterator.next(); while(true) { const pair = optional_pair orelse break; - const key = pair.key; - const value = pair.value; + const key = pair.key_ptr.*; + const value = pair.value_ptr.*; const evaled_value = try EVAL(value, try env.copy(Allocator)); try new_hashmap.hashmap_insert(key, evaled_value); optional_pair = iterator.next(); @@ -399,7 +400,7 @@ fn do_user_func(args: *MalLinkedList, mal_ptr: **MalType, env_ptr: **Env) MalErr const mal_func = try linked_list.pop_first(Allocator, args); const env = env_ptr.*; // First check if it is a user-defined Mal function - if(MalTypeValue(mal_func.data) == MalTypeValue.Func) { + if(@as(MalTypeValue, mal_func.data) == MalTypeValue.Func) { const func_data = mal_func.data.Func; const args_ll = try func_data.arg_list.sequence_linked_list(); const func_env = func_data.environment; @@ -418,7 +419,7 @@ fn do_user_func(args: *MalLinkedList, mal_ptr: **MalType, env_ptr: **Env) MalErr } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); core.set_allocator(Allocator); var environment = try make_environment(); @@ -447,10 +448,10 @@ pub fn main() !void { } }; if(optional_output) |output| { - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); Allocator.free(line); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } } diff --git a/impls/zig/step8_macros.zig b/impls/zig/step8_macros.zig index 4559db7d3d..8715af1857 100644 --- a/impls/zig/step8_macros.zig +++ b/impls/zig/step8_macros.zig @@ -35,10 +35,16 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { var mal = mal_arg; var env = env_arg; while(true) { + + // const stdout = std.io.getStdOut(); + // stdout.writeAll("EVAL: ") catch return MalError.ThrownError; + // stdout.writeAll(try PRINT(mal)) catch return MalError.ThrownError; + // stdout.writeAll("\n") catch return MalError.ThrownError; + mal = try macroexpand(mal, env); switch(mal.data) { .List => |ll| { - if(ll.len == 0) { + if(ll.items.len == 0) { return mal; } var first_mal = linked_list.first(&ll) orelse return MalError.ArgError; @@ -94,7 +100,7 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { else { var new_list = try eval_ast(mal, try env.copy(Allocator)); - if(MalTypeValue((try new_list.sequence_nth(0)).data) == MalTypeValue.Func) { + if(@as(MalTypeValue, (try new_list.sequence_nth(0)).data) == MalTypeValue.Func) { try do_user_func(try new_list.sequence_linked_list(), &mal, &env); new_list.shallow_destroy(Allocator); continue; @@ -121,10 +127,10 @@ fn starts_with(ast: *MalType, sym: []const u8) bool { .List => |l| l, else => return false, }; - if(ll.count() < 2) { + if(ll.items.len < 2) { return false; } - const ss = switch(ll.at(0).data) { + const ss = switch(ll.items[0].data) { .Generic => |s| s, else => return false, }; @@ -159,7 +165,7 @@ fn macroexpand(mal: *MalType, env: *Env) MalError!*MalType { while(optional_macro) |macro| { var new_list = (try cur_mal.sequence_linked_list()).*; - if(new_list.count() > 0) { + if(new_list.items.len > 0) { const first = try linked_list.pop_first(Allocator, &new_list); first.delete(Allocator); } @@ -205,15 +211,16 @@ fn EVAL_let(mal_ptr: **MalType, env_ptr: **Env) MalError!void { .Vector => |v| v, else => return MalError.TypeError, }; - var iterator = binding_ll.iterator(); - var optional_node = iterator.next(); - while(optional_node) |node| { - const key_mal = node; + if(binding_ll.items.len % 2 != 0) return MalError.ArgError; + var i: usize = 0; + while(i < binding_ll.items.len) { + const key_mal = binding_ll.items[i]; + i += 1; const key = try key_mal.as_symbol(); - const val_mal = iterator.next() orelse return MalError.ArgError; - const evaled_mal = try EVAL(val_mal, try new_env.copy(Allocator)); + const val_mal = binding_ll.items[i]; + i += 1; + const evaled_mal = try EVAL(val_mal, new_env); try new_env.set(key, evaled_mal); - optional_node = iterator.next(); key_mal.delete(Allocator); } @@ -290,7 +297,7 @@ fn EVAL_quote(mal: *MalType, env: *Env) MalError!*MalType { } fn quasiquote(ast: *MalType) MalError!*MalType { - const kind = MalTypeValue(ast.data); + const kind = @as(MalTypeValue, ast.data); if(kind == MalTypeValue.Generic or kind == MalTypeValue.HashMap) { const new_list = try MalType.new_list_empty(Allocator); try new_list.sequence_append(Allocator, try MalType.new_generic(Allocator, "quote")); @@ -335,11 +342,11 @@ fn quasiquote(ast: *MalType) MalError!*MalType { return result; } -fn PRINT(optional_mal: ?*MalType) MalError![] u8 { +fn PRINT(optional_mal: ?*MalType) MalError![]const u8 { return printer.print_str(optional_mal); } -fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { +fn rep(environment: *Env, input: []const u8) MalError!?[]const u8 { var read_input = (try READ(input)) orelse return null; var eval_input = try EVAL(read_input, try environment.copy(Allocator)); var print_input = try PRINT(eval_input); @@ -347,18 +354,18 @@ fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { return print_input; } -fn rep_and_print_errors(environment: *Env, input: [] const u8) ?[]u8 { +fn rep_and_print_errors(environment: *Env, input: [] const u8) ?[]const u8 { return rep(environment, input) catch |err| { switch(err) { MalError.KeyError => { }, MalError.OutOfBounds => { - warn("Error: out of bounds\n"); + warn("Error: out of bounds\n", .{}); }, MalError.ReaderUnmatchedParen => { - warn("Error: expected closing paren, got EOF\n"); + warn("Error: expected closing paren, got EOF\n", .{}); }, else => { - warn("Unhandled error\n"); + warn("Unhandled error\n", .{}); }, } return null; @@ -369,11 +376,7 @@ fn rep_and_print_errors(environment: *Env, input: [] const u8) ?[]u8 { fn lookup(environment: *Env, symbol: []const u8, do_warn: bool) MalError!*MalType { var mal = environment.get(symbol) catch |err| { if(do_warn) { - const s1 = string_concat(Allocator, "'", symbol) catch return MalError.SystemError; - const s2 = string_concat(Allocator, s1, "' not found") catch return MalError.SystemError; - defer Allocator.free(s1); - defer Allocator.free(s2); - warn("'{}' not found.\n", symbol); + warn("'{s}' not found.\n", .{symbol}); } return MalError.KeyError; }; @@ -390,8 +393,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .List => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -402,8 +404,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .Vector => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -412,14 +413,14 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { const ret_mal = MalType.new_vector(Allocator, new_ll); return ret_mal; }, - .HashMap => |hmap| { + .HashMap => |*hmap| { var new_hashmap = try MalType.new_hashmap(Allocator); var iterator = hmap.iterator(); var optional_pair = iterator.next(); while(true) { const pair = optional_pair orelse break; - const key = pair.key; - const value = pair.value; + const key = pair.key_ptr.*; + const value = pair.value_ptr.*; const evaled_value = try EVAL(value, try env.copy(Allocator)); try new_hashmap.hashmap_insert(key, evaled_value); optional_pair = iterator.next(); @@ -486,7 +487,7 @@ fn do_user_func(args: *MalLinkedList, mal_ptr: **MalType, env_ptr: **Env) MalErr const mal_func = try linked_list.pop_first(Allocator, args); const env = env_ptr.*; // First check if it is a user-defined Mal function - if(MalTypeValue(mal_func.data) == MalTypeValue.Func) { + if(@as(MalTypeValue, mal_func.data) == MalTypeValue.Func) { const func_data = mal_func.data.Func; const args_ll = try func_data.arg_list.sequence_linked_list(); const func_env = func_data.environment; @@ -505,7 +506,7 @@ fn do_user_func(args: *MalLinkedList, mal_ptr: **MalType, env_ptr: **Env) MalErr } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); core.set_allocator(Allocator); var environment = try make_environment(); @@ -527,9 +528,9 @@ pub fn main() !void { while(true) { var line = (try getline(Allocator)) orelse break; var output = rep_and_print_errors(environment, line) orelse continue; - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); Allocator.free(line); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } diff --git a/impls/zig/step9_try.zig b/impls/zig/step9_try.zig index d56146577e..e317ba65bc 100644 --- a/impls/zig/step9_try.zig +++ b/impls/zig/step9_try.zig @@ -37,10 +37,16 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { var mal = mal_arg; var env = env_arg; while(true) { + + // const stdout = std.io.getStdOut(); + // stdout.writeAll("EVAL: ") catch return MalError.ThrownError; + // stdout.writeAll(try PRINT(mal)) catch return MalError.ThrownError; + // stdout.writeAll("\n") catch return MalError.ThrownError; + mal = try macroexpand(mal, env); switch(mal.data) { .List => |ll| { - if(ll.len == 0) { + if(ll.items.len == 0) { env.delete(); return mal; } @@ -100,7 +106,7 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { else { var new_list = try eval_ast(mal, try env.copy(Allocator)); - if(MalTypeValue((try new_list.sequence_nth(0)).data) == MalTypeValue.Func) { + if(@as(MalTypeValue, (try new_list.sequence_nth(0)).data) == MalTypeValue.Func) { try do_user_func(try new_list.sequence_linked_list(), &mal, &env); new_list.shallow_destroy(Allocator); continue; @@ -127,10 +133,10 @@ fn starts_with(ast: *MalType, sym: []const u8) bool { .List => |l| l, else => return false, }; - if(ll.count() < 2) { + if(ll.items.len < 2) { return false; } - const ss = switch(ll.at(0).data) { + const ss = switch(ll.items[0].data) { .Generic => |s| s, else => return false, }; @@ -165,7 +171,7 @@ fn macroexpand(mal: *MalType, env: *Env) MalError!*MalType { while(optional_macro) |macro| { var new_list = (try cur_mal.sequence_linked_list()).*; - if(new_list.count() > 0) { + if(new_list.items.len > 0) { const first = try linked_list.pop_first(Allocator, &new_list); first.delete(Allocator); } @@ -211,15 +217,16 @@ fn EVAL_let(mal_ptr: **MalType, env_ptr: **Env) MalError!void { .Vector => |v| v, else => return MalError.TypeError, }; - var iterator = binding_ll.iterator(); - var optional_node = iterator.next(); - while(optional_node) |node| { - const key_mal = node; + if(binding_ll.items.len % 2 != 0) return MalError.ArgError; + var i: usize = 0; + while(i < binding_ll.items.len) { + const key_mal = binding_ll.items[i]; + i += 1; const key = try key_mal.as_symbol(); - const val_mal = iterator.next() orelse return MalError.ArgError; - const evaled_mal = try EVAL(val_mal, try new_env.copy(Allocator)); + const val_mal = binding_ll.items[i]; + i += 1; + const evaled_mal = try EVAL(val_mal, new_env); try new_env.set(key, evaled_mal); - optional_node = iterator.next(); key_mal.delete(Allocator); } @@ -333,7 +340,7 @@ fn EVAL_try(mal: *MalType, env: *Env) MalError!*MalType { } fn quasiquote(ast: *MalType) MalError!*MalType { - const kind = MalTypeValue(ast.data); + const kind = @as(MalTypeValue, ast.data); if(kind == MalTypeValue.Generic or kind == MalTypeValue.HashMap) { const new_list = try MalType.new_list_empty(Allocator); try new_list.sequence_append(Allocator, try MalType.new_generic(Allocator, "quote")); @@ -378,11 +385,11 @@ fn quasiquote(ast: *MalType) MalError!*MalType { return result; } -fn PRINT(optional_mal: ?*MalType) MalError![] u8 { +fn PRINT(optional_mal: ?*MalType) MalError![]const u8 { return printer.print_str(optional_mal); } -fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { +fn rep(environment: *Env, input: []const u8) MalError!?[]const u8 { var read_input = (try READ(input)) orelse return null; var eval_input = try EVAL(read_input, try environment.copy(Allocator)); var print_input = try PRINT(eval_input); @@ -390,28 +397,28 @@ fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { return print_input; } -fn rep_and_print_errors(environment: *Env, input: [] const u8) ?[]u8 { +fn rep_and_print_errors(environment: *Env, input: [] const u8) ?[]const u8 { return rep(environment, input) catch |err| { switch(err) { MalError.KeyError => { }, MalError.OutOfBounds => { - warn("Error: out of bounds\n"); + warn("Error: out of bounds\n", .{}); }, MalError.ThrownError => { - warn("Thrown error: "); + warn("Thrown error: ", .{}); const error_mal = lookup(environment, "__error", false) - catch {warn("\n"); return null;}; + catch {warn("\n", .{}); return null;}; const warning = PRINT(error_mal) - catch {warn("\n"); return null;}; - warn("{}\n", warning); + catch {warn("\n", .{}); return null;}; + warn("{s}\n", .{warning}); error_mal.delete(Allocator); Allocator.free(warning); }, MalError.ReaderUnmatchedParen => { - warn("Error: expected closing paren, got EOF\n"); + warn("Error: expected closing paren, got EOF\n", .{}); }, else => { - warn("Error: {}\n", error_string_repr(err)); + warn("Error: {s}\n", .{error_string_repr(err)}); }, } return null; @@ -442,8 +449,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .List => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -454,8 +460,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .Vector => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -464,14 +469,14 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { const ret_mal = MalType.new_vector(Allocator, new_ll); return ret_mal; }, - .HashMap => |hmap| { + .HashMap => |*hmap| { var new_hashmap = try MalType.new_hashmap(Allocator); var iterator = hmap.iterator(); var optional_pair = iterator.next(); while(true) { const pair = optional_pair orelse break; - const key = pair.key; - const value = pair.value; + const key = pair.key_ptr.*; + const value = pair.value_ptr.*; const evaled_value = try EVAL(value, try env.copy(Allocator)); try new_hashmap.hashmap_insert(key, evaled_value); optional_pair = iterator.next(); @@ -548,7 +553,7 @@ fn do_user_func(args: *MalLinkedList, mal_ptr: **MalType, env_ptr: **Env) MalErr const mal_func = try linked_list.pop_first(Allocator, args); const env = env_ptr.*; // First check if it is a user-defined Mal function - if(MalTypeValue(mal_func.data) == MalTypeValue.Func) { + if(@as(MalTypeValue, mal_func.data) == MalTypeValue.Func) { const func_data = mal_func.data.Func; const args_ll = try func_data.arg_list.sequence_linked_list(); const func_env = func_data.environment; @@ -570,9 +575,9 @@ fn apply_function(args: MalLinkedList) MalError!*MalType { const return_mal = apply_function_unsafe(Allocator, args) catch |err| { if(err == MalError.ReaderUnmatchedParen) { - warn("Error: expected closing paren, got EOF\n"); + warn("Error: expected closing paren, got EOF\n", .{}); } else if(err == MalError.ReaderUnmatchedString) { - warn("Error: expected closing string, got EOF\n"); + warn("Error: expected closing string, got EOF\n", .{}); } return err; }; @@ -580,7 +585,7 @@ fn apply_function(args: MalLinkedList) MalError!*MalType { } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); Allocator = CAllocator; core.set_allocator(Allocator); @@ -604,9 +609,9 @@ pub fn main() !void { while(true) { var line = (try getline(Allocator)) orelse break; var output = rep_and_print_errors(environment, line) orelse continue; - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); Allocator.free(line); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } diff --git a/impls/zig/stepA_mal.zig b/impls/zig/stepA_mal.zig index ff8e74fde3..d68be1cf5c 100644 --- a/impls/zig/stepA_mal.zig +++ b/impls/zig/stepA_mal.zig @@ -37,10 +37,16 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { var mal = mal_arg; var env = env_arg; while(true) { + + // const stdout = std.io.getStdOut(); + // stdout.writeAll("EVAL: ") catch return MalError.ThrownError; + // stdout.writeAll(try PRINT(mal)) catch return MalError.ThrownError; + // stdout.writeAll("\n") catch return MalError.ThrownError; + mal = try macroexpand(mal, env); switch(mal.data) { .List => |ll| { - if(ll.len == 0) { + if(ll.items.len == 0) { env.delete(); return mal; } @@ -100,7 +106,7 @@ fn EVAL(mal_arg: *MalType, env_arg: *Env) MalError!*MalType { else { var new_list = try eval_ast(mal, try env.copy(Allocator)); - if(MalTypeValue((try new_list.sequence_nth(0)).data) == MalTypeValue.Func) { + if(@as(MalTypeValue, (try new_list.sequence_nth(0)).data) == MalTypeValue.Func) { try do_user_func(try new_list.sequence_linked_list(), &mal, &env); new_list.shallow_destroy(Allocator); continue; @@ -127,10 +133,10 @@ fn starts_with(ast: *MalType, sym: []const u8) bool { .List => |l| l, else => return false, }; - if(ll.count() < 2) { + if(ll.items.len < 2) { return false; } - const ss = switch(ll.at(0).data) { + const ss = switch(ll.items[0].data) { .Generic => |s| s, else => return false, }; @@ -165,7 +171,7 @@ fn macroexpand(mal: *MalType, env: *Env) MalError!*MalType { while(optional_macro) |macro| { var new_list = (try cur_mal.sequence_linked_list()).*; - if(new_list.count() > 0) { + if(new_list.items.len > 0) { const first = try linked_list.pop_first(Allocator, &new_list); first.delete(Allocator); } @@ -211,15 +217,16 @@ fn EVAL_let(mal_ptr: **MalType, env_ptr: **Env) MalError!void { .Vector => |v| v, else => return MalError.TypeError, }; - var iterator = binding_ll.iterator(); - var optional_node = iterator.next(); - while(optional_node) |node| { - const key_mal = node; + if(binding_ll.items.len % 2 != 0) return MalError.ArgError; + var i: usize = 0; + while(i < binding_ll.items.len) { + const key_mal = binding_ll.items[i]; + i += 1; const key = try key_mal.as_symbol(); - const val_mal = iterator.next() orelse return MalError.ArgError; - const evaled_mal = try EVAL(val_mal, try new_env.copy(Allocator)); + const val_mal = binding_ll.items[i]; + i += 1; + const evaled_mal = try EVAL(val_mal, new_env); try new_env.set(key, evaled_mal); - optional_node = iterator.next(); key_mal.delete(Allocator); } @@ -333,7 +340,7 @@ fn EVAL_try(mal: *MalType, env: *Env) MalError!*MalType { } fn quasiquote(ast: *MalType) MalError!*MalType { - const kind = MalTypeValue(ast.data); + const kind = @as(MalTypeValue, ast.data); if(kind == MalTypeValue.Generic or kind == MalTypeValue.HashMap) { const new_list = try MalType.new_list_empty(Allocator); try new_list.sequence_append(Allocator, try MalType.new_generic(Allocator, "quote")); @@ -378,11 +385,11 @@ fn quasiquote(ast: *MalType) MalError!*MalType { return result; } -fn PRINT(optional_mal: ?*MalType) MalError![] u8 { +fn PRINT(optional_mal: ?*MalType) MalError![]const u8 { return printer.print_str(optional_mal); } -fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { +fn rep(environment: *Env, input: []const u8) MalError!?[]const u8 { var read_input = (try READ(input)) orelse return null; var eval_input = try EVAL(read_input, try environment.copy(Allocator)); var print_input = try PRINT(eval_input); @@ -390,28 +397,28 @@ fn rep(environment: *Env, input: [] const u8) MalError!?[] u8 { return print_input; } -fn rep_and_print_errors(environment: *Env, input: [] const u8) ?[]u8 { +fn rep_and_print_errors(environment: *Env, input: [] const u8) ?[]const u8 { return rep(environment, input) catch |err| { switch(err) { MalError.KeyError => { }, MalError.OutOfBounds => { - warn("Error: out of bounds\n"); + warn("Error: out of bounds\n", .{}); }, MalError.ThrownError => { - warn("Thrown error: "); + warn("Thrown error: ", .{}); const error_mal = lookup(environment, "__error", false) - catch {warn("\n"); return null;}; + catch {warn("\n", .{}); return null;}; const warning = PRINT(error_mal) - catch {warn("\n"); return null;}; - warn("{}\n", warning); + catch {warn("\n", .{}); return null;}; + warn("{s}\n", .{warning}); error_mal.delete(Allocator); Allocator.free(warning); }, MalError.ReaderUnmatchedParen => { - warn("Error: expected closing paren, got EOF\n"); + warn("Error: expected closing paren, got EOF\n", .{}); }, else => { - warn("Error: {}\n", error_string_repr(err)); + warn("Error: {s}\n", .{error_string_repr(err)}); }, } return null; @@ -442,8 +449,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .List => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -454,8 +460,7 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { }, .Vector => |*ll| { var new_ll = MalLinkedList.init(Allocator); - var iterator = ll.iterator(); - while(iterator.next()) |next_mal| { + for (ll.items) |next_mal| { const new_mal = try EVAL(next_mal, try env.copy(Allocator)); try linked_list.append_mal(Allocator, &new_ll, new_mal); } @@ -464,14 +469,14 @@ fn eval_ast(mal: *MalType, env: *Env) MalError!*MalType { const ret_mal = MalType.new_vector(Allocator, new_ll); return ret_mal; }, - .HashMap => |hmap| { + .HashMap => |*hmap| { var new_hashmap = try MalType.new_hashmap(Allocator); var iterator = hmap.iterator(); var optional_pair = iterator.next(); while(true) { const pair = optional_pair orelse break; - const key = pair.key; - const value = pair.value; + const key = pair.key_ptr.*; + const value = pair.value_ptr.*; const evaled_value = try EVAL(value, try env.copy(Allocator)); try new_hashmap.hashmap_insert(key, evaled_value); optional_pair = iterator.next(); @@ -506,7 +511,6 @@ fn make_environment() MalError!*Env { core.CorePairType.Fn3 => |func| MalData{.Fn3 = func}, core.CorePairType.Fn4 => |func| MalData{.Fn4 = func}, core.CorePairType.FVar => |func| MalData{.FVar = func}, - else => return MalError.TypeError, }; try environment.set(name, func_mal); } @@ -562,7 +566,7 @@ fn do_user_func(args: *MalLinkedList, mal_ptr: **MalType, env_ptr: **Env) MalErr const mal_func = try linked_list.pop_first(Allocator, args); const env = env_ptr.*; // First check if it is a user-defined Mal function - if(MalTypeValue(mal_func.data) == MalTypeValue.Func) { + if(@as(MalTypeValue, mal_func.data) == MalTypeValue.Func) { const func_data = mal_func.data.Func; const args_ll = try func_data.arg_list.sequence_linked_list(); const func_env = func_data.environment; @@ -584,9 +588,9 @@ fn apply_function(args: MalLinkedList) MalError!*MalType { const return_mal = apply_function_unsafe(Allocator, args) catch |err| { if(err == MalError.ReaderUnmatchedParen) { - warn("Error: expected closing paren, got EOF\n"); + warn("Error: expected closing paren, got EOF\n", .{}); } else if(err == MalError.ReaderUnmatchedString) { - warn("Error: expected closing string, got EOF\n"); + warn("Error: expected closing string, got EOF\n", .{}); } return err; }; @@ -594,7 +598,7 @@ fn apply_function(args: MalLinkedList) MalError!*MalType { } pub fn main() !void { - const stdout_file = try std.io.getStdOut(); + const stdout_file = std.io.getStdOut(); Allocator = CAllocator; core.set_allocator(Allocator); @@ -620,9 +624,9 @@ pub fn main() !void { while(true) { var line = (try getline(Allocator)) orelse break; var output = rep_and_print_errors(environment, line) orelse continue; - try stdout_file.write(output); + try stdout_file.writeAll(output); Allocator.free(output); Allocator.free(line); - try stdout_file.write("\n"); + try stdout_file.writeAll("\n"); } } diff --git a/impls/zig/types.zig b/impls/zig/types.zig index aa24a136c0..804153c362 100644 --- a/impls/zig/types.zig +++ b/impls/zig/types.zig @@ -97,7 +97,7 @@ pub const MalType = struct { pub fn new_keyword(allocator: *Allocator, value: [] const u8) MalError!*MalType { const mal = try MalType.new_nil(allocator); - const kwd_prefix: [] const u8 = [_]u8 {255}; + const kwd_prefix: [] const u8 = "\xFF"; const kwd_cpy = string_concat(allocator, kwd_prefix, value) catch return MalError.SystemError; mal.data = MalData { .Keyword = kwd_cpy }; @@ -184,7 +184,7 @@ pub const MalType = struct { // TODO: should we copy the data here, or downstream? switch(mal.data) { .HashMap => |hmap| { - return hmap.getValue(key); + return hmap.get(key); }, .Nil => { return null; @@ -196,7 +196,7 @@ pub const MalType = struct { pub fn hashmap_contains(mal: *MalType, key: []const u8) MalError!bool { // TODO: should we copy the data here, or downstream? return switch(mal.data) { - .HashMap => |hmap| (hmap.getValue(key) != null), + .HashMap => |hmap| (hmap.get(key) != null), else => MalError.TypeError, }; } @@ -234,7 +234,7 @@ pub const MalType = struct { pub fn sequence_pop_last(mal: *MalType, allocator: *Allocator) MalError!*MalType { var ll = try mal.sequence_linked_list(); - if(ll.count() == 0) { + if(ll.items.len == 0) { return MalError.OutOfBounds; } return ll.pop(); @@ -242,18 +242,18 @@ pub const MalType = struct { pub fn sequence_length(mal: *MalType) MalError!i64 { return switch(mal.data) { - .List => |l| @intCast(i64, l.count()), - .Vector => |v| @intCast(i64, v.count()), + .List => |l| @intCast(i64, l.items.len), + .Vector => |v| @intCast(i64, v.items.len), else => MalError.TypeError, }; } pub fn sequence_nth(mal: *MalType, pos: u32) MalError!*MalType { var ll = try mal.sequence_linked_list(); - if(ll.count() <= pos) { + if(ll.items.len <= pos) { return MalError.OutOfBounds; } - return ll.at(pos); + return ll.items[pos]; } pub fn as_int(mal: *const MalType) MalError!i64 { @@ -310,7 +310,7 @@ pub const MalType = struct { if(ref_count <= 1) atom.*.delete(allocator); }, - .HashMap => |hm| { + .HashMap => |*hm| { hash_map.destroy(allocator, hm, false); }, .Func => |func_data| { @@ -421,18 +421,18 @@ pub const MalType = struct { pub fn apply_function(allocator: *Allocator, args: MalLinkedList) MalError!*MalType { // TODO: this should take a MLL pointer var args_copy = try linked_list.deepcopy(allocator, args); //TODO: could be more efficient - var args_arr = args_copy.toSlice(); + var args_arr = args_copy.items; const mal_func = args_arr[0]; // First check if it is a user-defined Mal function - if(MalTypeValue(mal_func.data) == MalTypeValue.Func) { + if(@as(MalTypeValue, mal_func.data) == MalTypeValue.Func) { const func_data = mal_func.data.Func; const args_ll = try func_data.arg_list.sequence_linked_list(); const func_env = func_data.environment; const eval_func = func_data.eval_func orelse return MalError.TypeError; var new_env = try Env.new(allocator, func_env); // TODO: make sure that set_list checks that first_arg and first_arg_value have same len - try new_env.set_slice(args_ll.toSlice(), args_arr[1..args_arr.len]); + try new_env.set_slice(args_ll.items, args_arr[1..args_arr.len]); linked_list.destroy(allocator, &args_copy, true); const new_body = try func_data.body.copy(allocator);