\input texinfo @c -*-texinfo-*- @comment %**start of header @setfilename enigma-documentation.info @finalout @settitle Enigma @afourpaper @syncodeindex pg cp @comment %**end of header @copying This manual is for Enigma, version 0.1. Copyright @copyright{} 2010 Niels Serup @quotation Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". This document is also available under the terms of the Creative Commons Attribution-Share Alike 3.0 (or any later version) Unported license. A copy of the license is available at @url{http://creativecommons.org/@/licenses/@/by-sa/@/3.0/@/legalcode}. @end quotation @end copying @titlepage @title Enigma @subtitle A programming language @hskip 0pt plus 1filll Version 0.1 @sp 8 @center @image{../art/enigma-logo,11cm,,Enigma logo} @author Niels Serup (@email{ns@@metanohi.org}) @page @vskip 0pt plus 1filll @insertcopying @end titlepage @contents @ifnottex @node Top, Introduction, (dir), (dir) @top Enigma @insertcopying New versions of this manual will be available at @url{http://metanohi.org/@/projects/@/enigma/}. @end ifnottex @menu * Introduction:: * Language:: * Future:: * Implementations:: * Comparison:: * Built-In:: * Copying This Manual:: * Index:: @end menu @node Introduction, Language, Top, Top @chapter A short introduction Today, in the world of programming, the commonly used programming languages have --- to some extent --- adapted the same basic syntax. Both C, C++, Java, Python and Ruby (and others) all share several paradigms, even though they are still very different. Enigma, on the other hand, is very different from the ``common'' languages. See this small program to get an idea of Enigma: @verbatim {/a,b/ a 2 ! multiply = c; b c ! add = return; } = odd-add; 9 4 ! odd-add | stdout temp ! write; @end verbatim @noindent Here, 9 is first multiplied with 2 and then added to 4. The program then prints the result (22). With only a few constructs and built-in variables, Enigma is quite small and relatively simple. Any logic can be expressed in Enigma. The above example may seem odd, but its aspects will be dealt with in the next chapter. Enigma is @emph{not} the kind of programming language that likes to control programmers. When programming in Enigma, one creates functions that call other functions --- instead of creating functions that are called by built-in functions. On the other hand, Enigma is very restrictive. There are limits to certain things. If these limits were not present, chaos would ensue. Perhaps. @cindex pointers Like many other languages, Enigma is quite fond of pointers. In Enigma, all variables are pointers. When @code{x} is assigned to @code{a}, and @code{b} is assigned to @code{a}, changing @code{b} also changes @code{a}. As a matter of fact, when two pointers points to the same place, they are @strong{forever} linked together. Enigma is not recommended for serious use. Use with @strong{caution}! @node Language, Future, Introduction, Top @chapter The language Enigma consists of functions. Any file being parsed is a function. Within functions there can be local variables. These variables are to disappear when the function exits. Functions have return values. These values can be determined by the programmer. Within functions, there are commands. These commands constitute the very base of Enigma. Commands can interact with built-in functions, meaning that writing to and reading from files, calculating, as well as manipulating strings and lists, is possible. There are no simple types. Enigma lies in the world of objects. Numbers, strings, lists.. It's just objects. Also, all commands must end with a semicolon@code{;} @menu * Operators:: * Numbers:: * Strings:: * Lists:: * Booleans:: * Files:: * Functions:: * Conditionals:: * Loops:: * Undefined:: @end menu @node Operators, Numbers, Language, Language @section Operators @cindex operators Enigma has 4 operators: @code{!}, @code{=}, @code{|}, and @code{*}. @code{!} and @code{=} are the most important ones. To assign values to variables, use the @code{=} operator. For example: @verbatim obj = hello-string; @end verbatim Here, the variable @code{hello-string} receives the object @code{obj}. Note the syntax. The objects comes first. Unless @code{hello-string} is already defined, it is created as a local variable. Now, say we have a function called @code{think} and we want to send objects to it. This is how that's done: @verbatim obj1 obj2 obj3 ! think; @end verbatim There are no limits to the amount of objects that can be sent to a function. Whitespace characters are used to separate objects, also when assigning them to a variable. There @emph{is} a difference between using one object and more objects as arguments, though. When using only one object, that object is simply used, but when using more objects, a list containing all objects is created and transmitted instead. So, in reality, when assigning two or more objects to a variable, the variable points to a list with the objects. More about lists later. The @code{|} operator is merely a shortcut operator. It can merge several commands into one, long command. See the following example: @verbatim # Long version a ! b = c; d c ! e = c; # Short version a ! b | d temp ! e = c; @end verbatim Here, @code{a} is sent to @code{b}, which is then --- together with @code{d} --- sent to @code{e} and saved in @code{c}. The @code{|} acts like the semicolon, but it copies the return value of the last function (in this case @code{b}) and stores the value in the local variable @code{temp}. Hackers are encouraged to use this operator. The final operator, @code{*}, has the same function as @code{=}, except that it works on a global level. So, if the code is @code{b = a;} and @code{a} does not exist, it is created --- in the global space. @node Numbers, Strings, Operators, Language @section Numbers @cindex numbers Numbers in Enigma can be arbitrarily large. They are written as one usually writes numbers. Currently only the decimal system is supported. @verbatim 7587 = age; 2556 ! numfunc; @end verbatim @node Strings, Lists, Numbers, Language @section Strings @cindex strings @cindex characters Strings are defined using the @code{"} character. @verbatim "This is a string!" " This too!" ! add; "A" = A; "Now comes a newline" = nl; "\"\\\n\t\ " = escaped; @end verbatim @node Lists, Booleans, Strings, Language @section Lists @cindex lists @cindex arrays Lists are special in Enigma. They are used a lot, but unlike eg. numbers and strings they cannot be defined in their own syntax. When one writes this: @verbatim 123 "witch" = lst; @end verbatim ..one creates a list. Lists can be nested. @node Booleans, Files, Lists, Language @section Booleans @cindex booleans Booleans are used a lot in Enigma. The predefined variables @code{true} and @code{false} can be used. @node Files, Functions, Booleans, Language @section Files @cindex files Files can only be created using the built-in function @code{open}. Files are either readable or writeable. If a file is writeable, text written to the file may optionally be appended to any existing text. @cindex read @cindex write @cindex open @cindex close @verbatim "a" "r" ! open = f1; "b" "w" ! open = f2; "c" "a" ! open = f3; # Read one character f1 ! read | stdout temp ! write; # Write a string f2 "Aaar" ! write; # Append a string f3 "Ouu" ! write; f1!close;f2!close;f3!close; @end verbatim To read an entire file, one must use a loop construct. @xref{Loops}. When there are no more characters left, the @code{read} function returns an empty string. Using equality testing, reading a complete file is thus possible. @xref{Conditionals}. @verbatim filename "r" ! open = f; {f ! read = c; stdout c ! write; c "" ! equal ! not = return;} ! loop; @end verbatim At this point, it may not be obvious why this works. This will be explained in the next sections. @node Functions, Conditionals, Files, Language @section Functions @cindex functions Functions are defined and called using the following syntax: @verbatim # Defining them {stdout "Hello" ! write;} = func; {/x,y/stdout "x=" x ", y=" y!write;} = coorprint; {stdout args ! write;} = aprint; # Calling them !func; # Outputs "Hello" 52 12 ! coorprint; # Outputs "x=52, y=12" 999 "abc" 21 ! aprint; # Outputs "999 abc 21" @end verbatim Arguments can thus be accessed either by using the @code{/.../} syntax in the beginning of the function or by using the local @code{args} variable. Furthermore, to make @emph{all} new variables save in the global space, prepend the function content with a @code{*}. This will have the same effect as replacing all @code{=} signs in the function with the @code{*} operator. Remember that your file is also a function, just without the curly brackets. This means that when working on the top level of your program, @code{args} actually refer to the arguments specified on the command line. All arguments are strings, but built-in functions that can convert them to numbers exist. The previous example functions did not have any return values. This is merely because they didn't need such things. To define a return value, the return value must be sent to the special variable @code{return}. @verbatim {/a,b/a b ! multiply = return;} = 2mul; 33 3 ! 2mul = 2mult; stdout 2mult ! write; @end verbatim The execution of a function does @strong{@emph{not}} stop when a value is assigned to @code{return}. This has both advantages and disadvantages. Many things are almost impossible to do without the built-in functions. Some are completely impossible. @xref{Built-In}. As all objects in Enigma are pointers, several built-in functions actually modify the objects sent to them as arguments. To solve this problem, one must use the @code{clone} function. @node Conditionals, Loops, Functions, Language @section Conditionals Any value can be related to another value. 78 is less than 85. 2 equals 2. "Hi" is not "Bye". Enigma comes with a basic set of functions that can be used to test these relations. The functions @code{greater}, @code{lesser}, @code{equal}, @code{not}, @code{or} and @code{and} are available. These functions return either true or false. To run a function on the condition that a relational function has returned true, use the function @code{act}. While @code{lesser} and @code{greater} are aimed at numbers only, and @code{and}, @code{or} and @code{not} are aimed at booleans only, @code{equal} can be used on all objects. It tests for all equalities. @verbatim 2 = a; 4 = b; a 2 ! add | temp b ! equal = cond1; "47" ! num | temp 48 ! greater = cond2; cond1 cond2 ! and | temp write stdout "4 = 4 and 47 > 48\n" ! act; cond1 cond2 ! or | temp write stdout "4 = 4 or 47 > 48\n" ! act; cond2 ! not | cond1 temp ! and | temp write stdout "4 = 4 and !(47 > 48)\n" ! act; @end verbatim Even simpler, one can do this (though there's no real need for it): @verbatim # Instead of stdout "Hello" !write; true write stdout "Hello" !act; @end verbatim @node Loops, Undefined, Conditionals, Language @section Loops There are several ways to loop pieces of code in Enigma. One can create a function that calls itself, for example. It is, however, advised to use the @code{loop} function. @verbatim # Infinite loop {stdout "Forever\n" ! write; true = return;} ! loop; @end verbatim @code{loop} works a bit like @code{act}, except that it runs on the premise of the return value of the function it calls. If it returns true, or any other value that can be considered true (non-zero numbers, non-empty strings, files, etc.), it runs the function again. If it returns false, the loop stops. It naturally runs the first time no matter what (no return value has been created yet). @node Undefined, , Loops, Language @section Undefined behaviour Enigma is still new. The way built-in functions act, the way error messages appear, and the way some odd details of the language works are still undefined. In general, when something seems likely to work, it will work. But it's not necessarily defined to work. @node Future, Implementations, Language, Top @chapter Future aspects As Enigma is right now, it is quite limited. The only way that it can interact with the rest of one's system is by reading and writing files and by executing shell commands using the @code{system} built-in function. This obviously needs to be improved. A foreign function interface system must be implemented in version 0.2. It should be possible for Enigma to do everything C can. The number of built-in functions seems reasonable, but it may be a good idea to implement a few more. These eventual functions should be focused on making things easier. Specifically, an import function should be considered. It is possible to create an import function in Enigma directly, but it's not exactly fast. Introducing a ``compile'' function should solve that. @node Implementations, Comparison, Future, Top @chapter Implementations @pindex enigma As of right now (beginning of June 2010) there is only one implementation. It is written in Java and is called enigma (with a lowercase e). The code is bulky and was not written by an experienced Java hacker. For v0.2 it may be a good idea to write the interpreter in C instead. Implementing a foreign function interface should be easier that way. The current implementation can be downloaded at @url{http://metanohi.org/@/projects/@/enigma}. @node Comparison, Built-In, Implementations, Top @chapter Comparison with other languages @macro exmpl {lang,content} @quotation \lang\ @cartouche @example \content\ @end example @end cartouche @end quotation @end macro @menu * Compared assigning:: * Compared conditionals:: * Compared looping:: * Compared functions:: @end menu @node Compared assigning, Compared conditionals, Comparison, Comparison @section Assigning values @exmpl{C,type var = value;} @exmpl{Python,var = value} @exmpl{Enigma,value = var;} @node Compared conditionals, Compared looping, Compared assigning, Comparison @section Conditionals @exmpl{C,if ((a == 2 && b < 5) || (c != 4 && !d)) do_something();} @exmpl{Python,if (a == 2 and b < 5) or (c != 4 and not d): do_something()} @quotation Enigma @cartouche @example a 2 ! equal = cond-a; b 5 ! lesser = cond-b; c 4 ! equal ! not = cond-c; d ! not = cond-d; cond-a cond-b ! and = ncond-ab; cond-c cond-d ! and = ncond-cd; ncond-ab ncond-cd ! or = actcond; actcond do-something ! act; @end example @end cartouche @end quotation @node Compared looping, Compared functions, Compared conditionals, Comparison @section Looping @quotation C @cartouche @example while (thinking) run(); for (int i = 0; i < 18; i++) run(i); @end example @end cartouche @end quotation @quotation Python @cartouche @example while thinking: run() for i in range(18): run(i) @end example @end cartouche @end quotation @quotation Enigma @cartouche @verbatim {!run; thinking ! clone = return;} ! loop; 0 = i; {i ! run; i 1 ! add; i 18 ! equal = return;} ! loop; @end verbatim @end cartouche @end quotation @node Compared functions, , Compared looping, Comparison @section Functions @quotation C @cartouche @verbatim int time(float space) { return (int) space / 3; } t = time(81.65); @end verbatim @end cartouche @end quotation @quotation Python @cartouche @example def time(space): return int(space / 3) t = time(81.65) @end example @end cartouche @end quotation @quotation Enigma @cartouche @verbatim {/space/space 3 ! divide ! clone ! round = return;} = time; 81.65 ! time = t; @end verbatim @end cartouche @end quotation @node Built-In, Copying This Manual, Comparison, Top @chapter Built-in values and functions @menu * Built-In values:: * Built-In functions:: @end menu @node Built-In values, Built-In functions, Built-In, Built-In @section Values @cindex built-in values The following variables are special and can be accessed anytime. They can even be overwritten. @verbatim args, return, temp, stdin, stderr, stdout, zero, true, false, none, @pi, @e, cwd, cpd, fnm @end verbatim @code{zero} is a fake writable file that does nothing. @code{none} is an abstract variable with an internal value of.. none. @code{@@pi} is Pi. @code{@@e} is Euler's number. @code{cwd} is the directory from which Enigma is run, @code{cpd} is the directory in which the current program file resides, and @code{fnm} is the filename of the current program file. The rest are self-explanatory --- and @code{args}, @code{return} and @code{temp} are extra special. @node Built-In functions, , Built-In values, Built-In @section Functions @cindex built-in functions @macro func {param} @noindent @code{\param\} @end macro Enigma has few built-in functions. But they do exist. @func{str(OBJECT...)}: Converts all supplied values to strings. @func{num(OBJECT...)}: Converts all supplied values to numbers. @func{list(OBJECT...)}: Puts all supplied values in a list and destroys nested lists at one level. @func{bool(OBJECT...)}: Converts all supplied values to booleans. @func{code(OBJECT...)}: Converts all supplied values to code strings. @func{repr(OBJECT...)}: Converts all supplied values to representational strings. Strings get prepended and appended by " characters, code objects are surrounded by @{ and @}, and so on. @func{type(OBJECT...)}: Converts all supplied values to type strings (string, number, file, etc.). @func{len(OBJECT...)}: Converts all supplied values to their length. This can be used for both strings and lists. @func{clone(OBJECT...)}: Clones all supplied values. When an object is cloned, its value is assigned to a new variable. The list of clones is returned. @func{slice(LIST|STRING, NUMBER, NUMBER)}: Returns a list value sliced according to the first and second number if the first variable is a list variable, or a substring if the first variable is a string variable. @func{loop(FUNCTION, [OBJECT]...)}: Executes function until it returns false. Sends the rest of the specified variables (if any) to the function as arguments. @func{open(STRING, STRING)}: Opens the file by the name of the first string, using the second string as its guide as to how it should be opened. "r" means to read, "w" means to write, and "a" means to append. Returns a file object. @func{close(FILE...)}: Closes files. @func{read(FILE)}: Reads one character of a file and returns it. If no more characters are present, an empty string is returned. @func{write(FILE, STRING)}: Writes a string to a file. @func{greater(NUMBER, NUMBER...}: Checks if the first number is greater than the rest and returns true or false. @func{lesser(NUMBER, NUMBER...}: Checks if the first number is lesser than the rest and returns true or false. @func{equal(OBJECT, OBJECT...}: Checks if the objects are equal and returns true or false. @func{and(BOOLEAN...)}: Checks if all booleans are true and returns true or false. @func{or(BOOLEAN...)}: Checks if at least one boolean is true and returns true or false. @func{not(BOOLEAN...)}: Converts values of true to values of false, and vice-versa. @func{act(BOOLEAN, FUNCTION, [OBJECT]...)}: Run the function with the optional objects as arguments if the boolean is true. @func{system(STRING...)}: Join the strings and run the result as a system command. @func{add(NUMBER|STRING|CODE|LIST...)}: Add objects together. Numbers, strings, code strings and lists can be used, but only with similar types. The type of the first object determines what types the rest must be. The result is stored in the first object and also returned. @func{subtract(NUMBER...)}: Subtract numbers from each other. The first object receives the final number. It is also returned. @func{multiply(NUMBER...)}: Multiply numbers with each other. The first object receives the final number. It is also returned. @func{divide(NUMBER...)}: Divide numbers with each other. The first object receives the final number. It is also returned. @func{mod(NUMBER, NUMBER)}: Finds the remainder of the first number divided with the second number and returns it as a new variable. @func{pow(NUMBER, NUMBER)}: Returns first number^second number. @func{log(NUMBER, [NUMBER])}: Returns the logarithm of the first number. If the second number is not specified, the natural logarith is used. @func{random()}: Returns a random number between 0 and 1. @func{abs(NUMBER...)}: Sets and returns absolute values of numbers. @func{round(NUMBER, NUMBER)}: Rounds the first number with x decimals, where x is the second number. @func{floor(NUMBER, NUMBER)}: Floors the first number with x decimals, where x is the second number. @func{ceil(NUMBER, NUMBER)}: "Ceils" the first number with x decimals, where x is the second number. @func{sin(NUMBER...)}: Sets and returns sine values. @func{cos(NUMBER...)}: Sets and returns cosine values. @func{tan(NUMBER...)}: Sets and returns tangent values. @func{asin(NUMBER...)}: Sets and returns arcsine values. @func{acos(NUMBER...)}: Sets and returns arccosine values. @func{atan(NUMBER...)}: Sets and returns arctangent values. @func{sinh(NUMBER...)}: Sets and returns hyperbolic sine values. @func{cosh(NUMBER...)}: Sets and returns hyperbolic cosine values. @func{tanh(NUMBER...)}: Sets and returns hyperbolic tangent values. @node Copying This Manual, Index, Built-In, Top @appendix GNU Free Documentation License @include fdl.texi @node Index, , Copying This Manual, Top @unnumbered Index @printindex cp @bye