SMIL (Structured and Methodic and Innovative Language) is a metadata ASCII-smileys based language. Data are only input by command line, the program just contains instructions.
Every program begins with <3 and ends with </3.
Whitespace ("_"), tabs ("\t") and line breaks ("\n") can separate smileys and are ignored, even in variable names. Comments starts with ;) and end at the end of the line.
Standard input and output
To get an input from the command line, we use :$ to get the first argument, :$:$ for the second, etc. Note: these values cannot be assigned (changed) and there are no skippable characters between each :$.
To output strings and numbers, we use the print function:
:@ [content to print] @)
like this to output the third argument
:@ :$:$:$ @)
The too classic "Hello, world!" can be written as follows:
<3 :B </3
:B simply writes out "Hello, world!" if no arguments are given, and "Hello, [first argument]!" otherwise. To print something else (variable or operation):
:@ [content to print] @)
A variable declaration or usage starts with :( and ends with :). Anything inside is valid as variable name. A declaration starting with x( will set the variable to the inverse of the right end value or will invert the value of the variable if used in an operation or an assigment. An empty name will count as an anonymous variable, the value will not be stored. A variable can be created dynamically by putting a variable inside another one, the created variable will get its name from the nested variable. Example:
:( :( :P :) :) ;) Create a variable with the same name as the value of the variable :P
Assignment is done with =; with only a variable on the left hand side and input, variable or operation on the right hand side. Inputs cannot be overridden.
|operator||description||with 7 and 3||with "abc" and 2||with "abc" and "ab"|
|:>||Subtract||4||"a"||"c" (remove occurence)|
|:/||Divide||2||"a" (divide the length)||(error: invalid)|
|%)||Modulus||1||"cab" (shift to right)||(error: invalid)|
|:&||Logical and||1||(error: invalid)||(error: invalid)|
|:|||Logical or||1||(error: invalid)||(error: invalid)|
Note: :& and :| returns a binary number: zero (false) or one (true).
Push a variable or an input with :P, pop the last item of the stack to the variable :D with :O :( :D :) and clear the stack content with :D.
The loop structure is one of the most brilliant and brief ways to do it. If the condition is true (more than zero for a number, or a non-empty string), the then block is executed, until the condition is true. If the condition is false (equal to or less than zero, or an empty string) before the condition is evaluated, the thelse block (from then+else) is executed once, and the loop exits. The best idea in the fifty last years of programming!
8| [condition] |) [then block] 8) [thelse block] 8}
The nop instruction uses the special "paku-paku" smiley :v and does nothing at all, as expected.
To get the length of a string (or the number of digits of a number), use L)
L) [input | variable]
Exit the program (with a zero status code, i.e. success): #0
Factorial example (the first input is the number for which to calculate the factorial):
<3 :( =; :) =; :$ :/ :$ ;) (1) :( :P :) =; :( =; :) :( :D :) =; :( =; :) ;) (2) 8| :$ :> :( :D :) |) ;) (3) :( :D :) =; :( :D :) :# :( =; :) ;) (4) :( :P :) =; :( :P :) :* :( :D :) ;) (5) 8) 8} :@ :( :P :) @) </3
- the var '=;' is equal to 1
- the accumulator ':D' is equal to 1
- while ':D' < ':$'
- increment ':D'
- ':P' equals to ':P' times ':D'
And the golf version: