<commit_before>! Copyright (C) 2008, 2010 <NAME>.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs classes classes.private
classes.tuple.private continuations definitions generic
hash-sets init 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 ;

: throw-redefine-error ( definition -- )
    redefine-error boa throw-continue ;

<PRIVATE

: add-once ( key set -- )
    dupd ?adjoin [ drop ] [ throw-redefine-error ] if ;

: (remember-definition) ( definition loc set -- )
    [ over set-where ] dip add-once ;

PRIVATE>

: remember-definition ( definition loc -- )
    new-definitions get first (remember-definition) ;

: fake-definition ( definition -- )
    old-definitions get [ delete ] with each ;

: remember-class ( class loc -- )
    new-definitions get first2
    [ dupd in? [ dup throw-redefine-error ] when ]
    [ (remember-definition) ] bi-curry* bi* ;

: forward-reference? ( word -- ? )
    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 t f modify-code-heap ;

: filter-word-defs ( defset -- words )
    members [ word? ] filter ;

! Non-optimizing compiler
M: f update-call-sites
    2drop { } ;

M: f to-recompile
    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

: <definitions> ( -- pair ) { HS{ } HS{ } } [ clone ] map ;

SYMBOL: definition-observers

GENERIC: definitions-changed ( set obj -- )

[ V{ } clone definition-observers set-global ]
"compiler.units" add-startup-hook

! This goes here because vocabs cannot depend on init
[ V{ } clone vocab-observers set-global ]
"vocabs" add-startup-hook

: add-definition-observer ( obj -- )
    definition-observers get push ;

: remove-definition-observer ( obj -- )
    definition-observers get remove-eq! drop ;

: 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 ) REDEFINITION-COUNTER special-object ; inline

GENERIC: always-bump-effect-counter? ( defspec -- ? )

M: object always-bump-effect-counter? drop f ;

<PRIVATE

: changed-vocabs ( set -- vocabs )
    filter-word-defs [ vocabulary>> dup [ lookup-vocab ] when ] map ;

: 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 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? [
        REDEFINITION-COUNTER special-object 0 or
        1 + REDEFINITION-COUNTER set-special-object
    ] when ;

: notify-observers ( -- )
    updated-definitions dup null?
    [ drop ] [ notify-definition-observers notify-error-observers ] if ;

: update-existing? ( defs -- ? )
    new-words get [ in? not ] curry any? ;

: reset-pics? ( -- ? )
    outdated-generics get null? not ;

: finish-compilation-unit ( -- )
    [ ] [
        remake-generics
        to-recompile [<commit_msg>compiler.units: always call definition observers at the end of a compilation unit<commit_after>! Copyright (C) 2008, 2010 <NAME>.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs classes classes.private
classes.tuple.private continuations definitions generic
hash-sets init 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 ;

: throw-redefine-error ( definition -- )
    redefine-error boa throw-continue ;

<PRIVATE

: add-once ( key set -- )
    dupd ?adjoin [ drop ] [ throw-redefine-error ] if ;

: (remember-definition) ( definition loc set -- )
    [ over set-where ] dip add-once ;

PRIVATE>

: remember-definition ( definition loc -- )
    new-definitions get first (remember-definition) ;

: fake-definition ( definition -- )
    old-definitions get [ delete ] with each ;

: remember-class ( class loc -- )
    new-definitions get first2
    [ dupd in? [ dup throw-redefine-error ] when ]
    [ (remember-definition) ] bi-curry* bi* ;

: forward-reference? ( word -- ? )
    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 t f modify-code-heap ;

: filter-word-defs ( defset -- words )
    members [ word? ] filter ;

! Non-optimizing compiler
M: f update-call-sites
    2drop { } ;

M: f to-recompile
    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

: <definitions> ( -- pair ) { HS{ } HS{ } } [ clone ] map ;

SYMBOL: definition-observers

GENERIC: definitions-changed ( set obj -- )

[ V{ } clone definition-observers set-global ]
"compiler.units" add-startup-hook

! This goes here because vocabs cannot depend on init
[ V{ } clone vocab-observers set-global ]
"vocabs" add-startup-hook

: add-definition-observer ( obj -- )
    definition-observers get push ;

: remove-definition-observer ( obj -- )
    definition-observers get remove-eq! drop ;

: 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 ) REDEFINITION-COUNTER special-object ; inline

GENERIC: always-bump-effect-counter? ( defspec -- ? )

M: object always-bump-effect-counter? drop f ;

<PRIVATE

: changed-vocabs ( set -- vocabs )
    filter-word-defs [ vocabulary>> dup [ lookup-vocab ] when ] map ;

: 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 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? [
        REDEFINITION-COUNTER special-object 0 or
        1 + REDEFINITION-COUNTER set-special-object
    ] when ;

: notify-observers ( -- )
    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 [
{'fraction_non_alphanumeric': 0.11966850828729282, 'fraction_numerical': 0.0030939226519337017, 'mean_word_length': 2.9403569873748365, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3691214', 'n_tokens_mistral': 2871, 'n_tokens_neox': 2846, 'n_words': 757}