-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathappendix.html
More file actions
48 lines (42 loc) · 19 KB
/
appendix.html
File metadata and controls
48 lines (42 loc) · 19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>
<html>
<head>
<title>L.B.Stanza</title>
<link type="text/css" rel="stylesheet" href="resources/mainstyle.css">
<link type="text/css" rel="stylesheet" href="resources/documentation.css">
</head>
<body>
<table class="wrap">
<tr><td colspan="3" class="banner">
<a href="index.html">Home</a><a href="stanzabyexample.html">Table of Contents</a><a href="chapter11.html">Previous Chapter</a>
</td></tr>
<tr>
<td class="nav">
<h1>NAVIGATION</h1>
<h2><a href="#anchor399">Appendix</a></h2><h3><a href="#anchor114">Stanza Compiler Options</a></h3><h4><a href="#anchor400">.stanza Configuration File</a></h4><h4><a href="#anchor401">Basic Compilation</a></h4><h4><a href="#anchor402">Optimization</a></h4><h4><a href="#anchor403">Generating Assembly Files</a></h4><h4><a href="#anchor404">Pkg Files</a></h4><h4><a href="#anchor405">Automatic Pkg Loading</a></h4><h4><a href="#anchor406">C Compiler Options</a></h4><h4><a href="#anchor407">Target Platform Settings</a></h4><h3><a href="#anchor115">The When Expression</a></h3><h4><a href="#anchor408">Optional Else Branch</a></h4><h3><a href="#anchor116">The Where Expression</a></h3><h3><a href="#anchor117">The Switch Expression</a></h3><h3><a href="#anchor118">More on Visibility</a></h3><h4><a href="#anchor409">Package Qualified Identifiers</a></h4><h4><a href="#anchor410">Top Level Identifiers</a></h4><h4><a href="#anchor411">Protected Visibility</a></h4><h3><a href="#anchor119">Macro Plugins</a></h3><h4><a href="#anchor412">Including macro plugins directly</a></h4><h4><a href="#anchor413">Including macro plugins via a .proj file</a></h4>
</td>
<td class="main">
<h1 id="anchor399">Appendix</h1><p>Stanza has a number of convenience constructs that make your life easier, but they are not necessary for day to day programming. You may skim through this appendix and learn about these constructs as their need arises.</p><h2 id="anchor114">Stanza Compiler Options</h2><p></p><h3 id="anchor400">.stanza Configuration File</h3><p>Stanza's platform and compiler settings are stored in the <code>.stanza</code> file that was created when you installed Stanza with <code>stanza install</code>. When you run Stanza it will first look for an appropriate <code>.stanza</code> file. Here are the places that Stanza searches in, in order, for the <code>.stanza</code> file.</p><ol><li>Stanza first looks in the current working directory.
</li><li>If the <code>STANZA_CONFIG</code> environment variable is set, then Stanza looks in that directory.
</li><li>If the <code>HOME</code> environment variable is set, then Stanza looks in that directory.
</li></ol><h3 id="anchor401">Basic Compilation</h3><p>To compile <code>myfile.stanza</code> and generate the binary <code>myprogram</code> use the following command.</p><pre><code>stanza myfile.stanza -o myprogram</code></pre><h3 id="anchor402">Optimization</h3><p>To compile with optimizations, use the <code>-optimize</code> flag. </p><pre><code>stanza myfile.stanza -o myprogram -optimize</code></pre><p>Be warned that Stanza's optimizer is only designed to handle <span style="font-style:italic;">correct</span> programs. A <span style="font-style:italic;">correct</span> program is defined to be a program that successfully runs to completion without ever failing with a call to <code>fatal</code>. If an unoptimized program runs to completion and generates a result, then the optimized program is guaranteed to run to completion and generate the same result. However, if the unoptimized program fails, then the behaviour of the optimized program is undefined.</p><h3 id="anchor403">Generating Assembly Files</h3><p>By default, Stanza generates a temporary <code>.asm</code> file containing the generated assembly instructions and then links it with GCC. To use a specific name for the <code>.asm</code> file use the <code>-s</code> flag.</p><pre><code>stanza myfile.stanza -s myprogram.s -o myprogram</code></pre><p>The above command will generate the assembly file <code>myprogram.s</code> and link it to produce the binary file <code>myprogram</code>.</p><p>For expert users that only want the assembly file, the <code>-o</code> flag may be omitted. The following command only generates the assembly file <code>myprograms.s</code>.</p><pre><code>stanza myfile.stanza -s myprogram.s</code></pre><h3 id="anchor404">Pkg Files</h3><p>Stanza's separate compilation system allows for packages to be compiled into <code>.pkg</code> files. The following command compiles each package in <code>myfile.stanza</code> to a separate <code>.pkg</code> file.</p><pre><code>stanza myfile.stanza -pkg</code></pre><p>By default, the resultant <code>.pkg</code> files are generated in the current working directory. To specify the folder into which they should be generated, provide the path after the <code>-pkg</code> flag. The following command puts the resultant <code>.pkg</code> files in the <code>mypkgs</code> folder.</p><pre><code>stanza myfile.stanza -pkg mypkgs</code></pre><p>Note that the current compiler requires for source files containing mutually dependent packages to be compiled together. For example, if <code>myfile1.stanza</code> contains </p><pre><code>defpackage mypackage1 :<br> import mypackage2<br>... </code></pre><p>and <code>myfile2.stanza</code> contains</p><pre><code>defpackage mypackage2 :<br> import mypackage1<br>...</code></pre><p>then <code>myfile1.stanza</code> and <code>myfile2.stanza</code> must be compiled together with the following command.</p><pre><code>stanza myfile1.stanza myfile2.stanza -pkg</code></pre><h3 id="anchor405">Automatic Pkg Loading</h3><p>When you compile a program, Stanza automatically looks for the <code>.pkg</code> files containing the definitions of the packages that you import. Here is the order in which Stanza looks for appropriate <code>.pkg</code> files.</p><ol><li>If you've provided a path using the <code>-pkg-path</code> flag, then Stanza will first look there for <code>.pkg</code> files. For example, the following command compiles <code>myfile.stanza</code> using the <code>.pkg</code> files in the <code>mypkgs</code> folder.
<pre><code>stanza myfile.stanza -pkg-path mypkgs</code></pre>
</li><li>If the <code>-pkg-path</code> flag is not provided, then Stanza will first look in the current working directory for <code>.pkg</code> files.
</li><li>If the <code>-optimize</code> flag is provided, then Stanza will look in the directories specified by the <code>fast-pkg-dirs</code> option in your <code>.stanza</code> configuration file. To add additional directories to the pkg path, add the following to your <code>.stanza</code> file.
<pre><code>fast-pkg-dirs = ("/path/to/myfastpkgs1" "/path/to/myfastpkgs2")</code></pre>
</li><li>If the <code>-optimize</code> flag is provided, then Stanza will look in the <code>fast-pkgs</code> folder in your Stanza installation directory.
</li><li>Stanza will then look in the directories specified by the <code>pkg-dirs</code> option in your <code>.stanza</code> configuration file. To add additional directories to the pkg path, add the following to your <code>.stanza</code> file.
<pre><code>pkg-dirs = ("/path/to/mypkgs1" "/path/to/mypkgs2")</code></pre>
</li><li>Stanza will then look in the <code>pkgs</code> folder in your Stanza installation directory.
</li></ol><h3 id="anchor406">C Compiler Options</h3><p>Stanza provides the <code>-ccfiles</code> flag to include additional files to the call to the C compiler. The following command compiles the <code>myfile.stanza</code> program and links it against the functions contained in <code>supportfunctions.c</code> to produce the <code>myprogram</code> executable.</p><pre><code>stanza myfile.stanza -ccfiles supportfunctions.c -o myprogram</code></pre><p>You may also use the <code>-ccflags</code> flag to include additional flags to the C compiler. The following command compiles the <code>myfile.stanza</code> program and calls the C compiler with the additional <code>-lmylib</code> flag to produce the <code>myprogram</code> executable.</p><pre><code>stanza myfile.stanza -ccflags -lmylib -o myprogram</code></pre><p>Note that to provide multiple flags to the C compiler, the flags must be quoted.</p><pre><code>stanza myfile.stanza -ccflags -lmylib1 -lmylib2 -o myprogram</code></pre><h3 id="anchor407">Target Platform Settings</h3><p>By default, Stanza generates code appropriate for the platform that you specified in the call to <code>stanza install</code>. If you wish to generate code appropriate for a different platform, then you can override the platform using the <code>-platform</code> flag.</p><p>The following generates the assembly file <code>myprogram.s</code> appropriate for the Windows platform.</p><pre><code>stanza myfile.stanza -s myprogram.s -platform windows</code></pre><h2 id="anchor115">The When Expression</h2><p>The <code>when</code> expression provides a convenient syntax for very short if expressions. The following</p><pre><code>val name =<br> if meerkat? : "Timon"<br> else : "Pumbaa"</code></pre><p>assigns the string "Timon" to <code>name</code> if <code>meerkat?</code> is <code>true</code>, otherwise it assigns "Pumbaa". It can be equivalently written as</p><pre><code>val name = "Timon" when meerkat? else "Pumbaa"</code></pre><p>In general, the form</p><pre><code>a when c else b</code></pre><p>is equivalent to the if expression</p><pre><code>if c : a<br>else : b</code></pre><h3 id="anchor408">Optional Else Branch</h3><p>You may also leave off the <code>else</code> branch, in which case</p><pre><code>a when c</code></pre><p>is equivalent to the if expression</p><pre><code>if c : a</code></pre><p>This form is often convenient if you want to call a function only when some condition is <code>true</code>.</p><pre><code>press(button) when action == "press"</code></pre><p>The when expression is another example of a convenience construct implemented as a macro. </p><h2 id="anchor116">The Where Expression</h2><p>The <code>where</code> expression provides a convenient syntax for pulling out short definitions from complicated expressions. The following code</p><pre><code>println("They call me Mr. %_" % [name]) where :<br> val name = "Pig!" when angry? else "Pumbaa."</code></pre><p><span style="font-style:italic;">first</span> defines <code>name</code>, and then prints the message. It is equivalent to</p><pre><code>let :<br> val name = "Pig!" when angry? else "Pumbaa."<br> println("They call me Mr. %_" % [name])</code></pre><p>The where expression is also implemented as a macro. As you can see, Stanza's core library makes heavy use of macros.</p><h2 id="anchor117">The Switch Expression</h2><p>The <code>switch</code> expression provides a convenient syntax for choosing amongst a number of nested <code>if</code> branches. Here is an example of evaluating the first branch for which <code>empty?</code> evaluates to <code>true</code>.</p><pre><code>switch empty? :<br> a : println("List a is empty.")<br> b : println("List b is empty.")<br> head(c) : println("The head of list c is empty.")<br> else : println("Nothing is empty.")</code></pre><p>The above is equivalent to these nested <code>if</code> expressions.</p><pre><code>if empty?(a) :<br> println("List a is empty.")<br>else if empty?(b) :<br> println("List b is empty.")<br>else if empty?(head(c)) :<br> println("The head of list c is empty.")<br>else :<br> println("Nothing is empty.")</code></pre><p>If the <code>else</code> branch is omitted then a default <code>else</code> branch is provided that prints an error and causes the program to fail. </p><p>The <code>switch</code> construct is commonly used with an anonymous function as its predicate. Here is an example of using <code>switch</code> to evaluate different branches depending on the value of <code>x</code>.</p><pre><code>switch {x == _} :<br> 0 : println("Sunday")<br> 1 : println("Monday")<br> 2 : println("Tuesday")<br> 3 : println("Wednesday")<br> 4 : println("Thursday")<br> 5 : println("Friday")<br> 6 : println("Saturday")<br> else : println("Elseday")</code></pre><h2 id="anchor118">More on Visibility</h2><p></p><h3 id="anchor409">Package Qualified Identifiers</h3><p>Suppose our main program makes use of the following definitions from an <code>animals</code> package.</p><pre><code>public defstruct Dog<br>public defstruct Cat<br>public name (x:Dog|Cat) -> String<br>public sound (x:Dog|Cat) -> String</code></pre><p><span style="font-style:italic;">Package-qualified identifiers</span> allow us to reference those definitions without having to import the <code>animals</code> package. Here is a <code>main</code> function written using package-qualified identifiers and without importing <code>animals</code>.</p><pre><code>defpackage animal-main :<br> import core<br><br>defn main () :<br> val d = animals/Dog("Shadow")<br> val c = animals/Cat("Sassy")<br> println("My dog %_ goes %_!" % [animals/name(d), animals/sound(d)])<br> println("My cat %_ goes %_!" % [animals/name(c), animals/sound(c)])</code></pre><p>In general, a package qualified identifier is any identifier that contains the <code>'/'</code> character. The characters after the last occurrence of the <code>'/'</code> form the name of the definition being referenced. The characters before the last occurrence form the name of the package containing the definition being referenced. For example, the following identifier</p><pre><code>stanza/compiler/type/FunctionType</code></pre><p>refers to the <code>FunctionType</code> definition in the <code>stanza/compiler/type</code> package.</p><p>Package-qualified identifiers are mostly used by macro writers. Macros should expand into references to package-qualified identifiers to prevent users from having to explicitly import the runtime libraries that the macros depend upon.</p><h3 id="anchor410">Top Level Identifiers</h3><p>Identifiers whose only occurrence of the <code>'/'</code> character is at the beginning of the identifier are called <span style="font-style:italic;">top-level</span> identifiers. For example, <code>/sound</code> and <code>/name</code> are top-level identifiers. </p><p>Top level identifiers are used to refer to a definition that is visible from the top most scope in the current package. It is used to refer to a top-level definition when its actual name has been shadowed by a local definition.</p><p>For example, the following</p><pre><code>defn main () :<br> val s = "Hello"<br> val length = 42<br> println(length(s))</code></pre><p>fails to compile with the error</p><pre><code>Value length of type Int cannot be called as a function.</code></pre><p>This is because <code>length</code> refers to the value <code>42</code>, <span style="font-style:italic;">not</span> the function that returns the length of a string. We can get around this either by renaming the <code>length</code> value to something else, or by using a top-level identifier to refer to the length function.</p><pre><code>defn main () :<br> val s = "Hello"<br> val length = 42<br> println(/length(s))</code></pre><h3 id="anchor411">Protected Visibility</h3><p>In addition to public and private visibilities, Stanza supports one last visibility setting: the protected visibility. A definition with protected visibility <span style="font-style:italic;">can</span> be referred to from other packages, but they can <span style="font-style:italic;">only</span> be referred to using package-qualified identifiers. </p><p>Suppose we have an <code>animals</code> package containing the following definitions.</p><pre><code>public defstruct Dog<br>public defstruct Cat<br>public name (x:Dog|Cat) -> String<br>protected sound (x:Dog|Cat) -> String</code></pre><p>And we will import the <code>animals</code> package into our <code>animals-main</code> package.</p><pre><code>defpackage animals-main :<br> import animals<br><br>defn main () :<br> val d = Dog("Shadow")<br> val c = Cat("Sassy")<br> name(d)<br> animals/sound(c)</code></pre><p>All of the public definitions in <code>animals</code> can be directly referred to in <code>animals-main</code> after they have been imported, <span style="font-style:italic;">but</span> the protected function <code>sound</code> must be package-qualified. </p><p>Protected definitions are most often used by macro writers. Often, a macro simply expands into a decorated call to a helper function. We want to encourage users to use the macro form, and <span style="font-style:italic;">not</span> call the helper function directly. By annotating the macro with the protected visibility we make it unlikely for users to accidentally call the helper function. </p><h2 id="anchor119">Macro Plugins</h2><p>Starting from version <code>0.17.36</code>, Stanza now supports compiling macros into separate plugins that are then dynamically loaded by the compiler as needed.</p><p>The compilation command for creating a macro plugin looks like this:</p><pre><code>stanza compile-macros mymacros.stanza -o mymacros.macros -optimize</code></pre><p>The <code>-optimize</code> flag is optional and should only be used after you have fully debugged and tested your macro implementation.</p><p>Using the macros can then be done in one of two ways:</p><h3 id="anchor412">Including macro plugins directly</h3><p>The <code>-macros</code> flag can be used to include one or more macro plugins. The command looks like this:</p><pre><code>stanza myprogram.stanza -o myprogram -macros mymacros.macros</code></pre><p>The <code>-macros</code> flag is general and can be used for a number of different commands, such as <code>compile</code>, <code>build</code>, <code>extend</code>, <code>compile-macros</code>, <code>compile-test</code>, <code>repl</code>, <code>run</code>, <code>run-test</code>, <code>definitions-database</code>.</p><h3 id="anchor413">Including macro plugins via a .proj file</h3><p>Alternatively, you can add the following lines in a <code>.proj</code> file:</p><pre><code>syntax-packages (mysyntax) defined-in "mymacros.macros"</code></pre><p>And this will instruct Stanza to automatically load <code>mymacros.macros</code> whenever it sees the following directive:</p><pre><code>#use-added-syntax(mysyntax)</code></pre>
</td>
<td class="rest">
<img url="resources/spacer.gif"></img>
</td>
</tr>
<tr><td colspan="3" class="footer">
Site design by Luca Li. Copyright 2015.
</td></tr>
</table>
</body>
</html>