]> gitweb.factorcode.org Git - factor.git/blobdiff - core/compiler/units/units.factor
core: trim using lists with lint.vocabs tool
[factor.git] / core / compiler / units / units.factor
index 9ffb98a383b2bbeabaa993a7d42112d1b3c66975..90223e19eabd497dd99f750ab87cab0f5f7c1716 100644 (file)
@@ -1,27 +1,27 @@
-! Copyright (C) 2008, 2009 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays kernel continuations assocs namespaces
-sequences words vocabs definitions hashtables init sets
-math math.order classes classes.algebra classes.tuple
-classes.tuple.private generic source-files.errors
-kernel.private ;
+USING: accessors arrays assocs classes classes.private
+classes.tuple.private continuations definitions generic
+hash-sets kernel kernel.private math namespaces sequences
+sets source-files.errors vocabs words ;
 IN: compiler.units
 
+PRIMITIVE: modify-code-heap ( alist update-existing? reset-pics? -- )
+
 SYMBOL: old-definitions
 SYMBOL: new-definitions
 
 TUPLE: redefine-error def ;
 
-: redefine-error ( definition -- )
-    \ redefine-error boa
-    { { "Continue" t } } throw-restarts drop ;
+: throw-redefine-error ( definition -- )
+    redefine-error boa throw-continue ;
 
 <PRIVATE
 
-: add-once ( key assoc -- )
-    2dup key? [ over redefine-error ] when conjoin ;
+: add-once ( key set -- )
+    dupd ?adjoin [ drop ] [ throw-redefine-error ] if ;
 
-: (remember-definition) ( definition loc assoc -- )
+: (remember-definition) ( definition loc set -- )
     [ over set-where ] dip add-once ;
 
 PRIVATE>
@@ -30,62 +30,73 @@ PRIVATE>
     new-definitions get first (remember-definition) ;
 
 : fake-definition ( definition -- )
-    old-definitions get [ delete-at ] with each ;
+    old-definitions get [ delete ] with each ;
 
 : remember-class ( class loc -- )
-    [ dup new-definitions get first key? [ dup redefine-error ] when ] dip
-    new-definitions get second (remember-definition) ;
+    new-definitions get first2
+    [ dupd in? [ dup throw-redefine-error ] when ]
+    [ (remember-definition) ] bi-curry* bi* ;
 
 : forward-reference? ( word -- ? )
-    dup old-definitions get assoc-stack
-    [ new-definitions get assoc-stack not ]
-    [ drop f ] if ;
+    dup old-definitions get [ in? ] with any? [
+        new-definitions get [ in? ] with none?
+    [ drop f ] if ;
 
 SYMBOL: compiler-impl
 
+HOOK: update-call-sites compiler-impl ( class generic -- words )
+
+: changed-call-sites ( class generic -- )
+    update-call-sites [ changed-definition ] each ;
+
+M: generic update-generic
+    [ changed-call-sites ]
+    [ remake-generic drop ]
+    [ changed-conditionally drop ]
+    2tri ;
+
+M: sequence update-methods
+    implementors [ update-generic ] with each ;
+
 HOOK: recompile compiler-impl ( words -- alist )
 
 HOOK: to-recompile compiler-impl ( -- words )
 
 HOOK: process-forgotten-words compiler-impl ( words -- )
 
-: compile ( words -- ) recompile modify-code-heap ;
+: compile ( words -- )
+    recompile t f modify-code-heap ;
+
+: filter-word-defs ( defset -- words )
+    members [ word? ] filter ;
 
 ! Non-optimizing compiler
-M: f recompile
-    [ dup def>> ] { } map>assoc ;
+M: f update-call-sites
+    2drop { } ;
 
 M: f to-recompile
-    changed-definitions get [ drop word? ] assoc-filter
-    changed-generics get assoc-union keys ;
+    changed-definitions get filter-word-defs ;
+
+M: f recompile
+    [ def>> ] zip-with ;
 
 M: f process-forgotten-words drop ;
 
 : without-optimizer ( quot -- )
     [ f compiler-impl ] dip with-variable ; inline
 
-! Trivial compiler. We don't want to touch the code heap
-! during stage1 bootstrap, it would just waste time.
-SINGLETON: dummy-compiler
-
-M: dummy-compiler to-recompile f ;
-
-M: dummy-compiler recompile drop { } ;
-
-M: dummy-compiler process-forgotten-words drop ;
-
-: <definitions> ( -- pair ) { H{ } H{ } } [ clone ] map ;
+: <definitions> ( -- pair ) { HS{ } HS{ } } [ clone ] map ;
 
 SYMBOL: definition-observers
 
-GENERIC: definitions-changed ( assoc obj -- )
+GENERIC: definitions-changed ( set obj -- )
 
-[ V{ } clone definition-observers set-global ]
-"compiler.units" add-init-hook
+STARTUP-HOOK: [
+    V{ } clone definition-observers set-global
 
-! This goes here because vocabs cannot depend on init
-[ V{ } clone vocab-observers set-global ]
-"vocabs" add-init-hook
+    ! This goes here because vocabs cannot depend on init
+    V{ } clone vocab-observers set-global
+]
 
 : add-definition-observer ( obj -- )
     definition-observers get push ;
@@ -93,85 +104,107 @@ GENERIC: definitions-changed ( assoc obj -- )
 : remove-definition-observer ( obj -- )
     definition-observers get remove-eq! drop ;
 
-: notify-definition-observers ( assoc -- )
+: notify-definition-observers ( set -- )
     definition-observers get
     [ definitions-changed ] with each ;
 
 ! Incremented each time stack effects potentially changed, used
 ! by compiler.tree.propagation.call-effect for call( and execute(
 ! inline caching
-: effect-counter ( -- n ) 46 getenv ; inline
+: effect-counter ( -- n ) REDEFINITION-COUNTER special-object ; inline
 
-GENERIC: bump-effect-counter* ( defspec -- ? )
+GENERIC: always-bump-effect-counter? ( defspec -- ? )
 
-M: object bump-effect-counter* drop f ;
+M: object always-bump-effect-counter? drop f ;
 
 <PRIVATE
 
-: changed-vocabs ( assoc -- vocabs )
-    [ drop word? ] assoc-filter
-    [ drop vocabulary>> dup [ vocab ] when dup ] assoc-map ;
+: changed-vocabs ( set -- vocabs )
+    filter-word-defs [ vocabulary>> dup [ lookup-vocab ] when ] map ;
 
-: updated-definitions ( -- assoc )
-    H{ } clone
-    dup forgotten-definitions get update
-    dup new-definitions get first update
-    dup new-definitions get second update
-    dup changed-definitions get update
-    dup dup changed-vocabs update ;
-
-: process-forgotten-definitions ( -- )
-    forgotten-definitions get keys
+: updated-definitions ( -- set )
+    HS{ } clone
+    forgotten-definitions get union!
+    new-definitions get first union!
+    new-definitions get second union!
+    changed-definitions get union!
+    maybe-changed get union!
+    dup changed-vocabs over adjoin-all ;
+
+: process-forgotten-definitions ( forgotten-definitions -- )
+    members
     [ [ word? ] filter process-forgotten-words ]
     [ [ delete-definition-errors ] each ]
     bi ;
 
 : bump-effect-counter? ( -- ? )
-    changed-effects get new-words get assoc-diff assoc-empty? not
-    changed-definitions get [ drop bump-effect-counter* ] assoc-any?
-    or ;
+    changed-effects get members
+    maybe-changed get members
+    changed-definitions get members
+    [ always-bump-effect-counter? ] filter
+    3array union-all new-words get [ in? not ] curry any? ;
 
 : bump-effect-counter ( -- )
-    bump-effect-counter? [ 46 getenv 0 or 1 + 46 setenv ] when ;
+    bump-effect-counter? [
+        REDEFINITION-COUNTER special-object 0 or
+        1 + REDEFINITION-COUNTER set-special-object
+    ] when ;
 
 : notify-observers ( -- )
-    updated-definitions dup assoc-empty?
-    [ drop ] [ notify-definition-observers notify-error-observers ] if ;
+    updated-definitions notify-definition-observers
+    notify-error-observers ;
+
+: update-existing? ( defs -- ? )
+    new-words get [ in? not ] curry any? ;
+
+: reset-pics? ( -- ? )
+    outdated-generics get null? not ;
 
 : finish-compilation-unit ( -- )
-    remake-generics
-    to-recompile recompile
-    update-tuples
-    process-forgotten-definitions
-    modify-code-heap
-    bump-effect-counter
-    notify-observers ;
+    [ ] [
+        remake-generics
+        to-recompile [
+            recompile
+            outdated-tuples get update-tuples
+            forgotten-definitions get process-forgotten-definitions
+        ] keep update-existing? reset-pics? modify-code-heap
+        bump-effect-counter
+        notify-observers
+    ] if-bootstrapping ;
+
+TUPLE: nesting-observer { new-words hash-set } ;
+
+M: nesting-observer definitions-changed
+    [ members ] dip new-words>> [ delete ] curry each ;
+
+: add-nesting-observer ( -- )
+    new-words get nesting-observer boa
+    [ nesting-observer namespaces:set ] [ add-definition-observer ] bi ;
+
+: remove-nesting-observer ( -- )
+    nesting-observer get remove-definition-observer ;
 
 PRIVATE>
 
 : with-nested-compilation-unit ( quot -- )
-    [
-        H{ } clone changed-definitions set
-        H{ } clone changed-generics set
-        H{ } clone changed-effects set
-        H{ } clone outdated-generics set
-        H{ } clone outdated-tuples set
-        H{ } clone new-words set
-        H{ } clone new-classes set
-        [ finish-compilation-unit ] [ ] cleanup
-    ] with-scope ; inline
+    H{ } clone
+    HS{ } clone changed-definitions pick set-at
+    HS{ } clone maybe-changed pick set-at
+    HS{ } clone changed-effects pick set-at
+    HS{ } clone outdated-generics pick set-at
+    H{ } clone outdated-tuples pick set-at
+    HS{ } clone new-words pick set-at [
+        add-nesting-observer
+        [
+            remove-nesting-observer
+            finish-compilation-unit
+        ] finally
+    ] with-variables ; inline
 
 : with-compilation-unit ( quot -- )
-    [
-        H{ } clone changed-definitions set
-        H{ } clone changed-generics set
-        H{ } clone changed-effects set
-        H{ } clone outdated-generics set
-        H{ } clone forgotten-definitions set
-        H{ } clone outdated-tuples set
-        H{ } clone new-words set
-        H{ } clone new-classes set
-        <definitions> new-definitions set
-        <definitions> old-definitions set
-        [ finish-compilation-unit ] [ ] cleanup
-    ] with-scope ; inline
+    H{ } clone
+    <definitions> new-definitions pick set-at
+    <definitions> old-definitions pick set-at
+    HS{ } clone forgotten-definitions pick set-at [
+        with-nested-compilation-unit
+    ] with-variables ; inline