Funky
Introduction
Funky, a function-based language! It is an esolang where you can't do anything other than creating and executing functions (but I guess you can because its Javascript). The syntax is completely just Node.js's syntax (mainly because I am very lazy).
Functions
There are some pre-made functions in Funky... a lot of them. And they are:
- println(v) ---------------------------------- prints 'v' with a newline
- print(v) ------------------------------------ prints 'v'
- setVar(varName, varValue) ------------------- sets the variable 'varName' to 'varValue'
- getVar(varName) ----------------------------- returns the contents of the variable 'varName'
- incVar(varName) ----------------------------- varName++
- decVar(varName) ----------------------------- varName--
- loop(start, end, step, callback) ------------ basically a for-loop --- for (let i = start; i < end; i += step) {callback}
- length(array) ------------------------------- returns the length of an array 'array'
- push(varName, value) ------------------------ push 'value' into 'varName'
- pop(varName) -------------------------------- pop 'varName' and return it
- shift(varName) ------------------------------ shift 'varName'
- unshift(varName) ---------------------------- unshift 'varName'
- assert(condition, callback, fallback) ------- literally an if statement made into a function
- input(varName) ------------------------------ gets input and stores into 'varName' (needs to be called in an await way)
- exit(code) ---------------------------------- exit with code 'code'
- tryCatch(try, catch) ------------------------ try to execute 'try' or execute catch(e) if failed (e=errorMessage)
- readFile(file, varName) --------------------- works like input
- writeFile(file, data) ----------------------- over-write file with data
- randomInt(min, max) ------------------------- return a random integer with bounds of 'min' to 'max'
- randomFloat(min, max) ----------------------- works like randomInt
- randomString(len) --------------------------- random string with 'len' amount of characters
- randomItemOfArray(array) -------------------- select random item of array 'array'
- getCurrentTime() ---------------------------- get current time
- threeLettersBack(string) -------------------- encrypt 'string'
- threeLettersForward(string) ----------------- decrypt 'string'
Phew... thats a lot of functions!
Examples
Now, a normal program doing nothing would look something like this:
(async () => { exit(0) })()
and here are two examples:
Hello World
(async () => { println("Hello World") exit(0) })()
truth-machine
(async () => { await input("x") assert(getVar("x") === "1", () => { loop(0, Infinity, 1, () => { print("1") // Print 1 for the rest of eternity }) }, () => { assert(getVar("x") === "0", () => { println("0") }) }) exit(0) })()
Creating custom functions
So, you just made some of your programs and want to make more functions than Funky offers you (if so, ISN'T THAT ENOUGH???).
Well, You are in the right place, functions are basically variables. So this is how you can do it:
setVar("Function Name", (parameters) => { return (parameter + parameter * 4) - 4 })
Done! You have just created a function... but you don't know how to run it. No problemo!
setVar("x", getVar("Function Name")(10))
Here, 10 is the parameter. And because of the return (Why is the return keyword not a function??) the result gets passed into the variable "x"
Implementation (in Node.js)
And heres the implementation (2 files):
(index.js)
const fs = require('fs') const vm = require('vm') const readline = require('readline') const context = { console: console, readline: readline, process: process, fs: fs } const defenitionsCode = fs.readFileSync('defenitions.js', 'utf8') vm.runInNewContext(defenitionsCode, context) const funkyCode = fs.readFileSync(process.argv[2], 'utf8') vm.runInNewContext(funkyCode, context)
(defenitions.js)
// Initialize const rl = readline.createInterface({ input: process.stdin, output: process.stdout }) const vars = {} // Variable related functions function println(value) { console.log(value) } function print(value) { process.stdout.write(value) } function setVar(name="x", value) { vars[name] = value } function getVar(name="x") { return vars[name] } function incVar(name="x") { setVar(name, getVar(name) + 1) } function decVar(name="x") { setVar(name, getVar(name) - 1) } // Loop function loop(start=0, end=10, step=1, callback=()=>{println("You forgot")}) { if (step > 0) { for (let i = start; i < end; i += step) { callback(i) } } else if (step < 0) { for (let i = start; i > end; i += step) { callback(i) } } } // Array functions function length(array=["You", "forgot", "to", "give", "an", "argument"]) { return array.length } function push(name="x", value) { getVar(name).push(value) } function pop(name="x") { return getVar(name).pop() } function shift(name="x") { return getVar(name).shift() } function unshift(name="x", value) { getVar(name).unshift(value) } // Normal functions function assert(condition=true, callback=()=>{println("You forgot")}, fallback=()=>{}) { if (condition) { callback() } else if (fallback) { fallback() } } function input(name="x") { return new Promise((resolve) => { rl.question(`?> `, (input) => { setVar(name, input) resolve() }) }) } function exit(code=0) { process.exit(code) } function tryCatch(tryBlock=()=>{println("You forgot")}, catchBlock=e=>{console.error("You forgot\n"+e)}) { try { tryBlock() } catch (e) { catchBlock(e) } } // File functions function readFile(filename="youForgot.txt", name="x") { setVar(name, fs.readFileSync(filename, { encoding: 'utf8', flag: 'r' })) } function writeFile(filename="youForgot.txt", data="You forgot to give some data") { fs.writeFileSync(filename, data) } // Random functions function randomInt(min=0, max=10) { return Math.floor(Math.random() * (max - min + 1)) + min } function randomFloat(min=0, max=1) { return Math.random() * (max - min) + min } function randomString(len=15) { const charList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789~`!@#$%^&*()-_+={[}]|\\:;\"'<,>.?/" let result = for (let i = 0; i < len; i++) { result += charList[randomInt(0, charList.split("").length)] } return result } function randomItemOfArray(array=["You", "forgot", "to", "give", "an", "argument"]) { return array[Math.floor(Math.random() * array.length)] } // Date and time function function getCurrentTime() { const currentDate = new Date() const year = currentDate.getFullYear() const month = currentDate.getMonth() + 1 const day = currentDate.getDate() const hours = currentDate.getHours() const minutes = currentDate.getMinutes() const seconds = currentDate.getSeconds() const formattedDate = `${day}.${month}.${year} ${seconds}:${minutes}:${hours}` return formattedDate } // Encryption functions function threeLettersBack(text="You forgot") { let result = for (let i = 0; i < text.length; i++) { let char = text[i] if (char.match(/[a-z]/i)) { const code = text.charCodeAt(i) let shiftAmount = 3 % 26 let shiftedCode = code if (code >= 65 && code <= 90) { shiftedCode = ((code - 65 + shiftAmount) % 26) + 65 } else if (code >= 97 && code <= 122) { shiftedCode = ((code - 97 + shiftAmount) % 26) + 97 } result += String.fromCharCode(shiftedCode) } else { result += char } } return result } function threeLettersForward(text="You forgot") { let result = for (let i = 0; i < text.length; i++) { let char = text[i] if (char.match(/[a-z]/i)) { const code = text.charCodeAt(i) let shiftAmount = -3 % 26 let shiftedCode = code if (code >= 65 && code <= 90) { shiftedCode = ((code - 65 + shiftAmount) % 26) + 65 } else if (code >= 97 && code <= 122) { shiftedCode = ((code - 97 + shiftAmount) % 26) + 97 } result += String.fromCharCode(shiftedCode) } else { result += char } } return result }
Execution
So, you have everything set up and you want to run it, but how? Well, first you have to get to the directory where the index.js and defenitions.js is located and then run this command:
node . path/to/your/program.funky
Note: change "path/to/your/program.funky" to where your funky program is located.
And your program should successfully work!