diff --git a/doc/index.bmml b/doc/index.bmml index 0135bc189c04cb084740617f63deb6bd2560b3fa..53fdda3470f514173dd20e06b6f1980c11ca646a 100644 --- a/doc/index.bmml +++ b/doc/index.bmml @@ -23,9 +23,11 @@ $version manual Types - uLPC types are part of what makes uLPC a powerful language. They make - it easy to handle data without worrying about memory management and - other programming obstacles. + Data is stored in different ways, integers (eg. 1, 2, 3, 4 etc.) are + are stored in one way, real numbers (1.0, 1.1, etc.) in another. Each + different way get its own name. uLPC types are part of what makes uLPC + a powerful language. They make it easy to handle data without worrying + about memory management and other programming obstacles. KEYWORD_LIST types @@ -41,7 +43,7 @@ $version manual uLPC has a wide range of builtin functions. Most of these are implemented in C, but some are implemented in uLPC using the add_efun function. - LINK lpc_efuns Here's a list of all built-in functions. + LINK lpc/efuns Here's a list of all built-in functions. Operators @@ -62,4 +64,4 @@ $version manual KEYWORD_INDEX other - LINK lpc_all Here's a list of all pages. + LINK lpc/all Here's a list of all pages. diff --git a/doc/lpc/cast b/doc/lpc/cast new file mode 100644 index 0000000000000000000000000000000000000000..0ce25fc9fb7d7fe5d41584fabc0e5b9083b61db7 --- /dev/null +++ b/doc/lpc/cast @@ -0,0 +1,30 @@ +NAME + cast - convert one type to another + +SYNTAX + ( <type> ) <expression> + +DESCRIPTION + Casts convert types, in most cases it just tells the compiler what + type the expression has, but it can also be used to actually convert + the value of the expression into something else. + + Casting from float or int to string will convert the given number + into a decimal ascii string representation. + + Casting from string to float or int will do the opposite. IE. + Read a decimal number from the string and return that. + + Casting from string to program will call cast_to_program in the + master object and request a program to return. The standard master + object will consider the string a file name and compile the program + given by that string. It will then put the program in a chache in + case you cast the same string to a program again later. + + In all other cases, casts are just compiler hints. + +KEYWORDS + lpc + +SEE ALSO + compile_file, sscanf diff --git a/doc/lpc/functions b/doc/lpc/functions index 9b1c71d06d0efc7f7e631a4821dc2949f8fa1c43..0449087399ce9b2739eb7fd18e0c675fc1bb573e 100644 --- a/doc/lpc/functions +++ b/doc/lpc/functions @@ -8,6 +8,10 @@ SYNTAX } DESCRIPTION + A function is basically a piece of code which takes some data + does some things, and hands some data back. Data sent to a + a function is called an 'argument'. + This defines a function called 'function_name' returning the type 'type'. The argument_specification is a comma separated list of arguments. Each argument is specified with a type, whitespace and @@ -68,4 +72,4 @@ KEYWORDS lpc SEE ALSO - lambda, return, modifier \ No newline at end of file + lambda, return, modifier diff --git a/doc/lpc/modifier b/doc/lpc/modifier new file mode 100644 index 0000000000000000000000000000000000000000..1943996b8090fac5e953fcd36e181d40e1f8f7ee --- /dev/null +++ b/doc/lpc/modifier @@ -0,0 +1,17 @@ +NAME + modifier - modify function / variable definitions + +DESCRIPTION + Modifiers makes it possible to give functions and gobal variables + certain characteristics. A list of modifiers follows: + + static make this identifier unavailable by indexing + inline allow inlining this function + private hide this identifier to inheriting programs + nomask don't allow this identifier to be re-defined + +KEYWORDS + lpc + +SEE ALSO + functions, variables \ No newline at end of file diff --git a/doc/lpc/reserved b/doc/lpc/reserved deleted file mode 100644 index e20b6b5b17d93fd9dfccfc072794c76313714125..0000000000000000000000000000000000000000 --- a/doc/lpc/reserved +++ /dev/null @@ -1,5 +0,0 @@ -RESERVED WORDS - array break case catch continue default do efun else float for foreach - function gauge if inherit inline int lambda list mapping mixed nomask - object private program protected public return sscanf static string - switch typeof varargs void while diff --git a/doc/lpc/reserved.bmml b/doc/lpc/reserved.bmml new file mode 100644 index 0000000000000000000000000000000000000000..1facad0a80147007076f0caee3b5a87930f54fa9 --- /dev/null +++ b/doc/lpc/reserved.bmml @@ -0,0 +1,6 @@ +Reserved Words + + array break case catch continue default do efun else float for foreach + function gauge if inherit inline int lambda list mapping mixed nomask + object private program protected public return sscanf static string + switch typeof varargs void while diff --git a/doc/manual/example1 b/doc/manual/example1 index df87470cfb8a8d07cc66de302cfd005d5c179cca..5600124036e280301d1e05e923385adfa6c45048 100644 --- a/doc/manual/example1 +++ b/doc/manual/example1 @@ -33,8 +33,9 @@ write("hello world\n"); - The first statement is a call to the builtin function write. To this - function the constant string "hello world\n" is sent. write then of + The first statement is a call to the builtin function write. This will + execute the code in the function write with the arguments as input data. + In this case, the constant string "hello world\n" is sent. write() then of course writes this string to stdout when executed. return 0; @@ -59,8 +60,7 @@ $ chmod +x hello_world.lpc - Now we can run hello_world.lpc without having to bother about running - ulpc: + Now we can run hello_world.lpc without having to bother with running ulpc: $ ./hello_wold.lpc hello world @@ -73,9 +73,10 @@ 1.3 A better hello_world.lpc Now, wouldn't it be nice if it said "Hello world!" instead of "hello world" ? - But of course we don't want to make our program incompatible, so we'll add - a command line option that will make it type the old "hello world". - This is what it could look like: + But of course we don't want to make our program incompatible with the old + version. Someone might NEED the program to work the same as before. + Therefore we'll add a command line option that will make it type the old + "hello world". This is what it could look like: #!/usr/local/bin/ulpc @@ -135,3 +136,6 @@ write("hello world\n"); // old stype The // begins a comment which continues to the end of the line. + Comments lets you type in text in the program which will be ignored by the + computer. This is to inform whoever might read your code (like yourself) of + what the program does to make it easier to understand. diff --git a/doc/manual/example2 b/doc/manual/example2 index 394bc08f6fa3962f1c339d351107457c0d01344d..11fffb14b1ac4e21bcdf3f41960bb78552cbf118 100644 --- a/doc/manual/example2 +++ b/doc/manual/example2 @@ -1,11 +1,11 @@ - Now we will look at a slightly more useful example: +2. Now we will look at a slightly more useful example: #!/usr/local/bin/ulpc int main(int argc,string *argv) { int i; - string file; + string file_contents; if(argc<4) { @@ -15,16 +15,16 @@ for(i=3; i<argc; i++) { - if(file=read_bytes(argv[i])) + if(file_contents=read_bytes(argv[i])) { - if(-1!=strstr(file,argv[1])) + if(-1!=strstr(file_contents,argv[1])) { write("Processing "+argv[i]+".\n"); - file=replace(file,argv[1],argv[2]); + file_contents=replace(file_contents,argv[1],argv[2]); if( mv(argv[i],argv[i]+"~") ) { - write_file(argv[i],file); + write_file(argv[i],file_contents); }else{ write("Failed to create backup file.\n"); } @@ -43,7 +43,13 @@ #!/usr/local/bin/ulpc - Make UNIX run ulpc to interpret this program. + Make UNIX run ulpc to interpret this program. Interpret in this case + means to read the program, convert it to an internal representation and + then run the instructions in this internal representation. Note that uLPC + does not use the same low-level representation as for example C does, + instead it uses a simple and compact representation which are parsed by + a C program which actually implements the instructions in that + representation. int main(int argc,string *argv) { @@ -52,10 +58,10 @@ arguments into the parameters argc and argv. int i; - string file; + string file_contents; Declare two temporary variables to use later. The first one 'i' is an - integer, and the second one 'file' is a string. + integer, and the second one 'file_contents' is a string. if(argc<4) { @@ -65,20 +71,21 @@ If argc is lesser than four it means that the program received less than three arguments. Since rsif needs at least three arguments we write how - to use rsif to stderr using the function perror and then exit this function - with the return value 1. Nothing after the return will be executed if - argc is lesser than 4. + to use rsif to stderr (Standard error channel) using the function perror + and then exit this function with the return value 1. Nothing after the + return will be executed if argc is lesser than 4. for(i=3; i<argc; i++) { - This statement starts a loop. It will first set i to three, then execute - everything within the brackets for as long as i is lesser than argc. After - each time the block between the brackets the final statement, i++, will - be executed. ++ is the increment operator, it will increase i by one. + This statement starts a loop. (Loop means code repetition) It will first + set i to three, then execute everything within the brackets for as long as + i is lesser than argc. After each time the block between the brackets the + final statement, i++, will be executed. ++ is the increment operator, it + will increase i by one. - if(file=read_bytes(argv[i])) + if(file_contents=read_bytes(argv[i])) { Look closely, the experssion in this if-statement is not a comparison, it @@ -90,7 +97,7 @@ variable file. If there is no file with that name, zero will be returned and then the block within the brackets will not be executed. - if(-1!=strstr(file,argv[1])) + if(-1!=strstr(file_contents,argv[1])) { The function strstr searches for a string in in a string and returns the @@ -101,22 +108,25 @@ write("Processing "+argv[i]+".\n"); - Write that we are processing this file to stdout. + Write that we are processing this file to stdout. Stdout means + "Standard output channel" and is normally your screen unless you 'redirect' + it to somewhere else. - file=replace(file,argv[1],argv[2]); + file_contents=replace(file_contents,argv[1],argv[2]); Call the builtin function replace and replace oall occurances of the 'from' - string with the 'to' string and assign the new result to the variable 'file'. + string with the 'to' string and assign the new result to the variable + 'file_contents'. if( mv(argv[i],argv[i]+"~") ) { Try moving the file argv[i] to a backup file by adding a tilde to the end of the name. Then choose action depending on weather it worked or not. - write_file(argv[i],file); + write_file(argv[i],file_contents); - If it worked we re-create the file argv[i] by writing the string 'file' to - it. + If it worked we re-create the file argv[i] by writing the string + 'file_contents' to it. }else{ write("Failed to create backup file.\n"); diff --git a/doc/manual/example3 b/doc/manual/example3 index 2323435af7d952e9ba04ae4c13cf3d7b0901c02e..0d9552a40adb0e82e8d1d66b1a3f1b61cab58be7 100644 --- a/doc/manual/example3 +++ b/doc/manual/example3 @@ -1,5 +1,15 @@ - This example is a very simple www-server. +3. This example is a very simple www-server. + For you who are not familiar with WWW (World Wide Web), it works by using + client program which will fetch files from remote servers when asked. + Usually by clicking a pitcure or text. This example is a program for the + server which will send files to any computer that requests them. The + protocol used to send the file is called HTTP. (HyperText Transfer Protocol) + + Usually WWW involves HTML. HTML (HyperText Markup Language) is a way to + write documents with embedded pictures and links to other pages. These + links are normally displayed underlined and if you click them your WWW- + browser will load whatever document that link leads to. #!/usr/local/bin/ulpc @@ -12,14 +22,18 @@ inherit "/precompiled/port"; Inherit copies all the functionality of /precompiled/port into this program. - /precompiled/port makes it possible to bind a TCP socket to accept incoming - connections. + /precompiled/port makes it possible to bind a TCP (Transmission Control + Protocol, the internet stanard for computer communication) socket to accept + incoming connections. A socket is simply a number to separate communications + to and from different programs on the same computer. Next are some constants that will affect how uHTTPD will operate. This uses - the preprocessor directive #define. As an example, after the first define - below, BLOCK will be replaced with 16060. + the preprocessor directive #define. The preprocessor is the first stage in + the compiling process and can make textual processing of the code before + it is compiled. As an example, after the first define below, all occurances + of 'BLOCK' will be replaced with 16060. - /* number of bytes to read for each write */ + /* Amount of data moved in one operation */ #define BLOCK 16060 /* Where do we have the html files ? */ @@ -31,6 +45,11 @@ /* Port to open */ #define PORT 1905 + A port is a destination for a TCP connection. It is simply a number on the + local computer. 1905 is not the standard port for HTTP connections though, + which means that if you want to access this WWW server from a browser you + need to specify the port like this: http://my.host.my.domain:1905/ + Next we declare a global variable of the type program called output_class, and then we use the class construct to assign a program to it. class {} defines a clonable program. (or class for you C++ freaks) @@ -48,23 +67,32 @@ Then ther is a global variable called offset which is initalized to zero. (each instance of this class will have it's own instance of this variable, so it is not truly global, but..) - Note that the initalization is done when the clas is cloned. (or instanciated - if you prefer C++ terminology) - - - Next we define the function write_callback(). 'void' means that it does not - return a value. Write callback will be used further down as a callback and - will be called whenever there is room in the socket output buffer. + Note that the initalization is done when the class is cloned. (or + instanciated if you prefer C++ terminology) + + + Next we define the function write_callback(). Later the program will go + into a 'waiting' state, until something is received to process, or until + there is buffer space available to write output to. When that happens a + callback will be called to do this. The write_callback() is called when + there is buffer space available. In the following lines 'void' means that + it does not return a value. Write callback will be used further down as a + callback and will be called whenever there is room in the socket output + buffer. void write_callback() { int written; string data; + + The following line means: call seek in the inherited program 'file'. file::seek(offset); Move the file pointer to the where we want to the position we want to read - from. + from. The file pointer is simply a location in the file, usually it is where + the last read() ended and the next will begin. seek() can move this pointer + to where we want it though. data=file::read(BLOCK); @@ -106,8 +134,9 @@ string input=""; And then we define the function that will be called when there is something - in the socket input buffer. Ignore the argument 'id' for now. The second - argument is the contents of the input buffer. + in the socket input buffer. The first argument 'id' is declared as mixed, + which means that it can contain any type of value. The second argument is + the contents of the input buffer. void read_callback(mixed id,string data) { @@ -142,13 +171,18 @@ input=combine_path(BASE,input); Combine the requested file with the base of the HTML tree, this gives - us a full filename beginning with a slash. + us a full filename beginning with a slash. The HTML tree is the + directory on the server in which the HTML files are located. Normally + all files in this directory can be accessed by anybody by using a WWW + browser. So if a user requests 'index.html' then that file name is first + added to BASE (/home/hubbe/www/html/ in this case) and if that file exists + it will be returned to the browser. if(!file::open(input,"r")) { Try opening the file in read-only mode. If this fails, try opening NOFILE - instead. + instead. Opening the file will enable us to read it later. if(!file::open(NOFILE,"r")) { @@ -199,7 +233,7 @@ socket::set_nonblocking(read_callback,0,selfdestruct); - Then we set up the callback functions. (And sets the file nonblocking.) + Then we set up the callback functions and sets the file nonblocking. Nonblocking mode means that read() and write() will rather return that wait for I/O to finish. Then we sit back and wait for read_callback to be called. @@ -218,9 +252,15 @@ void accept_callback() { object tmp_output; + + This creates a local variable of type 'object'. An object variable can + contain a clone of any program. uLPC does not consider clones of different + programs different types. This also means that function calls to objects + have to be resolved at run time. + tmp_output=accept(); - The function accept clones a /precompiled/file and makes this equal to the + The function accept clones a /precompiled/file and makes this equal to the newly connected socket. if(!tmp_output) return; @@ -230,7 +270,10 @@ clone(output_class, tmp_output); Otherwise we clone an instanec of 'output_class' and let it take care of the - connection. + connection. Each clone of output_class will have it's own set of global + variables, which will enable many connections to be active at the same + time without data being mixed up. Note that the programs will not actually + run simulataneously though. destruct(tmp_output); diff --git a/doc/simulated/write_file b/doc/simulated/write_file index 174e7084ab1fad5f200c058f8c0532cea13146ae..46d1b770bcf59eca583c006890af2fc04a87fd95 100644 --- a/doc/simulated/write_file +++ b/doc/simulated/write_file @@ -11,4 +11,4 @@ KEYWORDS file SEE ALSO - read_file + read_bytes diff --git a/doc/types/mixed b/doc/types/mixed new file mode 100644 index 0000000000000000000000000000000000000000..6f620ced154f892cd10dd7bb8254a5cd0e5a3de0 --- /dev/null +++ b/doc/types/mixed @@ -0,0 +1,15 @@ +NAME + mixed - any type + +DESCRIPTION + This is not really a type. But this keyword can be used to specify + that a variable, argument or return type can be of any type. + +EXAMPLES + mixed i=1; + mixed j="foo"; + mixed foo() { return "bar"; } + mixed bar() { return ({}); } + +KEYWORDS + types diff --git a/doc/types/program b/doc/types/program index c653029056c9559b4c7553ed3e0a2fc73458e364..cf34036ebd93d2137b72dbc9490a12c1bd508387 100644 --- a/doc/types/program +++ b/doc/types/program @@ -8,6 +8,11 @@ DESCRIPTION arguments to clone() and the only operators that applies to programs are == and !=. +NOTA BENE + In uLPC the term 'program' is somewhat confusing, becuase it is used + both to reference a complete runnable software package, and to a + structure in uLPC containing code. + KEYWORDS types diff --git a/doc/types/string b/doc/types/string index 0586b1e690396643692312b96b6cc0384efb040b..e15c5437557f9c895d4ae2de75deaad7bcc2d9d2 100644 --- a/doc/types/string +++ b/doc/types/string @@ -5,8 +5,10 @@ SYNTAX EXAMPLE "foo" DESCRIPTION - This type can contain a string, or list of characters, strings can - contain any character, even null characters. Strings are a basic + This type can contan text. ie. a word, a sentence, or a book. Note + that this is not simply the letters A to Z, special characters, + null characters, newlines can all be stored in a string. Any 8-bit + character in fact. Strings are a basic type in LPC, as opposed to C where strings are represented by an array of char. This means that you cannot set individual characters in a string with the index operator for instance. In fact, there are @@ -14,6 +16,17 @@ DESCRIPTION are 'shared', that means that if the same string is used in several places, only one will be stored in memory. + When writing a string in a program, you enclose it in doublequotes. + To write special characters you need to use one of the following + syntaxes: + + \n newline + \r charriage return + \t tab + \b backspace + \" " + \\ \ + A list of operators that applies to strings follow: In this list a and b is used to represent a string expression: