https://github.com/melsman/apltail
APL Compiler targeting a typed array intermediate language
https://github.com/melsman/apltail
apl smlpkg
Last synced: 4 months ago
JSON representation
APL Compiler targeting a typed array intermediate language
- Host: GitHub
- URL: https://github.com/melsman/apltail
- Owner: melsman
- License: mit
- Created: 2014-10-20T22:46:05.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2024-09-02T09:16:25.000Z (almost 2 years ago)
- Last Synced: 2025-03-26T18:54:58.160Z (about 1 year ago)
- Topics: apl, smlpkg
- Language: Standard ML
- Homepage:
- Size: 592 KB
- Stars: 211
- Watchers: 15
- Forks: 9
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## apltail [](https://github.com/melsman/apltail/actions)
An APL Compiler based on a Typed Array Intermediate Language.
This software implements an APL compiler. The compiler is
based on a [typed array intermediate language](http://elsman.com/pdf/array14_final.pdf) [1]. The
executable also contains an interpreter for TAIL and a compiler from
TAIL into C.
See the [coverage page](doc/coverage.md) for information about what APL
functionality is supported.
See also [the compilation scheme](doc/comp.md) if you are curious about how the
compilation works.
## An example
Consider the following program:
```apl
f ← {5+⍵} ⍝ Function adding 5 to its argument (⍵)
+/ f ⍳ 30 ⍝ Apply f to the vector 1..30 and
⍝ sum up the elements in the resulting vector
```
Here is what happens when the program is compiled and executed:
bash-3.2$ ./aplt -p_tail lib/prelude.apl tests/test.apl
[Reading file: lib/prelude.apl]
[Reading file: tests/test.apl]
Resulting program:
let v0:30 = iotaV(30) in
i2d(reduce(addi,0,eachV(fn v1:[int]0 => addi(5,v1),v0)))
Evaluating
Result is [](615.0)
## Another example
Consider the program
```apl
diff ← {1↓⍵−¯1⌽⍵}
signal ← {¯50⌈50⌊50×(diff 0,⍵)÷0.01+⍵}
+/ signal ⍳ 100
```
Here is the result of compiling and evaluating it:
bash-3.2$ ./aplt -p_tail lib/prelude.apl tests/signal.apl
[Reading file: lib/prelude.apl]
[Reading file: tests/signal.apl]
Resulting program:
let v0:100 = iotaV(100) in
let v3:101 = consV(0,v0) in
reduce(addd,0.00,each(fn v11:[double]0 => maxd(~50.00,v11),each(fn v10:[double]0 => mind(50.00,v10),each(fn v9:[double]0 => muld(50.00,v9),zipWith(divd,each(i2d,drop(1,zipWith(subi,v3,rotateV(~1,v3)))),eachV(fn v2:[double]0 => addd(0.01,v2),eachV(i2d,v0)))))))
Evaluating
Result is [](258.557340366)
## Example demonstrating transpose and a double-reduce
Consider the following APL program:
```apl
a ← 3 2 ⍴ ⍳ 5
a2 ← 3 2 ⍴ ⍳ 4
b ← ⍉ a
c ← b, ⍉ a2
×/ +/ c
⍝ 1 2 1 3 5 1 3 1 -+-> 14
⍝ 3 4 2 4 1 2 4 2 -+-> 15
⍝ 5 1
⍝ ---
⍝ 210
```
Here is the result of compiling and evaluating it:
bash-3.2$ ./aplt -p_tail lib/prelude.apl tests/test15.apl
[Reading file: lib/prelude.apl]
[Reading file: tests/test15.apl]
Resulting program:
let v0:[int]2 = reshape([3,2],iotaV(5)) in
let v1:[int]2 = reshape([3,2],iotaV(4)) in
let v2:[int]2 = transp(v0) in
let v3:[int]2 = cat(v2,transp(v1)) in
i2d(reduce(muli,1,reduce(addi,0,v3)))
Evaluating
Result is [](210.0)
## Example demonstrating matrix-multiplication
```apl
a ← 3 2 ⍴ ⍳ 5
b ← ⍉ a
c ← a +.× b
×/ +/ c
⍝ 1 3 5
⍝ 2 4 1
⍝
⍝ 1 2 5 11 7 -+-> 23
⍝ 3 4 11 25 19 -+-> 55
⍝ 5 1 7 19 26 -+-> 52
⍝ 65780
```
Here is the result of compiling and evaluating the example using the
[prelude](/prelude.apl) definition of inner product:
bash-3.2$ ./aplt -p_tail lib/prelude.apl tests/test13.apl
[Reading file: lib/prelude.apl]
[Reading file: tests/test13.apl]
Resulting program:
let v0:[int]2 = reshape([3,2],iotaV(5)) in
let v1:[int]2 = transp(v0) in
let v6:[int]3 = transp2([2,1,3],reshape([3,3,2],v0)) in
let v12:[int]3 = transp2([1,3,2],reshape([3,2,3],v1)) in
let v17:[int]2 = reduce(addi,0,zipWith(muli,v6,v12)) in
i2d(reduce(muli,1,reduce(addi,0,v17)))
Evaluating
Result is [](65780.0)
Without optimizations, the compilation results in a slightly larger output:
bash-3.2$ ./aplt -p_tail -noopt lib/prelude.apl tests/test13.apl
[Reading file: lib/prelude.apl]
[Reading file: tests/test13.apl]
Resulting program:
let v0:[int]2 = reshape([3,2],iotaV(5)) in
let v1:[int]2 = transp(v0) in
let v2:3 = catV(dropV(b2iV(tt),shape(v1)),shape(v0)) in
let v3:[int]0 = subi(firstV(shapeV(shape(v0))),b2iV(tt)) in
let v4:3 = iotaV(firstV(shapeV(v2))) in
let v5:3 = catV(rotateV(v3,dropV(~1,v4)),takeV(~1,v4)) in
let v6:[int]3 = transp2(v5,reshape(v2,v0)) in
let v7:3 = catV(dropV(~1,shape(v0)),shape(v1)) in
let v8:S(int,2) = firstV(shapeV(shape(v0))) in
let v9:3 = iotaV(firstV(shapeV(v7))) in
let v10:1 = dropV(negi(v8),rotateV(v8,iotaV(firstV(shapeV(v9))))) in
let v11:3 = catV(dropV(~1,iotaV(v8)),snocV(v10,v8)) in
let v12:[int]3 = transp2(v11,reshape(v7,v1)) in
let v17:[int]2 = reduce(addi,0,zipWith(muli,v6,v12)) in
i2d(reduce(muli,1,reduce(addi,0,v17)))
Evaluating
Result is [](65780.0)
## Try it!
The software makes use of the [sml-unicode](https://github.com/diku-dk/sml-unicode) library for lexing and
the [sml-aplparse](https://github.com/diku-dk/sml-aplparse) library for
parsing. It also uses various other packages that can be installed with [smlpkg](https://github.com/diku-dk/smlpkg), which itself needs to be available on the system for pulling down the library sources.
You also need a Standard ML compiler (e.g., [Mlton](http://www.mlton.org/) or [MLKit](http://melsman.github.io/mlkit)).
To pull down the dependent libraries and to compile the source, execute the following commands in a shell:
$ make prepare
$ make all
These commands will leave an executable `aplt` in the root directory of the repository.
To run a series of tests, execute `make test` in your shell.
To get `aplt` to output type instantiation list for the polymorphic
functions, such as `reduce`, `each`, and `take`, you may pass the
option `-p_types` to `aplt`.
See also the [coverage page](doc/coverage.md).
To compile with MLKit instead of with MLton, which takes quite some
time, instead of typing `make all` above, type instead `MLCOMP=mlkit make all`.
## License
This software is published under the [MIT License](MIT_LICENSE.md).
## References
[1] Martin Elsman and Martin Dybdal. __Compiling a Subset of APL Into
a Typed Intermediate Language__. In _ACM SIGPLAN International
Workshop on Libraries, Languages and Compilers for Array Programming
(ARRAY'14)_. Edinburgh, UK. June,
2014. [pdf](http://elsman.com/pdf/array14_final.pdf),
[bibtex](http://elsman.com//pdf/array14_final.bibtex.txt).