]> gitweb.factorcode.org Git - factor.git/blob - core/compiler/units/units-docs.factor
48bce465298bc4f8cccdf9e235bdef5dc4168ad4
[factor.git] / core / compiler / units / units-docs.factor
1 USING: compiler.units.private definitions help.markup help.syntax kernel
2 kernel.private parser quotations sequences source-files stack-checker.errors
3 words ;
4 IN: compiler.units
5
6 ARTICLE: "compilation-units-internals" "Compilation units internals"
7 "These words do not need to be called directly, and only serve to support the implementation."
8 $nl
9 "Compiling a set of words:"
10 { $subsections compile }
11 "Words called to associate a definition with a compilation unit and a source file location:"
12 { $subsections
13     remember-definition
14     remember-class
15 }
16 "Forward reference checking (see " { $link "definition-checking" } "):"
17 { $subsections forward-reference? }
18 "A hook to be called at the end of the compilation unit. If the optimizing compiler is loaded, this compiles new words with the " { $link "compiler" } ":"
19 { $subsections recompile }
20 "Low-level compiler interface exported by the Factor VM:"
21 { $subsections modify-code-heap } ;
22
23 ARTICLE: "compilation-units" "Compilation units"
24 "A " { $emphasis "compilation unit" } " scopes a group of related definitions. They are compiled and entered into the system in one atomic operation."
25 $nl
26 "When a source file is being parsed, all definitions are part of a single compilation unit, unless the " { $link POSTPONE: << } " parsing word is used to create nested compilation units."
27 $nl
28 "Words defined in a compilation unit may not be called until the compilation unit is finished. The parser detects this case for parsing words and throws a " { $link staging-violation } ". Similarly, an attempt to use a macro from a word defined in the same compilation unit will throw a " { $link transform-expansion-error } ". Calling any other word from within its own compilation unit throws an " { $link undefined } " error."
29 $nl
30 "This means that parsing words and macros generally cannot be used in the same source file as they are defined. There are two means of getting around this:"
31 { $list
32     { "The simplest way is to split off the parsing words and macros into sub-vocabularies; perhaps suffixed by " { $snippet ".syntax" } " and " { $snippet ".macros" } "." }
33     { "Alternatively, nested compilation units can be created using " { $link "syntax-immediate" } "." }
34 }
35 "Parsing words which create new definitions at parse time will implicitly add them to the compilation unit of the current source file."
36 $nl
37 "Code which creates new definitions at run time will need to explicitly create a compilation unit with a combinator. There is an additional combinator used by the parser to implement " { $link "syntax-immediate" } "."
38 { $subsections with-compilation-unit with-nested-compilation-unit }
39 "Additional topics:"
40 { $subsections "compilation-units-internals" } ;
41
42 ABOUT: "compilation-units"
43
44 HELP: bump-effect-counter?
45 { $values { "?" boolean } }
46 { $description "Whether the " { $link REDEFINITION-COUNTER } " should be increased." } ;
47
48 HELP: old-definitions
49 { $var-description "Stores a pair of sets where the members form the set of definitions which were defined by " { $link current-source-file } " the most recent time it was loaded." } ;
50
51 HELP: redefine-error
52 { $values { "definition" "a definition specifier" } }
53 { $description "Throws a " { $link redefine-error } "." }
54 { $error-description "Indicates that a single source file contains two definitions for the same artifact, one of which shadows the other. This is an error since it indicates a likely mistake, such as two words accidentally named the same by the developer; the error is restartable." } ;
55
56 HELP: remember-definition
57 { $values { "definition" "a definition specifier" } { "loc" "a " { $snippet "{ path line# }" } " pair" } }
58 { $description "Saves the location of a definition and associates this definition with the current source file." } ;
59
60 HELP: new-definitions
61 { $var-description "Stores a pair of sets where the members form the set of definitions which were defined so far by the current parsing of " { $link current-source-file } "." } ;
62
63 HELP: with-compilation-unit
64 { $values { "quot" quotation } }
65 { $description "Calls a quotation in a new compilation unit. The quotation can define new words and classes, as well as forget words. When the quotation returns, any changed words are recompiled, and changes are applied atomically." }
66 { $notes "Calls to " { $link with-compilation-unit } " may be nested."
67 $nl
68 "The parser wraps every source file in a compilation unit, so parsing words may define new words without having to perform extra work; to define new words at any other time, you must wrap your defining code with this combinator."
69 $nl
70 "Since compilation is relatively expensive, you should try to batch up as many definitions into one compilation unit as possible." } ;
71
72 HELP: with-nested-compilation-unit
73 { $values { "quot" quotation } }
74 { $description "Calls a quotation in a new compilation unit. The only difference between this word and " { $link with-compilation-unit } " is that variables used by the parser to associate definitions with source files are not rebound." }
75 { $notes "This word is used by " { $link "syntax-immediate" } " to ensure that definitions in nested blocks are correctly recorded. User code should not depend on parser internals in such a way that calling this combinator is required." } ;
76
77 HELP: recompile
78 { $values { "words" "a sequence of words" } { "alist" "an association list mapping words to compiled definitions" } }
79 { $contract "Internal word which compiles words. Called at the end of " { $link with-compilation-unit } "." } ;
80
81 HELP: to-recompile
82 { $values { "words" sequence } }
83 { $description "Sequence of words that will be recompiled by the compilation unit." } ;
84
85 HELP: no-compilation-unit
86 { $values { "word" word } }
87 { $description "Throws a " { $link no-compilation-unit } " error." }
88 { $error-description "Thrown when an attempt is made to define a word outside of a " { $link with-compilation-unit } " combinator." } ;
89
90 HELP: modify-code-heap
91 { $values { "alist" "an association list with words as keys" } { "update-existing?" boolean } { "reset-pics?" boolean } }
92 { $description "Lowest-level primitive for defining words. Associates words with code blocks in the code heap."
93 $nl
94 "The alist maps words to one of the following:"
95 { $list
96     { "a quotation - in this case, the quotation is compiled with the non-optimizing compiler and the word will call the quotation when executed." }
97     { "a 6-element array " { $snippet "{ parameters literals relocation labels code stack-frame-size }" } " - in this case, a code heap block is allocated with the given data and the word will call the code block when executed. This is used by the optimizing compiler." }
98 }
99 "If any of the redefined words may already be referenced by other words in the code heap, from outside of the compilation unit, then a scan of the code heap must be performed to update all word call sites. Passing " { $link t } " as the " { $snippet "update-existing?" } " parameter enables this code path."
100 $nl
101 "If classes, methods or generic words were redefined, then inline cache call sites need to be updated as well. Passing " { $link t } " as the " { $snippet "reset-pics?" } " parameter enables this code path."
102 }
103 { $examples
104   "Manually creating a word using the non-optimizing compiler:"
105   { $example
106     "USING: compiler.units io ;"
107     "IN: test SYMBOL: foo"
108     "{ { foo [ \"hello!\" write nl ] } } t t modify-code-heap foo"
109     "hello!"
110   }
111 }
112 { $notes "This word is called at the end of " { $link with-compilation-unit } "." } ;
113
114 HELP: compile
115 { $values { "words" "a sequence of words" } }
116 { $description "Compiles a set of words." } ;