build.xml - Ant buildfile for Java interpreter.
factor/ - source code for Factor interpreter written in Java.
org/objectweb/asm/ - helper library for Java interpreter.
-Factor.jar - compiled, stand-alone Java interpreter
library/platform/jvm - JVM-specific Factor code
+Factor.jar - compiled, stand-alone Java interpreter
C interpreter
-------------
ratio. It runs faster than the Java interpreter, and uses
far less memory.
+Makefile - Makefile for building C interpreter.
native/ - source code for Factor interpreter written in C.
-native/build.sh - build script for C interpreter.
-native/f - compiled C interpreter - needs image to run
-native/factor.image - cross-compiler output
library/platform/native - C interpreter-specific code
+f - compiled C interpreter - needs image to run
+boot.image.le - image for x86
+boot.image.be - image for 32-bit SPARC and 32-bit PowerPC
Notes on the C interpreter
--------------------------
-At the moment it assumes little endian byte order, 32-bit
-words. This pretty much means x86.
+When you run the interpreter with a boot image, it loads a
+bunch of files and saves a 'factor.image'. Run the
+interpreter again with this image.
+
+At the moment it assumes a 32-bit architecture. Your C
+compiler's types must be as follows:
-Very soon I will add image input and output in both byte
-orders - this will allow Factor to run on powerpc and
-sparc.
+short - signed 16 bits
+long - signed 32 bits
+long long - signed 64 bits
+double -IEEE double precision 64-bit float
Moving to 64-bits would require a few changes in the image
cross-compiler, namely in the way it packs strings.
\r
+ native:\r
\r
+- eliminate usage of long long\r
- is the profiler using correct stack depth?\r
- read1\r
- sbuf-hashcode\r
+ misc:\r
\r
- alist -vs- assoc terminology\r
-- dissolve builtins vocabulary\r
- 'cascading' styles\r
- jedit ==> jedit-word, jedit takes a file name\r
- some way to run httpd from command line\r
<include name="factor/**/*.txt"/>
<include name="*.xml"/>
<include name="library/**/*.factor"/>
+ <include name="library/**/*.txt"/>
<include name="org/**/*.class"/>
<include name="*.factor"/>
<include name="doc/**/*.html"/>
--- /dev/null
+! Numbers game example
+
+IN: numbers-game
+USE: kernel
+USE: math
+USE: parser
+USE: random
+USE: stdio
+USE: stack
+
+: read-number ( -- n ) read parse-number ;
+
+: guess-banner
+ "I'm thinking of a number between 0 and 100." print ;
+: guess-prompt "Enter your guess: " write ;
+: too-high "Too high" print ;
+: too-low "Too low" print ;
+: correct "Correct - you win!" print ;
+
+: inexact-guess ( actual guess -- )
+ < [ too-high ] [ too-low ] ifte ;
+
+: judge-guess ( actual guess -- ? )
+ 2dup = [
+ correct f
+ ] [
+ inexact-guess t
+ ] ifte ;
+
+: number-to-guess ( -- n ) 0 100 random-int ;
+
+: numbers-game-loop ( actual -- )
+ dup guess-prompt read-number judge-guess [
+ numbers-game-loop
+ ] [
+ drop
+ ] ifte ;
+
+: numbers-game number-to-guess numbers-game-loop ;
--- /dev/null
+! Contractor timesheet example
+
+IN: timesheet
+USE: combinators
+USE: errors
+USE: format
+USE: kernel
+USE: lists
+USE: math
+USE: parser
+USE: stack
+USE: stdio
+USE: strings
+USE: unparser
+USE: vectors
+
+! Adding a new entry to the time sheet.
+
+: measure-duration ( -- duration )
+ millis
+ read drop
+ millis swap - 1000 /i 60 /i ;
+
+: add-entry-prompt ( -- duration description )
+ "Start work on the task now. Press ENTER when done." print
+ measure-duration
+ "Please enter a description:" print
+ read ;
+
+: add-entry ( timesheet -- )
+ add-entry-prompt cons swap vector-push ;
+
+! Printing the timesheet.
+
+: hh ( duration -- str ) 60 /i ;
+: mm ( duration -- str ) 60 mod unparse 2 digits ;
+: hh:mm ( millis -- str ) <% dup hh % ":" % mm % %> ;
+
+: print-entry ( duration description -- )
+ dup write
+ 60 swap pad-string write
+ hh:mm print ;
+
+: print-timesheet ( timesheet -- )
+ "TIMESHEET:" print
+ [ uncons print-entry ] vector-each ;
+
+! Displaying a menu
+
+: print-menu ( menu -- )
+ terpri [ cdr car print ] each terpri
+ "Enter a letter between ( ) to execute that action." print ;
+
+: menu-prompt ( menu -- )
+ read swap assoc dup [
+ cdr call
+ ] [
+ "Invalid input: " swap unparse cat2 throw
+ ] ifte ;
+
+: menu ( menu -- )
+ dup print-menu menu-prompt ;
+
+! Main menu
+
+: main-menu ( timesheet -- )
+ [
+ [ "e" "(E)xit" drop ]
+ [ "a" "(A)dd entry" dup add-entry main-menu ]
+ [ "p" "(P)rint timesheet" dup print-timesheet main-menu ]
+ ] menu ;
+
+: timesheet-app ( -- )
+ 10 <vector> main-menu ;
public class FactorInterpreter implements FactorObject, Runnable
{
- public static final String VERSION = "0.64";
+ public static final String VERSION = "0.65";
+
+ public static final Cons DEFAULT_USE = new Cons("builtins",
+ new Cons("syntax",new Cons("scratchpad",null)));
+ public static final String DEFAULT_IN = "scratchpad";
// command line arguments are stored here.
public Cons args;
/**
* Vocabulary search path for interactive parser.
*/
- public Cons use;
+ public Cons use = DEFAULT_USE;
/**
* Vocabulary to define new words in.
*/
- public String in;
-
- /**
- * Kernel vocabulary. Re-created on each startup, contains
- * primitives and parsing words.
- */
- public FactorNamespace builtins;
+ public String in = DEFAULT_IN;
/**
* Most recently defined word.
this.vocabularies = interp.vocabularies;
this.use = interp.use;
this.in = interp.in;
- this.builtins = interp.builtins;
this.last = interp.last;
this.global = interp.global;
this.startupDone = true;
//{{{ initBuiltinDictionary() method
private void initBuiltinDictionary() throws Exception
{
- builtins = new FactorNamespace();
- vocabularies.setVariable("builtins",builtins);
-
- in = "builtins";
- use = new Cons(in,null);
+ vocabularies.setVariable("builtins",new FactorNamespace());
+ vocabularies.setVariable("combinators",new FactorNamespace());
+ vocabularies.setVariable("syntax",new FactorNamespace());
/* comments */
- FactorWord lineComment = define("builtins","!");
+ FactorWord lineComment = define("syntax","!");
lineComment.parsing = new LineComment(lineComment,false);
- FactorWord stackComment = define("builtins","(");
+ FactorWord stackComment = define("syntax","(");
stackComment.parsing = new StackComment(stackComment);
- FactorWord docComment = define("builtins","#!");
+ FactorWord docComment = define("syntax","#!");
docComment.parsing = new LineComment(docComment,true);
/* strings */
- FactorWord str = define("builtins","\"");
+ FactorWord str = define("syntax","\"");
str.parsing = new StringLiteral(str,true);
- FactorWord ch = define("builtins","CHAR:");
+ FactorWord ch = define("syntax","CHAR:");
ch.parsing = new CharLiteral(ch);
/* constants */
- FactorWord t = define("builtins","t");
+ FactorWord t = define("syntax","t");
t.parsing = new T(t);
- FactorWord f = define("builtins","f");
+ FactorWord f = define("syntax","f");
f.parsing = new F(f);
- FactorWord complex = define("builtins","#{");
+ FactorWord complex = define("syntax","#{");
complex.parsing = new ComplexLiteral(complex,"}");
/* lists */
- FactorWord bra = define("builtins","[");
+ FactorWord bra = define("syntax","[");
bra.parsing = new Bra(bra);
- FactorWord ket = define("builtins","]");
+ FactorWord ket = define("syntax","]");
ket.parsing = new Ket(bra,ket);
- FactorWord bar = define("builtins","|");
+ FactorWord bar = define("syntax","|");
bar.parsing = new Bar(bar);
/* vectors */
- FactorWord beginVector = define("builtins","{");
+ FactorWord beginVector = define("syntax","{");
beginVector.parsing = new BeginVector(beginVector);
- FactorWord endVector = define("builtins","}");
+ FactorWord endVector = define("syntax","}");
endVector.parsing = new EndVector(beginVector,endVector);
/* word defs */
- FactorWord def = define("builtins",":");
+ FactorWord def = define("syntax",":");
def.parsing = new Def(def);
def.getNamespace().setVariable("doc-comments",Boolean.TRUE);
- FactorWord ine = define("builtins",";");
+ FactorWord ine = define("syntax",";");
ine.parsing = new Ine(def,ine);
- FactorWord shuffle = define("builtins","~<<");
+ FactorWord shuffle = define("syntax","~<<");
shuffle.parsing = new Shuffle(shuffle,">>~");
/* reading numbers with another base */
- FactorWord bin = define("builtins","BIN:");
+ FactorWord bin = define("syntax","BIN:");
bin.parsing = new Base(bin,2);
- FactorWord oct = define("builtins","OCT:");
+ FactorWord oct = define("syntax","OCT:");
oct.parsing = new Base(oct,8);
- FactorWord hex = define("builtins","HEX:");
+ FactorWord hex = define("syntax","HEX:");
hex.parsing = new Base(hex,16);
/* vocabulary parsing words */
- FactorWord noParsing = define("builtins","POSTPONE:");
+ FactorWord noParsing = define("syntax","POSTPONE:");
noParsing.parsing = new NoParsing(noParsing);
- FactorWord defer = define("builtins","DEFER:");
+ FactorWord defer = define("syntax","DEFER:");
defer.parsing = new Defer(defer);
- FactorWord in = define("builtins","IN:");
+ FactorWord in = define("syntax","IN:");
in.parsing = new In(in);
- FactorWord use = define("builtins","USE:");
+ FactorWord use = define("syntax","USE:");
use.parsing = new Use(use);
FactorWord interpreterGet = define("builtins","interpreter");
define.def = new Define(define);
// combinators
- FactorWord execute = define("builtins","execute");
+ FactorWord execute = define("words","execute");
execute.def = new Execute(execute);
- FactorWord call = define("builtins","call");
+ FactorWord call = define("combinators","call");
call.def = new Call(call);
call.inline = true;
- FactorWord ifte = define("builtins","ifte");
+ FactorWord ifte = define("combinators","ifte");
ifte.def = new Ifte(ifte);
ifte.inline = true;
} //}}}
"args",
"dump",
"interactive",
- "builtins",
"in",
"last",
"use"
*/
public class FactorReader
{
- public static final Cons DEFAULT_USE = new Cons("builtins",
- new Cons("scratchpad",null));
- public static final String DEFAULT_IN = "scratchpad";
-
private FactorInterpreter interp;
private FactorScanner scanner;
private Cons states;
pushState(toplevel,null);
this.alwaysDocComments = alwaysDocComments;
this.interactive = interactive;
- this.in = DEFAULT_IN;
- this.use = DEFAULT_USE;
+ this.in = FactorInterpreter.DEFAULT_IN;
+ this.use = FactorInterpreter.DEFAULT_USE;
} //}}}
//{{{ getScanner() method
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: cross-compiler
+USE: combinators
USE: kernel
USE: lists
USE: math
--- /dev/null
+! :folding=indent: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.
+
+IN: files
+USE: combinators
+USE: lists
+USE: namespaces
+USE: stack
+USE: strings
+
+: set-mime-types ( assoc -- )
+ "mime-types" global set* ;
+
+: mime-types ( -- assoc )
+ "mime-types" global get* ;
+
+: file-extension ( filename -- extension )
+ "." split cdr dup [ last ] when ;
+
+: mime-type ( filename -- mime-type )
+ file-extension mime-types assoc [ "text/plain" ] unless* ;
+
+[
+ [ "html" | "text/html" ]
+ [ "txt" | "text/plain" ]
+
+ [ "gif" | "image/gif" ]
+ [ "png" | "image/png" ]
+ [ "jpg" | "image/jpeg" ]
+ [ "jpeg" | "image/jpeg" ]
+
+ [ "jar" | "application/octet-stream" ]
+ [ "zip" | "application/octet-stream" ]
+ [ "tgz" | "application/octet-stream" ]
+ [ "tar.gz" | "application/octet-stream" ]
+ [ "gz" | "application/octet-stream" ]
+
+ [ "factor" | "application/x-factor" ]
+] set-mime-types
USE: html
USE: kernel
USE: lists
+USE: files
USE: namespaces
USE: parser
USE: regexp
USE: httpd
USE: httpd-responder
-!!! Support words.
-: mime-types ( -- alist )
- [
- [ "html" | "text/html" ]
- [ "txt" | "text/plain" ]
-
- [ "gif" | "image/gif" ]
- [ "png" | "image/png" ]
- [ "jpg" | "image/jpeg" ]
- [ "jpeg" | "image/jpeg" ]
-
- [ "jar" | "application/octet-stream" ]
- [ "zip" | "application/octet-stream" ]
- [ "tgz" | "application/octet-stream" ]
- [ "tar.gz" | "application/octet-stream" ]
- [ "gz" | "application/octet-stream" ]
- ] ;
-
-: mime-type ( filename -- mime-type )
- file-extension mime-types assoc [ "text/plain" ] unless* ;
-
!!! Serving files.
: file-header ( filename -- header )
"200 Document follows" swap mime-type response ;
!!! Serving directories.
: file>html ( filename -- ... )
"<li><a href=\"" swap
- !dup directory? [ "/" cat2 ] when
+ ! dup directory? [ "/" cat2 ] when
chars>entities
"\">" over "</a></li>" ;
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: quit-responder
+USE: combinators
USE: namespaces
USE: stdio
USE: stack
#! Parse command line arguments.
parse-switches run-files ;
-: (word-of-the-day) ( -- word )
- vocabs random-element words dup [
- random-element
- ] [
- drop (word-of-the-day) ( empty vocab )
- ] ifte ;
-
-: word-of-the-day ( -- )
- #! Something to entertain the poor hacker.
- (word-of-the-day) dup defined? [
- "WORD OF THE DAY: " print see
- ] [
- drop word-of-the-day
- ] ifte ;
-
: init-interpreter ( -- )
init-history
print-banner
- word-of-the-day
room.
interpreter-loop ;
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-IN: logic USE: kernel USE: stack
+IN: logic
+USE: combinators
+USE: kernel
+USE: stack
: ? ( cond t f -- t/f )
#! Push t if cond is true, otherwise push f.
"/library/styles.factor" run-resource ! styles
"/library/platform/jvm/threads.factor" run-resource ! threads
"/library/logging.factor" run-resource ! logging
+"/library/files.factor" run-resource ! files
!!! Math library.
"/library/platform/jvm/real-math.factor" run-resource ! real-math
!!! Minimum amount of words needed to be able to read other
!!! resources.
+USE: combinators
+
IN: stack
~<< dup A -- A A >>~
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: cross-compiler
+USE: combinators
USE: kernel
USE: lists
USE: math
t "startup-done" set
- "interactive" get [ init-interpreter ] when ;
+ "interactive" get [ init-interpreter 1 exit* ] when ;
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: parser
+USE: combinators
USE: errors
USE: namespaces
USE: stack
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: stack
+USE: combinators
USE: kernel
USE: vectors
[ "java.io.File" ] "java.io.File" "renameTo"
jinvoke ;
-: file-extension ( filename -- extension )
- ".*\\.(.*)" group1 ;
-
: <sreader> ( string -- reader )
[ "java.lang.String" ] "java.io.StringReader" jnew ;
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: strings
+USE: combinators
USE: kernel
USE: logic
USE: stack
IN: test
+USE: combinators
USE: compiler
USE: namespaces
USE: stdio
"/library/random.factor"
"/library/stdio-binary.factor"
"/library/platform/native/prettyprint.factor"
+ "/library/files.factor"
"/library/interpreter.factor"
"/library/inspector.factor"
"/library/inspect-vocabularies.factor"
USE: strings
USE: unparser
USE: vectors
+USE: words
: expired-port-error ( obj -- )
"Expired port: " write . ;
! Parsing words. 'builtins' is a stupid vocabulary name now
! that it does not contain Java words anymore!
-IN: builtins
+IN: syntax
USE: combinators
USE: cross-compiler
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: profiler
+USE: combinators
USE: kernel
USE: lists
USE: math
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: random
+USE: combinators
USE: kernel
USE: math
USE: stack
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: words
+USE: combinators
USE: lists
USE: namespaces
USE: stack
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: stdio
+USE: combinators
USE: errors
USE: kernel
USE: namespaces
--- /dev/null
+IN: scratchpad
+USE: files
+USE: test
+
+[ "txt" ] [ "foo.txt" file-extension ] unit-test
+[ f ] [ "foobar" file-extension ] unit-test
+[ "txt" ] [ "foo.bar.txt" file-extension ] unit-test
+[ "text/plain" ] [ "foo.bar.txt" mime-type ] unit-test
+[ "text/html" ] [ "index.html" mime-type ] unit-test
"hashtables"
"strings"
"namespaces/namespaces"
+ "files"
"format"
"parser"
"parse-number"
: init-search-path ( -- )
! For files
- "user" "file-in" set
- [ "user" "builtins" ] "file-use" set
+ "scratchpad" "file-in" set
+ [ "builtins" "syntax" "scratchpad" ] "file-use" set
! For interactive
- "user" "in" set
+ "scratchpad" "in" set
[
"user"
"arithmetic"
"streams"
"stdio"
"strings"
+ "syntax"
"test"
"threads"
"trace"