metanohi/site/projects/enigma/doc/enigma-0.1.texinfo

698 lines
22 KiB
Plaintext

\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