| 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 |
|---|
| 51 |
$ cp -a Vim/ftdetect Vim/syntax ~/.vim/. |
|---|
| 52 |
If your cp command does not accept the -a option then use -r |
|---|
| 53 |
$ cp -r Vim/ftdetect Vim/syntax ~/.vim/. |
|---|
| 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; |
|---|
| 79 |
for example, if you include the fortify macros in a latex file |
|---|
| 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 |
|
|---|
| 109 |
* J2SDK 1.5 or later. See http://java.sun.com/javase/downloads/index.jsp |
|---|
| 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 |
|
|---|
| 139 |
./ant clean test |
|---|
| 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 |
|
|---|
| 148 |
fortress compile somefile.fs{s,i} |
|---|
| 149 |
fortress [run] [-test] [-debug] somefile.fss arg... |
|---|
| 150 |
fortress help |
|---|
| 151 |
|
|---|
| 152 |
A command of the form "fortress compile somefile.fss" or |
|---|
| 153 |
"fortress compile somefile.fsi" calls the static checker on the given |
|---|
| 154 |
file and stores the result in a hidden "cache" directory. No user-visible |
|---|
| 155 |
object file is generated. (At present, the static checker has limited |
|---|
| 156 |
functionality. Most significantly, static type errors are not yet |
|---|
| 157 |
signaled.) A file with suffix .fsi should contain a single API definition. |
|---|
| 158 |
The name of the API should match the name of the file. Similarly, a file |
|---|
| 159 |
with the suffix .fss should contain a single component definition. The name |
|---|
| 160 |
of the component should match the name of the file. |
|---|
| 161 |
|
|---|
| 162 |
A command of the form "fortress run somefile.fss" checks whether a cached |
|---|
| 163 |
and up to date result of compiling the given file exists. If so, it runs |
|---|
| 164 |
the cached file. Otherwise, it compiles the given file and runs the result. |
|---|
| 165 |
This command can be abbreviated as "fortress somefile.fss". If the optional |
|---|
| 166 |
flag -test is given, all test functions defined in the given file are run. |
|---|
| 167 |
If the optional flag -debug is given, stack traces from the underlying |
|---|
| 168 |
interpreter are displayed when errors are signaled. |
|---|
| 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 |
------------- |
|---|
| 177 |
There exists a .project file in the directory ${FORTRESS_HOME}. |
|---|
| 178 |
Import this project into Eclipse. |
|---|
| 179 |
|
|---|
| 180 |
There exists a file called ${FORTRESS_HOME}/DOTCLASSPATH in |
|---|
| 181 |
the repository. Copy this file to either ${FORTRESS_HOME}/.classpath. |
|---|
| 182 |
If you are using the Java 5.0 jdk under Windows or Linux, you will need |
|---|
| 183 |
to add an entry to ${JAVA_HOME}/lib/tools.jar to the classpath. |
|---|
| 184 |
|
|---|
| 185 |
|
|---|
| 186 |
DEMO PROGRAMS |
|---|
| 187 |
------------- |
|---|
| 188 |
|
|---|
| 189 |
The directory ProjectFortress/demos/ contains some demonstration Fortress |
|---|
| 190 |
programs. Among them are: |
|---|
| 191 |
|
|---|
| 192 |
buffons.fss: Buffon's needle. Estimates pi using a Monte Carlo |
|---|
| 193 |
simulation. |
|---|
| 194 |
|
|---|
| 195 |
lutx.fss: Naive dense LU decomposition. Demonstrates how to define |
|---|
| 196 |
new subclasses of Array2. |
|---|
| 197 |
|
|---|
| 198 |
conjGrad.fss: Conjugate gradient, including the snapshot from the NAS |
|---|
| 199 |
CG benchmark that you've seen in many Fortress talks. Uses the Sparse |
|---|
| 200 |
library for sparse matrices and vectors. |
|---|
| 201 |
|
|---|
| 202 |
sudoku.fss: Solve a simple sudoku by elimination. Includes a |
|---|
| 203 |
tree-based set implementation. |
|---|
| 204 |
|
|---|
| 205 |
aStar.fss: Generic A* search, accompanied by a specific instance for |
|---|
| 206 |
solving sudoku that cannot be solved by elimination alone. |
|---|
| 207 |
|
|---|
| 208 |
Lambda.fss: A simple interpreter for the lambda calculus that permits |
|---|
| 209 |
top-level binding and reduces to both WNHF and NF. If you're curious |
|---|
| 210 |
how to parse text using the Fortress libraries, you should look here |
|---|
| 211 |
(it's presently far more painful than we'd like). |
|---|
| 212 |
|
|---|
| 213 |
|
|---|
| 214 |
TEST PROGRAMS |
|---|
| 215 |
------------- |
|---|
| 216 |
|
|---|
| 217 |
The directory ProjectFortress/tests/ contains some Fortress programs |
|---|
| 218 |
to test the interpreter. Test programs that are supposed to fail |
|---|
| 219 |
(for example, storing a String into a ZZ32-typed mutable) have names |
|---|
| 220 |
that are prefixed with XXX. |
|---|
| 221 |
|
|---|
| 222 |
The directory ProjectFortress/static_tests/ contains some Fortress |
|---|
| 223 |
programs to test the static end. Test programs that are supposed to |
|---|
| 224 |
fail have names that are prefixed with XXX. Test programs that are |
|---|
| 225 |
supposed to pass the static disambiguation then fail have names that |
|---|
| 226 |
are prefixed with DXX. |
|---|
| 227 |
|
|---|
| 228 |
The directory ProjectFortress/parser_tests/ contains some Fortress |
|---|
| 229 |
programs to test the parser. Test programs that are supposed to |
|---|
| 230 |
fail to be parsed have names that are prefixed with XXX. |
|---|
| 231 |
|
|---|
| 232 |
The directory ProjectFortress/not_passing_yet/ contains some Fortress |
|---|
| 233 |
programs that should pass, but do not. For example, if we had a test |
|---|
| 234 |
file containing an error that should be detected, but it isn't, that |
|---|
| 235 |
would be contained in ProjectFortress/not_passing_yet with a name |
|---|
| 236 |
prefixed with XXX. Test programs in this directory should pass |
|---|
| 237 |
the parser. |
|---|
| 238 |
|
|---|
| 239 |
|
|---|
| 240 |
COMPONENTS |
|---|
| 241 |
---------- |
|---|
| 242 |
|
|---|
| 243 |
Fortress currently lacks a full-blown component system. All the code |
|---|
| 244 |
in your Fortress program should reside in API and component file pairs. |
|---|
| 245 |
If you take a look at the Fortress programs in ProjectFortress/tests/, |
|---|
| 246 |
ProjectFortress/demos/, or SpecData/examples, you'll see that they have |
|---|
| 247 |
the same overall structure: |
|---|
| 248 |
|
|---|
| 249 |
|
|---|
| 250 |
component MyComponent |
|---|
| 251 |
exports Executable |
|---|
| 252 |
|
|---|
| 253 |
... Your program here ... |
|---|
| 254 |
|
|---|
| 255 |
run(args:String...):() = ... |
|---|
| 256 |
|
|---|
| 257 |
end |
|---|
| 258 |
|
|---|
| 259 |
|
|---|
| 260 |
LANGUAGE FEATURES THAT ARE IMPLEMENTED |
|---|
| 261 |
-------------------------------------- |
|---|
| 262 |
|
|---|
| 263 |
* Object and trait declarations, including polymorphic traits. |
|---|
| 264 |
Constructor invocations must *always* provide the static arguments |
|---|
| 265 |
explicitly. |
|---|
| 266 |
|
|---|
| 267 |
* Overloaded functions and ordinary methods. Top-level overloaded |
|---|
| 268 |
functions can be polymorphic. Nested functions and methods must be |
|---|
| 269 |
monomorphic. |
|---|
| 270 |
|
|---|
| 271 |
* Polymorphic top-level functions and methods, so long as the methods |
|---|
| 272 |
are not overloaded. |
|---|
| 273 |
|
|---|
| 274 |
* Checking and inference of argument types to functions, methods, and |
|---|
| 275 |
operators. These checks use the dynamic types of the arguments. |
|---|
| 276 |
Return types are NOT checked. Inference of static parameters is not |
|---|
| 277 |
complete yet; it is often necessary to provide static arguments |
|---|
| 278 |
explicitly. It is *always* necessary to do so in a constructor call |
|---|
| 279 |
and in any situation where a static parameter occurs only in the result |
|---|
| 280 |
and not in the arguments to a function. For example, you must always |
|---|
| 281 |
provide the array element type E and size n when invoking the |
|---|
| 282 |
factory array1[\E,n\](). |
|---|
| 283 |
|
|---|
| 284 |
* Arrays of up to three dimensions. Note that there isn't yet a |
|---|
| 285 |
single overarching Array type. For more details on the array types |
|---|
| 286 |
and operations defined see below. In particular, note that array |
|---|
| 287 |
comprehensions are not yet implemented; the array types provide |
|---|
| 288 |
functions to work around this lack. Another caveat: due to a bug we |
|---|
| 289 |
haven't fully understood, some (but not all) uses of the compact |
|---|
| 290 |
notation T[n,m] for an array type cause the interpreter to fail. |
|---|
| 291 |
Desugaring the code by hand to e.g. Array2[\T,0,n,0,m\] works around |
|---|
| 292 |
this bug. |
|---|
| 293 |
|
|---|
| 294 |
* Array aggregates except singleton arrays. |
|---|
| 295 |
|
|---|
| 296 |
* Parallel tupling and argument evaluation. |
|---|
| 297 |
|
|---|
| 298 |
* Parallel for loops over simple ranges such as 0#n. |
|---|
| 299 |
|
|---|
| 300 |
* Sequential for loops over simple ranges. The functional method seq() |
|---|
| 301 |
and the equivalent function sequential() can be used to turn any |
|---|
| 302 |
Generator into a SequentialGenerator. |
|---|
| 303 |
|
|---|
| 304 |
* While loops, typecase, if, etc. Note that for parametric types |
|---|
| 305 |
typecase isn't nearly as useful as you might think, since it cannot |
|---|
| 306 |
bind type variables; we are working to address this shortcoming. |
|---|
| 307 |
|
|---|
| 308 |
* The "atomic" construct uses code based on the DSTM2 library. Nested |
|---|
| 309 |
transactions are flattened. We use their obstruction free algorithm |
|---|
| 310 |
with a simple lowest-thread-wins contention manager. Reduction |
|---|
| 311 |
variables in for loops are not yet implemented, so perform an |
|---|
| 312 |
explicit atomic update or just use a reduction expression instead. |
|---|
| 313 |
|
|---|
| 314 |
* throw and catch expressions. |
|---|
| 315 |
|
|---|
| 316 |
* Generators. |
|---|
| 317 |
|
|---|
| 318 |
* at expressions. |
|---|
| 319 |
|
|---|
| 320 |
* spawn |
|---|
| 321 |
|
|---|
| 322 |
* also (multiple parallel blocks) |
|---|
| 323 |
|
|---|
| 324 |
|
|---|
| 325 |
LANGUAGE FEATURES THAT ARE NOT IMPLEMENTED |
|---|
| 326 |
------------------------------------------ |
|---|
| 327 |
|
|---|
| 328 |
* Numerals with radix specifiers (which implies that some numerals may be |
|---|
| 329 |
recognized as identifiers) |
|---|
| 330 |
|
|---|
| 331 |
* Unicode names |
|---|
| 332 |
|
|---|
| 333 |
* Dimensions and units |
|---|
| 334 |
|
|---|
| 335 |
* Static arguments: nat (using minus), int, bool, dimension, and unit |
|---|
| 336 |
|
|---|
| 337 |
* Modifiers |
|---|
| 338 |
|
|---|
| 339 |
* Keyword arguments |
|---|
| 340 |
|
|---|
| 341 |
* True type inference |
|---|
| 342 |
|
|---|
| 343 |
* Any checking of return types at all |
|---|
| 344 |
|
|---|
| 345 |
* Where clauses |
|---|
| 346 |
|
|---|
| 347 |
* Coercion |
|---|
| 348 |
|
|---|
| 349 |
* Constraint solving for nat parameters |
|---|
| 350 |
|
|---|
| 351 |
* Reduction variables |
|---|
| 352 |
|
|---|
| 353 |
* Distributions |
|---|
| 354 |
|
|---|
| 355 |
* Any of the types which classify operator properties |
|---|
| 356 |
|
|---|
| 357 |
* Any of the bits and storage types |
|---|
| 358 |
|
|---|
| 359 |
* Non-RR64 floats |
|---|
| 360 |
|
|---|
| 361 |
* Integers other than ZZ32 and ZZ64 |
|---|
| 362 |
|
|---|
| 363 |
* Use of ZZ64 for indexing (the JVM uses 32-bit indices) |
|---|
| 364 |
|
|---|
| 365 |
|
|---|
| 366 |
CHANGES SINCE FORTRESS LANGUAGE SPECIFICATION v.1.0 BETA |
|---|
| 367 |
-------------------------------------------------------- |
|---|
| 368 |
|
|---|
| 369 |
* This release of the Fortress language interpreter is the first to be |
|---|
| 370 |
released in tandem with the language specification, available as open source |
|---|
| 371 |
and online at: |
|---|
| 372 |
|
|---|
| 373 |
http://projectfortress.sun.com |
|---|
| 374 |
|
|---|
| 375 |
Each example in the specification is automatically generated from |
|---|
| 376 |
a corresponding working Fortress program which is run by every test run |
|---|
| 377 |
of the interpreter. |
|---|
| 378 |
|
|---|
| 379 |
* To synchronize the specification with the implementation, it was |
|---|
| 380 |
necessary to temporarily drop the following features from the specification: |
|---|
| 381 |
|
|---|
| 382 |
- Static checks (including static overloading checks) |
|---|
| 383 |
- Static type inference |
|---|
| 384 |
- Qualified names (including aliases of imported APIs) |
|---|
| 385 |
- Getters and setters |
|---|
| 386 |
- Array comprehensions |
|---|
| 387 |
- Keyword parameters and keyword expressions |
|---|
| 388 |
- Most modifiers |
|---|
| 389 |
- Dimensions and units |
|---|
| 390 |
- Type aliases |
|---|
| 391 |
- Where clauses |
|---|
| 392 |
- Coercions |
|---|
| 393 |
- Distributions |
|---|
| 394 |
- Parallel nested transactions |
|---|
| 395 |
- Abstract function declarations |
|---|
| 396 |
- Tests and properties |
|---|
| 397 |
- Syntactic abstraction |
|---|
| 398 |
|
|---|
| 399 |
* Libraries have significantly changed. |
|---|
| 400 |
|
|---|
| 401 |
* Syntax and semantics of the following features have changed: |
|---|
| 402 |
- Tuple and functional arguments |
|---|
| 403 |
- Operator rules: associativity, precedence, fixity, and juxtaposition |
|---|
| 404 |
- Operator declaration |
|---|
| 405 |
- Extremum expression |
|---|
| 406 |
- Import statement |
|---|
| 407 |
- Multiple variable declaration |
|---|
| 408 |
- Typecase expression |
|---|
| 409 |
|
|---|
| 410 |
* The following features have been added to the language: |
|---|
| 411 |
- "native" modifier |
|---|
| 412 |
- Operator associativity |
|---|
| 413 |
- Explicit static arguments to big operator applications |
|---|
| 414 |
|
|---|
| 415 |
* The following features have been eliminated from the language: |
|---|
| 416 |
- Identifier parameters |
|---|
| 417 |
- Explicit self parameters of dotted methods |
|---|
| 418 |
- Empty extends clauses |
|---|
| 419 |
- Local operator declarations |
|---|
| 420 |
- Shorthands for Set, List, and Map types |
|---|
| 421 |
- Tuple type encompassing all tuple types |
|---|
| 422 |
|
|---|
| 423 |
* Significantly more examples have been added. |
|---|
| 424 |
|
|---|
| 425 |
|
|---|
| 426 |
THE DEFAULT LIBRARIES |
|---|
| 427 |
--------------------- |
|---|
| 428 |
|
|---|
| 429 |
The components ProjectFortress/LibraryBuiltin/FortressBuiltin.fsi, |
|---|
| 430 |
ProjectFortress/LibraryBiltin/NativeSimpleTypes.fss and |
|---|
| 431 |
Library/FortressLibrary.fss are imported implicitly whenever any |
|---|
| 432 |
Fortress program is run. |
|---|
| 433 |
|
|---|
| 434 |
|
|---|
| 435 |
BUILT-IN TYPES |
|---|
| 436 |
-------------- |
|---|
| 437 |
|
|---|
| 438 |
There are a bunch of types that are defined internally by the Fortress |
|---|
| 439 |
interpreter. With the exception of Any, these cannot be overridden. |
|---|
| 440 |
The built-in types are found in |
|---|
| 441 |
ProjectFortress/LibraryBuiltin/FortressBuiltin.fsi and |
|---|
| 442 |
NativeSimpleTypes.fsi; documentation for the released version of these |
|---|
| 443 |
libraries can be found in the accompanying specification release. |
|---|
| 444 |
Most built-in types do not have any methods. Note that the types |
|---|
| 445 |
found in FortressBuiltin do not have methods. |
|---|
| 446 |
|
|---|
| 447 |
Tuple and arrow types are always built in, and cannot be overridden in |
|---|
| 448 |
any way. |
|---|
| 449 |
|
|---|
| 450 |
Note that there isn't (yet) a trait Object! Eventually user-written |
|---|
| 451 |
trait and object declarations will extend Object by default; right now, |
|---|
| 452 |
they instead extend Any by default. We plan to migrate to a new |
|---|
| 453 |
infrastructure for primitive objects (based on the one used for |
|---|
| 454 |
Boolean in NativeSimpleTypes) at which point we will remedy this |
|---|
| 455 |
situation. |
|---|
| 456 |
|
|---|
| 457 |
Meanwhile, operations on the primitive types in FortressBuiltin can be |
|---|
| 458 |
found in Library/FortressLibrary.fsi; again these primitive are |
|---|
| 459 |
documented in the specification as well. Note in particular that in |
|---|
| 460 |
the absence of coercion, you may occasionally need to make use of widen |
|---|
| 461 |
and narrow to convert between ZZ32 and ZZ64. |
|---|
| 462 |
|
|---|
| 463 |
|
|---|
| 464 |
LIBRARY HIGH POINTS |
|---|
| 465 |
------------------- |
|---|
| 466 |
|
|---|
| 467 |
Your best guide to library functionality is the library code itself; |
|---|
| 468 |
this can be found in Library/ and in ProjectFortress/LibraryBuiltin. |
|---|
| 469 |
The APIs for these libraries can also be found in the language |
|---|
| 470 |
specification (note, though, that if you downloaded the latest version |
|---|
| 471 |
of the Fortress implementation then the two may differ). This section |
|---|
| 472 |
provides an overview of things you may not immediately realize are |
|---|
| 473 |
there. |
|---|
| 474 |
|
|---|
| 475 |
Juxtaposition of strings means string append. You may also |
|---|
| 476 |
find the BIG STRING operation (that concatenates strings) useful. |
|---|
| 477 |
|
|---|
| 478 |
Several functions attempt to convert data of type Any to a string. |
|---|
| 479 |
These include print(), println(), assert(), and juxtaposition of Any |
|---|
| 480 |
with a string. Right now, the FortressBuiltin types are printed using |
|---|
| 481 |
internal magic, and object types are printed using the toString |
|---|
| 482 |
method. The consequence of this is that you will see a runtime error |
|---|
| 483 |
if you attempt to print an object without first defining a toString |
|---|
| 484 |
method. |
|---|
| 485 |
|
|---|
| 486 |
In the absence of array comprehensions, there are several ways to |
|---|
| 487 |
create and initialize an array (in these examples a 1-D array, but the |
|---|
| 488 |
2- and 3-D arrays work the same way): |
|---|
| 489 |
|
|---|
| 490 |
The simplest is to use an aggregate expression (this seems to fail at |
|---|
| 491 |
top level in your program, which is a known bug): |
|---|
| 492 |
z : ZZ32[3] = [1 2 3] |
|---|
| 493 |
|
|---|
| 494 |
If you know the size statically (it is a static parameter to your |
|---|
| 495 |
function, or is fixed at compile time): |
|---|
| 496 |
|
|---|
| 497 |
a : T[size] = array1[\T,size\]() (* lower bound 0 *) |
|---|
| 498 |
a[i] := f(i), i <- a.bounds() |
|---|
| 499 |
|
|---|
| 500 |
or: |
|---|
| 501 |
a : T[size] = array1[\T,size\](initialValue) |
|---|
| 502 |
|
|---|
| 503 |
or: |
|---|
| 504 |
a : T[size] = array1[\T,size\](fn (index:ZZ32) => ...) |
|---|
| 505 |
|
|---|
| 506 |
If you are computing the size at run time: |
|---|
| 507 |
a = array[\T\](size) |
|---|
| 508 |
a[i] := f(i), i <- a.bounds() |
|---|
| 509 |
|
|---|
| 510 |
or: |
|---|
| 511 |
a = array[\T\](size).fill(initialValue) |
|---|
| 512 |
|
|---|
| 513 |
or: |
|---|
| 514 |
a = array[\T\](size).fill(fn (index:ZZ32) => ...) |
|---|
| 515 |
|
|---|
| 516 |
At the moment, to create a non-0-indexed array you need to create a |
|---|
| 517 |
correctly-sized 0-indexed array as described above, then use the |
|---|
| 518 |
shift(newlower) method to shift the lower index. Thus, to create an |
|---|
| 519 |
nxn 1-indexed array you can do something like this: |
|---|
| 520 |
|
|---|
| 521 |
a = array2[\T,n,n\]().shift(1,1) |
|---|
| 522 |
|
|---|
| 523 |
The replicate[\T\]() method on arrays is a little unintuitive at |
|---|
| 524 |
first. It creates a fresh array whose element type is T but whose |
|---|
| 525 |
bounds are the same as the bounds of the array being replicated. When |
|---|
| 526 |
data distribution is fully implemented, it should respect that as well. |
|---|
| 527 |
It is a bit like saying array[\T\](a.bounds().upper()) for 0-indexed |
|---|
| 528 |
arrays but is slightly more graceful and deals well with non-0-indexed |
|---|
| 529 |
arrays. |
|---|
| 530 |
|
|---|
| 531 |
You can convert any array to use 0 indexing simply by indexing it with |
|---|
| 532 |
an empty range: |
|---|
| 533 |
a[:] or a[#] ==> a, only 0-indexed. |
|---|
| 534 |
|
|---|
| 535 |
Any operation that yields a subarray of an underlying array shares |
|---|
| 536 |
structure. If you want a fresh copy of the data, use the copy() method. |
|---|
| 537 |
|
|---|
| 538 |
To assign the contents of array a to array b, you can use: |
|---|
| 539 |
|
|---|
| 540 |
a.assign(b) |
|---|
| 541 |
|
|---|
| 542 |
if a is freshly allocated. The following should work all the time: |
|---|
| 543 |
|
|---|
| 544 |
a[:] := b[:] |
|---|
| 545 |
|
|---|
| 546 |
Right now type-level ranges don't really exist, so if you want to |
|---|
| 547 |
operate on subarrays with statically type-checked bounds, you'll need |
|---|
| 548 |
to work with the subarray method: |
|---|
| 549 |
|
|---|
| 550 |
subarray[\nat b, nat s, nat o\]():Array1[\T, b, s\] |
|---|
| 551 |
|
|---|
| 552 |
This returns a structure-sharing subarray with base b and size s |
|---|
| 553 |
starting from offset o in the current array. |
|---|
| 554 |
|
|---|
| 555 |
The special factory functions vector and matrix are restricted to numeric |
|---|
| 556 |
argument types and static dimensionality: |
|---|
| 557 |
|
|---|
| 558 |
x' : ZZ64[1000] = vector[\ZZ64,1000\](17) |
|---|
| 559 |
|
|---|
| 560 |
At the moment, any Array1 or Array2 whose element type extends Number |
|---|
| 561 |
is considered to be a valid vector or matrix respectively (this will |
|---|
| 562 |
eventually be accomplished by coercion, and vectors will be a distinct |
|---|
| 563 |
type). Note that the t() method on matrices is transposition, and |
|---|
| 564 |
will eventually be replaced by opr ()^T. |
|---|
| 565 |
|
|---|
| 566 |
|
|---|
| 567 |
GENERATORS, REDUCTIONS, and COMPREHENSIONS |
|---|
| 568 |
------------------------------------------ |
|---|
| 569 |
|
|---|
| 570 |
Defining new generators is discussed in detail in the Fortress |
|---|
| 571 |
language specification, but if you're trying it yourself for the first |
|---|
| 572 |
time, you may find it instructive to browse the source code of the libraries. |
|---|
| 573 |
|
|---|
| 574 |
|
|---|
| 575 |
DEFINING NEW PRIMITIVE FUNCTIONS |
|---|
| 576 |
-------------------------------- |
|---|
| 577 |
|
|---|
| 578 |
It is relatively easy to add new primitive functions to Fortress. To |
|---|
| 579 |
do this, you simply invoke the builtinPrimitive function with the name |
|---|
| 580 |
of a loadable Java class which extends glue.NativeApp. Useful |
|---|
| 581 |
subclasses are NativeFn1 and NativeFn2, and any of the classes in |
|---|
| 582 |
glue.prim (particularly the classes in glue.prim.Util). Here's a |
|---|
| 583 |
sample native binding, which defines the floor operator which returns |
|---|
| 584 |
an integer: |
|---|
| 585 |
|
|---|
| 586 |
opr |\a:RR64/|:ZZ64 = builtinPrimitive("glue.prim.Float$IFloor") |
|---|
| 587 |
|
|---|
| 588 |
You should *not* mention the type parameter to builtinPrimitive when |
|---|
| 589 |
invoking it; doing so will confuse the interpreter. Note also that |
|---|
| 590 |
the interpreter requires that you declare appropriate argument and |
|---|
| 591 |
return types for your native functions as shown above. If you give an |
|---|
| 592 |
incorrect type declaration on the Fortress side, you'll get |
|---|
| 593 |
non-user-friendly error messages when the Java code is run. |
|---|
| 594 |
|
|---|
| 595 |
|
|---|
| 596 |
DEFINING NEW PRIMITIVE CLASSES |
|---|
| 597 |
------------------------------ |
|---|
| 598 |
|
|---|
| 599 |
To define a new primitive class, you will need to write a native |
|---|
| 600 |
component. Examples of these can be found in Library; anything that |
|---|
| 601 |
starts with "native component" is a native component. Here's the |
|---|
| 602 |
first few lines of File.fss: |
|---|
| 603 |
|
|---|
| 604 |
native component File |
|---|
| 605 |
import FileSupport.{...} |
|---|
| 606 |
export File |
|---|
| 607 |
|
|---|
| 608 |
language="java" |
|---|
| 609 |
package="com.sun.fortress.interpreter.glue.prim" |
|---|
| 610 |
|
|---|
| 611 |
object FileReadStream(transient filename:String) |
|---|
| 612 |
extends { ReadStream, FileStream} |
|---|
| 613 |
getter fileName():String = |
|---|
| 614 |
builtinPrimitive( |
|---|
| 615 |
"com.sun.fortress.interpreter.glue.prim.FileReadStream$fileName") |
|---|
| 616 |
.... |
|---|
| 617 |
|
|---|
| 618 |
|
|---|
| 619 |
Note that we import a non-native component that defines traits |
|---|
| 620 |
mentioned in the extends clause. The first two bindings must be |
|---|
| 621 |
language and package in that order; right now only language="java" is |
|---|
| 622 |
supported, and the package is where the backing class will be found. |
|---|
| 623 |
In com.sun.fortress.interpreter.glue.prim.FileReadStream defines the |
|---|
| 624 |
corresponding backing data type. Note that FileReadStream extends |
|---|
| 625 |
Constructor, and defines an inner class that extends FOrdinaryObject |
|---|
| 626 |
that represents the actual values that get passed around at run time. |
|---|
| 627 |
|
|---|
| 628 |
The methods must extend NativeMethod, but are otherwise referenced |
|---|
| 629 |
using builtinPrimitive just as for top-level functions. |
|---|
| 630 |
|
|---|
| 631 |
A native class can contain a mix of native and non-native method |
|---|
| 632 |
code. Note, however, that the namespace in which a native object is |
|---|
| 633 |
defined is slightly odd from the perspective of library name |
|---|
| 634 |
visibility. For this reason, some primitive classes extend a parent |
|---|
| 635 |
trait (defined in a non-native component) that contains most of their |
|---|
| 636 |
non-native functionality and that has full access to the libraries. |
|---|
| 637 |
For example, FileStream provides a number of generator definitions |
|---|
| 638 |
that are inherited by FileReadStream. |
|---|