ç§ã¯æçš¿ã®äœè ã«é£çµ¡ãã圌ã¯èŠªåã«Zig 0.3.0ã®ãããžã§ã¯ããœãŒã¹ã®çŸåšã®ããŒãžã§ã³ã§ãªããžããªãžã®ãªã³ã¯ãæäŸããŸããã
ããã«ã¡ã¯ Brainfuckã€ã³ã¿ãŒããªã¿ãŒãäœæããŸãããïŒ ããªãïŒããšå°ããããšã¯ã§ããŸãããããã§ã¯çããèŠã€ãããŸããã
Zigã§ãããè¡ããŸãã
ãžã°ã¯...
...æ°ããããã°ã©ãã³ã°èšèªã ãŸã ããŒã¿çã§ãããæ¥éã«éçºäžã§ãã Zigã³ãŒãã以åã«èŠãããšãããã°ããã®æçš¿ã®ã³ãŒãã¯ããªããšã¯å°ãéãããã«èŠãããããããŸããã 圌ã¯æ¬åœã«éãïŒ Zig 0.2.0ããªãªãŒã¹ãããã°ããã§ãæ°é±éåã®LLVM 6ã®ãªãªãŒã¹ã«åãããŠãå€ãã®æ§æã®å€æŽãšäžè¬çãªèšèªã®æ¹åãå«ãŸããŠããŸãã ã»ãšãã©ã®å Žåãå€ãã®ãã¹ãã«ãã¯ããŒã¯ãŒãã«çœ®ãæããããŠããŸãã ãã¹ãŠã®å€æŽã®è©³çŽ°ã«ã€ããŠã¯ã ãã¡ããã芧ãã ããïŒ
Zigã¯èªã¿ãããããã«èšèšãããŠãã ãCãC ++ãããã³Rustãªã©ã®ã³ã³ãã€ã«ããåä»ããããèšèªã«ç²ŸéããŠãã人ã«ãšã£ãŠã¯æ¯èŒççŽæçã§ãã
ã³ãŒãã¯ãZig 0.2.0ã§ã³ã³ãã€ã«ããã³ãã¹ããããŠããŸããããã¯ãOSXã䜿çšããŠããå Žåãhomebrewãå«ãããŸããŸãªãã£ãã«ããããã«å ¥æã§ããŸããbrewinstall zigã
ããå§ããŸããã
Brainfuckã®ä»çµã¿ã«ã€ããŠã¯ã ãã¡ããã芧ãã ãã ã ããã§åŠã¶ããšã¯ã»ãšãã©ãããŸãããã ãã¥ãŒãªã³ã°å®å šãªèšèªã§ããããã äœã§ãæžãããšãã§ããŸãã
æçµè£œåãåæã®ã³ããããèŠããå Žåã«åããŠã ããã«ã³ãŒããæçš¿ããŸããã
Zigã¯ã³ã³ãã€ã«ãããèšèªã§ãã ããã°ã©ã ãã³ã³ãã€ã«ãããšããçµæã®ãã€ããªïŒã©ã€ãã©ãªã§ã¯ãªãå®è¡å¯èœãã€ããªãã³ã³ãã€ã«ããå ŽåïŒã«ã¯ããšã³ããªãã€ã³ããããŒã¯ããã¡ã€ã³é¢æ°ãå¿ èŠã§ãã
ã ãã...
// main.zig fn main() void { }
...ãããŠéå§...
$ zig build-exe main.zig
...é ã...
/zig/std/special/bootstrap.zig:70:33: error: 'main' is private /zigfuck/main.zig:2:1: note: declared here
ã¢ãžã¥ãŒã«ã®å€ããèŠããããã«ããã«ã¯ãmainãpublicãšããŠå®£èšããå¿ èŠããããŸã...
// main.zig pub fn main() void { }
Brainfuckããã°ã©ã ã30,000ãã€ãã®é åãã¡ã¢ãªãšããŠäœ¿çšããããã«ããŸãããã®ãããªé åãäœæããŸãã
// main.zig pub fn main() void { const mem: [30000]u8; }
å®æ°ïŒconstïŒãŸãã¯å€æ°ïŒvarïŒã宣èšã§ããŸãã ããã§ã¯ãmemã30,000ã®ç¬Šå·ãªãïŒuïŒãã€ãïŒ8ãããïŒã®é åãšããŠå®£èšããŸããã
ããã¯ã³ã³ãã€ã«ãããŸããã
/main.zig:3:5: error: variables must be initialized
åçã®Cããã°ã©ã ã¯æ£åžžã«ã³ã³ãã€ã«ãããŸããåæåããã«å€æ°ã宣èšã§ããŸãããå€æ°ã宣èšãããæç¹ã§ãZigãããã«æ±ºå®ãäžãããã«åŒ·å¶ããŸãã äœãæžã蟌ãŸãããã¯æ°ã«ããªããããããŸãããããããæ瀺çã«ç€ºãå¿ èŠããããŸãã ãããè¡ãã«ã¯ãå€æ°ãæªå®çŸ©ã®å€ïŒæªå®çŸ©ïŒã§åæåããŸãã
// main.zig pub fn main() void { const mem: [30000]u8 = undefined; }
æªå®çŸ©ã®å€ã§å€æ°ãåæåããŠããã¡ã¢ãªå ã®å€æ°ã®å€ã«é¢ããä¿èšŒã¯ãããŸããã ããã¯ãæ瀺çã«æå®ããå¿ èŠãããããšãé€ããŠãCã®åæåãããŠããªãå€æ°å®£èšãšåãã§ãã
ãããããã®ã¡ã¢ãªãåæåããæ¹æ³ã¯æ°ã«ããªããããããŸããã ããããããŒããŸãã¯ä»»æã®å€ãããã«æžã蟌ãŸããããšãä¿èšŒãããã®ã§ãã ãã®å Žåããããæ瀺çã«è¿°ã¹ãå¿ èŠããããŸãã
// main.zig pub fn main() void { const mem = []u8{0} ** 30000; }
å¥åŠã«æãããããããŸãããã**ã¯é åã®å±éã«äœ¿çšãããæŒç®åã§ãã 0ãã€ãã®é åã宣èšããããã30,000ã«æ¡åŒµãã30,000ãã€ãã®æçµåæåå€ãååŸããŸãã ãã®æäœã¯ã ã³ã³ãã€ã«æã« 1åçºçããŸã ã comptimeã¯Zigã®çŽ æŽãããã¢ã€ãã¢ã®1ã€ã§ããã次ã®æçš¿ã®1ã€ã§ããã«æ»ããŸãã
ã§ã¯ãæåã®ã¡ã¢ãªã¹ãããã5åå¢ããããšä»¥å€ã¯äœãããªãBrainfuckã®ããã°ã©ã ãäœæããŸãããã
pub fn main() void { const mem = []u8{0} ** 30000; const src = "+++++"; }
Zigã§ã¯ãæååã¯ãã€ãé åã§ãã ã³ã³ãã€ã©ããããæé»æå®ããŠãããããsrcããã€ãé åãšããŠå®£èšããªãã§ãã ããã ããã¯ãªãã·ã§ã³ã§ãããå¿ èŠãªå Žåã¯å¯èœã§ãã
const src: [5]u8 = "+++++";
ããã§åé¡ãªãã³ã³ãã€ã«ã§ããŸãã ãã ããããïŒ
const src: [6]u8= "+++++";
ãªããŸããã
main.zig:5:22: error: expected type '[6]u8', found '[5]u8'
ãã1ã€ã®æ³šæïŒæååã¯åãªãé åã§ããããããŒãã§çµããããšã¯ãããŸããã ãã ãããã«çµäºæååCã宣èšã§ããŸãããªãã©ã«ãšããŠã¯ã次ã®ããã«ãªããŸãã
c"Hello I am a null terminated string";
äžè¬çãªå©çã®ããã«...
æååã®ãã¹ãŠã®æåã§äœãããããã ã§ãããïŒ main.zigã®åé ã§ãæšæºã©ã€ãã©ãªããããã€ãã®é¢æ°ãã€ã³ããŒãããŸãã
const warn = @import("std").debug.warn;
importã¯ã@èšå·ã§å§ãŸãã»ãŒãã¹ãŠã®ãã®ãšåæ§ã«ã çµã¿èŸŒã¿ã³ã³ãã€ã©ãŒé¢æ°ã§ãã ãã®ãããªæ©èœã¯åžžã«ã°ããŒãã«ã«å©çšå¯èœã§ãã ããã§ã®ã€ã³ããŒãã¯ãjavascriptãšåæ§ã«æ©èœããŸããããŒã ã¹ããŒã¹ãæãäžããŠãããããå ¬éãããŠããé¢æ°ãŸãã¯å€æ°ãæœåºããããšã§ãäœã§ãã€ã³ããŒãã§ããŸãã äžèšã®äŸã§ã¯ãwarné¢æ°ãçŽæ¥ã€ã³ããŒãããçªç¶ãwarnå®æ°ã«å²ãåœãŠãŸãã ä»ã圌女ãåŒã³åºãããšãã§ããŸãã ããã¯äžè¬çãªãã¿ãŒã³ã§ããstdåå空éããçŽæ¥ã€ã³ããŒãããŠãããstd.debug.warnïŒïŒãåŒã³åºãããwarnå€æ°ã«å²ãåœãŠãŸãã 次ã®ããã«ãªããŸãã
const std = @import("std"); const warn = std.debug.warn;
const warn = @import("std").debug.warn; // main.zig pub fn main() void { const mem = []u8{0} ** 30000; const src = "+++++"; for (src) |c| { warn("{}", c); } }
ãããã°ããã³åæéçºãšãã¹ãäžã«ãç»é¢ã«äœããå°å·ãããã ãã§ãã Zigã¯ãšã©ãŒãèµ·ããããã ãstdoutããšã©ãŒãèµ·ãããããã§ãã ä»ã¯ããããããããããŸãããæšæºã©ã€ãã©ãªããã€ã³ããŒãããwarnã䜿çšããŠstderrã«çŽæ¥å°å·ã§ããŸãã
warnã¯Cã®printfã®ãããªãã©ãŒããããããæååãåãåããŸãïŒ äžèšã®ã³ãŒãã¯å°å·ãããŸãïŒ
4343434343
43ã¯ASCIIæåã³ãŒã+ã§ãã ç§ãæžãããšãã§ããŸãïŒ
warn("{c}", c);
ååŸïŒ
+++++
ããã§ãã¡ã¢ãªç©ºéãåæåããããã°ã©ã ãäœæããŸããã ä»ãç§ãã¡ã¯èšèªãã®ãã®ãå®çŸããŠããŸãã +ã§éå§ããforã«ãŒãã®æ¬äœãã¹ã€ããã«çœ®ãæããŸãã
for (src) |c| { switch(c) { '+' => mem[0] += 1 } }
次ã®2ã€ã®ãšã©ãŒã衚瀺ãããŸãã
/main.zig:10:7: error: switch must handle all possibilities switch(c) { ^ /main.zig:11:25: error: cannot assign to constant '+' => mem[0] += 1 ^
ãã¡ãããå€æ°ã«æ°ããå€ãå²ãåœãŠãããšã¯ã§ããŸãããããã¯å®æ°ã§ãïŒ memã¯å€æ°ã«ããå¿ èŠããããŸã...
var mem = []u8{0} ** 30000;
ä»ã®ãšã©ãŒãšåæ§ã«ãç§ã®ã¹ã€ããæ§æã¯ãäœãããå¿ èŠããªãå Žåã§ããæåã+ã§ãªãå Žåã«äœããã¹ãããç¥ã£ãŠããå¿ èŠããããŸãã ç§ã®å Žåãããã¯ãŸãã«ç§ãæããã®ã§ãã ãã®ã±ãŒã¹ã空ã®ãããã¯ã§åããŸãïŒ
for (src) |c| { switch(c) { '+' => mem[0] += 1, else => {} } }
ããã§ããã°ã©ã ãã³ã³ãã€ã«ã§ããŸãã æåŸã«èŠåãåŒã³åºããŠå®è¡ããŸãïŒ
const warn = @import("std").debug.warn; pub fn main() void { var mem = []u8{0} ** 30000; const src = "+++++"; for (src) |c| { switch(c) { '+' => mem[0] += 1, else => {} } } warn("{}", mem[0]); }
äºæ³ã©ããã stderrã«æ°åã®5ãåºåãããŸãã
ç¶ããŸããã...
åæ§ã«ããµããŒãããŸãã
switch(c) { '+' => mem[0] += 1, '-' => mem[0] -= 1, else => {} }
>ãš<ã䜿çšããã«ã¯ãè¿œå ã®å€æ°ã䜿çšããå¿ èŠããããŸãããã®å€æ°ã¯ããŠãŒã¶ãŒBrainfuckããã°ã©ã ã«å²ãåœãŠãã¡ã¢ãªå ã®ããã€ã³ã¿ãŒããšããŠæ©èœããŸãã
var memptr: u16 = 0;
笊å·ãªã16ãããã¯æ倧65535ã«ãªãå¯èœæ§ãããããã30,000ãã€ãã®ã¢ãã¬ã¹ç©ºéãã€ã³ããã¯ã¹ããã«ã¯ååã§ãã
å®éã15ãããã§ååãªã®ã§ã32767ãã€ããã¢ãã¬ã¹æå®ã§ããŸãã Zigã§ã¯ã ç°ãªãå¹ ã®åã䜿çšã§ããŸããããŸã u15ã¯äœ¿çšã§ããŸããã
å®éã«ãã®æ¹æ³ã§u15ãå®è¡ã§ããŸãã
const u15 = @IntType(false, 15):
[iu] \ d +åã¯æŽæ°åãšããŠæå¹ã§ããããšãææ¡ãããŠããŸãã
mem [0]ã䜿çšãã代ããã«ããã®å€æ°ã䜿çšã§ããŸãã
'+' => mem[memptr] += 1, '-' => mem[memptr] -= 1,
<and>ãã®ãã€ã³ã¿ãåçŽã«å¢æžããŸãã
'>' => memptr += 1, '<' => memptr -= 1,
ããã ããã§å®éã®ããã°ã©ã ãæžãããšãã§ããŸãïŒ
1,2,3ã確èªããŸã
Zigã«ã¯ãã¹ããšã³ãžã³ãçµã¿èŸŒãŸããŠããŸãã ä»»æã®ãã¡ã€ã«ã®ã©ãã«ã§ããã¹ããããã¯ãèšè¿°ã§ããŸãã
test "Name of Test" { // test code }
ã³ãã³ãã©ã€ã³ãããã¹ããå®è¡ããŸãïŒzig test $ FILENAMEã æ®ãã®ãã¹ããããã¯ã¯ãéåžžã®ã³ãŒããšåãã§ãã
ãããèŠãŠã¿ãŸãããïŒ
// test.zig test "testing tests" {} zig test test.zig Test 1/1 testing tests...OK
ãã¡ããã空ã®ãã¹ãã¯åœ¹ã«ç«ã¡ãŸããã assertã䜿çšããŠããã¹ãã®å®è¡ãå®éã«ç¢ºèªã§ããŸãã
const assert = @import("std").debug.assert; test "test true" { assert(true); } test "test false" { assert(false); }
zig test test.zig "thing.zig" 10L, 127C written :!zig test thing.zig Test 1/2 test true...OK Test 2/2 test false...assertion failure [37;1m_panic.7 [0m: [2m0x0000000105260f34 in ??? (???) [0m [37;1m_panic [0m: [2m0x0000000105260d6b in ??? (???) [0m [37;1m_assert [0m: [2m0x0000000105260619 in ??? (???) [0m [37;1m_test false [0m: [2m0x0000000105260cfb in ??? (???) [0m [37;1m_main.0 [0m: [2m0x00000001052695ea in ??? (???) [0m [37;1m_callMain [0m: [2m0x0000000105269379 in ??? (???) [0m [37;1m_callMainWithArgs [0m: [2m0x00000001052692f9 in ??? (???) [0m [37;1m_main [0m: [2m0x0000000105269184 in ??? (???) [0m [37;1m??? [0m: [2m0x00007fff5c75c115 in ??? (???) [0m [37;1m??? [0m: [2m0x0000000000000001 in ??? (???) [0m
ãã¹ãã¯èœã¡ãŸããã 次ã®ã³ãã³ãã䜿çšããŠããšã©ãŒãåçŸããŸãã
./zig-cache/test
ãããŒã®ã¹ã¿ãã¯ãã¬ãŒã¹ã¯ãŸã éçºäžã§ãã
ãããå¹ççã«ãã¹ãããã«ã¯ãå解ããå¿ èŠããããŸãã ããããå§ããŸãããïŒ
fn bf(src: []const u8, mem: [30000]u8) void { var memptr: u16 = 0; for (src) |c| { switch(c) { '+' => mem[memptr] += 1, '-' => mem[memptr] -= 1, '>' => memptr += 1, '<' => memptr -= 1, else => {} } } } pub fn main() void { var mem = []u8{0} ** 30000; const src = "+++++"; bf(src, mem); }
ããŸãããã¯ãã§ãããïŒ
ããã...
/main.zig:1:29: error: type '[30000]u8' is not copyable; cannot pass by value
ããã¯https://github.com/zig-lang/zig/issues/733ã§èª¬æãããŠããŸã ã
Zigã¯ããã«ã€ããŠå³æ Œã§ãã è€ååãããã³ãµã€ãºå€æŽå¯èœãªãã¹ãŠã®ãªããžã§ã¯ãã¯ãå€ã§æž¡ãããšã¯ã§ããŸããã ããã«ãããã¹ã¿ãã¯ã®å²ãåœãŠãäºæž¬å¯èœãã€è«ççã«ãªããäžèŠãªã³ããŒãåé¿ãããŸãã ããã°ã©ã ã§å€ã«ãã転éã®ã»ãã³ãã£ã¯ã¹ã䜿çšããå Žåã¯ãå²ãåœãŠæŠç¥ã䜿çšããŠèªåã§å®è£ ã§ããŸãããéåžžã®ç°å¢ã§ã¯èšèªèªäœãããããµããŒãããŠããŸããã
ãã®å¶éãåé¿ããèªç¶ãªæ¹æ³ã¯ãå€ã®ä»£ããã«ãã€ã³ã¿ãŒãæž¡ãããšã§ãïŒåç §æž¡ãïŒã Zigã¯å¥ã®æŠç¥ã§ããã¹ã©ã€ã¹ã䜿çšããŸãã ã¹ã©ã€ã¹ã¯ãé·ããä»å ããããã€ã³ã¿ãŒã§ãããå¢çã«åãŸããã©ããããã§ãã¯ããŸãã é¢æ°ã·ã°ããã£ã®æ§æã¯æ¬¡ã®ããã«ãªããŸãã
fn bf(src: []const u8, mem: []u8) void { ... }
é¢æ°ãåŒã³åºããšã次ã®ããã«ãªããŸãã
bf(src, mem[0..mem.len]);
é åã®é·ããåç §ããã ãã§äžéãå®çŸ©ããããšã«æ³šæããŠãã ããã ãã®ãããªå Žåã«ã¯ãè¡šèšã®çç¥åœ¢ããããŸãã
bf(src, mem[0..]);
ããã§ãbfïŒïŒé¢æ°ãçŽæ¥ãã¹ããããã¹ãã®äœæãéå§ã§ããŸãã ä»ã®ãšããããã¡ã€ã«ã®æåŸã«ãã¹ãæ©èœãè¿œå ããŸã...
test "+" { var mem = []u8{0}; const src = "+++"; bf(src, mem[0..]); assert(mem[0] == 3); }
memé åã1ãã€ãããååŸãã次ã«äœãèµ·ãããã確èªããŸãïŒãã€ãã¯3åã€ã³ã¯ãªã¡ã³ããããŸãïŒã ããŸãããïŒ
Test 1/1 +...OK
ã-ãã¯åãæ¹æ³ã§ãã§ãã¯ãããŸãã
test "-" { var mem = []u8{0}; const src = "---"; bf(src, mem[0..]); assert(mem[0] == 253); }
åäœããŸããïŒ 0ãã1ãæžç®ããããšãããšã...
Test 2/2 -...integer overflow
memã¯ç¬Šå·ãªããã€ãã®é åã§ããã0ãã1ãåŒããšãªãŒããŒãããŒãçºçããŸãã ç¹°ãè¿ãã«ãªããŸãããZigã¯ç§ã欲ãããã®ãæ瀺çã«å®£èšãããŸãã ãã®å Žåãç§ã¯ãªãŒããŒãããŒã«ã€ããŠå¿é ããå¿ èŠã¯ãããŸãããå®éãç§ãã¡ã¯Brainfuckã®ä»æ§ã«åŸã£ãŠã¢ãžã¥ã©ãŒæŒç®ãæ±ã£ãŠããã®ã§ããªãŒããŒãããŒãèµ·ããããšãæã¿ãŸãã ã€ãŸããæ°å€0ã®ã»ã«ããã¯ãªã¡ã³ããããš255ãåŸããã255ã®å¢åã§0ãåŸãããŸãã
Zigã«ã¯ãä¿èšŒããããã©ããã³ã°ãã®ã»ãã³ãã£ã¯ã¹ãæäŸããããã€ãã®è£å©çãªç®è¡æŒç®ããããŸãã
'+' => mem[memptr] +%= 1, '-' => mem[memptr] -%= 1,
ããã«ããããªãŒããŒãããŒã®åé¡å šäœã解決ãããæåŸ ã©ããã«åäœããŸãã
<and>ããã¹ãããããã«ãå°ããªé åãããã²ãŒãããã€ã³ã¯ãªã¡ã³ããããã»ã«ã®å€ã確èªããŸãã
test ">" { var mem = []u8{0} ** 5; const src = ">>>+++"; bf(src, mem[0..]); assert(mem[3] == 3); }
ãããŠ...
test "<" { var mem = []u8{0} ** 5; const src = ">>>+++<++<+"; bf(src, mem[0..]); assert(mem[3] == 3); assert(mem[2] == 2); assert(mem[1] == 1); }
åŸè ã®å Žåã...ã䜿çšããŠéçé åãšçµæãçŽæ¥æ¯èŒã§ããŸã...
const mem = std.mem;
ãã§ã«stdãã€ã³ããŒãããŠããããšãæãåºããŠãã ããã 以äžã®äŸã§ã¯ããã®åå空éã§mem.eqlã䜿çšããŠããŸãã
test "<" { var storage = []u8{0} ** 5; const src = ">>>+++<++<+"; bf(src, storage[0..]); assert(mem.eql(u8, storage, []u8{ 0, 1, 2, 3, 0 })); }
...ãããŠãæååãªãã©ã«ãæãåºããŠãã ããããããã¯zigã®u8é åã§ããã16é²ãªãã©ã«ãå ¥ããããšãã§ããŸãã 次ã®ã³ãŒããåãããã«æ©èœããŸãïŒ
assert(mem.eql(u8, storage, "\x00\x01\x02\x03\x00"));
ããããè¿œå ããŠãã ããïŒ ãã€ã³ã¿ãæãã»ã«ã®ãã€ãå€ãæåãšããŠåã«åºåããŸãã çŸåšwarnã䜿çšããŠããŸãããåŸã§stdoutã«çœ®ãæããŸãã ããã¯æŠå¿µçã«ã¯ç°¡åã§ãããå®è£ ã§ã¯å€å°æ··ä¹±ããŸãã åŸã§ãããŸãïŒ
'.' => warn("{c}", storage[memptr]),
ãµã€ã¯ã«
[ããã³]-éæ³ã¯ããããå§ãŸããŸã....
[-çŸåšã®ã»ã«ã®å€ããŒãã®å Žåãã³ãŒããå®è¡ããã«éãæ¬åŒ§ãžã®ã¹ããããã¹ãããããŸãã
]-çŸåšã®ã»ã«ã®å€ããŒãã§ãªãå Žåãéãæ¬åŒ§ã«æ»ããã³ãŒããå床å®è¡ããŸãã
ä»åã¯ãã¹ãããå§ããŸãããäžç·ã«ãã¹ãããŸãïŒæããã«ãåå¥ã«ãã¹ãããã®ã¯æå³ããããŸããïŒã æåã®ãã¹ãã±ãŒã¹-ã¹ãã¬ãŒãž[2]ã»ã«ã¯ç©ºã§ããå¿ èŠããããŸãããéå§ãããšã«ãŒããå¢å ããŸãã
test "[] skips execution and exits" { var storage = []u8{0} ** 3; const src = "+++++>[>+++++<-]"; bf(src, storage[0..]); assert(storage[0] == 5); assert(storage[1] == 0); assert(storage[2] == 0); }
switchã¹ããŒãã¡ã³ãã®ç©ºçœãäœæããŸãã
'[' => if (storage[memptr] == 0) { }, ']' => if (storage[memptr] == 0) { },
ä»äœãããŸããïŒ çŽ æŽãªã¢ãããŒãã䜿çšã§ããŸãã srcãã€ã³ã¿ãèŠã€ãããŸã§ã€ã³ã¯ãªã¡ã³ãããŸã]ã ããããç§ã¯ãã®ããã«ãžã°ã§forã«ãŒãã䜿çšããããšã¯ã§ããŸãããããã¯ãã³ã¬ã¯ã·ã§ã³ãå埩ããããã ãã«äœæããããã®ã§ãèŠçŽ ã倱ãããšã¯ãããŸããã ããã§é©åãªæ§æã¯æ¬¡ã®ãšããã§ãã
ã ã£ãïŒ
var memptr: u16 = 0; for (src) |c| { switch(c) { ... } }
ãªã£ã...
var memptr: u16 = 0; var srcptr: u16 = 0; while (srcptr < src.len) { switch(src[srcptr]) { ... } srcptr += 1; }
ããã§ããããã¯ã®äžå€®ã§srcptrãã€ã³ã¿ãŒãåå²ãåœãŠã§ããŸãããããè¡ããŸãã
'[' => if (storage[memptr] == 0) { while (src[srcptr] != ']') srcptr += 1; },
ããã¯ãã[]ã¯ã³ãŒãã®å®è¡ãã¹ãããããŠçµäºããããšãããã¹ããæºãããŸãã
ããã¯ãã[]ãå®è¡ãã¹ãããããŠçµäºããããšãããã¹ããæºãããŸãããå®å šã«ä¿¡é Œã§ããããã§ã¯ãããŸããããåŸã§èª¬æããŸãã
éãæ¬åŒ§ã«ã€ããŠã¯ã©ãã§ããïŒ ç§ã¯ãããåã«é¡æšã«ãã£ãŠæžãããšä¿¡ããŠããŸãïŒ
test "[] executes and exits" { var storage = []u8{0} ** 2; const src = "+++++[>+++++<-]"; bf(src, storage[0..]); assert(storage[0] == 0); assert(storage[1] == 25); } ']' => if (storage[memptr] != 0) { while (src[srcptr] != '[') srcptr -= 1; },
ããªãã¯äœãèµ·ããããèŠãããšãã§ããŸã... 2ã€ã®ãã©ã±ãããæã€çŽ æŽãªè§£æ±ºçã¯èŽåœçãªæ¬ é¥ãæã¡ããã¹ããããã«ãŒãã§å®å šã«å£ããŸãã 以äžãèæ ®ããŠãã ããã
++>[>++[-]++<-]
çµæã¯{2ã0}ã«ãªããŸãããæåã®éãæ¬åŒ§ã¯åçŽã«æãã«æåã®éãæ¬åŒ§ã«ç§»åãããã¹ãŠãæ··ä¹±ããŸãã åãã¬ãã«ã®ãã¹ãã§ã次ã®éãæ¬åŒ§ã«ãžã£ã³ãããå¿ èŠããããŸãã 深床ã«ãŠã³ã¿ãŒãè¿œå ããŠãã©ã€ã³ã«æ²¿ã£ãŠåé²ããã«ã€ããŠè¿œè·¡ããã®ã¯ç°¡åã§ãã ç§ãã¡ã¯äž¡æ¹åã§ãããè¡ããŸãïŒ
'[' => if (storage[memptr] == 0) { var depth:u16 = 1; srcptr += 1; while (depth > 0) { srcptr += 1; switch(src[srcptr]) { '[' => depth += 1, ']' => depth -= 1, else => {} } } }, ']' => if (storage[memptr] != 0) { var depth:u16 = 1; srcptr -= 1; while (depth > 0) { srcptr -= 1; switch(src[srcptr]) { '[' => depth -= 1, ']' => depth += 1, else => {} } } },
ããã³é¢é£ãããã¹ãïŒäž¡æ¹ã®ãã¹ãã®srcã«ã¯å éšã«ãŒããå«ãŸããŠããããšã«æ³šæããŠãã ããã
test "[] skips execution with internal braces and exits" { var storage = []u8{0} ** 2; const src = "++>[>++[-]++<-]"; try bf(src, storage[0..]); assert(storage[0] == 2); assert(storage[1] == 0); } test "[] executes with internal braces and exits" { var storage = []u8{0} ** 2; const src = "++[>++[-]++<-]"; try bf(src, storage[0..]); assert(storage[0] == 0); assert(storage[1] == 2); }
å¥ã«ã[-]ã«æ³šæããŠãã ãã-ããã®ã»ã«ããŒãããæå³ããBrainfuckã®ã€ãã£ãªã ã ã»ã«ãæåã«ã©ã®å€ãæã£ãŠãããã¯é¢ä¿ãªãã0ã«éãããŸã§ãã¯ãªã¡ã³ããããå®è¡ãç¶è¡ãããŸãã
äžéãªé
bfã®ããã°ã©ã ãå£ããå¯èœæ§ãæåŸ ããŠããŸããã§ããã ééã£ãå ¥åããã°ã©ã ãã€ã³ã¿ãŒããªã¿ãŒã«éä¿¡ãããšã©ããªããŸããïŒ ããšãã°ãåã«[éããã£ãããŸãã¯<ãªãã§ãããã«ã¡ã¢ãªé åãè¶ ããŸããïŒ ïŒã¡ã¢ãªãã€ã³ã¿ãã©ããããããšã¯ã§ããŸãããããããšã©ãŒãšèŠãªãããšããå§ãããŸãïŒã
å°ãå ãèŠãŠãã³ãŒãã®ãã¹ãŠã®éãã説æããŸãã bfã€ã³ã¿ãŒããªã¿ãŒé¢æ°ãå¥ã®ãã¡ã€ã«ã«é 眮ããseekBackããã³seekForwardæ©èœãç¬èªã®å°ããªé¢æ°ã«é 眮ããŸãã
const warn = @import("std").debug.warn; const sub = @import("std").math.sub; fn seekBack(src: []const u8, srcptr: u16) !u16 { var depth:u16 = 1; var ptr: u16 = srcptr; while (depth > 0) { ptr = sub(u16, ptr, 1) catch return error.OutOfBounds; switch(src[ptr]) { '[' => depth -= 1, ']' => depth += 1, else => {} } } return ptr; } fn seekForward(src: []const u8, srcptr: u16) !u16 { var depth:u16 = 1; var ptr: u16 = srcptr; while (depth > 0) { ptr += 1; if (ptr >= src.len) return error.OutOfBounds; switch(src[ptr]) { '[' => depth += 1, ']' => depth -= 1, else => {} } } return ptr; } pub fn bf(src: []const u8, storage: []u8) !void { var memptr: u16 = 0; var srcptr: u16 = 0; while (srcptr < src.len) { switch(src[srcptr]) { '+' => storage[memptr] +%= 1, '-' => storage[memptr] -%= 1, '>' => memptr += 1, '<' => memptr -= 1, '[' => if (storage[memptr] == 0) srcptr = try seekForward(src, srcptr), ']' => if (storage[memptr] != 0) srcptr = try seekBack(src, srcptr), '.' => warn("{c}", storage[memptr]), else => {} } srcptr += 1; } }
ããã«ãããã¹ã€ããã¯èªã¿ããããªããseekForwardãšseekBackã®å€èŠ³ãšåäœã¯éåžžã«äŒŒãŠãããç§ã¯ããããããã¹ããŒãã§ã³ã³ãã¯ããªãã®ã«ãªãã¡ã¯ã¿ãªã³ã°ããããšæããŸããããæçµçã«ã¯ç°ãªãããšãããŠãšã©ãŒãåŠçããŸããŸããããŸããŸãªæ¹æ³ã§ã ã³ããŒãšèª¿æŽãç°¡åãªã®ã§ãããæ確ã«ãªããŸãã ãŸãããããã次ã®æçš¿ã®ããããã§ãããæç¹ã§seekForwardã調æŽããŸãã
éèŠãªãã®ãè¿œå ããŸããïŒ 3ã€ã®é¢æ°ããã¹ãŠåãè¿ãããã«ãªããŸããïŒ..ããã¯ã以åã¯typeïŒ TïŒãšã©ãŒçµåïŒã ã£ããã®ã®æ°ããæ§æã§ãã ããã¯ãé¢æ°ãç¹å®ã®ã¿ã€ããŸãã¯ãšã©ãŒãè¿ãããšãã§ããããšãæå³ããŸãã ãã®ãããªé¢æ°ãåŒã³åºãããšãããšãé¢æ°ãåŒã³åºãåã«tryã䜿çšããå¿ èŠããããŸããããã¯ããšã©ãŒãçºçããå Žåã«åŒã³åºãã¹ã¿ãã¯ã«ãšã©ãŒãã¹ããŒããããcatchã䜿çšããŸãã
const x = functionCall() catch {}
catchãããã¯ã§ãšã©ãŒãåŠçããå Žæã æžããããã«ãcatchã¯ãšã©ãŒã飲ã¿èŸŒãå¯èœæ§ããããŸãã ããã¯æªãç¿æ £ã§ãããããã§ã¯Zigã«ãã£ãŠæ瀺çã«è¡ãããŸãã 空ã®ãããã¯ã§ãšã©ãŒããã£ãããããšããšã©ãŒãçºçããå¯èœæ§ããããšã¯æããªããããšã©ãŒãåŠçããå¿ èŠããªããšæèšããŸãã å®éã«ã¯ãTODOã®ãããªãã®ã«ãªãå¯èœæ§ããããŸããå®éãæ瀺çã«ããããšãéåžžã«ç°¡åã§ãã
const x = functionCall() catch { @panic("TODO") }
ãã®ãããªã±ãŒã¹ã¯æ¬çªã³ãŒãã§ã¯æ±ºããŠèµ·ãããªãããšãæãåºããŠãã ããã èªåãäœãããŠããããç¥ã£ãŠããããšãã³ã³ãã€ã©ãŒã«éç¥ããŠããŸãã ãšã©ãŒãçºçããå¯èœæ§ãããå Žåããšã©ãŒåŠçãè¿œå ããå¿ èŠããããŸãã
ããã§ãseekBackãŸãã¯seekForwardããè¿ããããšã©ãŒã¯äœã§ããïŒ
seekBackã®å ŽåïŒ
ptr = sub(u16, ptr, 1) catch return error.OutOfBounds;
ãã¯ãªã¡ã³ããã€ã³ã¿ãŒã眮ãæããŠãstd libã®ãµãé¢æ°ã䜿çšããŸãããã®é¢æ°ã¯ããªãŒããŒãããŒãçºçããå Žåã«ãªãŒããŒãããŒãšã©ãŒãã¹ããŒããŸãã ãã®ãšã©ãŒããã£ããããŠã代ããã«OutOfBoundsãšã©ãŒãè¿ãããã®ã§ãããã䜿çšããŠããã§äœæããŸãã
ãšã©ãŒZigã¯åºæ¬çã«ããšã©ãŒã䜿çšãããšãã«ã³ã³ãã€ã©ãŒã«ãã£ãŠçæããããšã©ãŒã³ãŒãã®é åã§ãã ãããã¯äžæã§ããããšãä¿èšŒãããŠãããswitchãããã¯ã®å€ãšããŠäœ¿çšã§ããŸãã
ããã§OutOfBoundsã䜿çšãããã®ã¯ãæå³çã«ãã¡ã¢ãªãã€ã³ã¿ã0æªæºã«ãªã£ãå Žåãã©ã³ã¿ã€ã ã«å²ãåœãŠãã¡ã¢ãªé åãè¶ ããããã«èŠæ±ããããã§ãã
åæ§ã«ãseekForwardé¢æ°ã§ïŒ
if (ptr >= src.len) return error.OutOfBounds;
ãã®å Žåããã€ã³ã¿ãŒãsrc.lenãã倧ããå Žåãããã§ãšã©ãŒããã£ããããåããšã©ãŒãè¿ããŸãã
åŒã³åºããšãïŒ
'[' => if (storage[memptr] == 0) srcptr = try seekForward(src, srcptr), ']' => if (storage[memptr] != 0) srcptr = try seekBack(src, srcptr),
ãããã®é¢æ°ãåŒã³åºãããšããŸãã æ£åžžã«åŒã³åºãããå Žåãæ£ããå®è¡ãããsrcptrãè¿ãããŸãã 倱æããå Žåãtryã¯é¢æ°ãçµäºããbfé¢æ°å šäœãåŒã³åºãããå Žæã«ãšã©ãŒãè¿ããŸãã
åŒã³åºãã¯ã¡ã€ã³ããã®å ŽåããããŸãïŒ
const bf = @import("./bf.zig").bf; // yes, hello const hello_world = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."; pub fn main() void { storage = []u8{0} ** 30000; bf(hello_world, storage[0..]) catch {}; }
ããã§ãã®ãšã©ãŒã飲ã¿èŸŒã¿ãŸããããããã¹ãã§ã¯ãããŸãããããžã°ãã©ã®ããã«ç°¡åã«ãšã©ãŒãåŒã³åºãã¹ã¿ãã¯ã«æž¡ãããšãã§ãããã«ã€ããŠã®éèŠãªãã€ã³ãã«æ³šæããŠãã ããã ãšã©ãŒã®ãã¹ãŠã®ã±ãŒã¹ããã§ãã¯ããã®ã¯åŒã³åºãåŽé¢æ°ã®è²¬ä»»ã§ã¯ãããŸããããã³ã³ãã€ã©ãŒã¯tryã§åŒã³åºãã«å€±æããå¯èœæ§ã®ããåé¢æ°ã匷å¶ããŸãã ãšã©ãŒãç¡èŠãããŠããããã¯åžžã«è¡ãããªããã°ãªããŸããïŒ
æ°ããtry / catchæ§æã¯ã人ã ãããã»ã©å«ã%%ãïŒ ã®ãããªå€ãã®åªæãæé€ããŸãã
ä»ãç§ã¯8人äž7人ã®Brainfuckãã£ã©ã¯ã¿ãŒãå®è£ ããŸãããããã¯ãæå³ã®ãããããã°ã©ã ãå®è¡ããã®ã«ååã§ãã
æå³ã®ããããã°ã©ã
ããã°ã©ã ã¯æ¬¡ã®ãšããã§ãã
// , const fib = "++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++>++++++++++++++++>>+<<[>>>>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>[<+>-]>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]<[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]<<<++++++++++++++++++++++++++++++++++++++++++++++++.[-]<<<<<<<.>.>>[>>+<<-]>[>+<<+>-]>[<+>-]<<<-]<<++...";
èµ·å...
pub fn main() void { storage = []u8{0} ** 30000; bf(fib, storage[0..]) catch {}; }
åºæ¥äžããïŒ
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 121, 98, 219,
ãã£ããããã·ãªãŒãºã®ããšãèãããã³ã«æãåºã1ã€è¿ã£ãŠããŸã... 80幎代ã®PBSïŒå ¬å ±æŸéãµãŒãã¹ãã¢ã¡ãªã«ã®éå¶å©ãã¬ãæŸéãµãŒãã¹ïŒçªçµã§ãããç¥ããŸããã å¿ãããããšæããŸãããã Youtubeã¯çŽ æŽããããã®ã§ãã
ã©ãããã°ãããæ¹åã§ããŸããïŒ
ç§ã¯ãã§ã«ããã€ãã®TODOãã»ã®ããããŸããã åºåã«stderrã䜿çšããã¹ãã§ã¯ãããŸããã stdoutã䜿çšãããã
ã€ã³ã¿ãŒããªã¿ãŒãéããã³ã«ãstdoutã§ã¹ããªãŒã ãéããå°å·ããŸãã
const io = std.io; ... pub fn bf(src: []const u8, storage: []u8) !void { const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream); ... '.' => stdout.print("{c}", storage[memptr]) catch unreachable, ...
ããã§äœãèµ·ãã£ãŠããŸããïŒç§ã¯io.getStdOutïŒïŒãåŒã³åºããŸããããã¯ãšã©ãŒãçæããå¯èœæ§ããããŸãïŒãŸããcatch unreachableã§ãšã©ãŒãæ瀺çã«é£²ã¿èŸŒã¿ãŸã-ãã®é¢æ°ããšã©ãŒãè¿ããšãããã°ã©ã ã¯ã¯ã©ãã·ã¥ããŸãïŒïŒãã¹ããªãŒã ãåæåãããã€ã³ã¿ãŒãååŸããprintãåŒã³åºããŠæžã蟌ã¿å¯èœãªåºåã¹ããªãŒã ãšããŠåæåããŸãã printã¯ãwarnã®ãããªãã©ãŒããããããæååãåãå ¥ããããã眮æã¯çŽæ¥ã§ãã printã§ããšã©ãŒãçºçããå¯èœæ§ãããããããã®ãšã©ãŒã飲ã¿èŸŒã¿ãŸãã
æ£ããèšè¿°ãããããã°ã©ã ã§ã¯ãstdoutãéãéã®æœåšçãªãšã©ãŒãšãstdoutã«æžã蟌ãããšããéã«çºçããå¯èœæ§ã®ãããšã©ãŒãèæ ®ããå¿ èŠããããŸãã Zigã䜿çšãããšãç¡èŠããŠããããšãããã£ãŠããéãããããã®ãšã©ãŒãéåžžã«ç°¡åã«ç¡èŠã§ããŸãã
ãããã¿ã€ãããªãªãŒã¹ã«ããããšæ±ºããå Žåã¯ã©ããªããŸããïŒã³ãŒããŒã飲ã¿ãªãã座ã£ãŠãšã©ãŒãåŠçãããšãããããããä»äºãããŸããäœå幎ãã®çµéšãšç¥èã«åºã¥ããŠããšã©ãŒã®å¯èœæ§ã®ãããã¹ãŠã®ã±ãŒã¹ããªã¹ãããã©ã®ããã«åŠçã§ããŸãããããããç§ãäœå幎ãã®çµéšãšç¥èãæã£ãŠããªãå Žåã¯ã©ããªããŸããïŒå€§äžå€«ãZigãããïŒ
匷åãªããšããšã©ãŒåºåã瀺ãããïŒ
const bf = @import("./bf.zig").bf; const warn = @import("std").debug.warn; const serpinsky = "++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[ -<<<[ ->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<< ]>.>+[>>]>+ ] "; pub fn main() void { var storage = []u8{0} ** 30000; bf(serpinsky, storage[0..]) catch unreachable; }
bfã¯è¿ããããããšã©ãŒãçæããããšãããããšãç¥ã£ãŠããŸãïŒã¡ã€ã³é¢æ°ã®åŒã³åºãåŽã§ãã®ãšã©ãŒã飲ã¿èŸŒã¿ãŸããéåœãåãå ¥ããŠæ£ããããšãããæºåãã§ãããã次ã®ãããªãšã©ãŒããã£ããã§ããŸãã
const bf = @import("./bf.zig").bf; const warn = @import("std").debug.warn; const serpinsky = "++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[ -<<<[ ->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<< ]>.>+[>>]>+ ] "; pub fn main() void { var storage = []u8{0} ** 30000; bf(serpinsky, storage[0..]) catch |err| switch (err) { }; }
ã³ã³ãã€ã©ã¯ä»ç§ã®å人ã§ãïŒ
/Users/jfo/code/zigfuck/main.zig:7:46: error: error.OutOfBounds not handled in switch shell returned 1
ãã®ãšã©ãŒã¯ãbfããã³è£å©é¢æ°ããçºçãããããããªãã¿ã®ã¯ãã§ãïŒããããbfã§é£²ã¿èŸŒãã stdoutã«ãã£ãŠçæããããšã©ãŒãèŠããšæ³åããŠã¿ãŸãããããããã飲ã¿èŸŒã代ããã«ãtryã䜿çšããŠãã§ãŒã³ãæŒãäžããå¿ èŠããããŸãããã£ããããã«ãšã©ãŒãçæããé¢æ°ã®åŒã³åºãã䜿çšããŠãtryã䜿çšããããšãæãåºããŠãã ãããtryã¯ããšã©ãŒãçºçãããšãã«é¢æ°ãçµäºããåŒã³åºãé¢æ°ã«æœåšçãªãšã©ãŒã®åŠçãæäŸããŸãã
ãããã£ãŠã代ããã«ïŒ
const io = std.io; ... pub fn bf(src: []const u8, storage: []u8) !void { const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream); ... '.' => stdout.print("{c}", storage[memptr]) catch unreachable, ...
ç§ãã¡ã¯ããïŒ
const io = std.io; ... pub fn bf(src: []const u8, storage: []u8) !void { const stdout = &(io.FileOutStream.init(&(try io.getStdOut())).stream); ... '.' => try stdout.print("{c}", storage[memptr]), ...
ã³ã³ãã€ã«ããŸãïŒ
const bf = @import("./bf.zig").bf; const warn = @import("std").debug.warn; const serpinsky = "++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[ -<<<[ ->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<< ]>.>+[>>]>+ ] "; pub fn main() void { var storage = []u8{0} ** 30000; bf(serpinsky, storage[0..]) catch |err| switch (err) { }; }
é¢æ°ãåŒã³åºãããšã§ååŸã§ãããã¹ãŠã®ãšã©ãŒã®ãªã¹ããååŸããŸãïŒ
/Users/jfo/code/zigfuck/main.zig:7:46: error: error.SystemResources not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.OperationAborted not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.IoPending not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.BrokenPipe not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.Unexpected not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.WouldBlock not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.FileClosed not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.DestinationAddressRequired not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.DiskQuota not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.FileTooBig not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.InputOutput not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.NoSpaceLeft not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.AccessDenied not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.OutOfBounds not handled in switch /Users/jfo/code/zigfuck/main.zig:7:46: error: error.NoStdHandles not handled in switch shell returned 1
Zigã䜿çšãããšããããã®ãšã©ãŒãå¿ èŠã«å¿ããŠåŠçã§ããããã«ãªããŸãããšã©ãŒå€ã«åºã¥ããŠåãæ¿ããè¡ããå¿ èŠã§ããã°ã±ãŒã¹ãåŠçããã¹ããããããå Žåã¯ã¹ãããããŸãã
pub fn main() void { var storage = []u8{0} ** 30000; bf(serpinsky, storage[0..]) catch |err| switch (err) { error.OutOfBounds => @panic("Out Of Bounds!"), else => @panic("IO error") }; }
å³å¯ã«èšãã°ãããã¯ãŸã æ£ãããšã©ãŒåŠçã§ã¯ãããŸãããããã¹ãŠã®çš®é¡ã®ãšã©ãŒã±ãŒã¹ãåŒã³åºãé¢æ°ã«å ±åããããšã«ãããZigãããã«ã¹ããŒãã§ããããå®èšŒãããã ãã§ãïŒãããŠããšã©ãŒãçºçãããšãã¹ã¿ãã¯ãã¬ãŒã¹ã®ä»£ããã«ãšã©ãŒãã¬ãŒã¹ãååŸããŸãïŒãã£ãããïŒ
è€å
ã€ã³ã¿ãŒããªã¿ãŒã䜿çšããŠããŸããŸãªæ¹åãè¡ãããšãã§ããŸãïŒãã¡ãããå®éã«ãã¹ãŠã®ãšã©ãŒãæ£ããåŠçããå¿ èŠããããŸãããŸããbrainfuckã§ã¯getcé¢æ°ãšããŠæ©èœããå®è¡æã«ããã°ã©ã ã«ããŒã¿ãå ¥åã§ãããããæŒç®åãå®è£ ããå¿ èŠããããŸãããŸããããŒãã³ãŒããããbfãœãŒã¹ã³ãŒãã䜿çšãã代ããã«ããœãŒã¹ãã¡ã€ã«ããããã¡ã«èªã¿èŸŒãã§è§£éã§ããããã«ããå¿ èŠããããŸããå³å¯ã«ã¯å¿ èŠã§ã¯ãªãæ¹åãããã€ããããŸãããZigã®æ©èœã®äžéšã瀺ãå ŽåããããŸããæçš¿ã®æåŸã«ãããããã¹ãŠãã³ãããã®ã§ã¯ãªããããããéšåã«åå²ããå°æ¥ã®æçš¿ã§å ¬éããŸãã
ãããã«
ãã®åå®æã®ãããã¥ã¢ãããžã§ã¯ãããZigã³ãŒããã©ã®ããã«èŠããäœã«äœ¿çšã§ãããã«ã€ããŠã®æŽå¯ãäžããŠãããããšãé¡ã£ãŠããŸãã Zigã¯ã¹ã€ã¹ã®ãã€ãã§ã¯ãããŸããããã¹ãŠã«æé©ãªããŒã«ã§ã¯ãããŸãããç¹å®ã®ããšã«çŠç¹ãåãããŠãããCãŸãã¯C ++ã®ä»£ããã«ãŸãã¯äžç·ã«äœ¿çšã§ããå®çšçãªã·ã¹ãã èšèªã§ããããšã«çŠç¹ãåœãŠãŠããŸããããã«ãããã¡ã¢ãªäœ¿çšéãã¡ã¢ãªç®¡çãããã³ãšã©ãŒåŠçã«æ éã«ã¢ãããŒãããŸããããªãœãŒã¹ãéãããŠããç°å¢ã§ã¯ãããã¯äŸ¿å©ãªæ©èœã§ããããã°ã§ã¯ãããŸããã Zigã¯æ±ºå®è«çã§ããããããŸããã¯ãªããåŸæ¥ã¯å°é£ã§ãã£ãç°å¢ã§ä¿¡é Œæ§ã®é«ãã³ãŒãã®èšè¿°ãä¿é²ããããšããŸãã
Zigã®æ§æãšæ©èœã®ããäžéšã説æããŸããããããŒãžã§ã³0.2.0以éã®èšèªã«ã¯å€ãã®èå³æ·±ãå€æŽããããŸãïŒç§ãæžããã³ãŒãã¯ãã¹ãŠãããã°ã¢ãŒãã§ã³ã³ãã€ã«ãããŸããããã¯ã»ãã¥ãªãã£ãã§ãã¯ã«æé©ã§ãã³ã³ãã€ã«æéãççž®ããŠå埩ãé«éåããã®ã«æé©ã§ãã --release-fastã¢ãŒããš--release-safeã¢ãŒãããããä»åŸããã«å€ãã®ã¢ãŒããè¿œå ãããŸãããããã®ã¢ãŒãã®éããšèª¬æã«ã€ããŠã¯ããã¡ããã芧ãã ããã
Zigã®éçºã®ã¹ããŒããšæ¹åã«ã¯åžžã«é©ããããŸããå€ãã¯ãŸã åããŠããŸãããããŒãžã§ã³1.0.0ã®ãªãªãŒã¹ãŸã§ã¯ããã§ãããZigãè©ŠããŠã¿ãããšã«ããã®ã§ããã°ãããããã®è¯ãã¢ã€ãã¢ãããããšãèŠããŠãããŠãã ããã
è©ŠããŠã¿ãŠã質åãããã°ãã€ã§ãfreenodeã§#zigã«åå ããŠãã ããã