2020-04-15 22:45:08 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
< html >
< head >
< title > A Brief Guide to Foundation< / title >
2020-04-23 22:23:44 +00:00
< link href = "../docs-assets/Breadcrumbs.css" rel = "stylesheet" rev = "stylesheet" type = "text/css" >
2020-04-15 22:45:08 +00:00
< meta name = "viewport" content = "width=device-width initial-scale=1" >
< meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" >
< meta http-equiv = "Content-Language" content = "en-gb" >
2020-04-20 22:26:08 +00:00
2020-05-02 22:50:23 +00:00
< link href = "../docs-assets/Contents.css" rel = "stylesheet" rev = "stylesheet" type = "text/css" >
2020-04-30 22:36:38 +00:00
< link href = "../docs-assets/Progress.css" rel = "stylesheet" rev = "stylesheet" type = "text/css" >
2020-04-25 10:33:39 +00:00
< link href = "../docs-assets/Navigation.css" rel = "stylesheet" rev = "stylesheet" type = "text/css" >
< link href = "../docs-assets/Fonts.css" rel = "stylesheet" rev = "stylesheet" type = "text/css" >
2020-04-20 22:26:08 +00:00
< link href = "../docs-assets/Base.css" rel = "stylesheet" rev = "stylesheet" type = "text/css" >
< script >
MathJax = {
2020-04-21 23:52:25 +00:00
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
2020-04-20 22:26:08 +00:00
};
< / script >
< script type = "text/javascript" id = "MathJax-script" async
2020-04-21 23:52:25 +00:00
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
2020-04-20 22:26:08 +00:00
< / script >
2020-04-21 16:55:17 +00:00
< link href = "../docs-assets/Colours.css" rel = "stylesheet" rev = "stylesheet" type = "text/css" >
2020-04-23 22:23:44 +00:00
2020-04-15 22:45:08 +00:00
< / head >
2020-04-25 10:33:39 +00:00
< body class = "commentary-font" >
2020-04-15 22:45:08 +00:00
< nav role = "navigation" >
< h1 > < a href = "../index.html" >
2020-04-20 22:26:08 +00:00
< img src = "../docs-assets/Octagram.png" width = 72 height = 72" >
2020-04-15 22:45:08 +00:00
< / a > < / h1 >
< ul > < li > < a href = "../inweb/index.html" > inweb< / a > < / li >
< / ul > < h2 > Foundation Module< / h2 > < ul >
< li > < a href = "index.html" > < span class = "selectedlink" > foundation< / span > < / a > < / li >
< li > < a href = "../foundation-test/index.html" > foundation-test< / a > < / li >
< / ul > < h2 > Example Webs< / h2 > < ul >
< li > < a href = "../goldbach/index.html" > goldbach< / a > < / li >
< li > < a href = "../twinprimes/twinprimes.html" > twinprimes< / a > < / li >
< li > < a href = "../eastertide/index.html" > eastertide< / a > < / li >
< / ul > < h2 > Repository< / h2 > < ul >
2020-04-20 22:34:44 +00:00
< li > < a href = "https://github.com/ganelson/inweb" > < img src = "../docs-assets/github.png" height = 18 > github< / a > < / li >
2020-04-15 22:45:08 +00:00
< / ul > < h2 > Related Projects< / h2 > < ul >
< li > < a href = "../../../inform/docs/index.html" > inform< / a > < / li >
< li > < a href = "../../../intest/docs/index.html" > intest< / a > < / li >
< / ul >
< / nav >
< main role = "main" >
2020-04-23 22:23:44 +00:00
<!-- Weave of 'A Brief Guide to Foundation' generated by Inweb -->
2020-04-30 22:36:38 +00:00
< div class = "breadcrumbs" >
< ul class = "crumbs" > < li > < a href = "../index.html" > Home< / a > < / li > < li > < a href = "index.html" > foundation< / a > < / li > < li > < a href = "index.html#P" > Preliminaries< / a > < / li > < li > < b > A Brief Guide to Foundation< / b > < / li > < / ul > < / div >
< p class = "purpose" > Notes on getting started with the Foundation library.< / p >
2020-04-15 22:45:08 +00:00
2020-04-17 18:18:40 +00:00
< ul class = "toc" > < li > < a href = "P-abgtf.html#SP1" > § 1. Introduction< / a > < / li > < li > < a href = "P-abgtf.html#SP3" > § 3. Truth< / a > < / li > < li > < a href = "P-abgtf.html#SP4" > § 4. Text streams and formatted output< / a > < / li > < li > < a href = "P-abgtf.html#SP10" > § 10. Objects< / a > < / li > < li > < a href = "P-abgtf.html#SP11" > § 11. Methods< / a > < / li > < li > < a href = "P-abgtf.html#SP13" > § 13. Collections< / a > < / li > < li > < a href = "P-abgtf.html#SP15" > § 15. Files and paths< / a > < / li > < li > < a href = "P-abgtf.html#SP19" > § 19. Handling webs< / a > < / li > < li > < a href = "P-abgtf.html#SP20" > § 20. Miscellaneous other features< / a > < / li > < / ul > < hr class = "tocbar" >
2020-04-15 22:45:08 +00:00
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP1" class = "paragraph-anchor" > < / a > < b > § 1. Introduction. < / b > The Foundation module supplies some of the conveniences of more modern
2020-04-15 22:45:08 +00:00
programming languages to ANSI C. It offers the usual stuff of standard
libraries everywhere: memory management, collection classes, filename and file
2022-03-05 21:36:26 +00:00
system access, regular-expression matching and so on, and it does so while
2020-04-15 22:45:08 +00:00
abstracting away differences between operating systems (Windows, Linux,
Unix, MacOS, Android and so on).
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > Almost all functionality is optional and can be ignored if not wanted. With a
2020-04-15 22:45:08 +00:00
few provisos, the code is thread-safe, sturdy and well tested, since it forms
the support code for the Inform programming language's compiler and outlying
tools, including Inweb itself. If you need to write a command-line utility in
ANSI C with no dependencies on other tools or libraries to speak of, you could
2020-04-21 23:52:25 +00:00
do worse. But you certainly don't need it to use < a href = "../inweb/index.html" class = "internal" > inweb< / a > , even if you're
2020-04-15 22:45:08 +00:00
writing in C.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > For a brief example of a command-line utility using some of the commoner
2020-04-21 23:52:25 +00:00
features of Foundation in a simple way, see < a href = "../eastertide/index.html" class = "internal" > eastertide< / a > . Further exercises
can be found in < a href = "../foundation-test/index.html" class = "internal" > foundation-test< / a > .
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP2" class = "paragraph-anchor" > < / a > < b > § 2. < / b > To use < a href = "index.html" class = "internal" > foundation< / a > , a program must at minimum do three things.
2020-04-15 22:45:08 +00:00
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > 1. The Contents section of its web must import Foundation as a module, thus:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "element-syntax" > Import< / span > < span class = "plain-syntax" > :< / span > < span class = "string-syntax" > foundation< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > Import lines appear after the metadata, but before the roster of sections
2020-04-15 22:45:08 +00:00
and chapters.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > 2. The constant < span class = "extract" > < span class = "extract-syntax" > PROGRAM_NAME< / span > < / span > must be defined equal to a C string with a
2020-04-15 22:45:08 +00:00
brief version of the program's name. For example,
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "function-syntax" > @d< / span > < span class = "plain-syntax" > PROGRAM_NAME "declutter"< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > 3. The < span class = "extract" > < span class = "extract-syntax" > main< / span > < / span > function for the client should, as one of its very first acts,
2020-04-22 22:57:09 +00:00
call < span class = "extract" > < span class = "extract-syntax" > Foundation::start()< / span > < / span > , and should similarly, just before it exits, call
< span class = "extract" > < span class = "extract-syntax" > Foundation::end()< / span > < / span > . Any other module used should be started after Foundation
2020-04-15 22:45:08 +00:00
starts, and ended before Foundation ends.
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP3" class = "paragraph-anchor" > < / a > < b > § 3. Truth. < / b > Every large C program starts by defining constants for truth and falsity. So
2020-04-22 22:57:09 +00:00
does Foundation: < span class = "extract" > < span class = "extract-syntax" > TRUE< / span > < / span > , < span class = "extract" > < span class = "extract-syntax" > FALSE< / span > < / span > , and a third state < span class = "extract" > < span class = "extract-syntax" > NOT_APPLICABLE< / span > < / span > .
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP4" class = "paragraph-anchor" > < / a > < b > § 4. Text streams and formatted output. < / b > Perhaps the most useful feature of Foundation is that it provides for
2020-04-15 22:45:08 +00:00
memory-managed strings of Unicode text. These are unified with text files
2020-04-21 23:52:25 +00:00
which are open for output, in a type called < a href = "2-str.html#SP15" class = "internal" > text_stream< / a > . It's expected
2020-04-15 22:45:08 +00:00
that they may be very large indeed, and appending text to or finding the
length of a text in memory runs in \(O(1)\) time.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > A typical function writing to one of these might be:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > void< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > Hypothetical::writer< / span > < span class = "plain-syntax" > (< / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > OUT< / span > < span class = "plain-syntax" > , < / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > authority< / span > < span class = "plain-syntax" > , < / span > < span class = "reserved-syntax" > int< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > N< / span > < span class = "plain-syntax" > ) {< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > WRITE< / span > < span class = "plain-syntax" > (< / span > < span class = "string-syntax" > "According to %S, the square of %d is %d.\n"< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > authority< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > N< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > N< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > N< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > }< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > Here < span class = "extract" > < span class = "extract-syntax" > WRITE< / span > < / span > is a variadic macro rather like < span class = "extract" > < span class = "extract-syntax" > printf< / span > < / span > , and note the use of
2020-04-22 22:57:09 +00:00
the escape < span class = "extract" > < span class = "extract-syntax" > %S< / span > < / span > to write a text stream. It writes formatted output into the
stream < span class = "extract" > < span class = "extract-syntax" > OUT< / span > < / span > , and is actually an abbreviation for this:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > void< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > Hypothetical::writer< / span > < span class = "plain-syntax" > (< / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > OUT< / span > < span class = "plain-syntax" > , < / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > authority< / span > < span class = "plain-syntax" > , < / span > < span class = "reserved-syntax" > int< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > N< / span > < span class = "plain-syntax" > ) {< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > WRITE_TO< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > OUT< / span > < span class = "plain-syntax" > , < / span > < span class = "string-syntax" > "According to %S, the square of %d is %d.\n"< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > authority< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > N< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > N< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > N< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > }< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > The function < span class = "extract" > < span class = "extract-syntax" > Hypothetical::writer< / span > < / span > can write equally to a text file or to a
2020-04-15 22:45:08 +00:00
string, whichever it's given, and doesn't need to worry about memory management
or text encodings.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > The standard output and standard error "files" on Unix-based systems are
2020-04-22 22:57:09 +00:00
referred to as < span class = "extract" > < span class = "extract-syntax" > STDOUT< / span > < / span > and < span class = "extract" > < span class = "extract-syntax" > STDERR< / span > < / span > , both constants of type < span class = "extract" > < span class = "extract-syntax" > text_stream *< / span > < / span >
defined by Foundation. The value < span class = "extract" > < span class = "extract-syntax" > NULL< / span > < / span > , used as a text stream, is valid and
2020-04-15 22:45:08 +00:00
prints as the empty string, while ignoring any content written to it.
2020-04-21 23:52:25 +00:00
All of these capitalised macros are defined in < a href = "2-str.html" class = "internal" > Streams< / a > .
2020-04-15 22:45:08 +00:00
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > < span class = "extract" > < span class = "extract-syntax" > PRINT("...")< / span > < / span > is an abbreviation for < span class = "extract" > < span class = "extract-syntax" > WRITE_TO(STDOUT, "...")< / span > < / span > , and
2020-04-22 22:57:09 +00:00
< span class = "extract" > < span class = "extract-syntax" > LOG("...")< / span > < / span > similarly writes to the log file. (See < a href = "2-dl.html" class = "internal" > Debugging Log< / a > .)
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP5" class = "paragraph-anchor" > < / a > < b > § 5. < / b > If you're using < a href = "../inweb/M-tid.html" class = "internal" > The InC Dialect (in inweb)< / a > , the slight extension to C made
2020-04-15 22:45:08 +00:00
by Inweb, there's a simple notation for constants of this type:
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > error_message< / span > < span class = "plain-syntax" > = < / span > < span class = "identifier-syntax" > I< / span > < span class = "string-syntax" > "quadro-triticale stocks depleted"< / span > < span class = "plain-syntax" > ;< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > The < span class = "extract" > < span class = "extract-syntax" > I< / span > < / span > prefix is meant to imitate the < span class = "extract" > < span class = "extract-syntax" > L< / span > < / span > used in standard C99 for long string
2020-04-21 23:52:25 +00:00
constants. But this is a feature of < a href = "../inweb/index.html" class = "internal" > inweb< / a > rather than of Foundation.
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP6" class = "paragraph-anchor" > < / a > < b > § 6. < / b > Programs doing a lot of parsing need to create and throw away strings all
2020-04-15 22:45:08 +00:00
of the time, so we shouldn't be too casual about memory management for them.
2020-04-21 23:52:25 +00:00
< a href = "4-sm.html#SP2" class = "internal" > Str::new< / a > creates a new empty string; < a href = "4-sm.html#SP3" class = "internal" > Str::duplicate< / a > duplicates an
2020-04-15 22:45:08 +00:00
existing one. But these are permanent creations, and not easy to deallocate
2020-04-21 23:52:25 +00:00
(though calling < a href = "4-sm.html#SP15" class = "internal" > Str::clear< / a > to empty out their text will free any large
2020-04-15 22:45:08 +00:00
amount of memory they might be using). If you want a string just for a
momentary period, do this:
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-06-27 22:03:14 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > TEMPORARY_TEXT< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > alpha< / span > < span class = "plain-syntax" > )< / span >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > WRITE_TO< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > alpha< / span > < span class = "plain-syntax" > , < / span > < span class = "string-syntax" > "This is temporary"< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > ...< / span >
2020-06-27 22:03:14 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > DISCARD_TEXT< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > alpha< / span > < span class = "plain-syntax" > )< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > Between the use of these two macros, < span class = "extract" > < span class = "extract-syntax" > alpha< / span > < / span > is a valid < span class = "extract" > < span class = "extract-syntax" > text_stream *< / span > < / span > ,
2020-04-15 22:45:08 +00:00
and is a string capable of growing to arbitrary size.
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP7" class = "paragraph-anchor" > < / a > < b > § 7. < / b > Foundation provides an elaborate system for providing new string escapes
2020-04-22 22:57:09 +00:00
like < span class = "extract" > < span class = "extract-syntax" > %S< / span > < / span > : see < a href = "2-wal.html" class = "internal" > Writers and Loggers< / a > . A similar system manages a debugging
2020-04-15 22:45:08 +00:00
log, to which it's easy to make "dollar escapes" for pretty-printing internal
2020-04-22 22:57:09 +00:00
data structures: for example, if you've made a structure called < span class = "extract" > < span class = "extract-syntax" > recipe< / span > < / span > , you
could make < span class = "extract" > < span class = "extract-syntax" > $R< / span > < / span > pretty-print one.
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP8" class = "paragraph-anchor" > < / a > < b > § 8. < / b > Foundation also has an extensive library of string-handling routines,
2020-04-15 22:45:08 +00:00
providing the sort of facilities you would expect in a typical scripting
2020-04-21 23:52:25 +00:00
language. See < a href = "4-sm.html" class = "internal" > String Manipulation< / a > and < a href = "4-pm.html" class = "internal" > Pattern Matching< / a > , which can
2020-04-15 22:45:08 +00:00
match text streams against regular expressions, though note that the latter
use an idiosyncratic notation.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > There's also < a href = "4-taa.html" class = "internal" > Tries and Avinues< / a > for rapid character sequence parsing.
2020-04-15 22:45:08 +00:00
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > For slicing, see the < a href = "4-sm.html#SP9" class = "internal" > string_position< / a > type, representing positions for the
2020-04-21 23:52:25 +00:00
benefit of functions like < a href = "4-sm.html#SP26" class = "internal" > Str::substr< / a > .
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP9" class = "paragraph-anchor" > < / a > < b > § 9. < / b > Individual characters are represented in Foundation using the standard
2020-04-22 22:57:09 +00:00
POSIX type < span class = "extract" > < span class = "extract-syntax" > wchar_t< / span > < / span > , which on all modern systems is a very wide integer,
2020-04-15 22:45:08 +00:00
whether or not signed. It's safe to assume it can hold all normal Unicode
2020-04-21 23:52:25 +00:00
code points. See < a href = "4-chr.html" class = "internal" > Characters< / a > for class functions like < a href = "4-chr.html#SP1" class = "internal" > Characters::isdigit< / a > ,
2020-04-15 22:45:08 +00:00
which have been carefully written to work equivalently on either Windows or
Unix-based systems.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > < a href = "4-cst.html" class = "internal" > C Strings< / a > and < a href = "4-ws.html" class = "internal" > Wide Strings< / a > provide bare-minimum facilities for handling
2020-04-22 22:57:09 +00:00
traditional null-terminated < span class = "extract" > < span class = "extract-syntax" > char< / span > < / span > and < span class = "extract" > < span class = "extract-syntax" > wchar_t< / span > < / span > arrays, but don't use these.
2020-04-15 22:45:08 +00:00
Texts are just better.
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP10" class = "paragraph-anchor" > < / a > < b > § 10. Objects. < / b > To a very limited extent, Foundation enables C programs to have "classes",
2020-05-09 12:05:00 +00:00
"objects" and "methods", and it makes use of that ability itself, too. (See
< a href = "2-fc.html" class = "internal" > Foundation Classes< / a > for the list of classes made by < a href = "index.html" class = "internal" > foundation< / a > .) For
example, suppose we are writing a program to store recipes, and we want
something in C which corresponds to objects of the class < span class = "extract" > < span class = "extract-syntax" > recipe< / span > < / span > . We need to
do three things:
2020-04-15 22:45:08 +00:00
< / p >
2020-05-09 12:05:00 +00:00
< p class = "commentary" > 1. Declare an enumerated constant ending < span class = "extract" > < span class = "extract-syntax" > _CLASS< / span > < / span > to represent this type in the
2020-04-15 22:45:08 +00:00
memory manager, and then make a matching use of a macro to define some associated
functions, which we never see or think about. For example:
2020-05-09 12:05:00 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "function-syntax" > @< / span > < span class = "plain-syntax" > Here are my classes...< / span >
2020-04-15 22:45:08 +00:00
2020-05-09 12:05:00 +00:00
< span class = "plain-syntax" > < / span > < span class = "function-syntax" > @e< / span > < span class = "plain-syntax" > recipe_CLASS< / span >
2020-04-15 22:45:08 +00:00
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > =< / span >
2020-05-09 12:05:00 +00:00
< span class = "plain-syntax" > DECLARE_CLASS(recipe)< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > The mention of "individually" is because this is for data structures where
2020-04-15 22:45:08 +00:00
we expect to have relatively few instances. If we expect to have huge numbers
of throwaway instances, we would instead write:
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "function-syntax" > @< / span > < span class = "plain-syntax" > Here are my classes...< / span >
2020-04-15 22:45:08 +00:00
2020-05-09 13:14:45 +00:00
< span class = "plain-syntax" > < / span > < span class = "function-syntax" > @e< / span > < span class = "plain-syntax" > salt_grain_CLASS< / span >
2020-04-15 22:45:08 +00:00
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > =< / span >
2020-05-09 12:05:00 +00:00
< span class = "plain-syntax" > DECLARE_CLASS_ALLOCATED_IN_ARRAYS(salt_grain, 1000)< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > The memory manager then claims these in blocks of 1000. Use this only if it's
2020-05-09 13:14:45 +00:00
actually needed; note that < span class = "extract" > < span class = "extract-syntax" > DESTROY< / span > < / span > cannot be used with objects created
this way.
2020-04-15 22:45:08 +00:00
< / p >
2020-05-09 12:05:00 +00:00
< p class = "commentary" > 2. We have to declare the actual structure, and < span class = "extract" > < span class = "extract-syntax" > typedef< / span > < / span > the name to it. For
2020-04-15 22:45:08 +00:00
example:
2020-05-09 12:05:00 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > typedef< / span > < span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > struct< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > {< / span >
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > struct< / span > < span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > name_of_dish< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > int< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > oven_temperature< / span > < span class = "plain-syntax" > ;< / span >
2020-05-09 12:05:00 +00:00
< span class = "plain-syntax" > < / span > < span class = "constant-syntax" > CLASS_DEFINITION< / span >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > } < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > ;< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-05-09 12:05:00 +00:00
< p class = "commentary" > Here < span class = "extract" > < span class = "extract-syntax" > CLASS_DEFINITION< / span > < / span > is a macro defined in < a href = "2-mmr.html" class = "internal" > Memory< / a > which expands to the
2020-04-15 22:45:08 +00:00
necessary field(s) to keep track of this. We won't use those fields, or ever
think about them.
< / p >
2020-05-09 12:05:00 +00:00
< p class = "commentary" > 3. In fact we've now finished. The macro < span class = "extract" > < span class = "extract-syntax" > CREATE(recipe)< / span > < / span > returns a new
2020-04-22 22:57:09 +00:00
instance, and < span class = "extract" > < span class = "extract-syntax" > DESTROY(R)< / span > < / span > would destroy an existing one, < span class = "extract" > < span class = "extract-syntax" > R< / span > < / span > . Unless manually
2020-04-15 22:45:08 +00:00
destroyed, objects last forever; there is no garbage collection. In practice
the Inform tools suite, for which Foundation was written, almost never destroy
objects.
2020-05-09 12:05:00 +00:00
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > Customarily, though, we wrap the use of < span class = "extract" > < span class = "extract-syntax" > CREATE< / span > < / span > in a constructor function:
2020-04-24 10:26:18 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > Recipes::new< / span > < span class = "plain-syntax" > (< / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > name< / span > < span class = "plain-syntax" > ) {< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > = < / span > < span class = "identifier-syntax" > CREATE< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > -> < / span > < span class = "identifier-syntax" > name_of_dish< / span > < span class = "plain-syntax" > = < / span > < span class = "function-syntax" > Str::duplicate< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > name< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > -> < / span > < span class = "identifier-syntax" > oven_temperature< / span > < span class = "plain-syntax" > = < / span > < span class = "constant-syntax" > 200< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > return< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > }< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > We also often use the convenient < span class = "extract" > < span class = "extract-syntax" > LOOP_OVER< / span > < / span > macro:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > void< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > Recipes::list_all< / span > < span class = "plain-syntax" > (< / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > OUT< / span > < span class = "plain-syntax" > ) {< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > WRITE< / span > < span class = "plain-syntax" > (< / span > < span class = "string-syntax" > "I know about the following recipes:\n"< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > LOOP_OVER< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > )< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > WRITE< / span > < span class = "plain-syntax" > (< / span > < span class = "string-syntax" > "- %S\n"< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > -> < / span > < span class = "identifier-syntax" > name_of_dish< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > }< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-05-09 12:05:00 +00:00
< p class = "commentary" > < span class = "extract" > < span class = "extract-syntax" > LOOP_OVER< / span > < / span > loops through all created < span class = "extract" > < span class = "extract-syntax" > recipe< / span > < / span > instances (which have not been
2020-04-15 22:45:08 +00:00
destroyed).
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > There are a few other facilities, for which see < a href = "2-mmr.html" class = "internal" > Memory< / a > , and also ways to
2020-05-09 12:05:00 +00:00
allocate memory for arrays — see < a href = "2-mmr.html#SP24" class = "internal" > Memory::calloc< / a > and < a href = "2-mmr.html#SP24" class = "internal" > Memory::malloc< / a > .
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP11" class = "paragraph-anchor" > < / a > < b > § 11. Methods. < / b > It's also possible to have method calls on object instances, though the
2020-04-15 22:45:08 +00:00
syntax is not as tidy as it would be in an object-oriented language. To allow
2020-04-22 22:57:09 +00:00
this for < span class = "extract" > < span class = "extract-syntax" > recipe< / span > < / span > , we would have to add another line to the structure:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > typedef< / span > < span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > struct< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > {< / span >
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > struct< / span > < span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > name_of_dish< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > int< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > oven_temperature< / span > < span class = "plain-syntax" > ;< / span >
2020-05-09 12:05:00 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > struct< / span > < span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > method_set< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > methods< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > < / span > < span class = "constant-syntax" > CLASS_DEFINITION< / span >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > } < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > ;< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > and another line to the constructor function:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > -> < / span > < span class = "identifier-syntax" > methods< / span > < span class = "plain-syntax" > = < / span > < span class = "function-syntax" > Methods::new_set< / span > < span class = "plain-syntax" > ();< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > The object < span class = "extract" > < span class = "extract-syntax" > R< / span > < / span > is then ready to receive method calls. Each different call needs
2020-04-22 22:57:09 +00:00
an enumerated constant ending < span class = "extract" > < span class = "extract-syntax" > _MTID< / span > < / span > to identify it, and an indication of the
2020-04-15 22:45:08 +00:00
type of the function call involved:
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "function-syntax" > @< / span > < span class = "plain-syntax" > Here is my "cook the recipe" method call:< / span >
2020-04-15 22:45:08 +00:00
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "function-syntax" > @e< / span > < span class = "plain-syntax" > COOK_MTID< / span >
2020-04-15 22:45:08 +00:00
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > =< / span >
2020-05-09 12:05:00 +00:00
< span class = "plain-syntax" > VOID_METHOD_TYPE(COOK_MTID, recipe *R, int time_in_oven)< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-05-09 12:05:00 +00:00
< p class = "commentary" > It's now possible to call this on any recipe:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-05-09 12:05:00 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > VOID_METHOD_CALL< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > duck_a_l_orange< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > COOK_MTID< / span > < span class = "plain-syntax" > , < / span > < span class = "constant-syntax" > 45< / span > < span class = "plain-syntax" > );< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > What then happens? Nothing at all, unless the recipe instance in question —
2020-04-22 22:57:09 +00:00
here, < span class = "extract" > < span class = "extract-syntax" > duck_a_l_orange< / span > < / span > — has been given a receiver function. Let's revisit
2020-04-15 22:45:08 +00:00
the constructor function for recipes:
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > Recipes::new< / span > < span class = "plain-syntax" > (< / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > name< / span > < span class = "plain-syntax" > ) {< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > = < / span > < span class = "identifier-syntax" > CREATE< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > -> < / span > < span class = "identifier-syntax" > name_of_dish< / span > < span class = "plain-syntax" > = < / span > < span class = "function-syntax" > Str::duplicate< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > name< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > -> < / span > < span class = "identifier-syntax" > oven_temperature< / span > < span class = "plain-syntax" > = < / span > < span class = "constant-syntax" > 200< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > -> < / span > < span class = "identifier-syntax" > methods< / span > < span class = "plain-syntax" > = < / span > < span class = "function-syntax" > Methods::new_set< / span > < span class = "plain-syntax" > ();< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > METHOD_ADD< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > COOK_MTID< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > Recipes::cook< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > return< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > }< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > and now add:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > void< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > Recipes::cook< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > , < / span > < span class = "reserved-syntax" > int< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > time_in_oven< / span > < span class = "plain-syntax" > ) {< / span >
< span class = "plain-syntax" > ...< / span >
< span class = "plain-syntax" > }< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > using the arguments promised in the declaration above. With all this done,
2020-04-15 22:45:08 +00:00
the effect of
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-05-09 12:05:00 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > VOID_METHOD_CALL< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > duck_a_l_orange< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > COOK_MTID< / span > < span class = "plain-syntax" > , < / span > < span class = "constant-syntax" > 45< / span > < span class = "plain-syntax" > );< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > is to call:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > Recipes::cook< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > duck_a_l_orange< / span > < span class = "plain-syntax" > , < / span > < span class = "constant-syntax" > 45< / span > < span class = "plain-syntax" > );< / span >
2020-04-24 10:26:18 +00:00
< / pre >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP12" class = "paragraph-anchor" > < / a > < b > § 12. < / b > In fact it's possible to attach multiple receivers to the same object, in
2020-04-15 22:45:08 +00:00
which case they each run in turn. As a variant on this, methods can also return
2020-04-22 22:57:09 +00:00
their "success". If multiple receivers run, the first to return < span class = "extract" > < span class = "extract-syntax" > TRUE< / span > < / span > has
2020-04-15 22:45:08 +00:00
claimed the right to act, and subsequent receivers aren't consulted.
< / p >
2020-05-09 12:05:00 +00:00
< p class = "commentary" > Such methods must be defined with < span class = "extract" > < span class = "extract-syntax" > INT_METHOD_CALL< / span > < / span > and are rarely needed. See
2020-04-21 23:52:25 +00:00
< a href = "2-mth.html" class = "internal" > Methods< / a > for more.
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP13" class = "paragraph-anchor" > < / a > < b > § 13. Collections. < / b > Foundation provides three sorts of "collection": see < a href = "2-llas.html" class = "internal" > Linked Lists and Stacks< / a > ,
2020-04-21 23:52:25 +00:00
and also < a href = "2-dct.html" class = "internal" > Dictionaries< / a > . These all collect values which are expected to be
2020-04-22 22:57:09 +00:00
pointers: for example, text streams (of type < span class = "extract" > < span class = "extract-syntax" > text_stream *< / span > < / span > ) or objects like
2020-04-15 22:45:08 +00:00
the ones created above. For example,
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > linked_list< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > cookbook< / span > < span class = "plain-syntax" > = < / span > < span class = "identifier-syntax" > NEW_LINKED_LIST< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > );< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > initialises a list as ready to use. It's then accessed by macros:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > lobster_thermidor< / span > < span class = "plain-syntax" > = < / span > < span class = "identifier-syntax" > Recipes::new< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > I< / span > < span class = "string-syntax" > "lobster thermidor"< / span > < span class = "plain-syntax" > , < / span > < span class = "constant-syntax" > 200< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > ADD_TO_LINKED_LIST< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > lobster_thermidor< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > cookbook< / span > < span class = "plain-syntax" > );< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > Similarly:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > LOOP_OVER_LINKED_LIST< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > recipe< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > cookbook< / span > < span class = "plain-syntax" > )< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > PRINT< / span > < span class = "plain-syntax" > (< / span > < span class = "string-syntax" > "I can make %S.\n"< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > R< / span > < span class = "plain-syntax" > -> < / span > < span class = "identifier-syntax" > name_of_dish< / span > < span class = "plain-syntax" > );< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > That's about all you can do with linked lists: they are not nearly so well
2020-04-15 22:45:08 +00:00
worked-through as texts.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > A dictionary is an associative hash which relates key names (which are text
2020-04-15 22:45:08 +00:00
streams) to values (which are usually, but not always, also text streams).
They behave very like hashes in Perl and, as the name suggests, use hashing
2020-04-21 23:52:25 +00:00
to make access rapid. See < a href = "2-dct.html" class = "internal" > Dictionaries< / a > .
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP14" class = "paragraph-anchor" > < / a > < b > § 14. < / b > Foundation also provides for < a href = "2-trs.html#SP1" class = "internal" > heterogeneous_tree< / a > , which is a structure
2020-04-17 18:18:40 +00:00
able to hold a rooted tree in which nodes can be a variety of different
objects, rather than having to be uniform. Functions are provided to
build and verify such trees.
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP15" class = "paragraph-anchor" > < / a > < b > § 15. Files and paths. < / b > Filenames and pathnames are, perhaps controversially, represented by two
2020-04-21 23:52:25 +00:00
different types: < a href = "3-fln.html#SP1" class = "internal" > filename< / a > and < a href = "3-pth.html#SP1" class = "internal" > pathname< / a > . The latter should perhaps
2020-04-15 22:45:08 +00:00
have been called "directoryname", but that ship has sailed.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > Foundation does not have a unified type for URLs, as most modern libraries do.
2020-04-15 22:45:08 +00:00
But there are some advantages to that, in that the type-checker forces us to
be clear which we intend at any given time. Anyway, that vessel is also now
well out to sea.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > These both hold names, not actual files: they are places where files or
2020-04-15 22:45:08 +00:00
directories might be.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > Both tend to refer relative to the current working directory, represented by
2020-04-22 22:57:09 +00:00
the null < span class = "extract" > < span class = "extract-syntax" > pathname< / span > < / span > pointer. < a href = "3-pth.html#SP7" class = "internal" > Pathnames::up< / a > and < a href = "3-pth.html#SP4" class = "internal" > Pathnames::down< / a > go
2020-04-15 22:45:08 +00:00
to parent or subdirectories, respectively. A filename cannot exist without
a pathname; for example,
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > pathname< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > P< / span > < span class = "plain-syntax" > = < / span > < span class = "function-syntax" > Pathnames::down< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > NULL< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > I< / span > < span class = "string-syntax" > "App"< / span > < span class = "plain-syntax" > )< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > P< / span > < span class = "plain-syntax" > = < / span > < span class = "function-syntax" > Pathnames::down< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > P< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > I< / span > < span class = "string-syntax" > "Config"< / span > < span class = "plain-syntax" > )< / span >
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > filename< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > F< / span > < span class = "plain-syntax" > = < / span > < span class = "function-syntax" > Filenames::in< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > P< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > I< / span > < span class = "string-syntax" > "options.txt"< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > PRINT< / span > < span class = "plain-syntax" > (< / span > < span class = "string-syntax" > "I have arrived at %f.\n"< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > F< / span > < span class = "plain-syntax" > );< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > produces, on platforms where < span class = "extract" > < span class = "extract-syntax" > /< / span > < / span > is used as the file system dividing character,
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > I have arrived at App/Config/options.txt.< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > Note the use of the escape < span class = "extract" > < span class = "extract-syntax" > %f< / span > < / span > for printing filenames; there's also < span class = "extract" > < span class = "extract-syntax" > %p< / span > < / span > for
2020-04-15 22:45:08 +00:00
pathnames.
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > See < a href = "3-fln.html" class = "internal" > Filenames< / a > and < a href = "3-pth.html" class = "internal" > Pathnames< / a > for more.
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP16" class = "paragraph-anchor" > < / a > < b > § 16. < / b > If you need to iterate over the contents of a directory in the file system,
2020-04-21 23:52:25 +00:00
see < a href = "3-drc.html" class = "internal" > Directories< / a > . But to create a directory, call < a href = "3-pth.html#SP9" class = "internal" > Pathnames::create_in_file_system< / a > .
For synchronisation, try < a href = "3-pth.html#SP10" class = "internal" > Pathnames::rsync< / a > , but don't expect too much.
2020-04-15 22:45:08 +00:00
< / p >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > See < a href = "3-pth.html" class = "internal" > Pathnames< / a > for how to access the user's home directory, the current
2020-04-15 22:45:08 +00:00
working directory, and the installation directory for a program.
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP17" class = "paragraph-anchor" > < / a > < b > § 17. < / b > < a href = "6-bf.html" class = "internal" > Binary Files< / a > does the tedious work of writing binary data while allowing
2022-03-05 21:36:26 +00:00
for endian-ness; and it can also compute md5 hashes of binary files, which is
useful for testing the correctness of our tools.
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP18" class = "paragraph-anchor" > < / a > < b > § 18. < / b > < a href = "4-tf.html" class = "internal" > Text Files< / a > allows us to read text files. Its most useful function is
2020-04-21 23:52:25 +00:00
< a href = "4-tf.html#SP5" class = "internal" > TextFiles::read< / a > , which opens a file, can print an error if it doesn't
2020-04-15 22:45:08 +00:00
exist, and if it does, then feeds the lines one at a time to an iterator.
2020-04-22 22:57:09 +00:00
For example, if < span class = "extract" > < span class = "extract-syntax" > F< / span > < / span > is a filename, the following reads the file into a
2020-04-15 22:45:08 +00:00
linked list of texts:
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > linked_list< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > Hypothetical::list_from_file< / span > < span class = "plain-syntax" > (< / span > < span class = "reserved-syntax" > filename< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > F< / span > < span class = "plain-syntax" > ) {< / span >
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > linked_list< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > L< / span > < span class = "plain-syntax" > = < / span > < span class = "identifier-syntax" > NEW_LINKED_LIST< / span > < span class = "plain-syntax" > (< / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > < / span > < span class = "function-syntax" > TextFiles::read< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > F< / span > < span class = "plain-syntax" > , < / span > < span class = "constant-syntax" > FALSE< / span > < span class = "plain-syntax" > , < / span > < span class = "string-syntax" > "can't open colony file"< / span > < span class = "plain-syntax" > ,< / span >
< span class = "plain-syntax" > < / span > < span class = "constant-syntax" > TRUE< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > Hypothetical::helper< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > NULL< / span > < span class = "plain-syntax" > , (< / span > < span class = "reserved-syntax" > void< / span > < span class = "plain-syntax" > *) < / span > < span class = "identifier-syntax" > L< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > return< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > L< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > }< / span >
2020-04-20 22:26:08 +00:00
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > void< / span > < span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > Hypothetical::helper< / span > < span class = "plain-syntax" > (< / span > < span class = "reserved-syntax" > text_stream< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > line< / span > < span class = "plain-syntax" > , < / span > < span class = "reserved-syntax" > text_file_position< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > tfp< / span > < span class = "plain-syntax" > , < / span > < span class = "reserved-syntax" > void< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > v_L< / span > < span class = "plain-syntax" > ) {< / span >
< span class = "plain-syntax" > < / span > < span class = "reserved-syntax" > linked_list< / span > < span class = "plain-syntax" > *< / span > < span class = "identifier-syntax" > L< / span > < span class = "plain-syntax" > = (< / span > < span class = "reserved-syntax" > linked_list< / span > < span class = "plain-syntax" > *) < / span > < span class = "identifier-syntax" > v_L< / span > < span class = "plain-syntax" > ;< / span >
< span class = "plain-syntax" > < / span > < span class = "identifier-syntax" > ADD_TO_LINKED_LIST< / span > < span class = "plain-syntax" > (< / span > < span class = "identifier-syntax" > text< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > line< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > L< / span > < span class = "plain-syntax" > );< / span >
< span class = "plain-syntax" > }< / span >
2020-04-15 22:45:08 +00:00
< / pre >
2020-04-24 23:06:02 +00:00
< p class = "commentary" > The < a href = "4-tf.html#SP2" class = "internal" > text_file_position< / a > here keeps track of where we are, and in particular,
2020-04-21 23:52:25 +00:00
functions from < a href = "3-em.html" class = "internal" > Error Messages< / a > can then report errors where they occur:
2020-04-15 22:45:08 +00:00
< / p >
2020-04-25 10:33:39 +00:00
< pre class = "displayed-code all-displayed-code code-font" >
2020-04-21 16:55:17 +00:00
< span class = "plain-syntax" > < / span > < span class = "function-syntax" > Errors::in_text_file< / span > < span class = "plain-syntax" > (< / span > < span class = "string-syntax" > "bad syntax here"< / span > < span class = "plain-syntax" > , < / span > < span class = "identifier-syntax" > tfp< / span > < span class = "plain-syntax" > );< / span >
2020-04-24 10:26:18 +00:00
< / pre >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP19" class = "paragraph-anchor" > < / a > < b > § 19. Handling webs. < / b > Foundation provides routines which can read the metadata of a web, i.e., a
2020-04-21 23:52:25 +00:00
literate program in the < a href = "../inweb/index.html" class = "internal" > inweb< / a > format, from a copy in the file system.
The main function here is < a href = "8-ws.html#SP5" class = "internal" > WebMetadata::get< / a > , which returns a < a href = "8-ws.html#SP2" class = "internal" > web_md< / a >
2020-04-15 22:45:08 +00:00
object. You can then access its bibliographic data using
2020-04-21 23:52:25 +00:00
< a href = "8-bdfw.html#SP6" class = "internal" > Bibliographic::get_datum< / a > , or look at the web MD object directly to see
its modules (instances of < a href = "8-wm.html#SP1" class = "internal" > module< / a > ), chapters (of < a href = "8-ws.html#SP3" class = "internal" > chapter_md< / a > ) and
sections (of < a href = "8-ws.html#SP4" class = "internal" > section_md< / a > ).
2020-04-15 22:45:08 +00:00
< / p >
2020-08-16 17:39:53 +00:00
< p class = "commentary firstcommentary" > < a id = "SP20" class = "paragraph-anchor" > < / a > < b > § 20. Miscellaneous other features. < / b > What else? Well:
2020-04-15 22:45:08 +00:00
< / p >
2020-05-17 22:05:11 +00:00
< ul class = "items" > < li > (a) < a href = "3-tm.html" class = "internal" > Time< / a > for the time of day and the date of Easter (no, really), and
for timing internal program activity using < a href = "3-tm.html#SP6" class = "internal" > Time::start_stopwatch< / a > and
< a href = "3-tm.html#SP7" class = "internal" > Time::stop_stopwatch< / a > ;
2020-04-24 23:06:02 +00:00
< / li > < li > (b) < a href = "3-shl.html" class = "internal" > Shell< / a > for issuing shell commands via the C library's < span class = "extract" > < span class = "extract-syntax" > system< / span > < / span > function,
2020-04-15 22:45:08 +00:00
or its equivalent;
2020-04-24 23:06:02 +00:00
< / li > < li > (c) < a href = "5-htm.html" class = "internal" > HTML< / a > and < a href = "5-ee.html" class = "internal" > Epub Ebooks< / a > for generating web pages and ebooks;
< / li > < li > (d) < a href = "6-id.html" class = "internal" > Image Dimensions< / a > and < a href = "6-sd.html" class = "internal" > Sound Durations< / a > for handling videos and music;
< / li > < li > (e) < a href = "7-vn.html" class = "internal" > Version Numbers< / a > and < a href = "7-vnr.html" class = "internal" > Version Number Ranges< / a > for managing version
2020-04-15 22:45:08 +00:00
numbers of software according to the Semantic Versioning standard.
2020-04-24 23:06:02 +00:00
< / li > < / ul >
2020-04-30 22:36:38 +00:00
< nav role = "progress" > < div class = "progresscontainer" >
2020-05-01 21:51:33 +00:00
< ul class = "progressbar" > < li class = "progressprevoff" > ❮ < / li > < li class = "progresscurrentchapter" > P< / li > < li class = "progresscurrent" > abgtf< / li > < li class = "progresschapter" > < a href = "1-fm.html" > 1< / a > < / li > < li class = "progresschapter" > < a href = "2-dl.html" > 2< / a > < / li > < li class = "progresschapter" > < a href = "3-em.html" > 3< / a > < / li > < li class = "progresschapter" > < a href = "4-chr.html" > 4< / a > < / li > < li class = "progresschapter" > < a href = "5-htm.html" > 5< / a > < / li > < li class = "progresschapter" > < a href = "6-bf.html" > 6< / a > < / li > < li class = "progresschapter" > < a href = "7-vn.html" > 7< / a > < / li > < li class = "progresschapter" > < a href = "8-ws.html" > 8< / a > < / li > < li class = "progressnext" > < a href = "1-fm.html" > ❯ < / a > < / li > < / ul > < / div >
2020-04-30 22:36:38 +00:00
< / nav > <!-- End of weave -->
2020-04-23 22:23:44 +00:00
2020-04-15 22:45:08 +00:00
< / main >
< / body >
< / html >