Deadfish x

From Esolang
Jump to: navigation, search

Deadfish x is a superset of Jonathan Todd Skinner's Deadfish. There are twice as many commands and uses the XKCD variant.

I (firefly431) will be writing a Python interpreter, but you guys can write whatever you want.

Commands

x Add 1 to x.
k Output x to the console.
c Square x.
d Subtract 1 from x.
X Start a function. The next character is the function name.
K Output x as an ASCII character.
C End the function or execute a function.
D Set x to 0.

Rules

X (the variable) can only go from 0 to 255. If it goes above or below, it will be set to 0. You can type as many commands as you want on a line, but the prompt will only be shown when you push enter.

Sample Programs

To run these, save them and run them, or just copy and paste.

xxcxxxxcxxxxxxxxKDxxcxxxxxxcxKxxxxxxxKKxxxKDxxxxxxxcdddddKDxxxxxxcddddKDxxxcxxcddKddddddddKxxxKddddddKddddddddKDxxxxxxcdddK

Prints out "Hello, world!"

XUxKCxxcxxxxcCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCUCU

Prints out the entire alphabet.

Interpreter

Python

My interpreter. Put something here if you find a bug.

# Deadfish x Programming Language
# By firefly431
# This is free and unencumbered software released into the public domain.
# Visit <http://unlicense.org/> for the full thing.

x = 0;
funcname = "";
curfunc = "";
lastc = '';
functions = {};

q_="i;iyratnrt gatmivpo";
_q=[0, 14, 17, 18, 4, 6, 10, 5, 7, 9, 2, 11, 8, 12, 16, 15, 13, 3, 1];
tar = [];
for i in _q: tar.append(q_[i]);
tar="".join(tar);

import webbrowser;

def openxkcd(num):
    webbrowser.open("http://xkcd.com/"+str(num)+"/");

def process(c): #Finite State Machine
    global x;
    global funcname;
    global curfunc;
    global lastc;
    global functions;
    if x<0 or x>255:
        x=0;
    if (lastc == 'X'): #we are starting a function
        funcname = c;
        print("Function start: "+c);
        lastc = ''; #so if the name is C or X we don't process it
        return;
    if (lastc == 'C'): #we are executing a function
        print("Execute function: "+c);
        lastc = ''; #same thing
        if (c in functions):
            for q in functions[c]: #c is taken
                process(q);
        else:
            print("Function '"+c+"' does not exist.");
        return;
    if funcname != "" and c != 'C': #We are in a function
        print("In function");
        curfunc += c;
        lastc = c;
        return;
    #check commands, function commands pass.
    if c == "x":
        x+=1;
    elif c == "k":
        print(str(x));
    elif c == "c":
        x*=x;
    elif c == "d":
        x-=1;
    elif c == "X":
        pass;
    elif c == "K":
        print(chr(x),end="");
    elif c == "C":
        if funcname != "":
            print("End Function");
            lastc = ''; #so we don't execute a function
            functions[funcname] = curfunc;
            funcname = "";
            curfunc = "";
            return;
    elif c == "D":
        x=0;
    lastc = c;

def getInput(str = ""):
    global x;
    global tar;
    if str=="":
        inp = input(">> "); #change this to raw_input() if using python 2.x
    else:
        inp = str;
    if inp == tar:
        openxkcd(1061%354);
    for c in inp:
        process(c);

import sys;
fname = "";
lines = [];
if len(sys.argv)>1:
    fname = sys.argv[1];
if fname != "":
    try:
        fp = open(fname,"r");
        lines = fp.readlines();
        fp.close();
    except:
        print("Could not open file '"+fname+"'.");
if len(lines)>0:
    for line in lines:
        getInput(line);
else:
    try:
        while True:
            getInput();
    except KeyboardInterrupt:
        print("Bye!");

Lua

-- Deadfish x in pure Lua
-- By Atenfyr


local functions = {}

function deadfishx(str, tx)
	local ignore = {}
	local tx = tx or 0
	
	for i = 1, #str do
		if tx < 0 or tx > 255 then tx = 0 end
		if not ignore[i] then
			local instr = str:sub(i, i)
			if instr == "x" then
				tx = tx + 1
			elseif instr == "k" then
				io.write(tx)
			elseif instr == "c" then
				tx = tx ^ 2
			elseif instr == "d" then
				tx = tx - 1
			elseif instr == "X" then
				local _, nextC = str:sub(i+2):find("C")
				nextC = nextC+i+1
				for n = i+1, nextC do
					ignore[n] = true
				end
				functions[str:sub(i+1, i+1)] = str:sub(i+2, nextC)
			elseif instr == "K" then
				io.write(string.char(tx))
			elseif instr == "C" then
				ignore[i+1] = true
				tx = deadfishx(functions[str:sub(i+1, i+1)]:sub(1, -2), tx)
			elseif instr == "D" then
				tx = 0
			end
		end
	end
	
	return tx
end

-- If it's being loaded as a library (for some reason), then they now have the deadfishx function and the file can be closed
if pcall(debug.getlocal, 4, 1) then
	return
end

local q_ = "i;iyratnrt gatmivpo"
local _q = {1, 15, 18, 19, 5, 7, 11, 6, 8, 10, 3, 12, 9, 13, 17, 16, 14, 4, 2}
local tar = {}
for _, i in pairs(_q) do
	tar[#tar+1] = q_:sub(i, i)
end
tar = table.concat(tar, "")

local function openXKCD(n)
	if package.config:sub(1,1) == "\\" then
		os.execute('start "" "http:///xkcd.com/' .. n .. '/" >nul 2>&1')
	else
		-- I don't want to install Linux so if this breaks Linux users please let me know
		os.execute("xdg-open http://xkcd.com/" .. n .. "/ &> /dev/null")
	end
end

local x = 0

local tArgs = {...}
if tArgs[1] then
	local open = io.open(tArgs[1], "r")
	if not open then print("File does not exist!") os.exit() end
	local content = open:read("*a"):gsub("\r\n", ""):gsub("\n", "")
	open:close()
	deadfishx(content, x)
	os.exit()
end


while true do
	io.write(">> ")
	local cmd = io.read()
	
	if cmd == tar then
		openXKCD(1061%354)
	else
		x = deadfishx(cmd, x)
	end
	io.write("\n")
end