cvs
Slava Pestov 2004-09-02 01:04:16 +00:00
parent 7670bf2c94
commit 209cb7cc90
10 changed files with 166 additions and 44 deletions

View File

@ -2,15 +2,29 @@ THE CONCATENATIVE LANGUAGE FACTOR
* Introduction * Introduction
Factor supports various data types; atomic types include numbers of various kinds, strings of characters, and booleans. Compound data types include lists consisting of cons cells, vectors, and string buffers. Factor supports various data types; atomic types include numbers of
various kinds, strings of characters, and booleans. Compound data types
include lists consisting of cons cells, vectors, and string buffers.
Factor encourages programming in a functional style where new objects are returned and input parameters remain unmodified, but does not enforce this. No manifest type declarations are necessary, and all data types use exactly one slot each on the stack (unlike, say, FORTH). Factor encourages programming in a functional style where new objects
are returned and input parameters remain unmodified, but does not
enforce this. No manifest type declarations are necessary, and all data
types use exactly one slot each on the stack (unlike, say, FORTH).
The internal representation of a Factor program is a linked list. Linked lists that are to be executed are referred to as ``quotations.'' The interpreter iterates the list, executing words, and pushing all other types of objects on the data stack. A word is a unique data type because it can be executed. Words come in two varieties: primitive and compound. Primitive words have an implementation coded in the host langauge (C or Java). Compound words are executed by invoking the interpreter recursively on their definition, which is also a linked list. The internal representation of a Factor program is a linked list. Linked
lists that are to be executed are referred to as ``quotations.'' The
interpreter iterates the list, executing words, and pushing all other
types of objects on the data stack. A word is a unique data type because
it can be executed. Words come in two varieties: primitive and compound.
Primitive words have an implementation coded in the host language (C or
Java). Compound words are executed by invoking the interpreter
recursively on their definition, which is also a linked list.
* Control flow * Control flow
Control flow rests on two basic concepts: recursion, and branching. Words with compound definitions may refer to themselves, and there is exactly one primitive for performing conditional execution: Control flow rests on two basic concepts: recursion, and branching.
Words with compound definitions may refer to themselves, and there is
exactly one primitive for performing conditional execution:
1 10 < [ "10 is less than 1." print ] [ "whoa!" print ] ifte 1 10 < [ "10 is less than 1." print ] [ "whoa!" print ] ifte
==> 10 is less than 1. ==> 10 is less than 1.
@ -34,7 +48,8 @@ An example:
5 [ 1 2 3 4 ] contains? 5 [ 1 2 3 4 ] contains?
==> f ==> f
It recurses down the list, until it reaches the end, in which case the outer ifte's 'false' branch is executed. It recurses down the list, until it reaches the end, in which case the
outer ifte's 'false' branch is executed.
A quick overview of the words used here: A quick overview of the words used here:
@ -54,12 +69,16 @@ Equality:
= ( x y -- ? ) = ( x y -- ? )
More complicated control flow constructs, such as loops and higher order functions, are usually built with the help of another primitive that simply executes a quotation at the top of the stack, removing it from the stack: More complicated control flow constructs, such as loops and higher order
functions, are usually built with the help of another primitive that
simply executes a quotation at the top of the stack, removing it from
the stack:
[ 2 2 + . ] call [ 2 2 + . ] call
==> 4 ==> 4
Here is an example of a word that applies a quotation to each element of a list. Note that it uses 'call' to execute the given quotation: Here is an example of a word that applies a quotation to each element of
a list. Note that it uses 'call' to execute the given quotation:
: each ( list quotation -- ) : each ( list quotation -- )
#! Push each element of a proper list in turn, and apply a #! Push each element of a proper list in turn, and apply a
@ -94,7 +113,8 @@ tuck ( x y -- y x y )
>r ( x -- r:x ) - move top of data stack to/from 'extra hand'. >r ( x -- r:x ) - move top of data stack to/from 'extra hand'.
r> ( r:x -- x ) r> ( r:x -- x )
Writing >r foo r> is analogous to [ foo ] in Joy. Occurrences of >r and r> must be balanced within a single word definition. Writing >r foo r> is analogous to [ foo ] in Joy. Occurrences of >r and
r> must be balanced within a single word definition.
Linked list deconstruction: Linked list deconstruction:

View File

@ -1,7 +1,24 @@
- telnetd should use multitasking
- file-responder: Content-Length
- HEAD request for file-responder
- nicer way to combine two paths
- icons for file responder
- -1.1 3 ^ shouldn't give a complex number
- don't show listener on certain commands
- inferior hangs
- plugin should not exit jEdit on fatal errors
- IN: format base: work with all types of numbers
- home key in the listener
- wordpreview: don't show for string literals and comments
- eliminate usage of long long
- 64 bit support
- alist -vs- assoc terminology - alist -vs- assoc terminology
- some way to run httpd from command line
- 'default responder' for when we go to root
- minimize stage2 initialization code, just move it to source files - minimize stage2 initialization code, just move it to source files
- clean up listener's action popups
- jedit ==> jedit-word, jedit takes a file name
- introduce ifte* and ?str-head/?str-tail where appropriate
- cwd, cd, pwd, dir., pwd. words
- namespace clone drops static var bindings
+ bignums: + bignums:
@ -10,13 +27,11 @@
- add a socket timeout - add a socket timeout
- >lower, >upper for strings - >lower, >upper for strings
- telnetd should use multitasking
- accept multi-line input in listener - accept multi-line input in listener
+ docs: + docs:
- logic - logic
- numbers game leaves extra on the stack
- examples of assoc usage - examples of assoc usage
- unparse examples, and difference from prettyprint - unparse examples, and difference from prettyprint
- review doc formatting with latex2html - review doc formatting with latex2html
@ -38,14 +53,13 @@
- java factor: equal numbers have non-equal hashcodes! - java factor: equal numbers have non-equal hashcodes!
- FactorLib.equal() not very good - FactorLib.equal() not very good
- IN: format base: work with all types of numbers
- investigate mandel.factor - investigate mandel.factor
+ listener/plugin: + listener/plugin:
- inferior hangs - some way to not have previous definitions from a source file
- plugin should not exit jEdit on fatal errors clutter the namespace
- balance needs USE: - use inferior.factor for everything not just listener
- fedit broken with listener - fedit broken with listener
- maple-like: press enter at old commands to evaluate there - maple-like: press enter at old commands to evaluate there
- input style after clicking link - input style after clicking link
@ -56,9 +70,6 @@
+ native: + native:
- eliminate usage of long long
- is the profiler using correct stack depth?
- read1
- sbuf-hashcode - sbuf-hashcode
- vector-hashcode - vector-hashcode
- irc: stack underflow? - irc: stack underflow?
@ -80,27 +91,20 @@
+ misc: + misc:
- directory listings: - some way to run httpd from command line
- nicer way to combine two paths
- icons for file responder
- cwd, cd, pwd, dir., pwd. words
- -1.1 3 ^ shouldn't give a complex number
- don't rehash strings on every startup - don't rehash strings on every startup
- 'cascading' styles - 'cascading' styles
- jedit ==> jedit-word, jedit takes a file name
- introduce ifte* and ?str-head/?str-tail where appropriate
- namespace clone drops static var bindings
- ditch expand - ditch expand
- set-object-path - set-object-path
+ httpd: + httpd:
- 'default responder' for when we go to root
- quit responder breaks with multithreading - quit responder breaks with multithreading
- wiki responder: - wiki responder:
- port to native - port to native
- text styles - text styles
- if user clicks stop in browser, doesn't stop sending? - if user clicks stop in browser, doesn't stop sending?
- log with date - log with date
- return more header fields, like Content-Length, Last-Modified, and so on basic authentication, using httpdAuth function from a config file
- HEAD request - file responder; last-modified field
- basic authentication, using httpdAuth function from a config file

View File

@ -810,21 +810,19 @@ Note that the word gives incorrect output if the two parameters are
equal. However, it will never be called this way. equal. However, it will never be called this way.
With this out of the way, the implementation of judge-guess is an With this out of the way, the implementation of judge-guess is an
easy task to tackle. Using the words \texttt{inexact-guess}, \texttt{=}, easy task to tackle. Using the words \texttt{inexact-guess}, \texttt{2dup}, \textttt{2drop} and \texttt{=}, we can write:
and \texttt{2dup}, we can write:
\begin{alltt} \begin{alltt}
: judge-guess ( actual guess -{}- ? ) : judge-guess ( actual guess -{}- ? )
2dup = {[} 2dup = {[}
correct f 2drop correct f
{]} {[} {]} {[}
inexact-guess t inexact-guess t
{]} ifte ; {]} ifte ;
\end{alltt} \end{alltt}
The word = is found in the \texttt{kernel} vocabulary, and the word 2dup is found in the \texttt{stack} vocabulary. Since \texttt{=} The word \texttt{=} is found in the \texttt{kernel} vocabulary, and the words \texttt{2dup} and \texttt{2drop} are found in the \texttt{stack} vocabulary. Since \texttt{=}
consumes both its parameters, we must first duplicate them with \texttt{2dup} so that later they can be passed consumes both its parameters, we must first duplicate them with \texttt{2dup}. The word \texttt{correct} does not need to do anything with these two numbers, so they are popped off the stack using \texttt{2drop}. Try evaluating the following
to \texttt{correct} and \texttt{inexact-guess}. Try evaluating the following
in the interpreter to see what's going on: in the interpreter to see what's going on:
\begin{alltt} \begin{alltt}
@ -833,6 +831,7 @@ clear 1 2 2dup = .s
clear 4 4 2dup = .s clear 4 4 2dup = .s
\emph{\{ 4 4 t \}} \emph{\{ 4 4 t \}}
\end{alltt} \end{alltt}
Test \texttt{judge-guess} with a few inputs: Test \texttt{judge-guess} with a few inputs:
\begin{alltt} \begin{alltt}
@ -928,7 +927,7 @@ USE: stack
: judge-guess ( actual guess -- ? ) : judge-guess ( actual guess -- ? )
2dup = [ 2dup = [
correct f 2drop correct f
] [ ] [
inexact-guess t inexact-guess t
] ifte ; ] ifte ;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -151,7 +151,7 @@ Note that while the Factor plugin requires jEdit 4.2pre15, you will need to down
<img class="nice-box" src="error.png"> <img class="nice-box" src="error.png">
<p>A common error is a missing <code>USE:</code> declaration. The <b>Plugins</b>&gt;<b>Factor</b>&gt;<b>Use word at caret</b> command searches for the word at the caret in all vocabularies, and adds a <code>USE:</code> declaration for the vocabulary to the start of the source file -- in this case, <code>ifte</code> is found in the <code>combinators</code> vocabulary, and the parse error instantly goes away:</p> <p>A common error is a missing <code>USE:</code> declaration. The <b>Use word at caret</b> command searches for the word at the caret in all vocabularies, and adds a <code>USE:</code> declaration for the vocabulary to the start of the source file -- in this case, <code>ifte</code> is found in the <code>combinators</code> vocabulary, and the parse error instantly goes away:</p>
<img class="nice-box" src="word-use.png"> <img class="nice-box" src="word-use.png">

View File

@ -29,16 +29,18 @@
package factor.jedit; package factor.jedit;
import factor.Cons; import factor.*;
import sidekick.*; import sidekick.*;
public class FactorParsedData extends SideKickParsedData public class FactorParsedData extends SideKickParsedData
{ {
public FactorInterpreter interp;
public String in; public String in;
public Cons use; public Cons use;
FactorParsedData(String fileName) FactorParsedData(FactorInterpreter interp, String fileName)
{ {
super(fileName); super(fileName);
this.interp = interp;
} }
} }

View File

@ -5,7 +5,7 @@ plugin.factor.jedit.FactorPlugin.activate=defer
plugin.factor.jedit.FactorPlugin.name=Factor plugin.factor.jedit.FactorPlugin.name=Factor
plugin.factor.jedit.FactorPlugin.version=0.65 plugin.factor.jedit.FactorPlugin.version=0.65
plugin.factor.jedit.FactorPlugin.author=Slava Pestov plugin.factor.jedit.FactorPlugin.author=Slava Pestov
plugin.factor.jedit.FactorPlugin.docs=/doc/plugin.html plugin.factor.jedit.FactorPlugin.docs=/doc/jedit/index.html
plugin.factor.jedit.FactorPlugin.depend.0=jedit 04.02.15.00 plugin.factor.jedit.FactorPlugin.depend.0=jedit 04.02.15.00
plugin.factor.jedit.FactorPlugin.depend.1=plugin errorlist.ErrorListPlugin 1.3.2 plugin.factor.jedit.FactorPlugin.depend.1=plugin errorlist.ErrorListPlugin 1.3.2

View File

@ -40,10 +40,39 @@ import sidekick.*;
public class FactorSideKickParser extends SideKickParser public class FactorSideKickParser extends SideKickParser
{ {
private WordPreview wordPreview;
//{{{ FactorSideKickParser constructor //{{{ FactorSideKickParser constructor
public FactorSideKickParser() public FactorSideKickParser()
{ {
super("factor"); super("factor");
wordPreview = new WordPreview();
} //}}}
//{{{ activate() method
/**
* This method is called when a buffer using this parser is selected
* in the specified view.
* @param editPane The edit pane
* @since SideKick 0.3.1
*/
public void activate(EditPane editPane)
{
super.activate(editPane);
editPane.getTextArea().addCaretListener(wordPreview);
} //}}}
//{{{ deactivate() method
/**
* This method is called when a buffer using this parser is no longer
* selected in the specified view.
* @param editPane The edit pane
* @since SideKick 0.3.1
*/
public void deactivate(EditPane editPane)
{
super.deactivate(editPane);
editPane.getTextArea().removeCaretListener(wordPreview);
} //}}} } //}}}
//{{{ parse() method //{{{ parse() method
@ -58,9 +87,9 @@ public class FactorSideKickParser extends SideKickParser
public SideKickParsedData parse(Buffer buffer, public SideKickParsedData parse(Buffer buffer,
DefaultErrorSource errorSource) DefaultErrorSource errorSource)
{ {
FactorParsedData d = new FactorParsedData(buffer.getPath());
FactorInterpreter interp = FactorPlugin.getInterpreter(); FactorInterpreter interp = FactorPlugin.getInterpreter();
FactorParsedData d = new FactorParsedData(
interp,buffer.getPath());
String text; String text;

View File

@ -0,0 +1,68 @@
/* :folding=explicit:collapseFolds=1: */
/*
* $Id$
*
* Copyright (C) 2004 Slava Pestov.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package factor.jedit;
import factor.*;
import java.util.*;
import javax.swing.event.*;
import org.gjt.sp.jedit.textarea.*;
import org.gjt.sp.jedit.*;
import org.gjt.sp.util.Log;
import sidekick.*;
public class WordPreview implements CaretListener
{
public void caretUpdate(CaretEvent e)
{
showPreview((JEditTextArea)e.getSource());
}
private void showPreview(JEditTextArea textArea)
{
View view = textArea.getView();
String word = FactorPlugin.getWordAtCaret(textArea);
if(word == null)
return;
SideKickParsedData data = SideKickParsedData
.getParsedData(view);
if(data instanceof FactorParsedData)
{
FactorParsedData fdata = (FactorParsedData)data;
FactorWord w = fdata.interp
.searchVocabulary(fdata.use,word);
if(w != null)
{
view.getStatus().setMessageAndClear(
FactorWordRenderer.getWordHTMLString(
fdata.interp,w,true));
}
}
}
}

View File

@ -79,7 +79,7 @@ void check_memory(void)
void flip_zones() void flip_zones()
{ {
ZONE z = prior; ZONE z = active;
active = prior; active = prior;
prior = z; prior = z;
} }