📄 tut.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Pico Lisp Tutorial</title><link rel="stylesheet" href="doc.css" type="text/css"></head><body><a href="mailto:abu@software-lab.de">abu@software-lab.de</a><h1>A Pico Lisp Tutorial</h1><p align=right>(c) Software Lab. Alexander Burger<p>This document demonstrates some aspects of the Pico Lisp system in detail andexample. For a general description of the Pico Lisp kernel please look at the <ahref="ref.html">Pico Lisp Reference</a>.<p>This is <i>not</i> a Lisp tutorial, as it assumes some working knowledge ofLisp (and programming in general). It concentrates on the specialties of PicoLisp, and its differences to other Lisp dialects.<p>If not stated otherwise, all examples assume that Pico Lisp was started fromthe shell prompt as<p><pre><code>$ ./p dbg.l:</code></pre><p>This loads the Pico Lisp base system and the debugging environment, and waitsfor you to enter input lines at the interpreter prompt (<code>:</code>). You canterminate the interpreter and return to the shell at any time, by either hittingthe ENTER key (i.e. by entering an empty line), or by executing the function<code><a href="refB.html#bye">(bye)</a></code>.<p>It is very helpful - though not absolutely necessary - when you know how touse the <code>vi</code> editor.<p>We notice that some people try to use Emacs - or some other IDE - as afrontend to the Pico Lisp console. This is not recommended, because the PicoLisp debugging environment will set the console (tty) to raw mode by itself anddo some special handling during character input.<p>If you feel that you absolutely have to use an input frontend, please removethe entry "@lib/led.l" from "dbg.l". Note that in this case, however, you willnot have the TAB symbol expansion feature available during command line editing.<p>We recommend that you have a terminal window open, and try the examples byyourself. You may either type them in, directly to the Pico Lisp interpreter, oredit a separate source file (e.g. <code>"test.l"</code>) in a second terminalwindow and load it into Pico Lisp with<p><pre><code>: (load "test.l")</code></pre><p>each time you have modified and saved it.<p>If you are new to Pico Lisp, you might want to read the following sections inthe given order, as some of them assume knowledge about previous ones. Otherwisejust jump anywhere you are interested in.<p><ul><li><a href="#ledit">Command Line Editing</a><li><a href="#brw">Browsing</a><li><a href="#fun">Defining Functions</a><li><a href="#dbg">Debugging</a><li><a href="#funio">Functional I/O</a><li><a href="#script">Scripting</a><li><a href="#oop">Objects and Classes</a><li><a href="#ext">Persistence (External Symbols)</a><li><a href="#db">Database Programming</a><li><a href="#gui">User Interface (GUI) Programming</a><li><a href="#pilog">Pilog -- Pico Lisp Prolog</a><li><a href="#sql">Poor Man's SQL</a><li><a href="#ref">References</a></ul><p><hr><h2><a name="ledit">Command Line Editing</a></h2><p>Pico Lisp permanently reads input from the current input channel (i.e. theconsole in interactive mode), evaluates it, and prints the result to the currentoutput channel.<p>To alleviate the task of manual line input, a command line editor is providedwhich is similar to (though much simpler than) the <code>readline</code> featureof the <code>bash</code> shell. Only a subset of the <code>vi</code> mode issupported, which is restricted to single-key commands (the "real"<code>vi</code> supports multi-key commands and the modification of mostcommands with count prefixes). It is loaded at startup via "dbg.l", you find itssource in "lib/led.l" if wish to take a look.<p>You can enter lines in the normal way, correcting mistypes with the BACKSPACEkey, and terminating them with the ENTER key. This is the <i>Insert Mode</i>.<p>If you hit ESC, you get into <i>Command Mode</i>. Now you can navigatehorizontally in the current input line, or vertically in the history ofpreviously entered lines, with key commands borrowed from the <code>vi</code>editor. Note, however, that there is always only a single line visible.<p>Let's say you did some calculation<p><pre><code>: (* (+ 2 3) (- 7 2))-> 25:</code></pre><p>If you want to repeat a modified version of this command, using<code>8</code> instead of <code>7</code>, you don't have to re-type thewhole command, but type<p><ul><li>ESC to get into <i>Command Mode</i><li><code>k</code> to get one line "up"<li><code>f</code> and <code>7</code> to "find" the character <code>7</code><li><code>r</code> and <code>8</code> to "replace" with <code>8</code></ul><p>Then you hit ENTER to execute the modified line. Instead of jumping to the<code>7</code> with the "find" command, you may also type <code>l</code> (move"right") repeatedly till you reach the correct position.<p>The key commands in the <i>Command Mode</i> are listed below. Some commandschange the mode back to <i>Insert Mode</i> as indicated in parentheses. Commandswhich operate on a "word" take either the current atom (number or symbol), or awhole expression when the cursor is at a left parenthesis.<p><ul><li><code>k</code> - Go up one line<li><code>j</code> - Go down one line<li><code>l</code> - Go right one character<li><code>h</code> - Go left one character<li><code>w</code> - Go right one word<li><code>b</code> - Go back (left) one word<li><code>0</code> - Go to the beginning of the line<li><code>$</code> - Go to the end of the line<li><code>i</code> - Enter <i>Insert Mode</i> at the cursor position<li><code>a</code> - Append (<i>Insert Mode</i>) after the cursor position<li><code>A</code> - Append (<i>Insert Mode</i>) at the end of the line<li><code>I</code> - Insert (<i>Insert Mode</i>) at the beginning of the line<li><code>x</code> - Delete the character at the cursor position<li><code>X</code> - Delete the character left of the cursor position<li><code>r</code> - Replace the character at the cursor position with the next key<li><code>s</code> - Substitute the character at the cursor position (<i>Insert Mode</i>)<li><code>S</code> - Substitute the whole line (<i>Insert Mode</i>)<li><code>d</code> - Delete the word at the cursor position (<i>Insert Mode</i>)<li><code>D</code> - Delete the rest of the line<li><code>c</code> - Change the word at the cursor position (<i>Insert Mode</i>)<li><code>C</code> - Change the rest of the line (<i>Insert Mode</i>)<li><code>f</code> - Find next key in the rest of the current line<li><code>p</code> - Paste data deleted with <code>x</code>, <code>X</code>, <code>d</code> or <code>D</code> after the cursor position<li><code>P</code> - Paste data deleted with <code>x</code>, <code>X</code>, <code>d</code> or <code>D</code> before the cursor position<li><code>/</code> - Accept an input pattern and search the history for it<li><code>n</code> - Search for next occurrence of pattern (as entered with <code>/</code>)<li><code>N</code> - Search for previous occurrence of pattern<li><code>%</code> - Show matching parenthesis<li><code>~</code> - Convert character to opposite (lower or upper) case and move right<li><code>u</code> - Undo the last change (one level only)<li><code>U</code> - Undo all changes of the current line<li><code>g</code> - Display current contents of cut buffer (not in <code>vi</code>)</ul><p>Notes:<ul><li>The <code>d</code> command corresponds to the <code>dw</code> command of the<code>vi</code> editor, and <code>c</code> corresponds to <code>cw</code>.<li>Search patterns may contain "<code>@</code>" characters as wildcards.<li>Lines shorter than 3 characters, lines beginning with a space character, orduplicate lines are not entered into the history.<li>The history is stored in a file named ".picoHistory" in the Pico Lisp homedirectory. The length of the history is limited to 4000 lines.</ul><p>The key combination <code>Ctrl-X</code> is useful when the program stopped ata breakpoint, or after program execution was interrupted with<code>Ctrl-C</code>, to abandon all further processing and return to theinterpreter's top level. This is equivalent to invoking <code><ahref="refQ.html#quit">quit</a></code>.<p>In <i>Input Mode</i>, only the following keys have a special meaning:<p><ul><li>BACKSPACE (<code>Ctrl-H</code>) and DEL erase the character to the left<li><code>Ctrl-V</code> inserts the next key literally<li>TAB performs symbol expansion: When a symbol name is entered partially andTAB is pressed subsequently, all internal symbols matching the partial input areshown in sequence.<li>ESC terminates <i>Input Mode</i> and enters <i>Command Mode</i></ul><p>Please take some time to experiment and to get used to command line editing.It will make life much easier in the future :-)<p><hr><h2><a name="brw">Browsing</a></h2><p>Pico Lisp provides some functionality for inspecting pieces of data and codewithin the running system.<p>Most commonly used is probably the <code>show</code> function. It takes asymbolic argument, and shows the symbol's name (if any), followed by its valuecell, and then the contents of the property list on the following lines.<p><pre><code>: (setq A '(This is the value)) # Set the value cell of 'A'-> (This is the value): (put 'A 'key1 'val1) # Store property 'key1'-> val1: (put 'A 'key2 'val2) # and 'key2'-> val2: (show 'A) # Now 'show' the symbol 'A'A (This is the value) key2 val2 key1 val1-> A</code></pre><p><code>show</code> accepts an arbitrary number of arguments which areprocessed according to the rules of <code><ahref="refG.html#get">get</a></code>, resulting in a symbol which is showed then.<p><pre><code>: (put 'B 'a 'A) # Put 'A' under the 'a'-property of 'B'-> A: (setq Lst '(A B C)) # Create a list with 'B' as second argument-> (A B C): (show Lst 2 'a) # Show the property 'a of the 2nd element of 'Lst'A (This is the value) # (which is 'A' again) key2 val2 key1 val1-> A</code></pre><p>Similar to <code>show</code> is <code>edit</code>. It takes an arbitrarynumber of symbolic arguments, writes them to a temporary file in a formatsimilar to <code>show</code>, and starts the <code>vim</code> editor with thatfile.<p><pre><code>: (edit 'A 'B)</code></pre><p>The <code>vim</code> window will look like<p><pre><code>A (This is the value)key1 val1key2 val2(********)B NILa A # (This is the value)(********)</code></pre><p>Now you can modify values or properties. You should not touch theparenthesized asterisks, as they serve as delimiters. If you position the cursoron the first char of a symbol name and type '<code>K</code>' ("Keyword lookup"),the editor will be restarted with that symbol added to the editor window.'<code>Q</code>' (for "quit") will bring you back to the previous view.<p><code>edit</code> is also very useful to browse in a database. You can followthe links between objects with '<code>K</code>', and even - e.g. for low-levelrepairs - modify the data (but only if you are really sure about what you aredoing, and don't forget to <code><a href="refC.html#commit">commit</a></code>when you are done).<p><code>more</code> is a simple tool that displays the elements of a list oneby one. It stops after each element and waits for input. If you just hit ENTER,<code>more</code> continues with the next element, otherwise (usually I type adot (<code>.</code>) followed by ENTER) it terminates.<p><pre><code>: (more (1 2 3 4 5 6))1 # Hit ENTER2. # Hit '.' and ENTER-> T # stopped</code></pre><p>Optionally <code>more</code> takes a function as a second argument andapplies that function to each element (instead of the default <code><ahref="refP.html#print">print</a></code>). Here, often <code>show</code> or<code>pp</code> (see below) is used.<p><pre><code>: (more '(A B)) # Step through 'A' and 'B'AB-> NIL: (more '(A B) show) # Step through 'A' and 'B' with 'show'A (This is the value) # showing 'A' key2 val2 key1 val1 # Hit ENTERB NIL # showing 'B' a A-> NIL</code></pre><p>The <i>pretty-print</i> function <code>pp</code> takes a symbol that has afunction defined (or two symbols that specify message and class for a methoddefinition), and displays that definition in a formatted and indented way.<p><pre><code>: (pp 'pretty)(de pretty (X N . @) (setq N (abs (space (or N 0)))) (while (args) (printsp (next))) (if (or (atom X) (>= 12 (size X))) (print X) (while (== 'quote (car X)) (prin "'") (pop 'X) ) (let Z X (prin "(") (when (memq (print (pop 'X)) "*PP") (cond ((memq (car Z) "*PP1") (if (and (pair (car X)) (pair (cdar X))) (when (>= 12 (size (car X))) (space) (print (pop 'X)) ) (space) (print (pop 'X)) (when (or (atom (car X)) (>= 12 (size (car X))) ) (space) (print (pop 'X)) ) ) ) ((memq (car Z) "*PP2") (inc 'N 3) (loop (prinl) (pretty (cadr X) N (car X)) (NIL (setq X (cddr X))) ) ) ((or (atom (car X)) (>= 12 (size (car X)))) (space) (print (pop 'X)) ) ) ) (when X (loop (T (== Z X) (prin " .")) (T (atom X) (prin " . ") (print X)) (prinl) (pretty (pop 'X) (+ 3 N)) (NIL X) ) (space) ) (prin ")") ) ) )-> pretty</code></pre><p>The style is the same as we use in all our source files:<ul><li>The indentation level is three spaces<li>If a list is too long, pretty-print the CAR on the current line, and eachelement of the CDR recursively on its own line.<li>A closing parenthesis a preceded by a space if the corresponding openparenthesis is not on the same line</ul><p>The <code>what</code> function returns a list of all internal symbols in thesystem. If an optional pattern argument (with '<code>@</code>' wildcardcharacters ) is given, only symbols matching that pattern are returned.<p><pre><code>: (what "prin@")-> (prin print prinl print> printsp println)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -