AsciiFunc
Paradigm(s) | imperative |
---|---|
Designed by | Ucrash |
Appeared in | 2021 |
Memory system | variable-based |
Dimensions | one-dimensional |
Computational class | Turing complete |
Major implementations | Original Node.js Interpreter |
File extension(s) | .ascf |
AsciiFunc is an esoteric programming language, developed by Ucrash and DexterHill0. It consists of 19 commands, each represented with it's own ascii character (Example: $
, #
, etc). Commands can also have arguments, that can either be identifiers, numbers, booleans, strings or pointers. Commands also cannot be put inside each other, they have to be followed one after another. The language mostly ignores whitespaces and indentation, apart from these rules: there has to be no whitespace between the command character and the corresponding opening parenthesis; there has to be whitespace between commands.
Here's an example of an AsciiFunc program:
$(bottles, num) $(lyric, str) =(bottles, 99) :(lyric, "") &(lyric, bottles) &(lyric, " bottles of beer on the wall, ") &(lyric, bottles) &(lyric, " bottles of beer") <(lyric) :(lyric, "Take one down and pass it around, ") +(bottles, -1) &(lyric, bottles) &(lyric, " bottles of beer on the wall") <(lyric) :(lyric, "") <(lyric) ?(bottles, 3)
Overview
Every AsciiFunc program has one or more commands. A command has it's own name (an ascii character), arguments and index. Command indexes start from 0 and increment with every new command. There are 19 commands: ~
, $
, +
, =
, %
, :
, &
, !
, .
, @
, "
, 1
, #
, ?
, <
, >
, /
, \
and |
. They allow user to create and manage variables, define and call functions, print and get user input, jump to other commands, jump conditionally and import functions and variables from other AsciiFunc files. Function arguments are separated with commas and can either be a booleans (true
/false
), numbers (integers and floats), strings (contained between two "
symbols), pointers or identifiers. Any text outside of a command is treated as a comment.
Commands
Here's a list of all AsciiFunc commands, along with their desciption and example uses:
Name | Arguments | Description | Example |
---|---|---|---|
~ | path (string) | Imports another asciifunc file, which allows for use of it's global functions and variables. | ~("../std-asciifunc.ascf")
|
$ | var name (identifier); var type ("str"/"num"/"bool") |
Declares a variable in the current scope. String variables default to "", number variables default to 0 and booleans default to false. |
$(my variable, num)
|
+ | target var (variable); what to add (number or variable) |
If the target var is of type number, adds what's in the second argument to it. Otherwise, leaves the variable as is. (if the second argument is not a number, also does nothing) |
+(my variable, 5)
|
= | target var (variable); target value (number or variable) |
If the target var is of type number, sets it to what's in the second argument. Otherwise, leaves it as is. (if the second argument is not a number, also does nothing) |
=(variable2, 10)
|
% | var1 (variable); tvar2 (variable); tvar3 (variable); |
Compares var1 and var2. If var1 == var2, sets var3 to 0, if var1 > var2, sets var3 to 1, Ootherwise, sets var3 to -1. var3 has to be of a type number, while var1 and var2 can be any type. |
%(my variable, variable2, var3)
|
: | target var (variable); target value (string or variable) |
If the target var is of type string, sets it to what's in the second argument. Otherwise, leaves it as is. (if the second argument is not a string, also does nothing) |
:(variable2, "Hello")
|
& | target var (variable); what to add (string or variable) |
If the target var is of type string, adds what's in the second argument to the end of it. Otherwise, leaves it as is. (if the second argument is not a string, also does nothing) |
&(variable2, ", world!")
|
! | target var (variable) | If the target var is of type number, multiplies it by -1. If it's of the type string, converts it to upper case. Otherwise, inverts the variable. |
myString is set to "Hi!"
|
. | target var (variable) | If the target var is of type string, converts it to lower case. Otherwise, leaves it as is. | myString is set to "HI!"
|
@ | target var (variable); arg1 (number or variable); arg2 (number or variable) |
If target var is of type number, clamps it to arg1 and arg2. If target var is of type string, slices it from arg1 to arg2 (similarly to JavaScript's slice method) |
@(myString, 0, -1)
|
" | var1 (variable); var2 (variable) |
Converts var1 to string (similarly to JavaScript's toString method) and stores the result in var2. If var2 is not of type string, does nothing. |
"(myNum, myString)
|
1 | var1 (variable); var2 (variable) |
Converts var1 to number and stores the result in var2. If the result is NaN, sets var2 to 0. If var2 is not of type number, does nothing. |
1(my variable, myNum)
|
# | index (pointer) | Goes to a command #index. Index can be absolute (examples: 5, 6, 12), or it can be relative to the current command (examples: -5, +6, +3, -12) |
#(6) #(+3)
|
? | var (variable); index1 (pointer); index2 (optional, pointer) |
Checks if var is truthy. If so, goes to command #index1, otherwise, if index2 is defined, goes to command #index2. |
?(myBool, +1, -3)
|
< | var (variable) | Prints var | <(myString)
|
> | type ("num"/"str"/"bool"); var (variable) |
Gets user input, then converts it to a specific type and stores it inside var | >(str, myString)
|
/ | function name (identifier); arguments (optional, any amount) |
Declares and opens a function. Each function has it's own scope. | /(my function, s)
|
\ | return value (optional, variable) | Closes the function. Optionally, you can also return a variable | /(helloworld)
|
| | name (function name); arguments (variables or constants); var (optional, variable) |
Calls a function with a certain name, providing certain values as arguments. Additionally, you can store the return value for that function inside var |
|(my function, "Hi!")
|
Memory System
AsciiFunc's variables and functions are only accessible after declaration in the scope they're declared in and in all of the children scopes. There's a global scope and each function also has it's own scope. There are 3 variable types: numbers, strings and booleans.
Example Programs
Hello, World!
$(s, str) :(s, "Hello, World!") <(s)
Truth Machine
declare zero and ones to be accessed later $(zero, num) $(one, num) =(zero, 0) =(one, 1) get input $(input, num) >(num, input) @(input, 0, 1) compare input (will output number) $(inputCompare, num) %(input, zero, inputCompare) convert comparison to bool ?(inputCompare, +1, +3) print 1 indefinitely <(one) #(-1) print 0 <(zero)
99 Bottles of Beer
$(bottles, num) $(lyric, str) =(bottles, 99) :(lyric, "") &(lyric, bottles) &(lyric, " bottles of beer on the wall, ") &(lyric, bottles) &(lyric, " bottles of beer") <(lyric) :(lyric, "Take one down and pass it around, ") +(bottles, -1) &(lyric, bottles) &(lyric, " bottles of beer on the wall") <(lyric) :(lyric, "") <(lyric) ?(bottles, 3)
Halting Program
#(0)
Library Support
Unlike most esolangs, AsciiFunc allows importing other files using the ~
command, in which case they're called libraries. The most popular library, as of now, is std-asciifunc.ascf in the official GitHub repository.