Skip to content

Instantly share code, notes, and snippets.

@Tpaefawzen
Created May 11, 2025 06:14
Show Gist options
  • Select an option

  • Save Tpaefawzen/8aee52bc9d62a1c2805cf4928ccf9eb3 to your computer and use it in GitHub Desktop.

Select an option

Save Tpaefawzen/8aee52bc9d62a1c2805cf4928ccf9eb3 to your computer and use it in GitHub Desktop.
Ben Olmstead's Malbolge language (1998) implementation in Zig language; kinda translated C implementation into Zig
const std = @import("std");
pub const xlat1 =
"+b(29e*j1VMEKLyC})8&m#~W>qxdRp0wkrUo[D7,XTcA\"lI"
++ ".v%{gJh4G\\-=O@5`_3i<?Z';FNQuY]szf$!BS/|t:Pn6^Ha";
pub const xlat2 =
"5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72FhOA1C"
++ "B6v^=I_0/8|jsb9m<.TVac`uY*MK'X~xDl}REokN:#?G\"i@";
pub fn main() !void {
// WONTFIX: POSIX only
var args = std.process.ArgIterator.init();
_ = args.next();
const arg1 = args.next() orelse return error.InvalidCommandLine;
var i: u16 = 0;
var mem: [59049]u16 = undefined;
{
var f = try std.fs.cwd().openFile(arg1, .{});
defer f.close();
while (f.reader().any().readByte()) |x| {
if (std.ascii.isWhitespace(x)) continue;
if (x < 127 and x > 32) {
_ = std.mem.indexOfScalar(u8, "ji*p</vo", xlat1[(x-33+i)%94])
orelse return error.InvalidCharacterInSourceCode;
}
if (i == 59049) return error.InputFileTooLong;
mem[i] = x;
i += 1;
} else |e| {
if (e != error.EndOfStream) return e;
}
}
while (i < 59049) : (i+=1)
mem[i] = op(mem[i-1], mem[i-2]);
exec(&mem);
}
pub fn exec(mem: *[59049]u16) void {
var a: u16 = 0;
var c: u16 = 0;
var d: u16 = 0;
while (true) {
if (mem[c] < 33 or mem[c] > 126) continue;
switch ( xlat1[(mem[c]-33+c)%94] ) {
'j' => { d = mem[d]; },
'i' => { c = mem[d]; },
'*' => {
mem[d] = mem[d]/3 + mem[d]%3 * 19683;
a = mem[d];
},
'p' => {
mem[d] = op(a, mem[d]);
a = mem[d];
},
'<' => {
_ = &std.io.getStdOut()
.writer().any().writeByte(@intCast(a&0xff));
},
'/' => {
a = std.io.getStdIn().reader().any().readByte()
catch 59048;
},
'v' => return,
else => {},
}
mem[c] = xlat2[mem[c]-33];
c = if (c==59048) 0 else c + 1;
d = if (d==59048) 0 else d + 1;
}
}
pub fn op(x: u16, y: u16) u16 {
var i: u16 = 0;
const p9: [5]u16 = .{ 1, 9, 81, 729, 6561 };
const o: [9][9]u16 =
.{
.{ 4, 3, 3, 1, 0, 0, 1, 0, 0 },
.{ 4, 3, 5, 1, 0, 2, 1, 0, 2 },
.{ 5, 5, 4, 2, 2, 1, 2, 2, 1 },
.{ 4, 3, 3, 1, 0, 0, 7, 6, 6 },
.{ 4, 3, 5, 1, 0, 2, 7, 6, 8 },
.{ 5, 5, 4, 2, 2, 1, 8, 8, 7 },
.{ 7, 6, 6, 7, 6, 6, 4, 3, 3 },
.{ 7, 6, 8, 7, 6, 8, 4, 3, 5 },
.{ 8, 8, 7, 8, 8, 7, 5, 5, 4 },
};
for (0..5) |j|
i += o[y/p9[j]%9][x/p9[j]%9]*p9[j];
return i;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment