Lets put our program for solving quadratic equations in a source file. Create a file named \texttt{quadratic.factor} in your favorite editor, and add the following content:
\begin{verbatim}
+IN: quadratic
+USE: math
+USE: kernel
+
: quadratic-e ( b a -- -b/2a )
2 * / neg ;
nargs[1] = jEdit.getProperty("factor.external.image");
nargs[2] = "-no-ansi";
nargs[3] = "-no-smart-terminal";
- System.arraycopy(args,0,nargs,3,args.length);
+ System.arraycopy(args,0,nargs,4,args.length);
p = Runtime.getRuntime().exec(nargs);
p.getErrorStream().close();
{
while(words != null)
{
- Object obj = words.car;
- FactorPlugin.getExternalInstance().forget((FactorWord)obj);
+ FactorWord word = (FactorWord)words.car;
+ // We're not allowed to forget parsing words.
+ if(word.parsing != null)
+ return;
+ FactorPlugin.getExternalInstance().forget(word);
words = words.next();
}
} //}}}
\r
"Cold boot in progress..." print\r
\r
+! vocabularies get [\r
+! "generic" off\r
+! ] bind\r
+\r
[\r
"/library/generic/generic.factor"\r
"/library/generic/object.factor"\r
"/library/syntax/parse-numbers.factor"\r
"/library/syntax/parser.factor"\r
"/library/syntax/parse-stream.factor"\r
- "/library/bootstrap/init.factor"\r
\r
"/library/syntax/unparser.factor"\r
"/library/io/presentation.factor"\r
USE: hashtables
"/library/bootstrap/primitives.factor" run-resource
-"/version.factor" run-resource
-"/library/stack.factor" run-resource
-"/library/combinators.factor" run-resource
-"/library/kernel.factor" run-resource
-"/library/cons.factor" run-resource
-"/library/assoc.factor" run-resource
-"/library/math/math.factor" run-resource
-"/library/math/integer.factor" run-resource
-"/library/math/ratio.factor" run-resource
-"/library/math/float.factor" run-resource
-"/library/math/complex.factor" run-resource
-"/library/words.factor" run-resource
-"/library/math/math-combinators.factor" run-resource
-"/library/lists.factor" run-resource
-"/library/vectors.factor" run-resource
-"/library/strings.factor" run-resource
-"/library/hashtables.factor" run-resource
-"/library/namespaces.factor" run-resource
-"/library/list-namespaces.factor" run-resource
-"/library/sbuf.factor" run-resource
-"/library/errors.factor" run-resource
-"/library/continuations.factor" run-resource
-"/library/threads.factor" run-resource
-"/library/io/stream.factor" run-resource
-"/library/io/stdio.factor" run-resource
-"/library/io/io-internals.factor" run-resource
-"/library/io/stream-impl.factor" run-resource
-"/library/vocabularies.factor" run-resource
-"/library/syntax/parse-numbers.factor" run-resource
-"/library/syntax/parser.factor" run-resource
-"/library/syntax/parse-stream.factor" run-resource
-! init.factor leaves a boot quotation on the stack
-"/library/bootstrap/init.factor" run-resource
+! The make-list form creates a boot quotation
+[
+ "/version.factor" parse-resource append,
+ "/library/stack.factor" parse-resource append,
+ "/library/combinators.factor" parse-resource append,
+ "/library/kernel.factor" parse-resource append,
+ "/library/cons.factor" parse-resource append,
+ "/library/assoc.factor" parse-resource append,
+ "/library/math/math.factor" parse-resource append,
+ "/library/math/integer.factor" parse-resource append,
+ "/library/math/ratio.factor" parse-resource append,
+ "/library/math/float.factor" parse-resource append,
+ "/library/math/complex.factor" parse-resource append,
+ "/library/words.factor" parse-resource append,
+ "/library/math/math-combinators.factor" parse-resource append,
+ "/library/lists.factor" parse-resource append,
+ "/library/vectors.factor" parse-resource append,
+ "/library/strings.factor" parse-resource append,
+ "/library/hashtables.factor" parse-resource append,
+ "/library/namespaces.factor" parse-resource append,
+ "/library/list-namespaces.factor" parse-resource append,
+ "/library/sbuf.factor" parse-resource append,
+ "/library/errors.factor" parse-resource append,
+ "/library/continuations.factor" parse-resource append,
+ "/library/threads.factor" parse-resource append,
+ "/library/io/stream.factor" parse-resource append,
+ "/library/io/stdio.factor" parse-resource append,
+ "/library/io/io-internals.factor" parse-resource append,
+ "/library/io/stream-impl.factor" parse-resource append,
+ "/library/vocabularies.factor" parse-resource append,
+ "/library/syntax/parse-numbers.factor" parse-resource append,
+ "/library/syntax/parser.factor" parse-resource append,
+ "/library/syntax/parse-stream.factor" parse-resource append,
-! A bootstrapping trick. See doc/bootstrap.txt.
-"/library/syntax/parse-syntax.factor" run-resource
+ "traits" [ "generic" ] search
+ "delegate" [ "generic" ] search
+
+ vocabularies get [ "generic" off ] bind
+
+ reveal
+ reveal
+
+ "/library/generic/generic.factor" parse-resource append,
+ "/library/generic/object.factor" parse-resource append,
+ "/library/generic/builtin.factor" parse-resource append,
+ "/library/generic/predicate.factor" parse-resource append,
+ "/library/generic/union.factor" parse-resource append,
+ "/library/generic/traits.factor" parse-resource append,
+
+ "/library/bootstrap/init.factor" parse-resource append,
+ "/library/syntax/parse-syntax.factor" parse-resource append,
+] make-list
+
+"boot" [ "kernel" ] search swons
vocabularies get [
"!syntax" get "syntax" set
"HOME" os-env [ "." ] unless* "~" set
init-search-path ;
-[
- boot
- "Good morning!" print
- flush
- "/library/bootstrap/boot-stage2.factor" run-resource
-]
+"Good morning!" print
+flush
+"/library/bootstrap/boot-stage2.factor" run-resource
[ "random" | "init-random" ]
[ "random" | "(random-int)" ]
[ "kernel" | "type" ]
- [ "kernel" | "size" ]
[ "files" | "cwd" ]
[ "files" | "cd" ]
[ "compiler" | "compiled-offset" ]
dup "c-types" get hash dup [
nip
] [
- drop "No such C type: " swap cat2 throw
+ drop "No such C type: " swap cat2 throw f
] ifte
] bind ;
: define-c-type ( quot name -- )
- c-types [ >r <c-type> swap extend r> set ] bind ;
+ c-types [ >r <c-type> swap extend r> set ] bind ; inline
: define-getter ( offset type name -- )
#! Define a word with stack effect ( alien -- obj ) in the
] "builtin-supertypes" set-word-property
builtin [
- ( vtable definition class -- )
- rot set-vtable
+ ( generic vtable definition class -- )
+ rot set-vtable drop
] "add-method" set-word-property
builtin 50 "priority" set-word-property
: set-vtable ( definition class vtable -- )
>r "builtin-type" word-property r> set-vector-nth ;
-: <empty-vtable> ( -- vtable )
- num-types [ drop [ undefined-method ] ] vector-project ;
-
: class-ord ( class -- n ) metaclass "priority" word-property ;
: class< ( cls1 cls2 -- ? )
: sort-methods ( methods -- alist )
hash>alist [ 2car class< ] sort ;
-: add-method ( vtable definition class -- )
+: add-method ( generic vtable definition class -- )
#! Add the method entry to the vtable. Unlike define-method,
#! this is called at vtable build time, and in the sorted
#! order.
dup metaclass "add-method" word-property
[ [ undefined-method ] ] unless* call ;
-: <vtable> ( methods -- vtable )
- <empty-vtable> swap sort-methods [
- dupd unswons add-method
- ] each ;
+: <empty-vtable> ( -- vtable )
+ num-types [ drop [ undefined-method ] ] vector-project ;
-DEFER: add-traits-dispatch
+: <vtable> ( generic methods -- vtable )
+ >r <empty-vtable> r> sort-methods [
+ >r 2dup r> unswons add-method
+ ] each nip ;
: define-generic ( word vtable -- )
over "combination" word-property cons define-compound ;
: (define-method) ( definition class generic -- )
- [ "methods" word-property [ set-hash ] keep <vtable> ] keep
- swap define-generic ;
+ [ "methods" word-property set-hash ] keep
+ dup dup "methods" word-property <vtable>
+ define-generic ;
! Defining generic words
: (GENERIC) ( combination -- )
#! Takes a combination parameter. A combination is a
#! quotation that takes some objects and a vtable from the
#! stack, and calls the appropriate row of the vtable.
- CREATE 2dup "combination" word-property = [
- 2drop
- ] [
- [ swap "combination" set-word-property ] keep
- dup <namespace> "methods" set-word-property
- <empty-vtable> [ add-traits-dispatch ] 2keep
- define-generic
- ] ifte ;
+ CREATE [ swap "combination" set-word-property ] keep
+ dup dup "methods" word-property [
+ dup <namespace> [ "methods" set-word-property ] keep
+ ] unless* <vtable> define-generic ;
: single-combination ( obj vtable -- )
>r dup type r> dispatch ; inline
] "builtin-supertypes" set-word-property
object [
- ( vtable definition class -- )
+ ( generic vtable definition class -- )
drop over vector-length [
pick pick -rot set-vector-nth
- ] times* 2drop
+ ] times* 3drop
] "add-method" set-word-property
object [ drop t ] "predicate" set-word-property
] "builtin-supertypes" set-word-property
predicate [
- ( vtable definition class -- )
+ ( generic vtable definition class -- )
dup builtin-supertypes [
( vtable definition class type# )
>r 3dup r> predicate-method
- ] each 3drop
+ ] each 2drop 2drop
] "add-method" set-word-property
predicate 25 "priority" set-word-property
#! definitions.
"traits-map" word-property ;
-traits [
- ( class generic quotation )
-
- swap rot traits-map set-hash
-] "define-method" set-word-property
-
-traits [
- \ vector "builtin-type" word-property unique,
-] "builtin-supertypes" set-word-property
-
-traits 10 "priority" set-word-property
-
! Hashtable slot holding an optional delegate. Any undefined
! methods are called on the delegate. The object can also
! manually pass any methods on to the delegate.
#! We will use hashtable? here when its a first-class type.
dup vector? [ traits swap hash ] [ drop f ] ifte ;
-: init-traits-map ( word -- )
- <namespace> "traits-map" set-word-property ;
-
: traits-dispatch ( selector traits -- traits quot )
#! Look up the method with the traits object on the stack.
#! Returns the traits to call the method on; either the
] ifte
] ifte ;
+: add-traits-dispatch ( word vtable -- )
+ >r unit [ car swap traits-dispatch call ] cons \ vector r>
+ set-vtable ;
+
+traits [
+ ( generic vtable definition class -- )
+ 2drop add-traits-dispatch
+] "add-method" set-word-property
+
+traits [
+ ( class generic quotation )
+ 3dup -rot (define-method)
+ over dup word-parameter car add-traits-dispatch
+ swap rot traits-map set-hash
+] "define-method" set-word-property
+
+traits [
+ drop vector "builtin-type" word-property unit
+] "builtin-supertypes" set-word-property
+
+traits 10 "priority" set-word-property
+
+: init-traits-map ( word -- )
+ <namespace> "traits-map" set-word-property ;
+
: traits-predicate ( word -- )
#! foo? where foo is a traits type tests if the top of stack
#! is of this type.
dup traits "metaclass" set-word-property
traits-predicate ; parsing
-: add-traits-dispatch ( word vtable -- )
- >r unit [ car swap traits-dispatch call ] cons \ vector r>
- set-vtable ;
-
: constructor-word ( word -- word )
word-name "<" swap ">" cat3 "in" get create ;
] "builtin-supertypes" set-word-property
union [
- ( vtable definition class -- )
- "members" word-property [ >r 2dup r> add-method ] each 2drop
+ ( generic vtable definition class -- )
+ "members" word-property [ >r 3dup r> add-method ] each 3drop
] "add-method" set-word-property
union 30 "priority" set-word-property
#values values-node
] extend ;
-: terminator? ( quot -- ? )
- #! This is a hack. undefined-method has a stack effect that
- #! probably does not match any other branch of the generic,
- #! so we handle it specially.
- literal-value \ undefined-method swap tree-contains? ;
+: terminator? ( obj -- ? )
+ dup word? [ "terminator" word-property ] [ drop f ] ifte ;
-: recursive-branch ( value -- )
+: terminator-quot? ( quot -- ? )
+ literal-value [ terminator? ] some? ;
+
+: recursive-branch ( rstate value -- )
#! Set base case if inference didn't fail.
[
f infer-branch [
- effect old-effect recursive-state get set-base
+ effect old-effect swap set-base
] bind
] [
- [ drop ] when
+ [ 2drop ] when
] catch ;
+: dual-branch ( branch branchlist -- rstate )
+ #! Return a recursive state for a branch other than the
+ #! given one in the list.
+ [ over eq? not ] subset nip car value-recursion ;
+
: infer-base-case ( branchlist -- )
- [
- dup terminator? [
+ dup [
+ dup terminator-quot? [
drop
] [
+ [ over dual-branch ] keep
recursive-branch
] ifte
- ] each ;
+ ] each drop ;
: (infer-branches) ( branchlist -- list )
dup infer-base-case [
- dup terminator? [
+ dup terminator-quot? [
t infer-branch [
meta-d off meta-r off d-in off
] extend
USE: vectors
USE: words
USE: hashtables
+USE: parser
: with-dataflow ( param op [ in | out ] quot -- )
#! Take input parameters, execute quotation, take output
\ call [ infer-call ] "infer" set-word-property
-\ - [ 2 | 1 ] "infer-effect" set-word-property
-\ * [ 2 | 1 ] "infer-effect" set-word-property
-\ / [ 2 | 1 ] "infer-effect" set-word-property
-\ gcd [ 2 | 1 ] "infer-effect" set-word-property
-\ hashcode [ 1 | 1 ] "infer-effect" set-word-property
+! These are due to bugs and will be removed
+\ - [ [ number number ] [ number ] ] "infer-effect" set-word-property
+\ * [ [ number number ] [ number ] ] "infer-effect" set-word-property
+\ / [ [ number number ] [ number ] ] "infer-effect" set-word-property
+\ gcd [ [ number number ] [ number ] ] "infer-effect" set-word-property
+\ hashcode [ [ object ] [ integer ] ] "infer-effect" set-word-property
+
+\ undefined-method t "terminator" set-word-property
+\ not-a-number t "terminator" set-word-property
[ str-compare " str str -- -1/0/1 " [ [ string string ] [ integer ] ] ]
[ str= " str str -- ? " [ [ string string ] [ boolean ] ] ]
[ str-hashcode " str -- n " [ [ string ] [ integer ] ] ]
- [ index-of* " n str/ch str -- n " [ [ integer text string ] [ integer ] ] ]
+ [ index-of* " n str/ch str -- n " [ [ integer string text ] [ integer ] ] ]
[ substring " start end str -- str " [ [ integer integer string ] [ string ] ] ]
[ str-reverse " str -- str " [ [ string ] [ string ] ] ]
[ <sbuf> " capacity -- sbuf " [ [ integer ] [ sbuf ] ] ]
[ word-parameter " word -- obj " [ [ word ] [ object ] ] ]
[ set-word-parameter " obj word -- " [ [ object word ] [ ] ] ]
[ word-plist " word -- alist" [ [ word ] [ general-list ] ] ]
- [ set-word-plist " alist word -- " [ [ general-list ] [ integer ] ] ]
+ [ set-word-plist " alist word -- " [ [ general-list word ] [ ] ] ]
[ drop " x -- " [ [ object ] [ ] ] ]
[ dup " x -- x x " [ [ object ] [ object object ] ] ]
[ swap " x y -- y x " [ [ object object ] [ object object ] ] ]
[ init-random " -- " [ 0 | 0 ] ]
[ (random-int) " -- n " [ 0 | 1 ] ]
[ type " obj -- n " [ 1 | 1 ] ]
- [ size " obj -- n " [ 1 | 1 ] ]
[ call-profiling " depth -- " [ 1 | 0 ] ]
[ call-count " word -- n " [ 1 | 1 ] ]
[ set-call-count " n word -- " [ 2 | 0 ] ]
[ [ [ 1 ] [ 2 ] ] ] [ [ t [ 1 ] [ 2 ] ifte ] dataflow kill-set ] unit-test
-[ [ t t f ] ] [ [ 1 2 ] [ 1 2 3 ] [ f <literal-value> ] map kill-mask ] unit-test
+[ [ t t f ] ] [ [ 1 2 ] [ 1 2 3 ] [ f <literal> ] map kill-mask ] unit-test
[ rational ] [ ratio integer class-or ] unit-test
[ number ] [ number object class-and ] unit-test
[ number ] [ object number class-and ] unit-test
+
+[ t ] [ del1 builtin-supertypes [ integer? ] all? ] unit-test
USE: kernel
USE: lists
USE: namespaces
+USE: parser
USE: kernel
USE: math-internals
USE: generic
[ [ 1 | 2 ] ] [ [ uncons ] infer old-effect ] unit-test
[ [ 1 | 1 ] ] [ [ unit ] infer old-effect ] unit-test
[ [ 1 | 2 ] ] [ [ unswons ] infer old-effect ] unit-test
-! [ [ 1 | 1 ] ] [ [ last* ] infer old-effect ] unit-test
-! [ [ 1 | 1 ] ] [ [ last ] infer old-effect ] unit-test
-! [ [ 1 | 1 ] ] [ [ list? ] infer old-effect ] unit-test
+[ [ 1 | 1 ] ] [ [ last* ] infer old-effect ] unit-test
+[ [ 1 | 1 ] ] [ [ last ] infer old-effect ] unit-test
+[ [ 1 | 1 ] ] [ [ list? ] infer old-effect ] unit-test
[ [ 1 | 1 ] ] [ [ length ] infer old-effect ] unit-test
[ [ 1 | 1 ] ] [ [ reverse ] infer old-effect ] unit-test
[ [ 2 | 1 ] ] [ [ contains? ] infer old-effect ] unit-test
[ [ 2 | 1 ] ] [ [ tree-contains? ] infer old-effect ] unit-test
[ [ 2 | 1 ] ] [ [ remove ] infer old-effect ] unit-test
-! [ [ 1 | 1 ] ] [ [ prune ] infer old-effect ] unit-test
+[ [ 1 | 1 ] ] [ [ prune ] infer old-effect ] unit-test
[ [ 2 | 1 ] ] [ [ bitor ] infer old-effect ] unit-test
[ [ 2 | 1 ] ] [ [ bitand ] infer old-effect ] unit-test
[ [ [ object ] [ object ] ] ] [ [ dup [ car ] when ] infer ] unit-test
[ [ [ vector ] [ vector ] ] ] [ [ vector-clone ] infer ] unit-test
[ [ [ number ] [ number ] ] ] [ [ dup + ] infer ] unit-test
+[ [ [ number number number ] [ number ] ] ] [ [ digit+ ] infer ] unit-test
primitive_init_random,
primitive_random_int,
primitive_type,
- primitive_size,
primitive_cwd,
primitive_cd,
primitive_compiled_offset,
{
drepl(tag_fixnum(type_of(dpeek())));
}
-
-void primitive_size(void)
-{
- drepl(tag_fixnum(object_size(dpeek())));
-}
CELL untagged_object_size(CELL pointer);
CELL object_size(CELL pointer);
void primitive_type(void);
-void primitive_size(void);
INLINE CELL type_of(CELL tagged)
{