| [1913] | 1 | PROJECT FORTRESS SUBVERSION REPOSITORY
|
|---|
| 2 | --------------------------------------
|
|---|
| 3 |
|
|---|
| 4 | This README exists in the top-level directory of the Fortress project.
|
|---|
| 5 | Information about Fortress can be found at the following web site:
|
|---|
| 6 |
|
|---|
| 7 | http://projectfortress.sun.com
|
|---|
| 8 |
|
|---|
| 9 | If you have Subversion installed, you can check out the Fortress
|
|---|
| 10 | repository by going to the directory in which you want to check it out
|
|---|
| 11 | and issuing the following command:
|
|---|
| 12 |
|
|---|
| 13 | svn checkout https://projectfortress.sun.com/svn/Community/trunk PFC
|
|---|
| 14 |
|
|---|
| 15 | (The name "PFC" merely specifies the name of the directory you want
|
|---|
| 16 | to check the code into. Feel free to substitute another directory
|
|---|
| 17 | name if you prefer.)
|
|---|
| 18 |
|
|---|
| 19 | You'll now have a subdirectory named 'PFC'. Go into that
|
|---|
| 20 | directory and you'll see several subdirectories:
|
|---|
| 21 |
|
|---|
| 22 | Fortify: The Fortify tool for converting Fortress code into LaTeX,
|
|---|
| 23 | both interactively and in batch mode. Scripts are provided for
|
|---|
| 24 | conveniently producing rendered Fortress code in LaTeX documents,
|
|---|
| 25 | for producing PDF "doc" files from Fortress source code, etc. See
|
|---|
| 26 | Fortify/fortify-doc.txt for more information.
|
|---|
| 27 |
|
|---|
| 28 | ProjectFortress: The Fortress interpreter. You'll need to build the
|
|---|
| 29 | interpreter by following the instructions below for setting up your
|
|---|
| 30 | environment in order to have a complete Fortress installation.
|
|---|
| 31 |
|
|---|
| 32 | Emacs: A directory holding the Emacs Lisp file fortress-mode.el,
|
|---|
| 33 | which defines a Fortress mode for Emacs. To use this file, load
|
|---|
| 34 | it from your .emacs file with the following command:
|
|---|
| 35 |
|
|---|
| 36 | (load (concat (getenv "FORTRESS_HOME")
|
|---|
| 37 | "/Emacs/fortress-mode.el"))
|
|---|
| 38 | (push '("\\.fs[si]$" . fortress-mode) auto-mode-alist)
|
|---|
| 39 |
|
|---|
| 40 | If you wish to use the Fortify package to format Fortress source code
|
|---|
| 41 | into LaTeX, you should also add the following to your .emacs (for more
|
|---|
| 42 | information about fortify, see Fortify/fortify-doc.txt):
|
|---|
| 43 |
|
|---|
| 44 | (load (concat (getenv "FORTRESS_HOME")
|
|---|
| 45 | "/Fortify/fortify.el"))
|
|---|
| 46 |
|
|---|
| 47 | Vim: A directory containing vim script files for syntax highlighting.
|
|---|
| 48 | To enable syntax highlighting for fortress code copy the sub-directories
|
|---|
| 49 | under Vim/ to your ~/.vim directory.
|
|---|
| 50 | $ mkdir ~/.vim
|
|---|
| [3322] | 51 | $ cp -a Vim/ftdetect Vim/syntax Vim/ftplugin ~/.vim/.
|
|---|
| [1913] | 52 | If your cp command does not accept the -a option then use -r
|
|---|
| [3322] | 53 | $ cp -r Vim/ftdetect Vim/syntax Vim/ftplugin ~/.vim/.
|
|---|
| [1913] | 54 |
|
|---|
| 55 | You should also add the following line to your ~/.vimrc file
|
|---|
| 56 | au BufNewFile,BufRead *.fsi,*.fss set ft=fortress
|
|---|
| 57 |
|
|---|
| 58 | SpecData: Machine-readable files used by the Fortress Language
|
|---|
| 59 | Specification (e.g., a list of all reserved words). Editors and other
|
|---|
| 60 | tools may also benefit from using these files. Moreover, all examples
|
|---|
| 61 | included in the language specification are included in the directory
|
|---|
| 62 | SpecData/examples.
|
|---|
| 63 |
|
|---|
| 64 | Specification: A directory containing a PDF of the Fortress Language
|
|---|
| 65 | Specification, Version 1.0.
|
|---|
| 66 |
|
|---|
| 67 | Library: The home for all of the Fortress standard libraries.
|
|---|
| 68 |
|
|---|
| 69 | bin: Shell scripts for our various projects. These are bash scripts;
|
|---|
| 70 | you will need an installation of Bash on your system to run them. To
|
|---|
| 71 | make these scripts "auto-homing", script "forfoobar" begins with the
|
|---|
| 72 | line
|
|---|
| 73 | FORTRESS_HOME=`${0%forfoobar}fortress_home`
|
|---|
| 74 | This replaces 'forfoobar' in whatever was used to invoke the script
|
|---|
| 75 | with 'fortress_home', runs that command, and assigns its output to
|
|---|
| 76 | FORTRESS_HOME for the remainder of the scripts. 'fortress_home'
|
|---|
| 77 | determines the location of fortress_home if it is not otherwise
|
|---|
| 78 | specified. This command can also be used in your own build files;
|
|---|
| [3711] | 79 | for example, if you include the fortify macros in a LaTeX file
|
|---|
| [1913] | 80 | \input{$FORTRESS_HOME/Fortify/fortify-macros}
|
|---|
| 81 | you might precede the latex command with
|
|---|
| 82 | FORTRESS_HOME="`fortress_home`"
|
|---|
| 83 | It is also possible to set FORTRESS_HOME in your environment, but
|
|---|
| 84 | if you have multiple versions of Fortress installed this can cause
|
|---|
| 85 | confusion and build problems.
|
|---|
| 86 |
|
|---|
| 87 | You will also see the following files:
|
|---|
| 88 |
|
|---|
| 89 | ant: A small bash script used for invoking the build.xml with
|
|---|
| 90 | specific Ant options. (This script defers to the script with the
|
|---|
| 91 | same name in directory ProjectFortress.)
|
|---|
| 92 |
|
|---|
| 93 | build.xml: The interpreter build script, written in Ant. (This
|
|---|
| 94 | script defers to the script with the same name in the directory
|
|---|
| 95 | ProjectFortress.)
|
|---|
| 96 |
|
|---|
| 97 | fortress.properties: This file defines several environment variables
|
|---|
| 98 | used by the internals of the Fortress interpreter. (Normally, there is
|
|---|
| 99 | no reason to override the settings in this file.)
|
|---|
| 100 |
|
|---|
| 101 |
|
|---|
| 102 | SETTING UP YOUR ENVIRONMENT
|
|---|
| 103 | ---------------------------
|
|---|
| 104 |
|
|---|
| 105 | We assume you are using an operating system with a Unix-style shell
|
|---|
| 106 | (for example, Solaris, Linux, Mac OS X, or Cygwin on Windows). You
|
|---|
| 107 | will need to have access to the following:
|
|---|
| 108 |
|
|---|
| [3373] | 109 | * J2SDK 1.6 or later. See http://java.sun.com/javase/downloads/index.jsp
|
|---|
| [1913] | 110 | * Ant 1.6.5 or later. See http://ant.apache.org/bindownload.cgi
|
|---|
| 111 | * Bash version 2.5 or later, installed at /bin/bash.
|
|---|
| 112 | See http://www.gnu.org/software/bash/
|
|---|
| 113 |
|
|---|
| 114 | Assume FORTRESS_HOME points to the PFC directory you checked out. On
|
|---|
| 115 | Unix-like systems this should be a matter of using export or setenv. If
|
|---|
| 116 | you are using Cygwin, one user reports success with the following
|
|---|
| 117 | command line for setting FORTRESS_HOME:
|
|---|
| 118 | export FORTRESS_HOME=`cygpath -am cygwin/path/to/fortress/install/directory`
|
|---|
| 119 | e.g.:
|
|---|
| 120 | export FORTRESS_HOME=`cygpath -am ${HOME}/tools/fortress`
|
|---|
| 121 |
|
|---|
| 122 |
|
|---|
| 123 | In your shell startup script, add $FORTRESS_HOME/bin to your path.
|
|---|
| 124 | The shell scripts in this directory are Bash scripts. To run them,
|
|---|
| 125 | you must have Bash accessible in /bin/bash.
|
|---|
| 126 |
|
|---|
| 127 | Make sure the following environment variables are set in your startup
|
|---|
| 128 | script:
|
|---|
| 129 |
|
|---|
| 130 | JAVA_HOME
|
|---|
| 131 | ANT_HOME
|
|---|
| 132 |
|
|---|
| 133 | (Although our scripts are sometimes able to guess the locations of
|
|---|
| 134 | JAVA_HOME and ANT_HOME, it is preferred that you set them manually.)
|
|---|
| 135 |
|
|---|
| 136 | Once all of these environment variables are set, build the interpreter
|
|---|
| 137 | by going to the directory FORTRESS_HOME and typing the command:
|
|---|
| 138 |
|
|---|
| [3566] | 139 | ./ant clean compile
|
|---|
| [1913] | 140 |
|
|---|
| 141 | If that doesn't work, there's a bug in the interpreter; please issue a
|
|---|
| 142 | bug report.
|
|---|
| 143 |
|
|---|
| 144 | Once you have built the interpreter, you can call it from any directory,
|
|---|
| 145 | on any Fortress file, simply by typing one of the following commands at a
|
|---|
| 146 | command line:
|
|---|
| 147 |
|
|---|
| [3464] | 148 | fortress [walk] [-test] [-debug interpreter] somefile.fss arg...
|
|---|
| [1913] | 149 | fortress help
|
|---|
| 150 |
|
|---|
| [3386] | 151 | The first time you run a Fortress program, the static checker is
|
|---|
| 152 | called on the given file and the results are stored in a cache
|
|---|
| 153 | directory (by default this cache is kept in default_repository/caches
|
|---|
| 154 | in the root of your Fortress distribution). No user-visible object
|
|---|
| [3711] | 155 | file is generated. A file with suffix .fsi should contain a single API
|
|---|
| [3386] | 156 | definition. The name of the API should match the name of the file.
|
|---|
| 157 | Similarly, a file with the suffix .fss should contain a single
|
|---|
| 158 | component definition. The name of the component should match the name
|
|---|
| 159 | of the file.
|
|---|
| [1913] | 160 |
|
|---|
| [3464] | 161 | A command of the form "fortress walk somefile.fss" checks whether a
|
|---|
| [3386] | 162 | cached and up to date result of compiling the given file exists. If
|
|---|
| 163 | so, it runs the cached file. Otherwise, it processes the given file
|
|---|
| 164 | and runs the result. This command can be abbreviated as "fortress
|
|---|
| 165 | somefile.fss". If the optional flag -test is given, all test
|
|---|
| 166 | functions defined in the given file are run instead. If the optional
|
|---|
| [3464] | 167 | flag "-debug interpreter" is given, stack traces from the underlying
|
|---|
| 168 | interpreter are displayed when errors are signaled.
|
|---|
| [1913] | 169 |
|
|---|
| 170 | If all else fails, look at the script bin/fortress to see if your system
|
|---|
| 171 | has peculiarities (for example cygwin requires ; separators in the
|
|---|
| 172 | classpath).
|
|---|
| 173 |
|
|---|
| 174 |
|
|---|
| 175 | USING ECLIPSE
|
|---|
| 176 | -------------
|
|---|
| [1972] | 177 | There exists a .project file in the directory ${FORTRESS_HOME}.
|
|---|
| 178 | Import this project into Eclipse.
|
|---|
| 179 |
|
|---|
| [2044] | 180 | There exists a file called ${FORTRESS_HOME}/DOTCLASSPATH in
|
|---|
| [2639] | 181 | the repository. Copy this file to ${FORTRESS_HOME}/.classpath.
|
|---|
| [1972] | 182 | If you are using the Java 5.0 jdk under Windows or Linux, you will need
|
|---|
| [1913] | 183 | to add an entry to ${JAVA_HOME}/lib/tools.jar to the classpath.
|
|---|
| 184 |
|
|---|
| [2410] | 185 | Setting up Eclipse to follow the Fortress project coding style
|
|---|
| 186 | conventions is a two-step process. The following instructions are
|
|---|
| 187 | known to work on Eclipse 3.4, and should work on Eclipse 3.3 as well.
|
|---|
| 188 | These will change preferences for all your Eclipse projects.
|
|---|
| [3803] | 189 | Open up Eclipse Preferences to start configuring your global
|
|---|
| [2410] | 190 | settings. First select General --> Editors --> Text Editors
|
|---|
| 191 | and make sure the checkbox is enabled for "Insert spaces for tabs".
|
|---|
| 192 | Second select Java --> Code Style --> Formatter and click on the "Edit..."
|
|---|
| 193 | button. Change the Tab policy to "Spaces only" and give the profile a new
|
|---|
| 194 | name (recommended name: "Spaces only"). Click "OK" and you are finished.
|
|---|
| [1913] | 195 |
|
|---|
| 196 | DEMO PROGRAMS
|
|---|
| 197 | -------------
|
|---|
| 198 |
|
|---|
| 199 | The directory ProjectFortress/demos/ contains some demonstration Fortress
|
|---|
| 200 | programs. Among them are:
|
|---|
| 201 |
|
|---|
| 202 | buffons.fss: Buffon's needle. Estimates pi using a Monte Carlo
|
|---|
| 203 | simulation.
|
|---|
| 204 |
|
|---|
| 205 | lutx.fss: Naive dense LU decomposition. Demonstrates how to define
|
|---|
| 206 | new subclasses of Array2.
|
|---|
| 207 |
|
|---|
| 208 | conjGrad.fss: Conjugate gradient, including the snapshot from the NAS
|
|---|
| 209 | CG benchmark that you've seen in many Fortress talks. Uses the Sparse
|
|---|
| 210 | library for sparse matrices and vectors.
|
|---|
| 211 |
|
|---|
| 212 | sudoku.fss: Solve a simple sudoku by elimination. Includes a
|
|---|
| 213 | tree-based set implementation.
|
|---|
| 214 |
|
|---|
| 215 | aStar.fss: Generic A* search, accompanied by a specific instance for
|
|---|
| 216 | solving sudoku that cannot be solved by elimination alone.
|
|---|
| 217 |
|
|---|
| 218 | Lambda.fss: A simple interpreter for the lambda calculus that permits
|
|---|
| 219 | top-level binding and reduces to both WNHF and NF. If you're curious
|
|---|
| 220 | how to parse text using the Fortress libraries, you should look here
|
|---|
| 221 | (it's presently far more painful than we'd like).
|
|---|
| 222 |
|
|---|
| 223 |
|
|---|
| 224 | TEST PROGRAMS
|
|---|
| 225 | -------------
|
|---|
| 226 |
|
|---|
| 227 | The directory ProjectFortress/tests/ contains some Fortress programs
|
|---|
| 228 | to test the interpreter. Test programs that are supposed to fail
|
|---|
| 229 | (for example, storing a String into a ZZ32-typed mutable) have names
|
|---|
| 230 | that are prefixed with XXX.
|
|---|
| 231 |
|
|---|
| 232 | The directory ProjectFortress/static_tests/ contains some Fortress
|
|---|
| 233 | programs to test the static end. Test programs that are supposed to
|
|---|
| 234 | fail have names that are prefixed with XXX. Test programs that are
|
|---|
| [3711] | 235 | supposed to pass static disambiguation then fail have names that
|
|---|
| [1913] | 236 | are prefixed with DXX.
|
|---|
| 237 |
|
|---|
| [2044] | 238 | The directory ProjectFortress/parser_tests/ contains some Fortress
|
|---|
| 239 | programs to test the parser. Test programs that are supposed to
|
|---|
| 240 | fail to be parsed have names that are prefixed with XXX.
|
|---|
| [1913] | 241 |
|
|---|
| 242 | The directory ProjectFortress/not_passing_yet/ contains some Fortress
|
|---|
| 243 | programs that should pass, but do not. For example, if we had a test
|
|---|
| 244 | file containing an error that should be detected, but it isn't, that
|
|---|
| 245 | would be contained in ProjectFortress/not_passing_yet with a name
|
|---|
| [2044] | 246 | prefixed with XXX. Test programs in this directory should pass
|
|---|
| 247 | the parser.
|
|---|
| [1913] | 248 |
|
|---|
| 249 |
|
|---|
| 250 | COMPONENTS
|
|---|
| 251 | ----------
|
|---|
| 252 |
|
|---|
| 253 | Fortress currently lacks a full-blown component system. All the code
|
|---|
| 254 | in your Fortress program should reside in API and component file pairs.
|
|---|
| 255 | If you take a look at the Fortress programs in ProjectFortress/tests/,
|
|---|
| 256 | ProjectFortress/demos/, or SpecData/examples, you'll see that they have
|
|---|
| 257 | the same overall structure:
|
|---|
| 258 |
|
|---|
| 259 |
|
|---|
| 260 | component MyComponent
|
|---|
| 261 | exports Executable
|
|---|
| 262 |
|
|---|
| 263 | ... Your program here ...
|
|---|
| 264 |
|
|---|
| [3546] | 265 | run():() = ...
|
|---|
| [1913] | 266 |
|
|---|
| 267 | end
|
|---|
| 268 |
|
|---|
| 269 |
|
|---|
| 270 | LANGUAGE FEATURES THAT ARE IMPLEMENTED
|
|---|
| 271 | --------------------------------------
|
|---|
| 272 |
|
|---|
| 273 | * Object and trait declarations, including polymorphic traits.
|
|---|
| 274 | Constructor invocations must *always* provide the static arguments
|
|---|
| 275 | explicitly.
|
|---|
| 276 |
|
|---|
| 277 | * Overloaded functions and ordinary methods. Top-level overloaded
|
|---|
| 278 | functions can be polymorphic. Nested functions and methods must be
|
|---|
| 279 | monomorphic.
|
|---|
| 280 |
|
|---|
| 281 | * Polymorphic top-level functions and methods, so long as the methods
|
|---|
| 282 | are not overloaded.
|
|---|
| 283 |
|
|---|
| 284 | * Checking and inference of argument types to functions, methods, and
|
|---|
| 285 | operators. These checks use the dynamic types of the arguments.
|
|---|
| 286 | Return types are NOT checked. Inference of static parameters is not
|
|---|
| 287 | complete yet; it is often necessary to provide static arguments
|
|---|
| 288 | explicitly. It is *always* necessary to do so in a constructor call
|
|---|
| 289 | and in any situation where a static parameter occurs only in the result
|
|---|
| 290 | and not in the arguments to a function. For example, you must always
|
|---|
| 291 | provide the array element type E and size n when invoking the
|
|---|
| 292 | factory array1[\E,n\]().
|
|---|
| 293 |
|
|---|
| 294 | * Arrays of up to three dimensions. Note that there isn't yet a
|
|---|
| 295 | single overarching Array type. For more details on the array types
|
|---|
| 296 | and operations defined see below. In particular, note that array
|
|---|
| 297 | comprehensions are not yet implemented; the array types provide
|
|---|
| 298 | functions to work around this lack. Another caveat: due to a bug we
|
|---|
| 299 | haven't fully understood, some (but not all) uses of the compact
|
|---|
| 300 | notation T[n,m] for an array type cause the interpreter to fail.
|
|---|
| 301 | Desugaring the code by hand to e.g. Array2[\T,0,n,0,m\] works around
|
|---|
| 302 | this bug.
|
|---|
| 303 |
|
|---|
| 304 | * Array aggregates except singleton arrays.
|
|---|
| 305 |
|
|---|
| 306 | * Parallel tupling and argument evaluation.
|
|---|
| 307 |
|
|---|
| 308 | * Parallel for loops over simple ranges such as 0#n.
|
|---|
| 309 |
|
|---|
| 310 | * Sequential for loops over simple ranges. The functional method seq()
|
|---|
| 311 | and the equivalent function sequential() can be used to turn any
|
|---|
| 312 | Generator into a SequentialGenerator.
|
|---|
| 313 |
|
|---|
| 314 | * While loops, typecase, if, etc. Note that for parametric types
|
|---|
| 315 | typecase isn't nearly as useful as you might think, since it cannot
|
|---|
| 316 | bind type variables; we are working to address this shortcoming.
|
|---|
| 317 |
|
|---|
| 318 | * The "atomic" construct uses code based on the DSTM2 library. Nested
|
|---|
| 319 | transactions are flattened. We use their obstruction free algorithm
|
|---|
| 320 | with a simple lowest-thread-wins contention manager. Reduction
|
|---|
| 321 | variables in for loops are not yet implemented, so perform an
|
|---|
| 322 | explicit atomic update or just use a reduction expression instead.
|
|---|
| 323 |
|
|---|
| 324 | * throw and catch expressions.
|
|---|
| 325 |
|
|---|
| 326 | * Generators.
|
|---|
| 327 |
|
|---|
| 328 | * at expressions.
|
|---|
| 329 |
|
|---|
| 330 | * spawn
|
|---|
| 331 |
|
|---|
| 332 | * also (multiple parallel blocks)
|
|---|
| 333 |
|
|---|
| 334 |
|
|---|
| 335 | LANGUAGE FEATURES THAT ARE NOT IMPLEMENTED
|
|---|
| 336 | ------------------------------------------
|
|---|
| 337 |
|
|---|
| 338 | * Numerals with radix specifiers (which implies that some numerals may be
|
|---|
| 339 | recognized as identifiers)
|
|---|
| 340 |
|
|---|
| 341 | * Unicode names
|
|---|
| 342 |
|
|---|
| 343 | * Dimensions and units
|
|---|
| 344 |
|
|---|
| 345 | * Static arguments: nat (using minus), int, bool, dimension, and unit
|
|---|
| 346 |
|
|---|
| 347 | * Modifiers
|
|---|
| 348 |
|
|---|
| 349 | * Keyword arguments
|
|---|
| 350 |
|
|---|
| 351 | * Where clauses
|
|---|
| 352 |
|
|---|
| 353 | * Coercion
|
|---|
| 354 |
|
|---|
| 355 | * Constraint solving for nat parameters
|
|---|
| 356 |
|
|---|
| 357 | * Reduction variables
|
|---|
| 358 |
|
|---|
| 359 | * Distributions
|
|---|
| 360 |
|
|---|
| 361 | * Any of the types which classify operator properties
|
|---|
| 362 |
|
|---|
| 363 | * Any of the bits and storage types
|
|---|
| 364 |
|
|---|
| 365 | * Non-RR64 floats
|
|---|
| 366 |
|
|---|
| 367 | * Integers other than ZZ32 and ZZ64
|
|---|
| 368 |
|
|---|
| 369 | * Use of ZZ64 for indexing (the JVM uses 32-bit indices)
|
|---|
| 370 |
|
|---|
| 371 |
|
|---|
| 372 | CHANGES SINCE FORTRESS LANGUAGE SPECIFICATION v.1.0 BETA
|
|---|
| 373 | --------------------------------------------------------
|
|---|
| 374 |
|
|---|
| [3711] | 375 | * Fortress 1.0 is the first release of the Fortress language
|
|---|
| 376 | interpreter is the first to be released in tandem with the language
|
|---|
| 377 | specification, available as open source and online at:
|
|---|
| [1913] | 378 |
|
|---|
| 379 | http://projectfortress.sun.com
|
|---|
| 380 |
|
|---|
| 381 | Each example in the specification is automatically generated from
|
|---|
| 382 | a corresponding working Fortress program which is run by every test run
|
|---|
| 383 | of the interpreter.
|
|---|
| 384 |
|
|---|
| 385 | * To synchronize the specification with the implementation, it was
|
|---|
| 386 | necessary to temporarily drop the following features from the specification:
|
|---|
| 387 |
|
|---|
| 388 | - Static checks (including static overloading checks)
|
|---|
| 389 | - Static type inference
|
|---|
| 390 | - Qualified names (including aliases of imported APIs)
|
|---|
| 391 | - Getters and setters
|
|---|
| 392 | - Array comprehensions
|
|---|
| 393 | - Keyword parameters and keyword expressions
|
|---|
| 394 | - Most modifiers
|
|---|
| 395 | - Dimensions and units
|
|---|
| 396 | - Type aliases
|
|---|
| 397 | - Where clauses
|
|---|
| 398 | - Coercions
|
|---|
| 399 | - Distributions
|
|---|
| 400 | - Parallel nested transactions
|
|---|
| 401 | - Abstract function declarations
|
|---|
| 402 | - Tests and properties
|
|---|
| 403 | - Syntactic abstraction
|
|---|
| 404 |
|
|---|
| 405 | * Libraries have significantly changed.
|
|---|
| 406 |
|
|---|
| 407 | * Syntax and semantics of the following features have changed:
|
|---|
| 408 | - Tuple and functional arguments
|
|---|
| 409 | - Operator rules: associativity, precedence, fixity, and juxtaposition
|
|---|
| 410 | - Operator declaration
|
|---|
| 411 | - Extremum expression
|
|---|
| 412 | - Import statement
|
|---|
| 413 | - Multiple variable declaration
|
|---|
| 414 | - Typecase expression
|
|---|
| 415 |
|
|---|
| 416 | * The following features have been added to the language:
|
|---|
| 417 | - "native" modifier
|
|---|
| 418 | - Operator associativity
|
|---|
| 419 | - Explicit static arguments to big operator applications
|
|---|
| 420 |
|
|---|
| 421 | * The following features have been eliminated from the language:
|
|---|
| 422 | - Identifier parameters
|
|---|
| 423 | - Explicit self parameters of dotted methods
|
|---|
| 424 | - Empty extends clauses
|
|---|
| 425 | - Local operator declarations
|
|---|
| 426 | - Shorthands for Set, List, and Map types
|
|---|
| 427 | - Tuple type encompassing all tuple types
|
|---|
| 428 |
|
|---|
| 429 | * Significantly more examples have been added.
|
|---|
| 430 |
|
|---|
| 431 |
|
|---|
| 432 | THE DEFAULT LIBRARIES
|
|---|
| 433 | ---------------------
|
|---|
| 434 |
|
|---|
| 435 | The components ProjectFortress/LibraryBuiltin/FortressBuiltin.fsi,
|
|---|
| 436 | ProjectFortress/LibraryBiltin/NativeSimpleTypes.fss and
|
|---|
| 437 | Library/FortressLibrary.fss are imported implicitly whenever any
|
|---|
| 438 | Fortress program is run.
|
|---|
| 439 |
|
|---|
| 440 |
|
|---|
| 441 | BUILT-IN TYPES
|
|---|
| 442 | --------------
|
|---|
| 443 |
|
|---|
| 444 | There are a bunch of types that are defined internally by the Fortress
|
|---|
| 445 | interpreter. With the exception of Any, these cannot be overridden.
|
|---|
| 446 | The built-in types are found in
|
|---|
| 447 | ProjectFortress/LibraryBuiltin/FortressBuiltin.fsi and
|
|---|
| 448 | NativeSimpleTypes.fsi; documentation for the released version of these
|
|---|
| 449 | libraries can be found in the accompanying specification release.
|
|---|
| 450 | Most built-in types do not have any methods. Note that the types
|
|---|
| 451 | found in FortressBuiltin do not have methods.
|
|---|
| 452 |
|
|---|
| 453 | Tuple and arrow types are always built in, and cannot be overridden in
|
|---|
| 454 | any way.
|
|---|
| 455 |
|
|---|
| 456 | Note that there isn't (yet) a trait Object! Eventually user-written
|
|---|
| 457 | trait and object declarations will extend Object by default; right now,
|
|---|
| 458 | they instead extend Any by default. We plan to migrate to a new
|
|---|
| 459 | infrastructure for primitive objects (based on the one used for
|
|---|
| 460 | Boolean in NativeSimpleTypes) at which point we will remedy this
|
|---|
| 461 | situation.
|
|---|
| 462 |
|
|---|
| 463 | Meanwhile, operations on the primitive types in FortressBuiltin can be
|
|---|
| 464 | found in Library/FortressLibrary.fsi; again these primitive are
|
|---|
| 465 | documented in the specification as well. Note in particular that in
|
|---|
| 466 | the absence of coercion, you may occasionally need to make use of widen
|
|---|
| 467 | and narrow to convert between ZZ32 and ZZ64.
|
|---|
| 468 |
|
|---|
| 469 |
|
|---|
| 470 | LIBRARY HIGH POINTS
|
|---|
| 471 | -------------------
|
|---|
| 472 |
|
|---|
| 473 | Your best guide to library functionality is the library code itself;
|
|---|
| 474 | this can be found in Library/ and in ProjectFortress/LibraryBuiltin.
|
|---|
| 475 | The APIs for these libraries can also be found in the language
|
|---|
| 476 | specification (note, though, that if you downloaded the latest version
|
|---|
| 477 | of the Fortress implementation then the two may differ). This section
|
|---|
| 478 | provides an overview of things you may not immediately realize are
|
|---|
| 479 | there.
|
|---|
| 480 |
|
|---|
| 481 | Juxtaposition of strings means string append. You may also
|
|---|
| 482 | find the BIG STRING operation (that concatenates strings) useful.
|
|---|
| 483 |
|
|---|
| 484 | Several functions attempt to convert data of type Any to a string.
|
|---|
| 485 | These include print(), println(), assert(), and juxtaposition of Any
|
|---|
| 486 | with a string. Right now, the FortressBuiltin types are printed using
|
|---|
| 487 | internal magic, and object types are printed using the toString
|
|---|
| 488 | method. The consequence of this is that you will see a runtime error
|
|---|
| 489 | if you attempt to print an object without first defining a toString
|
|---|
| 490 | method.
|
|---|
| 491 |
|
|---|
| 492 | In the absence of array comprehensions, there are several ways to
|
|---|
| 493 | create and initialize an array (in these examples a 1-D array, but the
|
|---|
| 494 | 2- and 3-D arrays work the same way):
|
|---|
| 495 |
|
|---|
| 496 | The simplest is to use an aggregate expression (this seems to fail at
|
|---|
| 497 | top level in your program, which is a known bug):
|
|---|
| 498 | z : ZZ32[3] = [1 2 3]
|
|---|
| 499 |
|
|---|
| 500 | If you know the size statically (it is a static parameter to your
|
|---|
| 501 | function, or is fixed at compile time):
|
|---|
| 502 |
|
|---|
| 503 | a : T[size] = array1[\T,size\]() (* lower bound 0 *)
|
|---|
| 504 | a[i] := f(i), i <- a.bounds()
|
|---|
| 505 |
|
|---|
| 506 | or:
|
|---|
| 507 | a : T[size] = array1[\T,size\](initialValue)
|
|---|
| 508 |
|
|---|
| 509 | or:
|
|---|
| 510 | a : T[size] = array1[\T,size\](fn (index:ZZ32) => ...)
|
|---|
| 511 |
|
|---|
| 512 | If you are computing the size at run time:
|
|---|
| 513 | a = array[\T\](size)
|
|---|
| 514 | a[i] := f(i), i <- a.bounds()
|
|---|
| 515 |
|
|---|
| 516 | or:
|
|---|
| 517 | a = array[\T\](size).fill(initialValue)
|
|---|
| 518 |
|
|---|
| 519 | or:
|
|---|
| 520 | a = array[\T\](size).fill(fn (index:ZZ32) => ...)
|
|---|
| 521 |
|
|---|
| 522 | At the moment, to create a non-0-indexed array you need to create a
|
|---|
| 523 | correctly-sized 0-indexed array as described above, then use the
|
|---|
| 524 | shift(newlower) method to shift the lower index. Thus, to create an
|
|---|
| 525 | nxn 1-indexed array you can do something like this:
|
|---|
| 526 |
|
|---|
| 527 | a = array2[\T,n,n\]().shift(1,1)
|
|---|
| 528 |
|
|---|
| 529 | The replicate[\T\]() method on arrays is a little unintuitive at
|
|---|
| 530 | first. It creates a fresh array whose element type is T but whose
|
|---|
| 531 | bounds are the same as the bounds of the array being replicated. When
|
|---|
| 532 | data distribution is fully implemented, it should respect that as well.
|
|---|
| 533 | It is a bit like saying array[\T\](a.bounds().upper()) for 0-indexed
|
|---|
| 534 | arrays but is slightly more graceful and deals well with non-0-indexed
|
|---|
| 535 | arrays.
|
|---|
| 536 |
|
|---|
| 537 | You can convert any array to use 0 indexing simply by indexing it with
|
|---|
| 538 | an empty range:
|
|---|
| 539 | a[:] or a[#] ==> a, only 0-indexed.
|
|---|
| 540 |
|
|---|
| 541 | Any operation that yields a subarray of an underlying array shares
|
|---|
| 542 | structure. If you want a fresh copy of the data, use the copy() method.
|
|---|
| 543 |
|
|---|
| 544 | To assign the contents of array a to array b, you can use:
|
|---|
| 545 |
|
|---|
| 546 | a.assign(b)
|
|---|
| 547 |
|
|---|
| 548 | if a is freshly allocated. The following should work all the time:
|
|---|
| 549 |
|
|---|
| 550 | a[:] := b[:]
|
|---|
| 551 |
|
|---|
| 552 | Right now type-level ranges don't really exist, so if you want to
|
|---|
| 553 | operate on subarrays with statically type-checked bounds, you'll need
|
|---|
| 554 | to work with the subarray method:
|
|---|
| 555 |
|
|---|
| 556 | subarray[\nat b, nat s, nat o\]():Array1[\T, b, s\]
|
|---|
| 557 |
|
|---|
| 558 | This returns a structure-sharing subarray with base b and size s
|
|---|
| 559 | starting from offset o in the current array.
|
|---|
| 560 |
|
|---|
| 561 | The special factory functions vector and matrix are restricted to numeric
|
|---|
| 562 | argument types and static dimensionality:
|
|---|
| 563 |
|
|---|
| 564 | x' : ZZ64[1000] = vector[\ZZ64,1000\](17)
|
|---|
| 565 |
|
|---|
| 566 | At the moment, any Array1 or Array2 whose element type extends Number
|
|---|
| 567 | is considered to be a valid vector or matrix respectively (this will
|
|---|
| 568 | eventually be accomplished by coercion, and vectors will be a distinct
|
|---|
| 569 | type). Note that the t() method on matrices is transposition, and
|
|---|
| 570 | will eventually be replaced by opr ()^T.
|
|---|
| 571 |
|
|---|
| 572 |
|
|---|
| 573 | GENERATORS, REDUCTIONS, and COMPREHENSIONS
|
|---|
| 574 | ------------------------------------------
|
|---|
| 575 |
|
|---|
| 576 | Defining new generators is discussed in detail in the Fortress
|
|---|
| 577 | language specification, but if you're trying it yourself for the first
|
|---|
| 578 | time, you may find it instructive to browse the source code of the libraries.
|
|---|
| 579 |
|
|---|
| 580 |
|
|---|
| 581 | DEFINING NEW PRIMITIVE FUNCTIONS
|
|---|
| 582 | --------------------------------
|
|---|
| 583 |
|
|---|
| 584 | It is relatively easy to add new primitive functions to Fortress. To
|
|---|
| 585 | do this, you simply invoke the builtinPrimitive function with the name
|
|---|
| 586 | of a loadable Java class which extends glue.NativeApp. Useful
|
|---|
| 587 | subclasses are NativeFn1 and NativeFn2, and any of the classes in
|
|---|
| 588 | glue.prim (particularly the classes in glue.prim.Util). Here's a
|
|---|
| 589 | sample native binding, which defines the floor operator which returns
|
|---|
| 590 | an integer:
|
|---|
| 591 |
|
|---|
| 592 | opr |\a:RR64/|:ZZ64 = builtinPrimitive("glue.prim.Float$IFloor")
|
|---|
| 593 |
|
|---|
| 594 | You should *not* mention the type parameter to builtinPrimitive when
|
|---|
| 595 | invoking it; doing so will confuse the interpreter. Note also that
|
|---|
| 596 | the interpreter requires that you declare appropriate argument and
|
|---|
| 597 | return types for your native functions as shown above. If you give an
|
|---|
| 598 | incorrect type declaration on the Fortress side, you'll get
|
|---|
| 599 | non-user-friendly error messages when the Java code is run.
|
|---|
| 600 |
|
|---|
| 601 |
|
|---|
| 602 | DEFINING NEW PRIMITIVE CLASSES
|
|---|
| 603 | ------------------------------
|
|---|
| 604 |
|
|---|
| 605 | To define a new primitive class, you will need to write a native
|
|---|
| 606 | component. Examples of these can be found in Library; anything that
|
|---|
| 607 | starts with "native component" is a native component. Here's the
|
|---|
| 608 | first few lines of File.fss:
|
|---|
| 609 |
|
|---|
| 610 | native component File
|
|---|
| 611 | import FileSupport.{...}
|
|---|
| 612 | export File
|
|---|
| 613 |
|
|---|
| [3179] | 614 | private language="java"
|
|---|
| 615 | private package="com.sun.fortress.interpreter.glue.prim"
|
|---|
| [1913] | 616 |
|
|---|
| [2826] | 617 | object FileReadStream(filename:String)
|
|---|
| [1913] | 618 | extends { ReadStream, FileStream}
|
|---|
| 619 | getter fileName():String =
|
|---|
| 620 | builtinPrimitive(
|
|---|
| 621 | "com.sun.fortress.interpreter.glue.prim.FileReadStream$fileName")
|
|---|
| 622 | ....
|
|---|
| 623 |
|
|---|
| 624 |
|
|---|
| 625 | Note that we import a non-native component that defines traits
|
|---|
| 626 | mentioned in the extends clause. The first two bindings must be
|
|---|
| 627 | language and package in that order; right now only language="java" is
|
|---|
| 628 | supported, and the package is where the backing class will be found.
|
|---|
| 629 | In com.sun.fortress.interpreter.glue.prim.FileReadStream defines the
|
|---|
| 630 | corresponding backing data type. Note that FileReadStream extends
|
|---|
| 631 | Constructor, and defines an inner class that extends FOrdinaryObject
|
|---|
| 632 | that represents the actual values that get passed around at run time.
|
|---|
| 633 |
|
|---|
| 634 | The methods must extend NativeMethod, but are otherwise referenced
|
|---|
| 635 | using builtinPrimitive just as for top-level functions.
|
|---|
| 636 |
|
|---|
| 637 | A native class can contain a mix of native and non-native method
|
|---|
| 638 | code. Note, however, that the namespace in which a native object is
|
|---|
| 639 | defined is slightly odd from the perspective of library name
|
|---|
| 640 | visibility. For this reason, some primitive classes extend a parent
|
|---|
| 641 | trait (defined in a non-native component) that contains most of their
|
|---|
| 642 | non-native functionality and that has full access to the libraries.
|
|---|
| 643 | For example, FileStream provides a number of generator definitions
|
|---|
| 644 | that are inherited by FileReadStream.
|
|---|