├── tests ├── c │ └── .gitignore ├── cos.apl ├── ln.apl ├── sign.apl ├── sin.apl ├── bool.apl ├── cos.out.ok ├── first.apl ├── ln.out.ok ├── pi.out.ok ├── rav.out.ok ├── sin.out.ok ├── test14.apl ├── athas.out.ok ├── boolean.out.ok ├── compress.out.ok ├── cons.out.ok ├── first.out.ok ├── fun2.out.ok ├── mean.out.ok ├── mult.out.ok ├── mult0.out.ok ├── opr1.out.ok ├── opr2.out.ok ├── opr3.out.ok ├── primes0.out.ok ├── reduce.out.ok ├── sign.out.ok ├── sort.out.ok ├── test.out.ok ├── test1.apl ├── test1.out.ok ├── test10.out.ok ├── test11.out.ok ├── test12.out.ok ├── test14.out.ok ├── test15.out.ok ├── test19.out.ok ├── test2.out.ok ├── test3.out.ok ├── test4.out.ok ├── test6.out.ok ├── test7.out.ok ├── test9.out.ok ├── timespi.out.ok ├── train.out.ok ├── train0.out.ok ├── vowels.out.ok ├── primes.out.ok ├── replicate.out.ok ├── slashbar.out.ok ├── test13.out.ok ├── test16.out.ok ├── test21.out.ok ├── test24.apl ├── test28.out.ok ├── test5.out.ok ├── bool1.apl ├── powscl.out.ok ├── signal.out.ok ├── train0.apl ├── blackscholes.out.ok ├── innerLegrand5.3.out.ok ├── innerproduct.out.ok ├── sum35.out.ok ├── timespi.apl ├── a1.apl ├── athas.apl ├── powscl.apl ├── residue.out.ok ├── tally.out.ok ├── test17.apl ├── test27.apl ├── test6.apl ├── test7.apl ├── cons.apl ├── squad.out.ok ├── test20.apl ├── test23.apl ├── test3.apl ├── vec.out.ok ├── expd.out.ok ├── reduce.apl ├── test8.apl ├── trainatop.out.ok ├── tup.out.ok ├── a2.apl ├── fib10.out.ok ├── powtup.out.ok ├── primes.apl ├── readfile.txt ├── streak.out.ok ├── anagram.out.ok ├── compose.out.ok ├── opr1.apl ├── eacheaster.out.ok ├── fun2.apl ├── primes2.apl ├── readintvecfile.txt ├── residue.apl ├── vowels.apl ├── format.out.ok ├── opr2.apl ├── fib.apl ├── opr3.apl ├── test28.apl ├── easter.out.ok ├── test22.apl ├── innerproduct.apl ├── replicate.apl ├── signal.apl ├── bench.apl ├── bench1.apl ├── tax.out.ok ├── test16.apl ├── test5.apl ├── gradeupdown.out.ok ├── mean.apl ├── readdoublevecfile.txt ├── test25.apl ├── pi.apl ├── signal1.apl ├── test2.apl ├── vrev.out.ok ├── else.out.ok ├── expd.apl ├── powmat.apl ├── tally.apl ├── transpose.apl ├── boolean.apl ├── ceilfloormaxmin.out.ok ├── test9.apl ├── rotfirst.out.ok ├── format.apl ├── signal2.apl ├── fib10.apl ├── squad.apl ├── test10.apl ├── test12.apl ├── test11.apl ├── trains1.out.ok ├── chars.out.ok ├── shape.out.ok ├── pow.out.ok ├── test18.apl ├── test19.apl ├── transpose.out.ok ├── abcd.out.ok ├── vec.apl ├── test.apl ├── chars.apl ├── pi2.apl ├── readfile.apl ├── compose.apl ├── gradeupdown.apl ├── readfile.out.ok ├── slashbar.apl ├── tax.apl ├── mult.apl ├── compress.apl ├── rav.apl ├── sum35.apl ├── readintvecfile.out.ok ├── else.apl ├── inv3.out.ok ├── mult0.apl ├── powmat.out.ok ├── now.apl ├── test15.apl ├── test29.apl ├── matmul.apl ├── test13.apl ├── test4.apl ├── powtup.apl ├── readintvecfile.apl ├── readdoublevecfile.apl ├── tup.apl ├── circ.out.ok ├── drop.out.ok ├── circ.apl ├── binaryops.out.ok ├── abcd.apl ├── cmplx.apl ├── cosmin.apl ├── shape.apl ├── inv.out.ok ├── sort.apl ├── rot.out.ok ├── vrev.apl ├── readdoublevecfile.out.ok ├── quadassign.apl ├── trainatop.apl ├── test30.apl ├── mandelbrot.out.ok ├── streak.apl ├── idx.out.ok ├── mandelbrotN.out.ok ├── trains1.apl ├── dtransp.out.ok ├── sierpinski.apl ├── idxassign.apl ├── anagram.apl ├── test26.apl ├── zfunc.apl ├── sierpinski0.apl ├── vrot.out.ok ├── inv3.apl ├── take.out.ok ├── zfunc.out.ok ├── quadassign.out.ok ├── mandel.apl ├── inner.apl ├── pow.apl ├── test21.apl ├── ceilfloormaxmin.apl ├── idxassign.out.ok ├── inner2.apl ├── train.apl ├── rotfirst.apl ├── cmplx.out.ok ├── repl.apl ├── inner3.apl ├── life.apl ├── dtransp.apl ├── inner4.apl ├── blackscholes.apl ├── repl.out.ok ├── binaryops.apl ├── eacheaster.apl ├── innerLegrand5.3.apl ├── blacksch.apl ├── matmul2.apl ├── life2.apl ├── easter.apl ├── easter3000.apl ├── idx.apl ├── rot.apl ├── mandel.out.ok ├── primes0.apl ├── drop.apl ├── vrot.apl ├── mandelbrotInnerPower.apl ├── mandelbrotInnerPower2.apl ├── mandelbrotN.apl ├── mandelbrot.apl ├── take.apl ├── sierpinski.out.ok ├── sierpinski0.out.ok ├── inv.apl ├── life.out.ok ├── Makefile └── pricer.apl ├── src ├── .gitignore ├── util.mlb ├── flags.mlb ├── laila │ ├── README.md │ ├── laila.mlb │ └── laila.sig ├── statistics.mlb ├── tail │ ├── apl.mlb │ ├── tail.mlb │ ├── apl.sig │ ├── tail_exp.sig │ ├── tail_type.sig │ ├── tail_type.sml │ └── tail.sig ├── statistics.sig ├── apl2tail.mlb ├── il │ ├── type.sig │ ├── il.mlb │ └── ilutil.sig ├── aplt.mlb ├── sml.pkg ├── Apl2Tail.sig ├── statistics.sml ├── flags.sml ├── flags.sig ├── util.sig ├── util.sml └── aplt.sml ├── .gitignore ├── doc ├── README_BIN ├── comp.md └── coverage.md ├── lib └── prelude.apl ├── MIT_LICENSE.md ├── .github └── workflows │ └── main.yml ├── Makefile ├── README.md └── include └── apl.h /tests/c/.gitignore: -------------------------------------------------------------------------------- 1 | *.c -------------------------------------------------------------------------------- /tests/cos.apl: -------------------------------------------------------------------------------- 1 | 2○0 2 | -------------------------------------------------------------------------------- /tests/ln.apl: -------------------------------------------------------------------------------- 1 | ⍟⋆1 2 | -------------------------------------------------------------------------------- /tests/sign.apl: -------------------------------------------------------------------------------- 1 | ×10 2 | -------------------------------------------------------------------------------- /tests/sin.apl: -------------------------------------------------------------------------------- 1 | 1○0 2 | -------------------------------------------------------------------------------- /tests/bool.apl: -------------------------------------------------------------------------------- 1 | a ← 3 < 4 2 | -------------------------------------------------------------------------------- /tests/cos.out.ok: -------------------------------------------------------------------------------- 1 | [](1.0) 2 | -------------------------------------------------------------------------------- /tests/first.apl: -------------------------------------------------------------------------------- 1 | 2 | ⊃ 1 2 -------------------------------------------------------------------------------- /tests/ln.out.ok: -------------------------------------------------------------------------------- 1 | [](1.0) 2 | -------------------------------------------------------------------------------- /tests/pi.out.ok: -------------------------------------------------------------------------------- 1 | [](1.0) 2 | -------------------------------------------------------------------------------- /tests/rav.out.ok: -------------------------------------------------------------------------------- 1 | [](1.0) 2 | -------------------------------------------------------------------------------- /tests/sin.out.ok: -------------------------------------------------------------------------------- 1 | [](0.0) 2 | -------------------------------------------------------------------------------- /tests/test14.apl: -------------------------------------------------------------------------------- 1 | a ← 7 - 3 -------------------------------------------------------------------------------- /tests/athas.out.ok: -------------------------------------------------------------------------------- 1 | [](50.0) 2 | -------------------------------------------------------------------------------- /tests/boolean.out.ok: -------------------------------------------------------------------------------- 1 | [](2.0) 2 | -------------------------------------------------------------------------------- /tests/compress.out.ok: -------------------------------------------------------------------------------- 1 | [](8.0) 2 | -------------------------------------------------------------------------------- /tests/cons.out.ok: -------------------------------------------------------------------------------- 1 | [](31.0) 2 | -------------------------------------------------------------------------------- /tests/first.out.ok: -------------------------------------------------------------------------------- 1 | [](1.0) 2 | -------------------------------------------------------------------------------- /tests/fun2.out.ok: -------------------------------------------------------------------------------- 1 | [](2.0) 2 | -------------------------------------------------------------------------------- /tests/mean.out.ok: -------------------------------------------------------------------------------- 1 | [](2.5) 2 | -------------------------------------------------------------------------------- /tests/mult.out.ok: -------------------------------------------------------------------------------- 1 | [](3025.0) 2 | -------------------------------------------------------------------------------- /tests/mult0.out.ok: -------------------------------------------------------------------------------- 1 | [](3025.0) 2 | -------------------------------------------------------------------------------- /tests/opr1.out.ok: -------------------------------------------------------------------------------- 1 | [](38.6) 2 | -------------------------------------------------------------------------------- /tests/opr2.out.ok: -------------------------------------------------------------------------------- 1 | [](39.44) 2 | -------------------------------------------------------------------------------- /tests/opr3.out.ok: -------------------------------------------------------------------------------- 1 | [](-19.0) 2 | -------------------------------------------------------------------------------- /tests/primes0.out.ok: -------------------------------------------------------------------------------- 1 | [](4.0) 2 | -------------------------------------------------------------------------------- /tests/reduce.out.ok: -------------------------------------------------------------------------------- 1 | [](202.0) 2 | -------------------------------------------------------------------------------- /tests/sign.out.ok: -------------------------------------------------------------------------------- 1 | [](1.0) 2 | -------------------------------------------------------------------------------- /tests/sort.out.ok: -------------------------------------------------------------------------------- 1 | [](1.0) 2 | -------------------------------------------------------------------------------- /tests/test.out.ok: -------------------------------------------------------------------------------- 1 | [](615.0) 2 | -------------------------------------------------------------------------------- /tests/test1.apl: -------------------------------------------------------------------------------- 1 | a ← 1 2 3 2 | +/a -------------------------------------------------------------------------------- /tests/test1.out.ok: -------------------------------------------------------------------------------- 1 | [](6.0) 2 | -------------------------------------------------------------------------------- /tests/test10.out.ok: -------------------------------------------------------------------------------- 1 | [](82.8) 2 | -------------------------------------------------------------------------------- /tests/test11.out.ok: -------------------------------------------------------------------------------- 1 | [](55.8) 2 | -------------------------------------------------------------------------------- /tests/test12.out.ok: -------------------------------------------------------------------------------- 1 | [](21.0) 2 | -------------------------------------------------------------------------------- /tests/test14.out.ok: -------------------------------------------------------------------------------- 1 | [](4.0) 2 | -------------------------------------------------------------------------------- /tests/test15.out.ok: -------------------------------------------------------------------------------- 1 | [](210.0) 2 | -------------------------------------------------------------------------------- /tests/test19.out.ok: -------------------------------------------------------------------------------- 1 | [](375.0) 2 | -------------------------------------------------------------------------------- /tests/test2.out.ok: -------------------------------------------------------------------------------- 1 | [](349.0) 2 | -------------------------------------------------------------------------------- /tests/test3.out.ok: -------------------------------------------------------------------------------- 1 | [](2320.0) 2 | -------------------------------------------------------------------------------- /tests/test4.out.ok: -------------------------------------------------------------------------------- 1 | [](6.0) 2 | -------------------------------------------------------------------------------- /tests/test6.out.ok: -------------------------------------------------------------------------------- 1 | [](15.0) 2 | -------------------------------------------------------------------------------- /tests/test7.out.ok: -------------------------------------------------------------------------------- 1 | [](9.0) 2 | -------------------------------------------------------------------------------- /tests/test9.out.ok: -------------------------------------------------------------------------------- 1 | [](231.0) 2 | -------------------------------------------------------------------------------- /tests/timespi.out.ok: -------------------------------------------------------------------------------- 1 | [](1.0) 2 | -------------------------------------------------------------------------------- /tests/train.out.ok: -------------------------------------------------------------------------------- 1 | [](25.65) 2 | -------------------------------------------------------------------------------- /tests/train0.out.ok: -------------------------------------------------------------------------------- 1 | [](-4.8) 2 | -------------------------------------------------------------------------------- /tests/vowels.out.ok: -------------------------------------------------------------------------------- 1 | [](4.0) 2 | -------------------------------------------------------------------------------- /tests/primes.out.ok: -------------------------------------------------------------------------------- 1 | [](1060.0) 2 | -------------------------------------------------------------------------------- /tests/replicate.out.ok: -------------------------------------------------------------------------------- 1 | [](30.0) 2 | -------------------------------------------------------------------------------- /tests/slashbar.out.ok: -------------------------------------------------------------------------------- 1 | [](405.0) 2 | -------------------------------------------------------------------------------- /tests/test13.out.ok: -------------------------------------------------------------------------------- 1 | [](65780.0) 2 | -------------------------------------------------------------------------------- /tests/test16.out.ok: -------------------------------------------------------------------------------- 1 | [](1934351.0) 2 | -------------------------------------------------------------------------------- /tests/test21.out.ok: -------------------------------------------------------------------------------- 1 | [](4090.0) 2 | -------------------------------------------------------------------------------- /tests/test24.apl: -------------------------------------------------------------------------------- 1 | a ← 4 3 2 | +/ a + 8 -------------------------------------------------------------------------------- /tests/test28.out.ok: -------------------------------------------------------------------------------- 1 | [](1934351.0) 2 | -------------------------------------------------------------------------------- /tests/test5.out.ok: -------------------------------------------------------------------------------- 1 | [](479001643.0) 2 | -------------------------------------------------------------------------------- /tests/bool1.apl: -------------------------------------------------------------------------------- 1 | +/ 2.1 + 2 < 3 2 3 5 3 23 3 -------------------------------------------------------------------------------- /tests/powscl.out.ok: -------------------------------------------------------------------------------- 1 | [](103) 2 | [](0.0) 3 | -------------------------------------------------------------------------------- /tests/signal.out.ok: -------------------------------------------------------------------------------- 1 | [](258.557340366) 2 | -------------------------------------------------------------------------------- /tests/train0.apl: -------------------------------------------------------------------------------- 1 | a ← (-,÷)5 2 | 3 | +/a -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | version.sml 2 | lib 3 | *~ 4 | MLB -------------------------------------------------------------------------------- /tests/blackscholes.out.ok: -------------------------------------------------------------------------------- 1 | [](5.34836535975) 2 | -------------------------------------------------------------------------------- /tests/innerLegrand5.3.out.ok: -------------------------------------------------------------------------------- 1 | [](27190.4) 2 | -------------------------------------------------------------------------------- /tests/innerproduct.out.ok: -------------------------------------------------------------------------------- 1 | [](4.31703601) 2 | -------------------------------------------------------------------------------- /tests/sum35.out.ok: -------------------------------------------------------------------------------- 1 | [](23) 2 | [](233168.0) 3 | -------------------------------------------------------------------------------- /tests/timespi.apl: -------------------------------------------------------------------------------- 1 | 0.000001>|3.141592-(○1) 2 | -------------------------------------------------------------------------------- /tests/a1.apl: -------------------------------------------------------------------------------- 1 | a ← +/ 2 3 2 1 2 | 3 | f ← {⍵ + 3 5} -------------------------------------------------------------------------------- /tests/athas.apl: -------------------------------------------------------------------------------- 1 | {+/+/⍵×⍵=2×((⍴⍵)⍴⍳⊃⍴⍵)}5 5⍴10 2 | -------------------------------------------------------------------------------- /tests/powscl.apl: -------------------------------------------------------------------------------- 1 | 2 | ⎕ ← ({ ⍵ + 1 }⍣3) 100 3 | 4 | 0 -------------------------------------------------------------------------------- /tests/residue.out.ok: -------------------------------------------------------------------------------- 1 | [4](2,-2,4,-2) 2 | [](2.0) 3 | -------------------------------------------------------------------------------- /tests/tally.out.ok: -------------------------------------------------------------------------------- 1 | [](3) 2 | [](3) 3 | [](0.0) 4 | -------------------------------------------------------------------------------- /tests/test17.apl: -------------------------------------------------------------------------------- 1 | a ← 80 30 ⍴ ⍳ 50 2 | +/ +/ a 3 | -------------------------------------------------------------------------------- /tests/test27.apl: -------------------------------------------------------------------------------- 1 | a ← ¯1 ↑ (12 2 3 4 5) 2 | 3 | +/a -------------------------------------------------------------------------------- /tests/test6.apl: -------------------------------------------------------------------------------- 1 | opr ← { ⍺⍺ + ⍵ } 2 | 6 opr 9 ⍝ 15 -------------------------------------------------------------------------------- /tests/test7.apl: -------------------------------------------------------------------------------- 1 | +/ ((⍴ 2 3 ⍴ 1 2 3 4 5 6) + 2) ⍝ 9 -------------------------------------------------------------------------------- /tests/cons.apl: -------------------------------------------------------------------------------- 1 | a ← ⊃ ⍴ 1 2 3 2 | +/ a, ⍳ 7 ⍝ --> 31 -------------------------------------------------------------------------------- /tests/squad.out.ok: -------------------------------------------------------------------------------- 1 | [](130) 2 | [](130.0) 3 | [](0.0) 4 | -------------------------------------------------------------------------------- /tests/test20.apl: -------------------------------------------------------------------------------- 1 | f ← { a ← ⍵ 2 | a } 3 | 4 | f 6 -------------------------------------------------------------------------------- /tests/test23.apl: -------------------------------------------------------------------------------- 1 | +/ 3.2 4, 8 3 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tests/test3.apl: -------------------------------------------------------------------------------- 1 | +/ 1000 {⍵+⍺} 300 20 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /tests/vec.out.ok: -------------------------------------------------------------------------------- 1 | [2](2,8) 2 | [3](25,13,8) 3 | [](0.0) 4 | -------------------------------------------------------------------------------- /tests/expd.out.ok: -------------------------------------------------------------------------------- 1 | [](8.0) 2 | [](20.0855369232) 3 | [](0.0) 4 | -------------------------------------------------------------------------------- /tests/reduce.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← 10 30 ⍴ ⍳ 34 3 | ⌈ / +/ ⍉ a 4 | 5 | -------------------------------------------------------------------------------- /tests/test8.apl: -------------------------------------------------------------------------------- 1 | a ← (⍳ 10) - 2 2 | b ← (× ¨ a) + (÷ ¨ a) 3 | +/b -------------------------------------------------------------------------------- /tests/trainatop.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 2 4 6 3 | 1 3 5 4 | 5 | [](1.75) 6 | -------------------------------------------------------------------------------- /tests/tup.out.ok: -------------------------------------------------------------------------------- 1 | hello 2 | [4](1,2,4,3) 3 | [](19) 4 | [](0.0) 5 | -------------------------------------------------------------------------------- /tests/a2.apl: -------------------------------------------------------------------------------- 1 | b ← 34 2 | res ← b + ×/ a + f a + f 2 4 3 | 4 | APLC_a ← 2 -------------------------------------------------------------------------------- /tests/fib10.out.ok: -------------------------------------------------------------------------------- 1 | [12](0,1,1,2,3,5,8,13,21,34,55,89) 2 | [](0.0) 3 | -------------------------------------------------------------------------------- /tests/powtup.out.ok: -------------------------------------------------------------------------------- 1 | [2](5,6) 2 | asbchejhejhej 3 | [](3) 4 | [](0.0) 5 | -------------------------------------------------------------------------------- /tests/primes.apl: -------------------------------------------------------------------------------- 1 | A←1↓⍳100 2 | primes ← (1=+⌿0=A∘.|A)/A 3 | 4 | +/ primes -------------------------------------------------------------------------------- /tests/readfile.txt: -------------------------------------------------------------------------------- 1 | This is the content 2 | of a text file (2 lines). 3 | -------------------------------------------------------------------------------- /tests/streak.out.ok: -------------------------------------------------------------------------------- 1 | [](8) 2 | [](0) 3 | [](0) 4 | [](3) 5 | [](0.0) 6 | -------------------------------------------------------------------------------- /tests/anagram.out.ok: -------------------------------------------------------------------------------- 1 | [1](1) 2 | [1](1) 3 | [1](0) 4 | [1](0) 5 | [](0.0) 6 | -------------------------------------------------------------------------------- /tests/compose.out.ok: -------------------------------------------------------------------------------- 1 | [1](3) 2 | [](58) 3 | [](-7) 4 | [](7) 5 | [](0.0) 6 | -------------------------------------------------------------------------------- /tests/opr1.apl: -------------------------------------------------------------------------------- 1 | 2 | op ← {⍵ + ⍺⍺ 3 + ⍵} 3 | 4 | {⍵ × 4.2} op 5 ⍝ --> 38.6 -------------------------------------------------------------------------------- /tests/eacheaster.out.ok: -------------------------------------------------------------------------------- 1 | [4](20150405,20160327,20170416,20180401) 2 | [](0.0) 3 | -------------------------------------------------------------------------------- /tests/fun2.apl: -------------------------------------------------------------------------------- 1 | 2 | 3 | myfun ← { ⍺ - ⍵ } 4 | 5 | 5 myfun 3 ⍝ ---> 2 -------------------------------------------------------------------------------- /tests/primes2.apl: -------------------------------------------------------------------------------- 1 | A←1↓⍳10000 2 | primes ← (1=+⌿0=A∘.|A)/A 3 | 4 | ⎕← ⌈/ primes 5 | -------------------------------------------------------------------------------- /src/util.mlb: -------------------------------------------------------------------------------- 1 | local $(SML_LIB)/basis/basis.mlb 2 | in util.sig 3 | util.sml 4 | end -------------------------------------------------------------------------------- /tests/readintvecfile.txt: -------------------------------------------------------------------------------- 1 | 23 45 2323 4 0 34 34 2 | 34 2 1 3 | 3 4 5 543243 5543 2 4 | -------------------------------------------------------------------------------- /tests/residue.apl: -------------------------------------------------------------------------------- 1 | 2 | X ← 3 ¯5 6 ¯3 | 29 43 ¯14 ¯14 3 | 4 | ⎕ ← X 5 | 6 | a ← +/ X -------------------------------------------------------------------------------- /tests/vowels.apl: -------------------------------------------------------------------------------- 1 | 2 | vowels ← { +/,⍵ ∘.= 'AEIOUaeiou' } 3 | 4 | vowels'APL is Cool' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | aplt 3 | *.tl 4 | *.res 5 | *.resn 6 | *.out 7 | *.resc 8 | *.outc 9 | dist -------------------------------------------------------------------------------- /tests/format.out.ok: -------------------------------------------------------------------------------- 1 | The double value is 34.32 and the integer value is 55. 2 | [](0.0) 3 | -------------------------------------------------------------------------------- /tests/opr2.apl: -------------------------------------------------------------------------------- 1 | 2 | op ← {⍵ + ⍺⍺ 3 + ⍵⍵ 5.2} 3 | 4 | {⍵ × 4.2} op {⍵ ⌈ 4.5} 5 ⍝ --> 39.44 -------------------------------------------------------------------------------- /src/flags.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | in 4 | flags.sig 5 | flags.sml 6 | end -------------------------------------------------------------------------------- /tests/fib.apl: -------------------------------------------------------------------------------- 1 | m ← 2 2 ⍴ 0 1 1 1 2 | f ← { ({m +.× ⍵}⍣⍵) (1 1)} 3 | fib ← {1 ⊃ f ⍵} 4 | 5 | fib 16 -------------------------------------------------------------------------------- /tests/opr3.apl: -------------------------------------------------------------------------------- 1 | 2 | op ← { (⍺ ⍺⍺ ⍺) - ⍵ ⍵⍵ ⍵ } 3 | 4 | 3 + op × 5 ⍝ --> 6 - 25 = -19 5 | 6 | -------------------------------------------------------------------------------- /tests/test28.apl: -------------------------------------------------------------------------------- 1 | i ← 10 30 2 | a ← i ⍴ ⍳ 49 3 | b ← (⍉ a), ⍳ 30 4 | c ← a +.× b 5 | +/ +/ c 6 | -------------------------------------------------------------------------------- /tests/easter.out.ok: -------------------------------------------------------------------------------- 1 | [](20140420) 2 | [](20150405) 3 | [](20160327) 4 | [](20170416) 5 | [](0.0) 6 | -------------------------------------------------------------------------------- /tests/test22.apl: -------------------------------------------------------------------------------- 1 | i ← 10 30 2 | a ← i ⍴ ((⍳ 49), 3.0) 3 | b ← ⍉ a, ⍳ 10 4 | c ← a +.× b 5 | -/ +/ c 6 | -------------------------------------------------------------------------------- /src/laila/README.md: -------------------------------------------------------------------------------- 1 | LAILA: Low-level Array Intermediate LAnguage 2 | 3 | 4 | APL -> TAIL -> LAILA -> IL -------------------------------------------------------------------------------- /tests/innerproduct.apl: -------------------------------------------------------------------------------- 1 | a ← 0.31938153 ¯0.356563782 1.781477937 ¯1.821255978 1.330274429 2 | a +.× ⍳5 3 | 4 | -------------------------------------------------------------------------------- /tests/replicate.apl: -------------------------------------------------------------------------------- 1 | a ← ⍳ 4 2 | 3 | b ← a / a ⍝ --> 1 2 2 3 3 3 4 4 4 4 4 | 5 | +/ b ⍝ --> 30 6 | -------------------------------------------------------------------------------- /tests/signal.apl: -------------------------------------------------------------------------------- 1 | diff ← {1↓⍵−¯1⌽⍵} 2 | signal ← {¯50⌈50⌊50×(diff 0,⍵)÷0.01+⍵} 3 | +/ signal ⍳ 100 4 | 5 | 6 | -------------------------------------------------------------------------------- /tests/bench.apl: -------------------------------------------------------------------------------- 1 | N ← 1000 2 | f ← { ⍵ ⋄ ⌈/ ⌈/ N N ⍴ ⍳ 10000 } 3 | 4 | x ← (f ⎕BENCH 100) 5 5 | 6 | ⎕ ← x 7 | 8 | 0 -------------------------------------------------------------------------------- /tests/bench1.apl: -------------------------------------------------------------------------------- 1 | N ← 10000 2 | f ← { ⍵ ⋄ ⌈/ ⌈/ N N ⍴ ⍳ 10000 } 3 | 4 | x ← (f ⎕BENCH 1) 5 5 | 6 | ⎕ ← x 7 | 8 | 0 -------------------------------------------------------------------------------- /tests/tax.out.ok: -------------------------------------------------------------------------------- 1 | tax(400000) = 2 | [](180800.0) 3 | tax(400000, 220000) = 4 | [2](180800.0,78800.0) 5 | [](0.0) 6 | -------------------------------------------------------------------------------- /tests/test16.apl: -------------------------------------------------------------------------------- 1 | i ← 10 30 2 | a ← i ⍴ ⍳ 49 3 | b ← (⍉ a), ⍳ 30 4 | c ← a +.× b 5 | +/ +/ c ⍝ 1934351 6 | -------------------------------------------------------------------------------- /tests/test5.apl: -------------------------------------------------------------------------------- 1 | a ← (((+))/⍬) + (×/⍬) + (×/⍳ 12) 2 | b ← +/ 1 2 3 4 + + {⍵ ⍺⍺ 5}¨ ⍳ 4 3 | c ← a+b+2 ⍝ 479001643 4 | -------------------------------------------------------------------------------- /src/statistics.mlb: -------------------------------------------------------------------------------- 1 | 2 | local $(SML_LIB)/basis/basis.mlb 3 | util.mlb 4 | in statistics.sig 5 | statistics.sml 6 | end -------------------------------------------------------------------------------- /tests/gradeupdown.out.ok: -------------------------------------------------------------------------------- 1 | [9](83,1,4,99,33,0,6,4,5) 2 | [9](6,2,3,8,9,7,5,1,4) 3 | [9](4,1,5,7,9,3,8,2,6) 4 | [](1.0) 5 | -------------------------------------------------------------------------------- /tests/mean.apl: -------------------------------------------------------------------------------- 1 | mean ← { ⍝ Arithmetic mean 2 | sum←+/⍵ 3 | num←⍴⍵ 4 | sum÷⊃num 5 | } 6 | 7 | mean 1 2 3 4 -------------------------------------------------------------------------------- /tests/readdoublevecfile.txt: -------------------------------------------------------------------------------- 1 | 23.23 45.121 2323 4.2322 0 34.232 34 2 | 34 2 1.232 3 | 3 4 5 543243.232 5543.1 2.22323 4 | -------------------------------------------------------------------------------- /tests/test25.apl: -------------------------------------------------------------------------------- 1 | A ← 3 2 ⍴ ⍳ 5 ⋄ B ← ⍉ A 2 | a ← ⍴B 3 | b ← 1 4 | c ← b,0 5 | x ← b↓a 6 | y ← ⍴A 7 | WA ← x,y 8 | 9 | +/WA -------------------------------------------------------------------------------- /tests/pi.apl: -------------------------------------------------------------------------------- 1 | ⍝ Compute pi 2 | n ← 20000 3 | pi ← 4×(+/1>(+/(?n 2⍴0)*2)*÷2)÷n 4 | 5 | ⍝ ⎕ ← pi 6 | 7 | 0.1 > | pi - ○ 1 8 | -------------------------------------------------------------------------------- /tests/signal1.apl: -------------------------------------------------------------------------------- 1 | f ← { diff ← {1↓⍵-¯1⌽⍵} ⋄ signal ← {¯50⌈50⌊50×(diff 0,⍵)÷0.01+⍵} ⋄ +/ signal ⍳ ⍵ } 2 | f 1000 3 | 4 | 5 | -------------------------------------------------------------------------------- /tests/test2.apl: -------------------------------------------------------------------------------- 1 | signal ← {5+⍵} 2 | { ⍵ ⌈ ⍺ } / 3 ↓ signal 1 2 23 3 4 5 344 6 7 7 5, signal (⍳ 30), ⍳ 22 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/vrev.out.ok: -------------------------------------------------------------------------------- 1 | [](13) 2 | [3](3,2,1) 3 | 4 | 8 9 0 1 5 | 4 5 6 7 6 | 0 1 2 3 7 | 8 | [0]() 9 | [](0.0) 10 | -------------------------------------------------------------------------------- /tests/else.out.ok: -------------------------------------------------------------------------------- 1 | [](58) 2 | [](-2) 3 | 4 | 31 32 5 | 33 34 6 | 7 | 8 | -29 -28 9 | -27 -26 10 | 11 | [](0.0) 12 | -------------------------------------------------------------------------------- /tests/expd.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← 2 * 3 3 | 4 | ⎕ ← a ⍝ --> [](8.0) 5 | 6 | 7 | a ← * 3 8 | 9 | ⎕ ← a ⍝ --> e^3 = 10 | 11 | 0 -------------------------------------------------------------------------------- /tests/powmat.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← 3 7 ⍴ ⍳ 9 3 | 4 | ⎕ ← a 5 | 6 | ⎕ ← ({1 ⌽ ⍵} ⍣ 2) a 7 | 8 | ⎕ ← ({¯1 ⌽ ⍵} ⍣ 2) a 9 | 10 | 0 -------------------------------------------------------------------------------- /tests/tally.apl: -------------------------------------------------------------------------------- 1 | tally ← {⍬⍴(⍴⍵),1} 2 | 3 | x ← ⍉ 4 5 3 ⍴ ⍳ 10 4 | ⎕ ← tally x ⍝ -> 3 5 | 6 | ⎕ ← ≢x ⍝ -> 3 7 | 8 | 0 9 | -------------------------------------------------------------------------------- /tests/transpose.apl: -------------------------------------------------------------------------------- 1 | 2 | i ← 5 3 3 | a ← i ⍴ ⍳ 6 4 | 5 | ⎕ ← a 6 | 7 | b ← (⍉ a), 2+⍳ 3 8 | 9 | ⎕ ← b 10 | 11 | 0 12 | -------------------------------------------------------------------------------- /tests/boolean.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← (0 ∧ 1) + (1 ∨ 0) 3 | b ← (1 ⍲ 0) 4 | c ← ~ b 5 | d ← (1 ⍱ 0) 6 | ⍝ e ← 1 2 ∈ 1 3 4 7 | a + b + c + d 8 | -------------------------------------------------------------------------------- /tests/ceilfloormaxmin.out.ok: -------------------------------------------------------------------------------- 1 | [](6) 2 | [](2) 3 | [](14.0) 4 | [](2.0) 5 | [](0) 6 | [](1) 7 | [](1) 8 | [](0) 9 | [](0.0) 10 | -------------------------------------------------------------------------------- /tests/test9.apl: -------------------------------------------------------------------------------- 1 | a ← 3 2 ⍴ ⍳ 6 2 | ×/ (+/ a) 3 | 4 | ⍝ 1 2 --> 3 5 | ⍝ 3 4 --> 7 6 | ⍝ 5 6 --> 11 7 | ⍝ -- 8 | ⍝ 21×11=231 -------------------------------------------------------------------------------- /tests/rotfirst.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 4 5 6 7 3 | 8 9 9 9 4 | 0 1 2 3 5 | 6 | 7 | 4 5 6 7 8 | 8 9 9 9 9 | 0 1 2 3 10 | 11 | [](0.0) 12 | -------------------------------------------------------------------------------- /tests/format.apl: -------------------------------------------------------------------------------- 1 | 2 | y ← +/ ⍳ 10 3 | 4 | x ←'The double value is ', (⍕ 34.32) ,' and the integer value is ', (⍕ y), '.' 5 | 6 | ⎕ ← x 7 | 8 | 0 -------------------------------------------------------------------------------- /tests/signal2.apl: -------------------------------------------------------------------------------- 1 | v ← 9 8 6 8 7 4 4 3 2 2 1 2 4 5 6 2 | diff ← {1↓⍵−¯1⌽⍵} 3 | signal ← {¯50⌈50⌊50×(diff 0,⍵)÷0.01+⍵} 4 | +/ signal v 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/tail/apl.mlb: -------------------------------------------------------------------------------- 1 | local $(SML_LIB)/basis/basis.mlb 2 | ../lib/github.com/diku-dk/sml-sort/listsort.mlb 3 | in apl.sig 4 | apl.sml 5 | end 6 | -------------------------------------------------------------------------------- /tests/fib10.apl: -------------------------------------------------------------------------------- 1 | ⍝ Power allows us to calculate a Fibonacci series 2 | fibo ← {(,⍵),+/¯2↑,⍵} 3 | 4 | fib ← {(fibo⍣⍵) 0 1} 5 | 6 | ⎕ ← fib 10 7 | 8 | 0 -------------------------------------------------------------------------------- /tests/squad.apl: -------------------------------------------------------------------------------- 1 | 2 | x ← 3 4 5 ⍴ ⍳ 232 3 | 4 | y ← ⌷ x[2;;] 5 | 6 | ⎕ ← +/⌈/y 7 | 8 | s ← 0.0 + x 9 | z ← ⌷ s[2;;] 10 | 11 | ⎕ ← +/⌈/z 12 | 13 | 0 -------------------------------------------------------------------------------- /tests/test10.apl: -------------------------------------------------------------------------------- 1 | a ← 3 2 ⍴ (⍳ 5),3.2 2 | b ← ⍉ a 3 | ×/ (+/ b) 4 | 5 | ⍝ 1 3 5 --> 9 6 | ⍝ 2 4 3.2 --> 9.2 7 | ⍝ -- 8 | ⍝ 9×9.2=82.8 9 | -------------------------------------------------------------------------------- /tests/test12.apl: -------------------------------------------------------------------------------- 1 | a ← 3 2 ⍴ (⍳ 5), 4.2 2 | b ← ⍉ a 3 | ×/ (⌈/ b) 4 | 5 | ⍝ 1 3 5 --> 5 6 | ⍝ 2 4 4.2 --> 4.2 7 | ⍝ --- 8 | ⍝ 21.0 9 | -------------------------------------------------------------------------------- /tests/test11.apl: -------------------------------------------------------------------------------- 1 | a ← 3 2 ⍴ (⍳ 5), 0.2 2 | b ← ⍉ a 3 | ×/ (+/ b) 4 | 5 | ⍝ 1 3 5 --> 9 6 | ⍝ 2 4 0.2 --> 6.2 7 | ⍝ --- 8 | ⍝ 9×6.2=55.8 9 | -------------------------------------------------------------------------------- /tests/trains1.out.ok: -------------------------------------------------------------------------------- 1 | [](3.625) 2 | [8](-1.625,-0.625,0.375,-1.625,0.375,2.375,-0.625,1.375) 3 | [3](3.625,1.734375,1.31695671911) 4 | [6](1,2,2,3,3,3) 5 | [](0.0) 6 | -------------------------------------------------------------------------------- /tests/chars.out.ok: -------------------------------------------------------------------------------- 1 | dlrow olleH 2 | [](X) 3 | Xdlrow olleH 4 | 5 | Hweol 6 | eolrl 7 | lrllo 8 | llod 9 | od Hw 10 | Hweo 11 | 12 | oaaa 13 | [](12.0) 14 | -------------------------------------------------------------------------------- /tests/shape.out.ok: -------------------------------------------------------------------------------- 1 | Shape of scalar 2 | [0]() 3 | Shape of vector 4 | [1](10) 5 | Shape of array 6 | [3](10,4,6) 7 | Shape of empty array 8 | [1](0) 9 | [](0.0) 10 | -------------------------------------------------------------------------------- /tests/pow.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 1 2 3 3 | 8 0 4 4 | 7 6 5 5 | 6 | 7 | 5 6 7 8 | 4 0 8 9 | 3 2 1 10 | 11 | [](1) 12 | [12](0,1,1,2,3,5,8,13,21,34,55,89) 13 | [](0.0) 14 | -------------------------------------------------------------------------------- /tests/test18.apl: -------------------------------------------------------------------------------- 1 | a ← 3 2 ⍴ ⍳ 5 2 | b ← ×/ ⍉ a 3 | +/ b 4 | 5 | ⍝ 1 2 1 3 5 -×-> 15 6 | ⍝ 3 4 2 4 1 -×-> 8 7 | ⍝ 5 1 -- 8 | ⍝ 23 9 | -------------------------------------------------------------------------------- /tests/test19.apl: -------------------------------------------------------------------------------- 1 | n ← 5 2 | i ← n, 30 3 | a ← (-1) + i ⍴ ⍳ 2 4 | b ← ⍉ a 5 | c ← a +.× b 6 | v ← n,n 7 | x ← (-1) + v ⍴ ⍳ 2 8 | d ← x ⌈.× c 9 | +/ +/ d ⍝ 375 10 | -------------------------------------------------------------------------------- /tests/transpose.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 1 2 3 3 | 4 5 6 4 | 1 2 3 5 | 4 5 6 6 | 1 2 3 7 | 8 | 9 | 1 4 1 4 1 3 10 | 2 5 2 5 2 4 11 | 3 6 3 6 3 5 12 | 13 | [](0.0) 14 | -------------------------------------------------------------------------------- /tests/abcd.out.ok: -------------------------------------------------------------------------------- 1 | 2 | CCCAAC 3 | BAADAB 4 | CAACDC 5 | ACDDBC 6 | DDCCCB 7 | ADCBCC 8 | CACCCB 9 | CCBACC 10 | 11 | Result: 12 | [8](0,0,0,1,0,1,0,0) 13 | [](0.0) 14 | -------------------------------------------------------------------------------- /tests/vec.apl: -------------------------------------------------------------------------------- 1 | 2 | b ← 8 3 | a ← 2 b 4 | 5 | ⎕ ← a ⍝ --> [2](2,8) 6 | 7 | c ← (d+4+e) (d ← 5+e) (e ← 8) ⍝ --> [3](25,13,8) 8 | 9 | ⎕ ← c 10 | 0 -------------------------------------------------------------------------------- /src/statistics.sig: -------------------------------------------------------------------------------- 1 | signature STATISTICS = sig 2 | type stat 3 | val new : string -> bool ref -> stat 4 | val incr : stat -> string -> unit 5 | val report : stat -> unit 6 | end 7 | -------------------------------------------------------------------------------- /tests/test.apl: -------------------------------------------------------------------------------- 1 | f ← {5+⍵} ⍝ Function adding 5 to its argument (⍵) 2 | +/ f ⍳ 30 ⍝ Apply f to the vector 1..30 and 3 | ⍝ sum up the elements in the resulting vector 4 | 5 | -------------------------------------------------------------------------------- /tests/chars.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← 'Hello world' 3 | 4 | ⎕ ← ⌽ a 5 | 6 | b ← 'X' 7 | 8 | ⎕ ← b 9 | 10 | ⎕ ← b,⌽ a 11 | 12 | ⎕ ← ⍉ 5 6 ⍴ a 13 | 14 | ⎕ ← 0 1 3 0 / 'boat' 15 | 16 | ⊃ ⍴ b,a 17 | -------------------------------------------------------------------------------- /tests/pi2.apl: -------------------------------------------------------------------------------- 1 | ⍝ Compute pi 2 | n ← 10000000 3 | pi ← 4×(+/1>+/(?n 2⍴0)*2)÷n 4 | err ← | pi - ○ 1 5 | 6 | ⎕ ← 'Computed pi:' 7 | ⎕ ← pi 8 | 9 | ⎕ ← 'Error:' 10 | ⎕ ← err 11 | 12 | 0.001 > err 13 | -------------------------------------------------------------------------------- /tests/readfile.apl: -------------------------------------------------------------------------------- 1 | 2 | vs ← ⎕ReadFile 'readfile.txt' 3 | 4 | ⎕ ← 'File size:' 5 | ⎕ ← ⊃ ⍴ vs 6 | 7 | ⎕ ← 'File content:' 8 | ⎕ ← vs 9 | 10 | ⎕ ← 'File content reversed:' 11 | ⎕ ← ⌽ vs 12 | 13 | 0 -------------------------------------------------------------------------------- /tests/compose.apl: -------------------------------------------------------------------------------- 1 | 2 | rank ← ⍴ ∘ ⍴ 3 | 4 | ⎕ ← rank 7 3 2 ⍴ ⍳ 23 5 | 6 | h ← {⍵ + 2} ∘ {⍵ × 7} 7 | 8 | ⎕ ← h 8 ⍝ --> 58 9 | 10 | ⎕ ← (2∘-) 9 ⍝ --> -7 11 | 12 | ⎕ ← (-∘2) 9 ⍝ --> 7 13 | 14 | 0 -------------------------------------------------------------------------------- /tests/gradeupdown.apl: -------------------------------------------------------------------------------- 1 | 2 | v ← 83 1 4 99 33 0 6 4 5 3 | 4 | ⎕ ← v 5 | 6 | ⎕ ← ⍋v 7 | 8 | ⎕ ← ⍒v 9 | 10 | T1 ← ∧/(⍋v)=6 2 3 8 9 7 5 1 4 11 | 12 | T2 ← ∧/(⍒v)=4 1 5 7 9 3 8 2 6 13 | 14 | ∧/ T1 T2 15 | -------------------------------------------------------------------------------- /tests/readfile.out.ok: -------------------------------------------------------------------------------- 1 | File size: 2 | [](46) 3 | File content: 4 | This is the content\nof a text file (2 lines).\n 5 | File content reversed: 6 | \n.)senil 2( elif txet a fo\ntnetnoc eht si sihT 7 | [](0.0) 8 | -------------------------------------------------------------------------------- /tests/slashbar.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← 2 3 ⍴ ⍳ 6 ⍝ 1 2 3 3 | ⍝ 4 5 6 4 | 5 | b ← +⌿ a ⍝ 5 7 9 6 | c ← +/ a ⍝ 6 15 7 | 8 | (×/b) + ×/c ⍝ 5 × 7 × 9 + 6 × 15 = 315 + 90 = 405 -------------------------------------------------------------------------------- /tests/tax.apl: -------------------------------------------------------------------------------- 1 | 2 | tax ← {(0 ⌈ 0.2 × ⍵ - 250000) + 0 ⌈ 0.4 × ⍵ - 23000} 3 | 4 | ⎕← 'tax(400000) = ' 5 | ⎕← tax 400000 6 | 7 | 8 | ⎕← 'tax(400000, 220000) = ' 9 | ⎕← tax 400000 220000 10 | 11 | 0 12 | -------------------------------------------------------------------------------- /tests/mult.apl: -------------------------------------------------------------------------------- 1 | ⍝ Multiplication table 2 | ⍝ a × b scalar multiplication, "a times b" 3 | ⍝ ∘. is the "outer product" operator 4 | ⍝ A ∘.× B every item in A times every item in B 5 | b ← (⍳ 10) ∘.× ⍳ 10 6 | +/+/b -------------------------------------------------------------------------------- /tests/compress.apl: -------------------------------------------------------------------------------- 1 | a ← (0 1 0 1=1 1 1 1) / ⍳ 4 ⍝ --> 2 4 2 | 3 | b ← ⊃ ⍴ a ⍝ --> 2 4 | 5 | c ← +/a ⍝ --> 6 6 | 7 | b + c ⍝ --> 8 8 | -------------------------------------------------------------------------------- /tests/rav.apl: -------------------------------------------------------------------------------- 1 | 2 | A ← 2 3 ⍴ ⍳6 3 | V ← ⌽⍳5 4 | 5 | R1 ← ,⍉A ⍝ → 1 4 2 5 3 6 6 | T1 ← ∧/R1=1 4 2 5 3 6 7 | 8 | R2 ← ,V 9 | T2 ← ∧/R2=5 4 3 2 1 10 | 11 | ⍝ R3 ← ,4 12 | ⍝ T3 ← ∧/R3=1⍴4 13 | 14 | ∧ / T1 T2 -------------------------------------------------------------------------------- /tests/sum35.apl: -------------------------------------------------------------------------------- 1 | 2 | ⍝ Calculate the sum of all multiples of 3 or 5 below 1000 3 | 4 | f ← {+/⍵×(0=3|⍵)∨0=5|⍵} 5 | 6 | sumbelow ← {f⍳⍵-1} 7 | 8 | ⎕ ← sumbelow 10 ⍝ → 23 9 | 10 | sumbelow 1000 ⍝ → 233168 11 | 12 | -------------------------------------------------------------------------------- /tests/readintvecfile.out.ok: -------------------------------------------------------------------------------- 1 | Number of integers in file: 2 | [](16) 3 | File content: 4 | [16](23,45,2323,4,0,34,34,34,2,1,3,4,5,543243,5543,2) 5 | File content reversed: 6 | [16](2,5543,543243,5,4,3,1,2,34,34,34,0,4,2323,45,23) 7 | [](0.0) 8 | -------------------------------------------------------------------------------- /tests/else.apl: -------------------------------------------------------------------------------- 1 | 2 | else ← {(⍺⍺⍣⍺)(⍵⍵⍣(~⍺))⍵} 3 | 4 | f ← {⍵ + 30} 5 | g ← {⍵ - 30} 6 | 7 | ⎕ ← (3>2) f else g 28 8 | 9 | ⎕ ← (3>3) f else g 28 10 | 11 | A ← (2 2 ⍴ ⍳ 4) 12 | ⎕ ← (3>2) f else g A 13 | 14 | ⎕ ← (3>3) f else g A 15 | 16 | 0 -------------------------------------------------------------------------------- /tests/inv3.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 2 3 4 3 | 5 6 7 4 | 8 9 1 5 | 6 | 7 | -2.11111111111 1.22222222222 -0.111111111111 8 | 1.88888888889 -1.11111111111 0.222222222222 9 | -0.111111111111 0.222222222222 -0.111111111111 10 | 11 | [](0.0) 12 | -------------------------------------------------------------------------------- /tests/mult0.apl: -------------------------------------------------------------------------------- 1 | out ← { 2 | A ← ⍺ 3 | B ← ⍵ 4 | T ← (⊃(⍴⍴B))⌽⍳⊃⍴(⍴B),⍴A 5 | ⍝ T ← (⊃(⍴⍴B))⌽⍳⊃(⍴⍴B)+⍴⍴A 6 | x ← T ⍉ ((⍴B),(⍴A)) ⍴ A 7 | y ← ((⍴A),(⍴B)) ⍴ B 8 | z ← x ⍺⍺ y 9 | } 10 | 11 | res ← (⍳ 10) × out (⍳ 10) 12 | 13 | +/+/res -------------------------------------------------------------------------------- /tests/powmat.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 1 2 3 4 5 6 7 3 | 8 9 1 2 3 4 5 4 | 6 7 8 9 1 2 3 5 | 6 | 7 | 3 4 5 6 7 1 2 8 | 1 2 3 4 5 8 9 9 | 8 9 1 2 3 6 7 10 | 11 | 12 | 6 7 1 2 3 4 5 13 | 4 5 8 9 1 2 3 14 | 2 3 6 7 8 9 1 15 | 16 | [](0.0) 17 | -------------------------------------------------------------------------------- /tests/now.apl: -------------------------------------------------------------------------------- 1 | 2 | start ← ⎕NOW 0 3 | 4 | ⎕ ← 'Starting computation:' 5 | 6 | ⍝ time consuming operation 7 | res ← ⌈/ +/ 5000 5000 ⍴ ⍳ 28 8 | 9 | ⎕ ← 'Result:' 10 | ⎕ ← res 11 | 12 | ⎕ ← 'Time (ms):' 13 | ⎕ ← (⎕NOW 0) - start 14 | 15 | 0 16 | -------------------------------------------------------------------------------- /tests/test15.apl: -------------------------------------------------------------------------------- 1 | a ← 3 2 ⍴ ⍳ 5 2 | a2 ← 3 2 ⍴ ⍳ 4 3 | b ← ⍉ a 4 | c ← b, ⍉ a2 5 | ×/ +/ c 6 | 7 | ⍝ 1 2 1 3 5 1 3 1 -+-> 14 8 | ⍝ 3 4 2 4 1 2 4 2 -+-> 15 9 | ⍝ 5 1 10 | ⍝ --- 11 | ⍝ 210 -------------------------------------------------------------------------------- /tests/test29.apl: -------------------------------------------------------------------------------- 1 | a0 ← ((+))/1 2 3 2 | 3 | a ← ⍳ 8 ⍝ array [1..8] 4 | b ← +/ a ⍝ sum of elements in a 5 | f ← {2+⍵×⍵} ⍝ function x^2 + 2 6 | c ← +/ f ¨a ⍝ apply f to all elements of a and sum the elements 7 | 8 | r ← a0 + b + c -------------------------------------------------------------------------------- /tests/matmul.apl: -------------------------------------------------------------------------------- 1 | a ← 3 2 ⍴ ⍳ 5 2 | b ← ⍉ a 3 | c ← a +.× b 4 | ×/ +/ c 5 | 6 | ⍝ 1 3 5 7 | ⍝ 2 4 1 8 | ⍝ 9 | ⍝ 1 2 5 11 7 -+-> 23 10 | ⍝ 3 4 11 25 19 -+-> 55 11 | ⍝ 5 1 7 19 26 -+-> 52 12 | ⍝ 65780 13 | -------------------------------------------------------------------------------- /tests/test13.apl: -------------------------------------------------------------------------------- 1 | a ← 3 2 ⍴ ⍳ 5 2 | b ← ⍉ a 3 | c ← a +.× b 4 | ×/ +/ c 5 | 6 | ⍝ 1 3 5 7 | ⍝ 2 4 1 8 | ⍝ 9 | ⍝ 1 2 5 11 7 -+-> 23 10 | ⍝ 3 4 11 25 19 -+-> 55 11 | ⍝ 5 1 7 19 26 -+-> 52 12 | ⍝ 65780 13 | -------------------------------------------------------------------------------- /tests/test4.apl: -------------------------------------------------------------------------------- 1 | a0 ← ((+))/1 2 3 2 | 3 | ⍝ a ← ⍳ 8 ⍝ array [1..8] 4 | ⍝ b ← +/ a ⍝ sum of elements in a 5 | ⍝ f ← {2+⍵×⍵} ⍝ function x^2 + 2 6 | ⍝ c ← +/ f ¨a ⍝ apply f to all elements of a and sum the elements 7 | 8 | ⍝ r ← a0 + b + c -------------------------------------------------------------------------------- /src/laila/laila.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | ../lib/github.com/diku-dk/sml-uref/uref.mlb 4 | ../util.mlb 5 | ../statistics.mlb 6 | in 7 | ../il/il.mlb 8 | laila.sig 9 | laila-flat-pull-arrays.sml 10 | laila.sml 11 | end 12 | -------------------------------------------------------------------------------- /tests/powtup.apl: -------------------------------------------------------------------------------- 1 | 2 | f ← { 3 | a1 ← ⍵[1] 4 | a2 ← ⍵[2] 5 | a3 ← ⍵[3] 6 | r1 ← (1 1) + a1 7 | r2 ← a2,'hej' 8 | (r1 r2 3) 9 | } 10 | 11 | res ← (f⍣3) ((2 3) 'asbc' 8) 12 | ⍝ res ← f (2 '') 13 | ⎕ ← res[1] 14 | ⎕ ← res[2] 15 | ⎕ ← res[3] 16 | 17 | 0 -------------------------------------------------------------------------------- /tests/readintvecfile.apl: -------------------------------------------------------------------------------- 1 | 2 | is ← ⎕ReadIntVecFile 'readintvecfile.txt' 3 | 4 | ⎕ ← 'Number of integers in file:' 5 | ⎕ ← ⊃ ⍴ is ⍝ -> 16 6 | 7 | ⎕ ← 'File content:' 8 | ⎕ ← is 9 | 10 | ⎕ ← 'File content reversed:' 11 | ⎕ ← ⌽ is 12 | 13 | 0 -------------------------------------------------------------------------------- /src/apl2tail.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | lib/github.com/diku-dk/sml-aplparse/aplparse.mlb 4 | lib/github.com/diku-dk/sml-parse/parse.mlb 5 | util.mlb 6 | flags.mlb 7 | in 8 | tail/tail.mlb 9 | Apl2Tail.sig 10 | Apl2Tail.sml 11 | end 12 | -------------------------------------------------------------------------------- /tests/readdoublevecfile.apl: -------------------------------------------------------------------------------- 1 | 2 | is ← ⎕ReadDoubleVecFile 'readdoublevecfile.txt' 3 | 4 | ⎕ ← 'Number of doubles in file:' 5 | ⎕ ← ⊃ ⍴ is ⍝ -> 16 6 | 7 | ⎕ ← 'File content:' 8 | ⎕ ← is 9 | 10 | ⎕ ← 'File content reversed:' 11 | ⎕ ← ⌽ is 12 | 13 | 0 -------------------------------------------------------------------------------- /tests/tup.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← 1 2 4 3 3 | 4 | b ← 'hello' 5 | 6 | c ← a (b a) 4 7 | 8 | ⎕ ← (c[2])[1] 9 | 10 | ⎕ ← c[1] 11 | 12 | f ← { a1 ← +/⍵[1] 13 | a2 ← ⊃⍴(⍵[2])[1] 14 | a1 + a2 + ⍵[3] 15 | } 16 | 17 | ⎕ ← f c ⍝ --> [](19) 18 | 19 | ⍝ ⎕ ← 1 ⊃ c 20 | 0 21 | -------------------------------------------------------------------------------- /tests/circ.out.ok: -------------------------------------------------------------------------------- 1 | Pi times 1 2 | [](3.14159265359) 3 | Pi times 3 4 | [](9.42477796077) 5 | Pi times 3.1 6 | [](9.73893722613) 7 | Sin 3.14 8 | [](0.00159265291649) 9 | Cos 3.14 10 | [](-0.999998731728) 11 | Tan 3.14 12 | [](-0.00159265493641) 13 | [](11.8646009323) 14 | [](0.0) 15 | -------------------------------------------------------------------------------- /tests/drop.out.ok: -------------------------------------------------------------------------------- 1 | [2](4,5) 2 | [0]() 3 | 4 | 11 12 13 14 15 5 | 16 17 18 19 20 6 | 7 | [0,5]() 8 | [3](1,2,3) 9 | 10 | 1 2 11 | 3 4 12 | 13 | [0]() 14 | [0,2]() 15 | [0,2]() 16 | [0]() 17 | [0]() 18 | [4](1,2,3,4) 19 | 20 | 1 2 21 | 3 4 22 | 23 | [0]() 24 | [](0.0) 25 | -------------------------------------------------------------------------------- /tests/circ.apl: -------------------------------------------------------------------------------- 1 | 2 | ⎕ ← 'Pi times 1' 3 | ⎕ ← ○ 1 4 | 5 | ⎕ ← 'Pi times 3' 6 | ⎕ ← ○ 3 7 | 8 | ⎕ ← 'Pi times 3.1' 9 | ⎕ ← ○ 3.1 10 | 11 | ⎕ ← 'Sin 3.14' 12 | ⎕ ← 1 ○ 3.14 13 | 14 | ⎕ ← 'Cos 3.14' 15 | ⎕ ← 2 ○ 3.14 16 | 17 | ⎕ ← 'Tan 3.14' 18 | ⎕ ← 3 ○ 3.14 19 | 20 | ⎕ ← 2 + ○ 3.14 21 | 22 | 0 -------------------------------------------------------------------------------- /tests/binaryops.out.ok: -------------------------------------------------------------------------------- 1 | Test of or_1: OK 2 | Test of or_2: OK 3 | Test of and_1: OK 4 | Test of and_2: OK 5 | Test of xor_1: OK 6 | Test of xor_2: OK 7 | Test of shl_1: OK 8 | Test of shl_2: OK 9 | Test of shr_1: OK 10 | Test of shr_2: OK 11 | Test of shar_1: OK 12 | Test of shar_2: OK 13 | [](0.0) 14 | -------------------------------------------------------------------------------- /tests/abcd.apl: -------------------------------------------------------------------------------- 1 | 2 | elements ← 'ABCD' 3 | 4 | samples ← 8 6 ⍴ 'CCCAACBAADABCAACDCACDDBCDDCCCBADCBCCCACCCBCCBACC' 5 | 6 | ⎕← samples 7 | 8 | X ← elements ∘.= samples 9 | 10 | ⎕← 'Result:' 11 | ⎕← ∧⌿∨/ X ⍝ --> [8](0,0,0,1,0,1,0,0) 12 | 13 | ⍝ {∧/⍵}¨∨/{⍵ = elements}¨samples 14 | 15 | 0 16 | -------------------------------------------------------------------------------- /tests/cmplx.apl: -------------------------------------------------------------------------------- 1 | a ← 2.0j3.2 + 1.0j3.2 2 | ⎕ ← a 3 | 4 | v ← 2j1 3 1 3J¯2 4 23 2 3 44 3 1 23j.3 5 | a ← 2 3 ⍴ v 6 | ⎕ ← a 7 | a1 ← ⎕ ← a × 2 8 | a2 ← ⎕ ← ⍉ a1 9 | a3 ← ⎕ ← 2 ⊖ a2 10 | a4 ← ⎕ ← ⌽ a3 11 | 12 | b ← ⌽ 2 ⊖ ⍉ a × 2 13 | 14 | ⎕ ← b 15 | 16 | ⎕ ← a +.× b 17 | 18 | ⎕ ← |3j4 ⍝ -> 5 19 | 20 | 0 -------------------------------------------------------------------------------- /tests/cosmin.apl: -------------------------------------------------------------------------------- 1 | M ← 200 2 | N ← 300 3 | K ← 200 300 4 | Kr ← 300 200 5 | ⍝ b ← 1 4 6 | ⍝ 2 5 7 | ⍝ 3 6 8 | 9 | ⍝ c ← 11 24 10 | ⍝ 12 25 11 | ⍝ 13 26 12 | 13 | ⍝ d ← 35 37 39 14 | ⍝ e ← 50505 15 | 16 | a ← K ⍴ ⍳ M × N 17 | b ← ⍉ a 18 | c ← b + 10 × Kr ⍴ ⍳ M 19 | d ← +/ Kr ⍴ c 20 | e ← +/ d -------------------------------------------------------------------------------- /src/il/type.sig: -------------------------------------------------------------------------------- 1 | signature TYPE = sig 2 | eqtype T (* Type constructors *) 3 | val Int : T 4 | val Double : T 5 | val Bool : T 6 | val Char : T 7 | val Vec : T -> T 8 | val prType : T -> string 9 | val vecElem : T -> T (* may fail *) 10 | end 11 | -------------------------------------------------------------------------------- /tests/shape.apl: -------------------------------------------------------------------------------- 1 | 2 | ⎕ ← 'Shape of scalar' 3 | shS ← ⍴ 4 4 | ⎕ ← shS 5 | 6 | ⎕ ← 'Shape of vector' 7 | shV ← (⍴ 5 ⍴ 4) + ⍴ 'hello' 8 | ⎕ ← shV 9 | 10 | ⎕ ← 'Shape of array' 11 | shA ← (⍴ 5 2 3 ⍴ 4) + ⍴ 5 2 3 ⍴ 'hello' 12 | ⎕ ← shA 13 | 14 | ⎕ ← 'Shape of empty array' 15 | shZ ← ⍴ ⍬ 16 | ⎕ ← shZ 17 | 18 | 0 -------------------------------------------------------------------------------- /tests/inv.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 2 3 4 3 | 5 6 7 4 | 8 9 1 5 | 6 | 7 | -2.11111111111 1.22222222222 -0.111111111111 8 | 1.88888888889 -1.11111111111 0.222222222222 9 | -0.111111111111 0.222222222222 -0.111111111111 10 | 11 | 12 | 4 7 13 | 2 6 14 | 15 | 16 | 0.6 -0.7 17 | -0.2 0.4 18 | 19 | [](0.0) 20 | -------------------------------------------------------------------------------- /tests/sort.apl: -------------------------------------------------------------------------------- 1 | 2 | v ← 4 3 32 45 656 23 545 23 65 45 56 76 3 | 4 | r1 ← v[⍋v] 5 | T1 ← ∧/r1=3 4 23 23 32 45 45 56 65 76 545 656 6 | 7 | r2 ← v[⍒v] 8 | T2 ← ∧/r2=656 545 76 65 56 45 45 32 23 23 4 3 9 | 10 | r3 ← ⍋ 0 ↑ 2 3 34 2 11 | T3 ← ∧/r3=⍬ 12 | 13 | r4 ← ⍋ 1 ↑ 2 3 34 2 14 | T4 ← ∧/r4=1⍴1 15 | 16 | ∧/ T1 T2 T3 T4 -------------------------------------------------------------------------------- /tests/rot.out.ok: -------------------------------------------------------------------------------- 1 | [3](10,26,42) 2 | [3](10,26,42) 3 | 4 | 2 3 4 1 5 | 6 7 8 5 6 | 1 2 3 9 7 | 8 | 9 | 1 2 3 4 10 | 5 6 7 8 11 | 9 1 2 3 12 | 13 | 14 | 4 1 2 3 15 | 8 5 6 7 16 | 3 9 1 2 17 | 18 | 19 | 1 2 3 4 20 | 5 6 7 8 21 | 9 1 2 3 22 | 23 | 24 | 1 2 3 4 25 | 5 6 7 8 26 | 9 1 2 3 27 | 28 | [](0.0) 29 | -------------------------------------------------------------------------------- /tests/vrev.apl: -------------------------------------------------------------------------------- 1 | 2 | ⍝ Reverse along first axis 3 | 4 | ⎕ ← ⊖ 13 ⍝ --> 13 5 | 6 | ⎕ ← ⊖ 1 2 3 ⍝ --> 3 2 1 7 | 8 | x ← ⊖ 3 4 ⍴ ⍳ 10 ⍝ --> 9 10 1 2 9 | ⍝ 5 6 7 8 10 | ⍝ 1 2 3 4 11 | 12 | ⎕ ← x - 1 13 | 14 | ⎕ ← ⊖ ⍬ ⍝ --> [0]() 15 | 16 | 0 -------------------------------------------------------------------------------- /tests/readdoublevecfile.out.ok: -------------------------------------------------------------------------------- 1 | Number of doubles in file: 2 | [](16) 3 | File content: 4 | [16](23.23,45.121,2323.0,4.2322,0.0,34.232,34.0,34.0,2.0,1.232,3.0,4.0,5.0,543243.232,5543.1,2.22323) 5 | File content reversed: 6 | [16](2.22323,5543.1,543243.232,5.0,4.0,3.0,1.232,2.0,34.0,34.0,34.232,0.0,4.2322,2323.0,45.121,23.23) 7 | [](0.0) 8 | -------------------------------------------------------------------------------- /tests/quadassign.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← ⎕ ← ⍉ 7 3 ⍴ 1 2 3 4 3 | 4 | b ← 10 20 40 20 ∧.> 1 2 3 4 5 | 6 | b2 ← 10 1 40 20 ∧.> 1 2 3 4 7 | 8 | ⎕ ← b 9 | ⎕ ← b2 10 | 11 | c ← (⍳ 5) ∘.< ⍳ 8 12 | 13 | ⎕ ← c 14 | 15 | d ← c × 3.1 16 | 17 | ⎕ ← d 18 | 19 | ⎕ ← 10 20 40 20 ∨.≤ 1 2 40 4 20 | ⎕ ← 10 20 40 20 ∨.≤ 1 2 39 4 21 | 22 | 5 + +/+/a + b 23 | -------------------------------------------------------------------------------- /tests/trainatop.apl: -------------------------------------------------------------------------------- 1 | 2 | x1 ← (-÷)4 ⍝ -> ¯0.25 3 | x2 ← 8(-÷)4 ⍝ -> ¯2.0 4 | 5 | y ← (--)4 ⍝ -> 4 6 | 7 | A ← 3 2 ⍴ ⍳ 6 8 | z ← (⍉⌽)A ⍝ 2 1 9 | ⍝ 4 3 10 | ⍝ 6 5 -> ⍝ 2 4 6 11 | ⍝ 1 3 5 12 | 13 | ⎕ ← z 14 | x1 + x2 + y ⍝ --> 1.75 -------------------------------------------------------------------------------- /tests/test30.apl: -------------------------------------------------------------------------------- 1 | A ← 3 2 ⍴ ⍳ 5 ⍝ Example input A 2 | B ← ⍉ A ⍝ Example input B 3 | R ← A +.× B 4 | R2 ← ×/ +/ R 5 | 6 | ⍝ 1 3 5 7 | ⍝ 2 4 1 8 | ⍝ 9 | ⍝ 1 2 5 11 7 -+-> 23 | 10 | ⍝ 3 4 11 25 19 -+-> 55 × 11 | ⍝ 5 1 7 19 26 -+-> 52 | 12 | ⍝ 65780 v 13 | -------------------------------------------------------------------------------- /tests/mandelbrot.out.ok: -------------------------------------------------------------------------------- 1 | 2 | +$$$$ - 3 | -$$$$$$- 4 | - $$$$$$$$ 5 | +$:-$$$$$$$$ 6 | -$$$:$$$$$$$$ 7 | $$$$$$$$$$$$$$$$ 8 | -$$$:$$$$$$$$ 9 | +$:-$$$$$$$$ 10 | - $$$$$$$$ 11 | -$$$$$$- 12 | +$$$$ - 13 | $$ 14 | 15 | [](0.0) 16 | -------------------------------------------------------------------------------- /tests/streak.apl: -------------------------------------------------------------------------------- 1 | ⍝ Longest streak of increasing numbers. Solution to Problem 2 of 2 | ⍝ 2015 International APL Problem Solving Competition - Phase I 3 | 4 | streak ← { is ← ¯1↓⍵<1⌽⍵ ⋄ s ← +\is ⋄ ⌈/0,s - ⌈\s - s × is } 5 | 6 | ⎕ ← streak 1 2 3 4 5 6 7 8 9 7 | 8 | ⎕ ← streak 1 9 | 10 | ⎕ ← streak 9 8 7 6 5 4 11 | 12 | ⎕ ← streak 1 5 3 4 2 6 7 8 13 | 14 | 0 -------------------------------------------------------------------------------- /tests/idx.out.ok: -------------------------------------------------------------------------------- 1 | [](5) 2 | [2](5,2) 3 | [7](1,2,3,4,5,6,7) 4 | [7](8,9,10,11,12,13,14) 5 | [5](2,9,16,23,30) 6 | [3](10,9,10) 7 | 8 | 13 14 15 9 | 16 17 18 10 | 19 20 21 11 | 22 23 24 12 | 13 | 14 | 16 17 18 15 | 28 29 30 16 | 40 41 42 17 | 52 53 54 18 | 19 | 20 | 14 17 20 23 21 | 26 29 32 35 22 | 38 41 44 47 23 | 50 53 56 59 24 | 25 | [](0.0) 26 | -------------------------------------------------------------------------------- /tests/mandelbrotN.out.ok: -------------------------------------------------------------------------------- 1 | 2 | +$$$$ - 3 | -$$$$$$- 4 | - $$$$$$$$ 5 | +$:-$$$$$$$$ 6 | -$$$:$$$$$$$$ 7 | $$$$$$$$$$$$$$$$ 8 | -$$$:$$$$$$$$ 9 | +$:-$$$$$$$$ 10 | - $$$$$$$$ 11 | -$$$$$$- 12 | +$$$$ - 13 | $$ 14 | 15 | [](0.0) 16 | -------------------------------------------------------------------------------- /src/aplt.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | flags.mlb 4 | apl2tail.mlb 5 | laila/laila.mlb 6 | util.mlb 7 | local lib/github.com/diku-dk/sml-setmap/string_map.mlb 8 | in Tail2Laila.sml 9 | end 10 | lib/github.com/diku-dk/sml-aplparse/aplparse.mlb 11 | lib/github.com/diku-dk/sml-parse/parse.mlb 12 | version.sml 13 | in aplt.sml 14 | end 15 | -------------------------------------------------------------------------------- /tests/trains1.apl: -------------------------------------------------------------------------------- 1 | mean ← +/÷≢ 2 | 3 | a ← 2 3 4 2 4 6 3 5 4 | 5 | ⎕ ← mean a 6 | 7 | meandev ← ⊢ - +/ ÷ ≢ 8 | 9 | ⎕ ← meandev a 10 | 11 | var ← mean ({⍵×⍵}⊢-+/÷≢) 12 | 13 | stddev ← {⍵*0.5} var 14 | 15 | all ← mean, var, stddev 16 | 17 | ⎕ ← all a ⍝ -> 18 | 19 | ⎕ ← (⍳{⍺/⍵}⍳)3 ⍝ -> 1 2 2 3 3 3 20 | 21 | ⍝ ⎕ ← (⍳(/∘⊢)⍳)3 22 | ⍝ ⎕ ← (2 2 3/⍳)3 ok now 23 | 24 | 0 25 | -------------------------------------------------------------------------------- /src/il/il.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | ../lib/github.com/diku-dk/sml-setmap/mono_set.mlb 4 | ../lib/github.com/diku-dk/sml-setmap/mono_map.mlb 5 | ../lib/github.com/diku-dk/sml-setmap/string_map.mlb 6 | ../lib/github.com/diku-dk/sml-random/random.mlb 7 | ../util.mlb 8 | in 9 | type.sig 10 | il.sml 11 | ilutil.sig 12 | ilutil.sml 13 | end 14 | -------------------------------------------------------------------------------- /tests/dtransp.out.ok: -------------------------------------------------------------------------------- 1 | A: 2 | [2,3,4](1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24) 3 | B: 4 | [3,2,4](1,2,3,4,13,14,15,16,5,6,7,8,17,18,19,20,9,10,11,12,21,22,23,24) 5 | 6 | 10 58 7 | 26 74 8 | 42 90 9 | 10 | C: 11 | [3,4,2](1,13,2,14,3,15,4,16,5,17,6,18,7,19,8,20,9,21,10,22,11,23,12,24) 12 | 13 | 14 16 18 20 14 | 22 24 26 28 15 | 30 32 34 36 16 | 17 | [](0.0) 18 | -------------------------------------------------------------------------------- /tests/sierpinski.apl: -------------------------------------------------------------------------------- 1 | ⍝ 2 | ⍝ * if S is the triangle of rank n, then rank n+1 would be 3 | ⍝ the two-dimensional catenation: 4 | ⍝ S 0 5 | ⍝ S S 6 | ⍝ where "0" is an all-blank matrix same size as S. 7 | 8 | ⍝ f : [b]2 -> [b]2 ← {(⍵,(⍴⍵)⍴0)⍪⍵,⍵} 9 | f ← {(⍵,(⍴⍵)⍴0)⍪⍵,⍵} 10 | ⍝S ← {' #'[(f⍣⍵) 1 1 ⍴ 1]} 11 | S ← {(f⍣⍵) 1 1 ⍴ 1} 12 | 13 | ⎕ ← S 5 14 | 15 | 0 -------------------------------------------------------------------------------- /tests/idxassign.apl: -------------------------------------------------------------------------------- 1 | 2 | v ← ⍳ 28 3 | 4 | v[4] ← 34 5 | 6 | ⎕ ← v 7 | 8 | m ← 3 4 ⍴ ⍳ 9 9 | 10 | m[2;3] ← 0 11 | 12 | ⎕ ← m 13 | 14 | a ← 3 4 3 ⍴ ⍳ 128 15 | 16 | a[1;1;3] ← 1000 17 | 18 | ⎕ ← a 19 | 20 | b ← a + 0.2 21 | 22 | k ← 3 23 | 24 | b[2;k;1] ← 2001 25 | 26 | ⎕ ← b 27 | 28 | x ← 7 5 ⍴ 'hello this is a great story I think' 29 | 30 | x[3;4] ← 'X' 31 | 32 | ⎕ ← x 33 | 34 | 0 -------------------------------------------------------------------------------- /tests/anagram.apl: -------------------------------------------------------------------------------- 1 | ⍝ Anagram checking. Ignore spaces. 2 | 3 | elimSp ← {(⍵≠(≢⍵)⍴' ')/⍵} 4 | 5 | ⍝ ⎕ ← elimSp 'hi there you are' 6 | 7 | anagram ← { a ← elimSp ⍺ ⋄ w ← elimSp ⍵ ⋄ ((⍴a)=⍴w) ∧ ∧/(+/a ∘.= w) = +/a ∘.= a } 8 | 9 | ⎕ ← 'anagram' anagram 'nag a ram' 10 | 11 | ⎕ ← 'dyalog apl' anagram 'dog pay all' 12 | 13 | ⎕ ← ' ' anagram 'dog pay all' 14 | 15 | ⎕ ← 'cat' anagram 'dog' 16 | 17 | 0 -------------------------------------------------------------------------------- /tests/test26.apl: -------------------------------------------------------------------------------- 1 | A ← 3 2 ⍴ ⍳ 5 ⋄ B ← ⍉ A 2 | 3 | WA ← (1↓⍴B),⍴A 4 | KA ← (⊃⍴⍴A)-1 5 | VA ← ⍳ ⊃ ⍴WA 6 | ZA ← (KA⌽¯1↓VA),¯1↑VA 7 | TA ← ZA⍉WA⍴A 8 | 9 | WB ← (¯1↓⍴A),⍴B ⍝ size-3 vector with shape (3 2 3) 10 | KB ← ⊃ ⍴⍴A ⍝ 2 11 | VB ← ⍳ ⊃ ⍴WB ⍝ (1 2 3) 12 | 13 | ZB ← (KB+⍳(⊃⍴VB)-KB),KB ⍝ ((KB≠VB)/VB),KB ⍝ 1 3 2 14 | ⍝ ZB ← (⍳ KB-1),ZB 15 | 16 | +/+/+/TA 17 | 18 | -------------------------------------------------------------------------------- /tests/zfunc.apl: -------------------------------------------------------------------------------- 1 | 2 | zfunc ← { 3 | NP ← ⍺ 4 | NC ← ⍵ 5 | X1←1⌈+⌿NP 6 | X2←1⌈+⌿NC 7 | N1←(⍴NP)⍴X1 8 | N2←(⍴NC)⍴X2 9 | B1←NP÷N1 10 | B2←NC÷N2 11 | B←(NP+NC)÷N1+N2 12 | T←B1-B2 13 | N←B×(1-B)×((÷N1)+÷N2) 14 | N←N⋆0.5 15 | NA2←,N 16 | NA2 ← NA2+NA2=0 17 | N←(⍴N)⍴NA2 18 | Z←T÷N 19 | ⌈100×Z 20 | } 21 | 22 | X ← ⍳ 100 23 | 24 | Y ← 100 + ⍳ 100 25 | 26 | R ← X zfunc Y 27 | 28 | ⎕ ← R 29 | 30 | 0 -------------------------------------------------------------------------------- /tests/sierpinski0.apl: -------------------------------------------------------------------------------- 1 | ⍝ 2 | ⍝ * if S is the triangle of rank n, then rank n+1 would be 3 | ⍝ the two-dimensional catenation: 4 | ⍝ S 0 5 | ⍝ S S 6 | ⍝ where "0" is an all-blank matrix same size as S. 7 | 8 | f ← {(⍵,(⍴⍵)⍴0)⍪⍵,⍵} 9 | ⍝ S ← {(f⍣⍵) 1 1 ⍴ 1} 10 | ⍝ S 5 11 | a ← 1 1 ⍴ 1 12 | a ← f a 13 | a ← f a 14 | a ← f a 15 | a ← f a 16 | a ← f a 17 | 18 | ⎕ ← a 19 | 20 | +/+/a ⍝ ---> 243 21 | -------------------------------------------------------------------------------- /tests/vrot.out.ok: -------------------------------------------------------------------------------- 1 | [](13) 2 | [](13) 3 | [](13) 4 | [3](2,3,1) 5 | [3](2,3,1) 6 | [3](3,1,2) 7 | [3](1,2,3) 8 | 9 | 5 6 7 8 10 | 9 1 2 3 11 | 1 2 3 4 12 | 13 | 14 | 5 6 7 8 15 | 9 1 2 3 16 | 1 2 3 4 17 | 18 | 19 | 9 1 2 3 20 | 1 2 3 4 21 | 5 6 7 8 22 | 23 | 24 | 9 1 2 3 25 | 1 2 3 4 26 | 5 6 7 8 27 | 28 | 29 | 1 2 3 4 30 | 5 6 7 8 31 | 9 1 2 3 32 | 33 | [0]() 34 | [0]() 35 | [0]() 36 | [0,4]() 37 | [](0.0) 38 | -------------------------------------------------------------------------------- /tests/inv3.apl: -------------------------------------------------------------------------------- 1 | 2 | inv3 ← { 3 | x ← ,⍵ 4 | a ← x[1] ⋄ b ← x[2] ⋄ c ← x[3] 5 | d ← x[4] ⋄ e ← x[5] ⋄ f ← x[6] 6 | g ← x[7] ⋄ h ← x[8] ⋄ i ← x[9] 7 | det ← ((a×((e×i)-f×h)) - (b×((d×i)-f×g))) + c×((d×h)-e×g) 8 | adj ← 3 3 ⍴ ((e×i)-f×h) ((c×h)-b×i) ((b×f)-c×e) ((f×g)-d×i) ((a×i)-c×g) ((c×d)-a×f) ((d×h)-e×g) ((b×g)-a×h) ((a×e)-b×d) 9 | adj ÷ det 10 | } 11 | 12 | ⍝ Examples 13 | A ← ⌷ 3 3 ⍴ 1 ⌽ ⍉ ⍳ 9 14 | ⎕ ← A 15 | 16 | B ← ⌷ inv3 A 17 | ⎕ ← B 18 | 0 -------------------------------------------------------------------------------- /tests/take.out.ok: -------------------------------------------------------------------------------- 1 | [3](1,2,3) 2 | [6](1,2,3,4,0,0) 3 | 4 | 9 8 7 6 5 5 | 4 3 2 1 0 6 | 7 | 8 | 1 2 3 4 5 9 | 6 7 8 1 2 10 | 0 0 0 0 0 11 | 0 0 0 0 0 12 | 13 | [2](4,5) 14 | 15 | 5 6 16 | 7 8 17 | 18 | [6](0,0,1,2,3,4) 19 | 20 | 0 0 21 | 0 0 22 | 1 2 23 | 3 4 24 | 5 6 25 | 7 8 26 | 27 | [3](0,0,0) 28 | [3](0,0,0) 29 | [0]() 30 | [0,2]() 31 | [0]() 32 | [3](23,0,0) 33 | [3](0,0,23) 34 | [1](23) 35 | [1](23) 36 | [0]() 37 | [](0.0) 38 | -------------------------------------------------------------------------------- /tests/zfunc.out.ok: -------------------------------------------------------------------------------- 1 | [100](-563,-546,-530,-514,-498,-483,-468,-453,-439,-425,-411,-397,-384,-371,-358,-345,-333,-320,-308,-296,-284,-273,-262,-250,-239,-228,-218,-207,-196,-186,-176,-166,-156,-146,-136,-127,-117,-108,-99,-90,-81,-72,-63,-54,-45,-37,-28,-20,-12,-4,5,13,21,28,36,44,52,59,67,74,82,89,96,104,111,118,125,132,139,146,153,159,166,173,179,186,192,199,205,212,218,224,231,237,243,249,255,261,267,273,279,285,291,297,302,308,314,320,325,331) 2 | [](0.0) 3 | -------------------------------------------------------------------------------- /tests/quadassign.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 1 4 3 2 1 4 3 3 | 2 1 4 3 2 1 4 4 | 3 2 1 4 3 2 1 5 | 6 | [](1) 7 | [](0) 8 | 9 | 0 1 1 1 1 1 1 1 10 | 0 0 1 1 1 1 1 1 11 | 0 0 0 1 1 1 1 1 12 | 0 0 0 0 1 1 1 1 13 | 0 0 0 0 0 1 1 1 14 | 15 | 16 | 0.0 3.1 3.1 3.1 3.1 3.1 3.1 3.1 17 | 0.0 0.0 3.1 3.1 3.1 3.1 3.1 3.1 18 | 0.0 0.0 0.0 3.1 3.1 3.1 3.1 3.1 19 | 0.0 0.0 0.0 0.0 3.1 3.1 3.1 3.1 20 | 0.0 0.0 0.0 0.0 0.0 3.1 3.1 3.1 21 | 22 | [](1) 23 | [](0) 24 | [](77.0) 25 | -------------------------------------------------------------------------------- /tests/mandel.apl: -------------------------------------------------------------------------------- 1 | ⍝ Mandelbrot one-liner: 2 | 3 | ⍝ Compared to Dyalog APL, additional parentheses are needed around 4 | ⍝ bindings (←) and around the power operator (⍣). Moreover, the 5 | ⍝ function parameter to the power operator needs to be monadic. 6 | 7 | ⎕ ← ' #'[1+9>|({m+⍵×⍵}⍣9)(m←¯3×.7j.5-⍉a∘.+0j1×(a←(1+⍳n+1)÷(n←28)))] 8 | 9 | ⍝ And one that uses trains, which does not work...: 10 | ⍝ ⎕ ← ' #'[1+9>|m∘(2*⍨+)⍣9⊢(m←¯3×.7j.5-⍉a∘.+0j1×(a←(1+⍳n+1)÷(n←98)))] 11 | 12 | 0 -------------------------------------------------------------------------------- /tests/inner.apl: -------------------------------------------------------------------------------- 1 | 2 | A ← 3 2 ⍴ ⍳ 5 ⋄ B ← ⍉ A 3 | 4 | WA ← (1↓⍴B),⍴A ⋄ KA ← (⍴⍴A)-1 5 | VA ← ⍳⍴WA ⋄ ZA ← (KA⌽¯1↓VA),¯1↑VA 6 | TA ← ZA⍉WA⍴A 7 | 8 | WB ← (¯1↓⍴A),⍴B ⋄ KB ← ⍴⍴A 9 | VB ← ⍳⍴WB ⋄ ZB ← ((KB≠VB)/VB),VB[KB] 10 | TB ← ZB⍉WB⍴B 11 | 12 | R ← +/TA×TB 13 | 14 | R2 ← ×/ +/ R 15 | 16 | ⍝ 1 3 5 17 | ⍝ 2 4 1 18 | ⍝ 19 | ⍝ 1 2 5 11 7 -+-> 23 20 | ⍝ 3 4 11 25 19 -+-> 55 21 | ⍝ 5 1 7 19 26 -+-> 52 22 | ⍝ 65780 23 | -------------------------------------------------------------------------------- /tests/pow.apl: -------------------------------------------------------------------------------- 1 | 2 | ⍝ Power Operator example from Legrands "Mastering Dyalog APL", page 415 (first edition). 3 | 4 | mat ← 3 3 ⍴ 1 2 3 8 0 4 7 6 5 5 | 6 | Spin ← {⊖⍉ ⍵} 7 | 8 | ⎕ ← mat 9 | 10 | ⎕ ← Spin Spin mat 11 | 12 | x ← (Spin ⍣ 14) mat 13 | 14 | y ← x = Spin Spin mat 15 | 16 | ⎕ ← ∧/,y 17 | 18 | ⍝ Power allows us to calculate a Fibonacci series 19 | fibo ← {(,⍵),+/¯2↑,⍵} 20 | 21 | fib ← {(fibo⍣⍵) 0 1} 22 | 23 | ⎕ ← fib 10 24 | 25 | ⍝ (⌊ ⍣ 1) 23.73 42.25 26 | 27 | 0 -------------------------------------------------------------------------------- /tests/test21.apl: -------------------------------------------------------------------------------- 1 | ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 2 | ⍝⍝⍝ A one-line function 3 | ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 4 | f ← { a ← 5 ⋄ b ← 2 2 ⍴ ⍳ 4 ⋄ a + b + ⍵ } 5 | 6 | ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 7 | ⍝⍝⍝ A multi-line function 8 | ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 9 | g ← { a ← 5 ⍝ This is a comment 10 | b ← 2 2 ⍴ ⍳ 4 11 | a + b + ⍵ } 12 | 13 | ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 14 | ⍝⍝⍝ Using the functions 15 | ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 16 | y ← ×/ +/ 2 2 ⍴ f 8 + g 9 17 | a ← b + (b ← 5) + y -------------------------------------------------------------------------------- /src/sml.pkg: -------------------------------------------------------------------------------- 1 | require { 2 | github.com/diku-dk/sml-setmap 0.1.2 #8549d0d64a4b63b1e7fba3e545c5cac89c2ff447 3 | github.com/diku-dk/sml-aplparse 0.1.5 #2049660efbfaed7152bf736a1aeca58581995220 4 | github.com/diku-dk/sml-uref 0.0.2 #6881e4ab970febf55d4e684753dfd173b2fb033d 5 | github.com/diku-dk/sml-random 0.1.1 #0a0f79c857207f948e89e18b320f162e30e1fdaf 6 | github.com/diku-dk/sml-sort 0.2.1 #9efbabfd57e2db2514a07e69156d6857efe1a99f 7 | github.com/diku-dk/sml-parse 1.0.0 #bf7584331036903a1c01be3cb1bba72931639857 8 | } 9 | -------------------------------------------------------------------------------- /tests/ceilfloormaxmin.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← ⌈ 3.2 2.8 ¯2.3 0.0 2.0 ¯1.7 3 | b ← ⌊ 3.2 2.8 ¯2.3 0.0 2.0 ¯1.7 4 | 5 | ⎕ ← +/ a ⍝ --> 6 6 | ⎕ ← +/ b ⍝ --> 2 7 | 8 | c ← 2.0 ⌈ 3.2 2.8 ¯2.3 0.0 2.0 ¯1.7 9 | 10 | ⎕ ← +/ c ⍝ --> 14.0 11 | 12 | d ← 2.0 ⌊ 3.2 2.8 ¯2.3 0.0 2.0 ¯1.7 13 | 14 | ⎕ ← +/ d ⍝ --> 2.0 15 | 16 | ⍝ boolean promotion 17 | ⎕ ← 0 ⌊ 1 ⍝ --> 0 18 | ⎕ ← 0 ⌈ 1 ⍝ --> 1 19 | ⎕ ← ⌊ 1 ⍝ --> 1 20 | ⎕ ← ⌊ 0 ⍝ --> 0 21 | 22 | 0 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/tail/tail.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | ../lib/github.com/diku-dk/sml-setmap/mono_map.mlb 4 | ../lib/github.com/diku-dk/sml-setmap/mono_set.mlb 5 | ../lib/github.com/diku-dk/sml-random/random.mlb 6 | ../lib/github.com/diku-dk/sml-uref/uref.mlb 7 | in 8 | ../util.mlb 9 | 10 | apl.mlb (* interpreter *) 11 | 12 | tail_type.sig 13 | tail_exp.sig 14 | tail.sig 15 | 16 | tail_exp.sml (* functor *) 17 | tail_optimize.sml 18 | tail_type.sml 19 | tail.sml 20 | end 21 | -------------------------------------------------------------------------------- /tests/idxassign.out.ok: -------------------------------------------------------------------------------- 1 | [28](1,2,3,34,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28) 2 | 3 | 1 2 3 4 4 | 5 6 0 8 5 | 9 1 2 3 6 | 7 | [3,4,3](1,2,1000,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) 8 | [3,4,3](1.2,2.2,1000.2,4.2,5.2,6.2,7.2,8.2,9.2,10.2,11.2,12.2,13.2,14.2,15.2,16.2,17.2,18.2,2001.0,20.2,21.2,22.2,23.2,24.2,25.2,26.2,27.2,28.2,29.2,30.2,31.2,32.2,33.2,34.2,35.2,36.2) 9 | 10 | hello 11 | this 12 | isXa 13 | grea 14 | t sto 15 | ry I 16 | think 17 | 18 | [](0.0) 19 | -------------------------------------------------------------------------------- /tests/inner2.apl: -------------------------------------------------------------------------------- 1 | A ← 3 2 ⍴ ⍳ 5 ⍝ Example input A 2 | B ← ⍉ A ⍝ Example input B 3 | 4 | WA ← (1↓⍴B),⍴A 5 | KA ← (⊃⍴⍴A)-1 6 | VA ← ⍳ ⊃ ⍴WA 7 | ZA ← (KA⌽¯1↓VA),¯1↑VA 8 | TA ← ZA⍉WA⍴A 9 | 10 | WB ← (¯1↓⍴A),⍴B 11 | KB ← ⊃ ⍴⍴A 12 | VB ← ⍳ ⊃ ⍴WB 13 | ZB0 ← (-KB) ↓ KB ⌽ ⍳(⊃⍴VB) 14 | ZB ← (¯1↓(⍳ KB)),ZB0,KB 15 | TB ← ZB⍉WB⍴B 16 | 17 | R ← +/ 3 3 2 ⍴ TA×TB 18 | 19 | R2 ← ×/ +/ R 20 | 21 | ⍝ 1 3 5 22 | ⍝ 2 4 1 23 | ⍝ 24 | ⍝ 1 2 5 11 7 -+-> 23 25 | ⍝ 3 4 11 25 19 -+-> 55 26 | ⍝ 5 1 7 19 26 -+-> 52 27 | ⍝ 65780 28 | -------------------------------------------------------------------------------- /src/Apl2Tail.sig: -------------------------------------------------------------------------------- 1 | signature APL2TAIL = sig 2 | 3 | structure T : TAIL 4 | 5 | (* supported flags: [-o f, -tl, -c, -v, -noopt, -nomat, -p_types, -s_tail, -s_parse] *) 6 | type flags = {verbose : bool, optlevel : int, prtype : bool, materialize : bool} 7 | 8 | (* APL extensions. The parser needs this to disambiguate whether the 9 | functions are dyadic/monadic or both *) 10 | val initialParseEnv : AplParse.env 11 | 12 | (* Compile the APL-expression into a TAIL-expression *) 13 | val compile : flags -> AplAst.exp -> (unit, T.Double T.Num) T.prog 14 | end 15 | -------------------------------------------------------------------------------- /tests/train.apl: -------------------------------------------------------------------------------- 1 | a ← (-,÷)5 ⍝ +/a -> ¯4.8 2 | 3 | b ← (+,-,÷)5 ⍝ +/b -> 0.2 4 | 5 | f ← { ⍵ + 1 } 6 | t ← f,÷ 7 | 8 | x ← t 4 ⍝ +/x -> 5.25 9 | 10 | h ← 4 (++-) 2 ⍝ h -> 8 11 | 12 | minmax ← ⌊/,⌈/ 13 | 14 | mm ← minmax 3 4 2 3 2 10 2 3 1 3 4 ⍝ +/mm -> 11 15 | 16 | ⍝ Agh ← (2{⍺/⍵}⍳)3 17 | ⍝ Agh ← (2/⍳)3 18 | 19 | k ← (⊣ + ⊢) ⍝ 2 k 4 -> 6 20 | 21 | (+/a) + (+/b) + (+/x) + h + (+/mm) + (2 k 4) ⍝ TOT: 25.65 -------------------------------------------------------------------------------- /tests/rotfirst.apl: -------------------------------------------------------------------------------- 1 | ⍝ Rotate along the first axis as in (1 ⊖ A) 2 | 3 | rotfirst ← { (⍺ ↓ ⍵) ⍪ ⍺ ↑ ⍵ } 4 | 5 | A ← 3 4 ⍴ ⍳ 12 6 | 7 | X ← 1 rotfirst A ⍝ --> 5 6 7 8 8 | ⍝ 9 10 11 12 9 | ⍝ 1 2 3 4 10 | 11 | ⎕ ← 9 ⌊ X - 1 ⍝ --> 4 5 6 7 12 | ⍝ 8 9 9 9 13 | ⍝ 0 1 2 3 14 | 15 | ⎕ ← 9 ⌊ (1 ⊖ A) - 1 ⍝ --> 4 5 6 7 16 | ⍝ 8 9 9 9 17 | ⍝ 0 1 2 3 18 | 19 | 0 -------------------------------------------------------------------------------- /tests/cmplx.out.ok: -------------------------------------------------------------------------------- 1 | [](3.0j6.4) 2 | 3 | 2.0j1.0 3.0j0.0 1.0j0.0 4 | 3.0j-2.0 4.0j0.0 23.0j0.0 5 | 6 | 7 | 4.0j2.0 6.0j0.0 2.0j0.0 8 | 6.0j-4.0 8.0j0.0 46.0j0.0 9 | 10 | 11 | 4.0j2.0 6.0j-4.0 12 | 6.0j0.0 8.0j0.0 13 | 2.0j0.0 46.0j0.0 14 | 15 | 16 | 2.0j0.0 46.0j0.0 17 | 4.0j2.0 6.0j-4.0 18 | 6.0j0.0 8.0j0.0 19 | 20 | 21 | 46.0j0.0 2.0j0.0 22 | 6.0j-4.0 4.0j2.0 23 | 8.0j0.0 6.0j0.0 24 | 25 | 26 | 46.0j0.0 2.0j0.0 27 | 6.0j-4.0 4.0j2.0 28 | 8.0j0.0 6.0j0.0 29 | 30 | 31 | 118.0j34.0 22.0j8.0 32 | 346.0j-108.0 160.0j4.0 33 | 34 | [](5.0) 35 | [](0.0) 36 | -------------------------------------------------------------------------------- /tests/repl.apl: -------------------------------------------------------------------------------- 1 | N ← 20 2 | sh ← 2 (3×N) 3 | G ← ⍉ sh ⍴((3/N)/0 1 2),(3×N)⍴⍳N 4 | 5 | G ← ⌈ G ÷ 3 6 | 7 | ⎕ ← G 8 | 9 | ⍝ compress boolean 10 | X ← 0 / 1 11 | ⎕ ← X ⍝ --> [0]() 12 | X1 ← 1 / 1 13 | ⎕ ← X1 ⍝ --> [1](1) 14 | 15 | ⍝ replicate booleans 16 | Z ← 3 / 1 17 | ⎕ ← Z ⍝ --> [3](1,1,1) 18 | Z0 ← ⍬ / ⍬ 19 | ⎕ ← Z0 ⍝ --> [0]() 20 | ZN ← 3 2 / 1 0 21 | ⎕ ← ZN ⍝ --> [5](1,1,1,0,0) 22 | 23 | 24 | ⍝ replicate doubles 25 | Z ← 3 / 2.0 26 | ⎕ ← Z ⍝ --> [3](2.0,2.0,2.0) 27 | ZN ← 3 2 / 1.0 0.0 28 | ⎕ ← ZN ⍝ --> [5](1.0,1.0,1.0,0.0,0.0) 29 | 30 | 0 -------------------------------------------------------------------------------- /tests/inner3.apl: -------------------------------------------------------------------------------- 1 | A ← 3 2 ⍴ ⍳ 5 ⍝ Example input A 2 | B ← ⍉ A ⍝ Example input B 3 | 4 | WA ← (1↓⍴B),⍴A 5 | KA ← (⊃⍴⍴A)-1 6 | VA ← ⍳ ⊃ ⍴WA 7 | ZA ← (KA⌽¯1↓VA),¯1↑VA 8 | TA ← ZA⍉WA⍴A ⍝ Replicate, transpose 9 | WB ← (¯1↓⍴A),⍴B 10 | KB ← ⊃ ⍴⍴A 11 | VB ← ⍳ ⊃ ⍴WB 12 | ZB0 ← (-KB) ↓ KB ⌽ ⍳(⊃⍴VB) 13 | ZB ← (¯1↓(⍳ KB)),ZB0,KB 14 | TB ← ZB⍉WB⍴B ⍝ Replicate, transpose 15 | 16 | R ← +/ TA×TB 17 | 18 | R2 ← ×/ +/ R 19 | 20 | ⍝ 1 3 5 21 | ⍝ 2 4 1 22 | ⍝ 23 | ⍝ 1 2 5 11 7 -+-> 23 | 24 | ⍝ 3 4 11 25 19 -+-> 55 × 25 | ⍝ 5 1 7 19 26 -+-> 52 | 26 | ⍝ 65780 v 27 | -------------------------------------------------------------------------------- /tests/life.apl: -------------------------------------------------------------------------------- 1 | ⍝ Conway's Game of Life in APL without the use of nested arrays 2 | ⍝ Martin Elsman, 2014-11-10 3 | 4 | ⍝ Function computing the next generation of a board of life 5 | life ← { 6 | rowsum ← { 7 | (¯1⌽⍵) + ⍵ + 1⌽⍵ 8 | } 9 | neighbor ← { 10 | (rowsum ¯1⊖⍵) + (rowsum ⍵) + rowsum 1⊖⍵ 11 | } 12 | n ← neighbor ⍵ 13 | (n=3) ∨ (n=4) ∧ ⍵ 14 | } 15 | 16 | lifepr ← { 17 | ⎕ ← life ⍵ 18 | } 19 | 20 | nlife ← { 21 | (lifepr ⍣ ⍺) ⍵ 22 | } 23 | 24 | glider ← 3 3⍴1 1 1 1 0 0 0 1 0 25 | 26 | board ← ⍉ ¯10 ↑ ⍉ ¯10 ↑ glider 27 | 28 | ⍝ board ← 5 5⍴0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 0 0 29 | 30 | ⍝ ⎕ ← board 31 | 32 | ⍝ ⎕ ← neighbor board 33 | 34 | a ← 20 nlife board 35 | 36 | 0 -------------------------------------------------------------------------------- /tests/dtransp.apl: -------------------------------------------------------------------------------- 1 | A ← 2 3 4 ⍴ ⍳ 24 2 | ⎕ ← 'A:' 3 | ⎕ ← A 4 | 5 | B ← 2 1 3 ⍉ A ⍝ ⍴B = 3 2 4 6 | ⎕ ← 'B:' 7 | ⎕ ← B 8 | ⎕ ← +/B ⍝ --> 10 58 9 | ⍝ 26 74 10 | ⍝ 42 90 11 | 12 | ⍝ The following example requires a correct definition of exchange - see ARRAY'14 13 | ⍝ paper is wrong wrt the specification of exchange - here is a correct 14 | ⍝ specification: 15 | ⍝ exchange_p(q) = r where r(p(i)) = q(i) 16 | 17 | C ← 3 1 2 ⍉ A ⍝ ⍴C = 3 4 2 18 | ⎕ ← 'C:' 19 | ⎕ ← C 20 | ⎕ ← +/C ⍝ --> 14 16 18 20 21 | ⍝ 22 24 26 28 22 | ⍝ 30 32 34 36 23 | 24 | 0 25 | 26 | -------------------------------------------------------------------------------- /tests/inner4.apl: -------------------------------------------------------------------------------- 1 | dot ← { 2 | WA ← (1↓⍴⍵),⍴⍺ 3 | KA ← (⊃⍴⍴⍺)-1 4 | VA ← ⍳ ⊃ ⍴WA 5 | ZA ← (KA⌽¯1↓VA),¯1↑VA 6 | TA ← ZA⍉WA⍴⍺ ⍝ Replicate, transpose 7 | WB ← (¯1↓⍴⍺),⍴⍵ 8 | KB ← ⊃ ⍴⍴⍺ 9 | VB ← ⍳ ⊃ ⍴WB 10 | ZB0 ← (-KB) ↓ KB ⌽ ⍳(⊃⍴VB) 11 | ZB ← (¯1↓(⍳ KB)),ZB0,KB 12 | TB ← ZB⍉WB⍴⍵ ⍝ Replicate, transpose 13 | ⍺⍺ / TA ⍵⍵ TB ⍝ Compute the result 14 | } 15 | 16 | A ← 3 2 ⍴ ⍳ 5 ⍝ Example input A 17 | B ← ⍉ A ⍝ Example input B 18 | R ← A + dot × B 19 | R2 ← ×/ +/ R 20 | 21 | ⍝ 1 3 5 22 | ⍝ 2 4 1 23 | ⍝ 24 | ⍝ 1 2 5 11 7 -+-> 23 | 25 | ⍝ 3 4 11 25 19 -+-> 55 × 26 | ⍝ 5 1 7 19 26 -+-> 52 | 27 | ⍝ 65780 v 28 | -------------------------------------------------------------------------------- /tests/blackscholes.apl: -------------------------------------------------------------------------------- 1 | CND ← { 2 | X ← ⍵ 3 | a ← 0.31938153 ¯0.356563782 1.781477937 ¯1.821255978 1.330274429 4 | 5 | l ← |X 6 | k ← ÷1+0.2316419×l 7 | w ← 1 - (÷(2×(○1))⋆0.5) × (⋆-l×l÷2) × (a +.× k⋆⍳5) 8 | 9 | ⍝ This magic sets w = 1-w if x<0 10 | ((|0⌊×X)×(1-w))+(1-|0⌊×X)×w 11 | } 12 | 13 | ⍝ S - current price 14 | ⍝ X - strike price 15 | ⍝ T - expiry in years 16 | ⍝ r - riskless interest rate 17 | ⍝ v - volatility 18 | 19 | S ← 60 20 | X ← 65 21 | T ← 1 22 | r ← 0.1 23 | v ← 0.2 24 | 25 | d1 ← ((⍟S÷X)+(r+(v⋆2)÷2)×T)÷(v×T⋆0.5) 26 | d2 ← d1-v×T⋆0.5 27 | 28 | ⍝ Call price 29 | callPrice ← (S×CND(d1))-(X×⋆-r×T)×CND(d2) 30 | 31 | ⍝ Put price (not tested) 32 | ⍝ putPrice ← (X×⋆-r×T)×CND(-d2)-S×CND(-d1) 33 | -------------------------------------------------------------------------------- /tests/repl.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 0 1 3 | 0 1 4 | 0 1 5 | 0 2 6 | 0 2 7 | 0 2 8 | 0 3 9 | 0 3 10 | 0 3 11 | 0 4 12 | 0 4 13 | 0 4 14 | 0 5 15 | 0 5 16 | 0 5 17 | 0 6 18 | 0 6 19 | 0 6 20 | 0 7 21 | 0 7 22 | 1 1 23 | 1 1 24 | 1 1 25 | 1 2 26 | 1 2 27 | 1 2 28 | 1 3 29 | 1 3 30 | 1 3 31 | 1 4 32 | 1 4 33 | 1 4 34 | 1 5 35 | 1 5 36 | 1 5 37 | 1 6 38 | 1 6 39 | 1 6 40 | 1 7 41 | 1 7 42 | 1 1 43 | 1 1 44 | 1 1 45 | 1 2 46 | 1 2 47 | 1 2 48 | 1 3 49 | 1 3 50 | 1 3 51 | 1 4 52 | 1 4 53 | 1 4 54 | 1 5 55 | 1 5 56 | 1 5 57 | 1 6 58 | 1 6 59 | 1 6 60 | 1 7 61 | 1 7 62 | 63 | [0]() 64 | [1](1) 65 | [3](1,1,1) 66 | [0]() 67 | [5](1,1,1,0,0) 68 | [3](2.0,2.0,2.0) 69 | [5](1.0,1.0,1.0,0.0,0.0) 70 | [](0.0) 71 | -------------------------------------------------------------------------------- /tests/binaryops.apl: -------------------------------------------------------------------------------- 1 | else ← {(⍺⍺⍣⍺)(⍵⍵⍣(~⍺))⍵} 2 | 3 | tst ← { 4 | s ← 'Test of ', ⍵[1] 5 | r ← ⍵[4] = ⍵[2] ⍺⍺ ⍵[3] 6 | waste ← r { ⎕ ← s,': OK' ⋄ ⍵ + 1 } else { ⎕ ← s,': ERR' ⋄ ⍵ + 2 } 3 7 | r 8 | } 9 | 10 | t1a ← ⎕INT32OR tst ('or_1' 1 2 3) 11 | t1b ← ⎕INT32OR tst ('or_2' 4 5 5) 12 | t2a ← ⎕INT32AND tst ('and_1' 3 4 0) 13 | t2b ← ⎕INT32AND tst ('and_2' 3 5 1) 14 | t3a ← ⎕INT32XOR tst ('xor_1' 3 5 6) 15 | t3b ← ⎕INT32XOR tst ('xor_2' 0 5 5) 16 | 17 | t5a ← ⎕INT32SHL tst ('shl_1' 1 10 1024) 18 | t5b ← ⎕INT32SHL tst ('shl_2' 1 31 ¯2147483648) 19 | 20 | t6a ← ⎕INT32SHR tst ('shr_1' 1024 10 1) 21 | t6b ← ⎕INT32SHR tst ('shr_2' ¯2147483648 30 2) 22 | 23 | t7a ← ⎕INT32SHAR tst ('shar_1' 1024 10 1) 24 | t7b ← ⎕INT32SHAR tst ('shar_2' ¯1024 1 ¯512) 25 | 26 | 0 -------------------------------------------------------------------------------- /tests/eacheaster.apl: -------------------------------------------------------------------------------- 1 | easter←{ ⍝ Easter Sunday in year ⍵ 2 | G←1+19|⍵ ⍝ year "golden number" 3 | C←1+⌊⍵÷100 ⍝ Century: eg 1984 → 20th 4 | X← ¯12 + ⌊ C×3÷4 ⍝ yrs in which leap yr omitted 5 | Z← ¯5 + ⌊ (5+8×C)÷25 ⍝ synch Easter & moon's orbit 6 | S←(⌊(5×⍵)÷4)-X+10 ⍝ find Sunday 7 | E←30|(11×G)+20+Z-X ⍝ Epact 8 | F←E+(E=24)∨(E=25)∧G>11 ⍝ (when full moon occurs) 9 | N←(30×F>23)+44-F ⍝ find full moon 10 | N←N+7-7|S+N ⍝ advance to Sunday 11 | M←3+N>31 ⍝ month: March or April 12 | D←N-31×N>31 ⍝ day within month 13 | 10000 100 1+.×⍵ M D ⍝ yyyymmdd 14 | } 15 | 16 | ⎕ ← easter ¨ 2014+⍳ 4 17 | 18 | 0 -------------------------------------------------------------------------------- /tests/innerLegrand5.3.apl: -------------------------------------------------------------------------------- 1 | ⍝ ******************* 2 | ⍝ Example 1 3 | ⍝ ******************* 4 | 5 | HMS ← 3 44 29 6 | good ← +/ 3600 60 1 × HMS ⍝ --> 13469 7 | excelent ← 3600 60 1 +.× HMS ⍝ --> 13469 8 | 9 | ex1 ← good + excelent ⍝ --> 13469+13469 = 26938 10 | 11 | ⍝ ******************* 12 | ⍝ Example 2 13 | ⍝ ******************* 14 | 15 | Price ← 6 4.2 1.5 8.9 31 18 16 | Qty ← 2 6 3 5 1 0.5 17 | 18 | beginnerSolution ← +/ Price × Qty ⍝ --> 126.2 19 | innerSolution ← Price +.× Qty ⍝ --> 126.2 20 | 21 | ex2 ← beginnerSolution + innerSolution ⍝ --> 252.4 22 | 23 | ⍝ ******************* 24 | ⍝ Total 25 | ⍝ ******************* 26 | ex1 + ex2 ⍝ --> 26938 + 252.4 = 27190.4 -------------------------------------------------------------------------------- /src/il/ilutil.sig: -------------------------------------------------------------------------------- 1 | signature ILUTIL = sig 2 | type e 3 | type ss 4 | type Env 5 | type value = IL.value 6 | 7 | exception Halted of string (* evaluation may Halt *) 8 | 9 | val emptyEnv : Env 10 | val add : Env -> Name.t * value -> Env 11 | val lookup : Env -> Name.t -> value option 12 | val eval : Env -> e -> value 13 | val evalSS : Env -> ss -> Name.t -> Env 14 | 15 | val ppSS : int -> ss -> string (* int is indent level *) 16 | val ppExp : e -> string 17 | val ppFunction : string -> Type.T * Type.T -> Name.t -> ss -> string 18 | val ppValue : value -> string 19 | val typeExp : e -> Type.T 20 | 21 | val cse : ss -> ss 22 | val hoist : ss -> ss 23 | val loopSplit : ss -> ss 24 | 25 | end 26 | -------------------------------------------------------------------------------- /tests/blacksch.apl: -------------------------------------------------------------------------------- 1 | CND ← { 2 | X ← ⍵ 3 | a ← 0.31938153 ¯0.356563782 1.781477937 ¯1.821255978 1.330274429 4 | 5 | l ← |X 6 | k ← ÷1+0.2316419×l 7 | w ← 1 - (÷((2×(○1))*0.5)) × (*-(l×l)÷2) × (a +.× (k*⍳5)) 8 | 9 | ((|0⌊×X)×(1-w))+(1-|0⌊×X)×w 10 | } 11 | 12 | ⍝ S - current price 13 | ⍝ X - strike price 14 | ⍝ T - expiry in years 15 | ⍝ r - riskless interest rate 16 | ⍝ v - volatility 17 | 18 | S ← 60 19 | X ← 65 20 | T ← 1 21 | r ← 0.1 22 | v ← 0.2 23 | 24 | d1 ← { ((⍟S÷X)+(r+(v*2)÷2)×⍵)÷(v×⍵*0.5) } 25 | d2 ← { (d1 ⍵) -v×⍵*0.5 } 26 | 27 | ⍝ Call price 28 | callPrice ← { (S×CND(d1 ⍵))-(X×*-r×⍵)×CND(d2 ⍵) } 29 | 30 | avg ← { (+/⍵) ÷ ⊃⍴ ⍵ } 31 | 32 | ⎕←avg callPrice¨ (⍳ 100000) ÷ 10000 33 | 34 | ⍝ Put price (not tested) 35 | ⍝ putPrice ← { (X×*-r×⍵)×CND(-d2 ⍵)-S×CND(-d1 ⍵) } 36 | -------------------------------------------------------------------------------- /tests/matmul2.apl: -------------------------------------------------------------------------------- 1 | dot ← { ⍝: (κ→κ→κ)→(κ→κ→κ)→[κ]⍴→[κ]⍴→[κ]⍴ 2 | WA ← (1↓⍴⍵),⍴⍺ 3 | KA ← (⊃⍴⍴⍺)-1 4 | VA ← ⍳ ⊃ ⍴WA 5 | ZA ← (KA⌽¯1↓VA),¯1↑VA 6 | TA ← ZA⍉WA⍴⍺ ⍝ Replicate, transpose 7 | WB ← (¯1↓⍴⍺),⍴⍵ 8 | KB ← ⊃ ⍴⍴⍺ 9 | VB ← ⍳ ⊃ ⍴WB 10 | ZB0 ← (-KB) ↓ KB ⌽ ⍳(⊃⍴VB) 11 | ZB ← (¯1↓(⍳ KB)),ZB0,KB 12 | TB ← ZB⍉WB⍴⍵ ⍝ Replicate, transpose 13 | ⍺⍺ / TA ⍵⍵ TB ⍝ Compute final array 14 | } 15 | 16 | A ← 3 2 ⍴ ⍳ 5 ⍝ Example input A 17 | B ← ⍉ A ⍝ Example input B 18 | R ← A + dot × B 19 | R2 ← ×/ +/ R ⍝ Reduce on the result 20 | 21 | ⍝ 1 3 5 22 | ⍝ 2 4 1 23 | ⍝ 24 | ⍝ 1 2 5 11 7 -+-> 23 | 25 | ⍝ 3 4 11 25 19 -+-> 55 × 26 | ⍝ 5 1 7 19 26 -+-> 52 | 27 | ⍝ 65780 v 28 | -------------------------------------------------------------------------------- /doc/README_BIN: -------------------------------------------------------------------------------- 1 | ## Usage 2 | 3 | To use this software, either refer directly to the executable aplt in 4 | the bin-directory or make sure that the bin-directory is mentioned in 5 | your PATH environment variable. 6 | 7 | See the web page https://github.com/melsman/apltail for general 8 | information about the usage of the system. The lib/apltail directory 9 | contains the prelude.apl file and the share/apltail/tests/ directory 10 | contains APL test files. 11 | 12 | ## Running the tests 13 | 14 | To run the tests in the tests/ directory, execute the following 15 | commands: 16 | 17 | $ cd tests/ 18 | $ APLT=../../../bin/aplt PRELUDE=../../../lib/apltail/prelude.apl make test 19 | 20 | ## License 21 | 22 | This software is distributed under the MIT License. See the file 23 | MIT_LICENSE for details. -------------------------------------------------------------------------------- /tests/life2.apl: -------------------------------------------------------------------------------- 1 | ⍝ Conway's Game of Life in APL without the use of nested arrays 2 | ⍝ Martin Elsman, 2014-11-10 3 | 4 | ⍝ Function computing the next generation of a board of life 5 | life ← { 6 | rowsum ← { 7 | (¯1⌽⍵) + ⍵ + 1⌽⍵ 8 | } 9 | neighbor ← { 10 | (rowsum ¯1⊖⍵) + (rowsum ⍵) + rowsum 1⊖⍵ 11 | } 12 | n ← neighbor ⍵ 13 | (n=3) ∨ (n=4) ∧ ⍵ 14 | } 15 | 16 | lifepr ← { 17 | ⍝ ⎕ ← life ⍵ 18 | life ⍵ 19 | } 20 | 21 | nlife ← { 22 | (lifepr ⍣ ⍺) ⍵ 23 | } 24 | 25 | glider ← 3 3⍴1 1 1 1 0 0 0 1 0 26 | 27 | board ← ⍉ ¯10 ↑ ⍉ ¯10 ↑ glider 28 | 29 | square ← { x ← (5 ⊖ ⍵), 3 ⌽ ⍉ ⍵ ⋄ x ⍪ 4 ⊖ x } 30 | 31 | board ← square board 32 | board ← square board 33 | 34 | a ← 20000 nlife board 35 | 36 | b ← life a 37 | 38 | ⎕ ← a 39 | 40 | ⎕ ← 'Stable: ' 41 | s ← ∧/,a=b 42 | s 43 | -------------------------------------------------------------------------------- /tests/easter.apl: -------------------------------------------------------------------------------- 1 | easter←{ ⍝ Easter Sunday in year ⍵ 2 | G←1+19|⍵ ⍝ year "golden number" 3 | C←1+⌊⍵÷100 ⍝ Century: eg 1984 → 20th 4 | X← ¯12 + ⌊ C×3÷4 ⍝ yrs in which leap yr omitted 5 | Z← ¯5 + ⌊ (5+8×C)÷25 ⍝ synch Easter & moon's orbit 6 | S←(⌊(5×⍵)÷4)-X+10 ⍝ find Sunday 7 | E←30|(11×G)+20+Z-X ⍝ Epact 8 | F←E+(E=24)∨(E=25)∧G>11 ⍝ (when full moon occurs) 9 | N←(30×F>23)+44-F ⍝ find full moon 10 | N←N+7-7|S+N ⍝ advance to Sunday 11 | M←3+N>31 ⍝ month: March or April 12 | D←N-31×N>31 ⍝ day within month 13 | 10000 100 1+.×⍵ M D ⍝ yyyymmdd 14 | } 15 | 16 | ⎕ ← easter 2014 17 | ⎕ ← easter 2015 18 | ⎕ ← easter 2016 19 | ⎕ ← easter 2017 20 | 21 | 0 -------------------------------------------------------------------------------- /tests/easter3000.apl: -------------------------------------------------------------------------------- 1 | easter←{ ⍝ Easter Sunday in year ⍵ 2 | G←1+19|⍵ ⍝ year "golden number" 3 | C←1+⌊⍵÷100 ⍝ Century: eg 1984 → 20th 4 | X← ¯12 + ⌊ C×3÷4 ⍝ yrs in which leap yr omitted 5 | Z← ¯5 + ⌊ (5+8×C)÷25 ⍝ synch Easter & moon's orbit 6 | S←(⌊(5×⍵)÷4)-X+10 ⍝ find Sunday 7 | E←30|(11×G)+20+Z-X ⍝ Epact 8 | F←E+(E=24)∨(E=25)∧G>11 ⍝ (when full moon occurs) 9 | N←(30×F>23)+44-F ⍝ find full moon 10 | N←N+7-7|S+N ⍝ advance to Sunday 11 | M←3+N>31 ⍝ month: March or April 12 | D←N-31×N>31 ⍝ day within month 13 | 10000 100 1+.×⍵ M D ⍝ yyyymmdd 14 | } 15 | 16 | run ← { 17 | ⌈/easter¨⍳ 3000+⍵ 18 | } 19 | 20 | ⎕←⌊/run ¨ ⍳ 400 21 | 22 | 0 23 | -------------------------------------------------------------------------------- /tests/idx.apl: -------------------------------------------------------------------------------- 1 | 2 | V ← ⍳ 28 3 | A ← 5 7 ⍴ ⍳ 35 4 | A3 ← 5 4 3 ⍴ ⍳ 60 5 | X ← ⍳ 2 6 | Y ← 1 4 2 7 | 8 | V1 ← V[5] 9 | ⎕ ← V1 ⍝ → [](5) 10 | 11 | V2 ← V[5 2] 12 | ⎕ ← V2 ⍝ → [2](5,2) 13 | 14 | B1 ← A[1;] 15 | ⎕ ← B1 ⍝ → [7](1,2,3,4,5,6,7) 16 | 17 | B2 ← A[2;] 18 | ⎕ ← B2 ⍝ → [7](8,9,10,11,12,13,14) 19 | 20 | B2_ ← A[;2] 21 | ⎕ ← B2_ ⍝ → [5](2,9,16,23,30) 22 | 23 | ⍝ C ← A[1 1;] 24 | ⍝ ⎕ ← C ⍝ → 1 2 3 4 5 6 7 25 | ⍝ 1 2 3 4 5 6 7 26 | 27 | Z ← A[2; 3 2 3] 28 | ⎕ ← Z ⍝ → [3](10,9,10) 29 | 30 | ⍝ D ← A[1 0;3 2] 31 | ⍝ E ← A[;X] 32 | ⍝ F ← A[Y;X] 33 | ⍝ G ← A[Y;] 34 | ⍝ H ← A3[;;2 2] 35 | ⍝ I ← A3[;2 2;] 36 | ⍝ J ← A3[X;;] 37 | 38 | J1_2 ← A3[2;;] 39 | ⎕ ← J1_2 40 | J2_2 ← A3[;2;] 41 | ⎕ ← 1 ↓ J2_2 42 | J3_2 ← A3[;;2] 43 | ⎕ ← 1 ↓ J3_2 44 | 45 | 0 -------------------------------------------------------------------------------- /src/statistics.sml: -------------------------------------------------------------------------------- 1 | structure Statistics : STATISTICS = struct 2 | 3 | type stat = {name: string, enabled: bool ref, table: (string, int ref) Util.alist ref} 4 | 5 | fun new s r = {name=s,enabled=r,table=ref (Util.emptyAlist())} 6 | 7 | fun incr {name,table,enabled} s = 8 | if !enabled then 9 | case Util.lookupAlist (!table) s of 10 | SOME r => r := !r + 1 11 | | NONE => table := Util.extendAlist (!table) (s,ref 1) 12 | else () 13 | 14 | fun report {name,enabled,table} = 15 | if !enabled then 16 | let val sz = List.foldl (fn ((s,_),a) => (Int.max(size s,a))) 0 (!table) 17 | val () = Util.prln ("[" ^ name ^ " Statistics Report]") 18 | val () = List.app (fn (s,r) => 19 | let val line = StringCvt.padRight #" " sz s ^ " -> " ^ Int.toString(!r) 20 | in Util.prln (" " ^ line) 21 | end) (!table) 22 | in () 23 | end 24 | else () 25 | end 26 | -------------------------------------------------------------------------------- /lib/prelude.apl: -------------------------------------------------------------------------------- 1 | $dot ← { 2 | WA ← (1↓⍴⍵),⍴⍺ 3 | KA ← (⊃⍴⍴⍺)-1 4 | VA ← ⍳ ⊃ ⍴WA 5 | ZA ← (KA⌽¯1↓VA),¯1↑VA 6 | TA ← ZA⍉WA⍴⍺ ⍝ Replicate, transpose 7 | WB ← (¯1↓⍴⍺),⍴⍵ 8 | KB ← ⊃ ⍴⍴⍺ 9 | VB ← ⍳ ⊃ ⍴WB 10 | ZB0 ← (-KB) ↓ KB ⌽ ⍳(⊃⍴VB) 11 | ZB ← (¯1↓(⍳ KB)),ZB0,KB 12 | TB ← ZB⍉WB⍴⍵ ⍝ Replicate, transpose 13 | ⍺⍺ / TA ⍵⍵ TB ⍝ Compute the result 14 | } 15 | 16 | $out ← { 17 | A ← ⍺ 18 | B ← ⍵ 19 | T ← (⊃(⍴⍴A))⌽⍳⊃⍴(⍴B),⍴A 20 | x ← T ⍉ ((⍴B),(⍴A)) ⍴ A 21 | y ← ((⍴A),(⍴B)) ⍴ B 22 | x ⍺⍺ y 23 | } 24 | 25 | $slashbar ← { 26 | ⍉ ⍺⍺ / ⍉ ⍵ 27 | } 28 | 29 | $log ← { 30 | ⍝ Dyadic logarithm 31 | (⍟⍵)÷⍟⍺ 32 | } 33 | 34 | $tally ← { 35 | ⍝ bind to ≢ 36 | ⍝ ⍬⍴(⍴⍵),1 37 | ⊃(⍴⍵),1 38 | } 39 | 40 | ReadCSVDouble ← ⎕ReadDoubleVecFile 41 | ReadCSVInt ← ⎕ReadIntVecFile 42 | xor ← ⎕INT32XOR 43 | and ← ⎕INT32AND 44 | sll ← ⎕INT32SHL 45 | srl ← ⎕INT32SHR 46 | testBit ← { 0≠⍵ and 1 sll (⍺-1) } 47 | 48 | now ← ⎕NOW 49 | 50 | ⍝ [(f bench n) 0] runs f n times and prints the avg time in ms. 51 | bench ← ⎕BENCH 52 | 53 | -------------------------------------------------------------------------------- /tests/rot.apl: -------------------------------------------------------------------------------- 1 | ⍝ Rotate along the last axis as in (1 ⌽ A) 2 | 3 | rot ← { (⍉ ⍺ ↓ ⍉ ⍵) , ⍉ ⍺ ↑ ⍉ ⍵ } 4 | 5 | A ← 3 4 ⍴ ⍳ 12 6 | 7 | X ← 1 rot A ⍝ --> 2 3 4 1 8 | ⍝ 6 7 8 5 9 | ⍝ 10 11 12 9 10 | 11 | ⎕ ← +/ X ⍝ --> [3](10,26,42) 12 | 13 | ⎕ ← +/ 1 ⌽ A ⍝ --> [3](10,26,42) 14 | 15 | A ← 3 4 ⍴ ⍳ 9 16 | 17 | ⎕ ← 1 ⌽ A ⍝ --> 2 3 4 1 18 | ⍝ 6 7 8 5 19 | ⍝ 1 2 3 9 20 | 21 | ⎕ ← 4 ⌽ A ⍝ --> 1 2 3 4 22 | ⍝ 5 6 7 8 23 | ⍝ 9 1 2 3 24 | 25 | ⎕ ← ¯1 ⌽ A ⍝ --> 4 1 2 3 26 | ⍝ 8 5 6 7 27 | ⍝ 3 9 1 2 28 | 29 | ⎕ ← ¯4 ⌽ A ⍝ --> 1 2 3 4 30 | ⍝ 5 6 7 8 31 | ⍝ 9 1 2 3 32 | 33 | ⎕ ← 0 ⌽ A ⍝ --> 1 2 3 4 34 | ⍝ 5 6 7 8 35 | ⍝ 9 1 2 3 36 | 37 | 0 -------------------------------------------------------------------------------- /tests/mandel.out.ok: -------------------------------------------------------------------------------- 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 | [](0.0) 33 | -------------------------------------------------------------------------------- /tests/primes0.apl: -------------------------------------------------------------------------------- 1 | A←1↓⍳9 ⍝ 2 3 4 5 6 7 8 9 2 | 3 | residual ← A∘.|A ⍝ 0 1 0 1 0 1 0 1 4 | ⍝ 2 0 1 2 0 1 2 0 5 | ⍝ 2 3 0 1 2 3 0 1 6 | ⍝ 2 3 4 0 1 2 3 4 7 | ⍝ 2 3 4 5 0 1 2 3 8 | ⍝ 2 3 4 5 6 0 1 2 9 | ⍝ 2 3 4 5 6 7 0 1 10 | ⍝ 2 3 4 5 6 7 8 0 11 | 12 | b ← 0=residual ⍝ 1 0 1 0 1 0 1 0 13 | ⍝ 0 1 0 0 1 0 0 1 14 | ⍝ 0 0 1 0 0 0 1 0 15 | ⍝ 0 0 0 1 0 0 0 0 16 | ⍝ 0 0 0 0 1 0 0 0 17 | ⍝ 0 0 0 0 0 1 0 0 18 | ⍝ 0 0 0 0 0 0 1 0 19 | ⍝ 0 0 0 0 0 0 0 1 20 | 21 | c ← +⌿ b ⍝ 1 1 2 1 3 1 3 2 22 | 23 | d ← 1=c ⍝ 1 1 0 1 0 1 0 0 24 | 25 | e ← +/ d ⍝ 4 <--- number of prime numbers less than 10 26 | 27 | ⍝ (1=+⌿0=residual)/A ⍝ compress not supported yet 28 | -------------------------------------------------------------------------------- /tests/drop.apl: -------------------------------------------------------------------------------- 1 | ⍝ --------------------------------------------- 2 | ⍝ Drop operations on arrays of different ranks 3 | ⍝ --------------------------------------------- 4 | 5 | ⍝ Normal drop 6 | ⎕ ← 3 ↓ 1 2 3 4 5 ⍝ --> 4 5 7 | 8 | ⍝ Normal overdrop 9 | ⎕ ← 6 ↓ 1 2 3 4 ⍝ --> [0]() 10 | 11 | ⍝ Multi-dimensional drop 12 | ⎕ ← 2 ↓ 4 5 ⍴ ⍳ 20 ⍝ --> 11 12 13 14 15 13 | ⍝ 16 17 18 19 20 14 | 15 | ⍝ Multi-dimensional overdrop 16 | ⎕ ← 4 ↓ 2 5 ⍴ ⍳ 8 ⍝ --> [0,5]() 17 | 18 | ⍝ Test of negative drop 19 | ⎕ ← ¯2 ↓ 1 2 3 4 5 ⍝ --> 1 2 3 20 | 21 | ⎕ ← ¯2 ↓ 4 2 ⍴ ⍳ 8 ⍝ --> 1 2 22 | ⍝ 3 4 23 | 24 | ⍝ Test of underdrop 25 | ⎕ ← ¯6 ↓ 1 2 3 4 ⍝ --> [0]() 26 | ⎕ ← ¯6 ↓ 4 2 ⍴ ⍳ 8 ⍝ --> [0,2]() 27 | ⎕ ← ¯4 ↓ 4 2 ⍴ ⍳ 8 ⍝ --> [0,2]() 28 | 29 | ⍝ Drop from zilde 30 | ⎕ ← 3 ↓ ⍬ ⍝ --> [0]() 31 | ⎕ ← ¯3 ↓ ⍬ ⍝ --> [0]() 32 | 33 | ⍝ zero-drops 34 | ⎕ ← 0 ↓ 1 2 3 4 ⍝ --> [4](1,2,3,4) 35 | ⎕ ← 0 ↓ 2 2 ⍴ ⍳ 4 ⍝ --> 1 2 36 | ⍝ 3 4 37 | ⎕ ← 0 ↓ ⍬ ⍝ --> [0]() 38 | 39 | ⍝ MEMO: drop from scalars!? 40 | 41 | 0 -------------------------------------------------------------------------------- /MIT_LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2012-2016 Martin Elsman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/flags.sml: -------------------------------------------------------------------------------- 1 | structure Flags :> FLAGS = 2 | struct 3 | 4 | type flags = (string * string option) list 5 | 6 | fun flag_p flags s = 7 | List.exists (fn p => p = (s,NONE)) flags 8 | 9 | fun flag flags s = 10 | case List.find (fn (s',_) => s' = s) flags of 11 | SOME (_,SOME v) => SOME v 12 | | _ => NONE 13 | 14 | fun isFlag s = 15 | case String.explode s of 16 | #"-" :: _ :: _ => true 17 | | _ => false 18 | 19 | fun runargs {unaries: string list, 20 | usage : unit -> string, 21 | run: flags * string list -> unit} : unit = 22 | let fun loop args acc : unit = 23 | case args of 24 | opt :: arg :: rest => 25 | if List.exists (fn x => x = opt) unaries then 26 | loop rest ((opt,SOME arg)::acc) 27 | else if isFlag opt then loop (arg::rest) ((opt,NONE)::acc) 28 | else run(rev acc, args) 29 | | f :: rest => 30 | if isFlag f then loop rest ((f,NONE)::acc) 31 | else run(rev acc, args) 32 | | nil => (print(usage () ^ "\n"); OS.Process.exit OS.Process.success) 33 | in loop (CommandLine.arguments()) nil 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /tests/vrot.apl: -------------------------------------------------------------------------------- 1 | ⍝ Rotate along first axis as in (1 ⊖ A) 2 | 3 | ⍝ scalars 4 | ⎕ ← 1 ⊖ 13 ⍝ --> 13 5 | ⎕ ← 34 ⊖ 13 ⍝ --> 13 6 | ⎕ ← ¯2 ⊖ 13 ⍝ --> 13 7 | 8 | ⍝ vectors 9 | 10 | ⎕ ← 1 ⊖ 1 2 3 ⍝ --> 2 3 1 11 | ⎕ ← 4 ⊖ 1 2 3 ⍝ --> 2 3 1 12 | ⎕ ← ¯1 ⊖ 1 2 3 ⍝ --> 3 1 2 13 | ⎕ ← 0 ⊖ 1 2 3 ⍝ --> 1 2 3 14 | 15 | ⍝ multi-dimensional arrays 16 | A ← 3 4 ⍴ ⍳ 9 17 | 18 | ⎕ ← 1 ⊖ A ⍝ --> 5 6 7 8 19 | ⍝ 9 1 2 3 20 | ⍝ 1 2 3 4 21 | 22 | ⎕ ← 4 ⊖ A ⍝ --> 5 6 7 8 23 | ⍝ 9 1 2 3 24 | ⍝ 1 2 3 4 25 | 26 | ⎕ ← ¯1 ⊖ A ⍝ --> 9 1 2 3 27 | ⍝ 1 2 3 4 28 | ⍝ 5 6 7 8 29 | 30 | ⎕ ← ¯4 ⊖ A ⍝ --> 9 1 2 3 31 | ⍝ 1 2 3 4 32 | ⍝ 5 6 7 8 33 | 34 | ⎕ ← 0 ⊖ A ⍝ --> 1 2 3 4 35 | ⍝ 5 6 7 8 36 | ⍝ 9 1 2 3 37 | 38 | ⍝ rotating empty vectors 39 | 40 | ⎕ ← ¯2 ⊖ ⍬ ⍝ --> [0]() 41 | ⎕ ← 11 ⊖ ⍬ ⍝ --> [0]() 42 | ⎕ ← 0 ⊖ ⍬ ⍝ --> [0]() 43 | 44 | ⎕ ← 12 ⊖ 0 ↑ A ⍝ --> [0,4]() 45 | 46 | 0 -------------------------------------------------------------------------------- /tests/mandelbrotInnerPower.apl: -------------------------------------------------------------------------------- 1 | ⍝ Mandelbrot 2 | ⍝ grid-size in left argument (e.g., (1024 768)) 3 | ⍝ X-range, Y-range in right argument 4 | 5 | mandelbrot ← { 6 | X ← ⊃⍺ ⍝ e.g., 1024 7 | Y ← ⊃1↓⍺ ⍝ e.g., 768 8 | xRng ← 2↑⍵ 9 | yRng ← 2↓⍵ 10 | dx ← ((xRng[2])-xRng[1]) ÷ X 11 | dy ← ((yRng[2])-yRng[1]) ÷ Y 12 | cxA ← Y X ⍴ (xRng[1]) + dx × ⍳X ⍝ real plane 13 | cyA ← ⍉ X Y ⍴ (yRng[1]) + dy × ⍳Y ⍝ img plane 14 | N ← 90 ⍝ iterations 15 | mandel1 ← { 16 | cx ← ⍺ 17 | cy ← ⍵ 18 | f ← { 19 | arg ← 3 ⍴ ⍵ 20 | x ← arg[1] ⍝ real value 21 | y ← arg[2] ⍝ imaginary value 22 | count ← arg[3] 23 | zx ← cx+(x×x)-(y×y) 24 | zy ← cy+(x×y)+(x×y) 25 | conv ← 4 > (zx × zx) + zy × zy 26 | count2 ← count + 1 - conv 27 | (zx zy count2) 28 | } 29 | res ← (f ⍣ N) (0 0 0) ⍝ perform N iteration of a single mandelbrot point 30 | res[3] 31 | } 32 | res ← cxA mandel1¨ cyA 33 | res ÷ N 34 | } 35 | 36 | layout ← { 37 | arr ← '$#Oo*=+:- ' 38 | arr[⍵+1] 39 | } 40 | 41 | norm ← { layout¨ ⌈9 × ⍵ } 42 | 43 | mandelWrap ← { 44 | ⎕ ← norm (⌽⍵) ⍴ ⍵ mandelbrot ¯2 0.75 ¯0.75 0.75 45 | } 46 | 47 | mandelWrap 20 12 48 | 49 | 0 -------------------------------------------------------------------------------- /tests/mandelbrotInnerPower2.apl: -------------------------------------------------------------------------------- 1 | ⍝ Mandelbrot 2 | ⍝ grid-size in left argument (e.g., (1024 768)) 3 | ⍝ X-range, Y-range in right argument 4 | 5 | mandelbrot ← { 6 | X ← ⊃⍺ ⍝ e.g., 1024 7 | Y ← ⊃1↓⍺ ⍝ e.g., 768 8 | xRng ← 2↑⍵ 9 | yRng ← 2↓⍵ 10 | dx ← ((xRng[2])-xRng[1]) ÷ X 11 | dy ← ((yRng[2])-yRng[1]) ÷ Y 12 | cxA ← Y X ⍴ (xRng[1]) + dx × ⍳X ⍝ real plane 13 | cyA ← ⍉ X Y ⍴ (yRng[1]) + dy × ⍳Y ⍝ img plane 14 | N ← 90 ⍝ iterations 15 | mandel1 ← { 16 | cx ← ⍺ 17 | cy ← ⍵ 18 | f ← { 19 | arg ← ⍵ 20 | x ← arg[1] ⍝ real value 21 | y ← arg[2] ⍝ imaginary value 22 | count ← arg[3] 23 | dummy ← arg[4] 24 | zx ← cx+(x×x)-(y×y) 25 | zy ← cy+(x×y)+(x×y) 26 | conv ← 4 > (zx × zx) + zy × zy 27 | count2 ← count + 1 - conv 28 | (zx zy count2 dummy) 29 | } 30 | res ← (f ⍣ N) (0 0 0 'dummy') ⍝ perform N iteration of a single mandelbrot point 31 | res[3] 32 | } 33 | res ← cxA mandel1¨ cyA 34 | res ÷ N 35 | } 36 | 37 | layout ← { 38 | arr ← '$#Oo*=+:- ' 39 | arr[⍵+1] 40 | } 41 | 42 | norm ← { layout¨ ⌈9 × ⍵ } 43 | 44 | mandelWrap ← { 45 | ⎕ ← norm (⌽⍵) ⍴ ⍵ mandelbrot ¯2 0.75 ¯0.75 0.75 46 | } 47 | 48 | mandelWrap 20 12 49 | 50 | 0 -------------------------------------------------------------------------------- /tests/mandelbrotN.apl: -------------------------------------------------------------------------------- 1 | ⍝ grid-size in left argument (e.g., (1024 768)) 2 | ⍝ X-range, Y-range in right argument 3 | 4 | mandelbrot ← { 5 | X ← ⊃⍺ ⍝ e.g., 1024 6 | Y ← ⊃1↓⍺ ⍝ e.g., 768 7 | xRng ← 2↑⍵ 8 | yRng ← 2↓⍵ 9 | dx ← ((xRng[2])-xRng[1]) ÷ X 10 | dy ← ((yRng[2])-yRng[1]) ÷ Y 11 | cx ← Y X ⍴ (xRng[1]) + dx × ⍳X ⍝ real plane 12 | cy ← ⍉ X Y ⍴ (yRng[1]) + dy × ⍳Y ⍝ img plane 13 | mandel1 ← { ⍝ perform one iteration of mandelbrot - vectorized 14 | zx ← Y X ⍴ ⍵[1] ⍝ real plane 15 | zy ← Y X ⍴ ⍵[2] ⍝ imaginary plane 16 | count ← Y X ⍴ ⍵[3] ⍝ count plane 17 | zzx ← cx + (zx × zx) - zy × zy 18 | zzy ← cy + (zx × zy) + zx × zy 19 | conv ← 4 > (zzx × zzx) + zzy × zzy 20 | count2 ← count + 1 - conv 21 | (zzx zzy count2) 22 | } 23 | pl ← Y X ⍴ 0 ⍝ zero-plane 24 | N ← 90 ⍝ iterations 25 | res ← (mandel1 ⍣ N) (pl pl pl) 26 | res[3] ÷ N ⍝ return normalized count plane 27 | } 28 | 29 | layout ← { 30 | arr ← '$#Oo*=+:- ' 31 | arr[⍵+1] 32 | } 33 | 34 | norm ← { layout¨ ⌈9 × ⍵ } 35 | 36 | mandelWrap ← { 37 | ⎕ ← norm (⌽⍵) ⍴ ⍵ mandelbrot ¯2 0.75 ¯0.75 0.75 38 | } 39 | 40 | mandelWrap 20 12 41 | 42 | 0 -------------------------------------------------------------------------------- /tests/mandelbrot.apl: -------------------------------------------------------------------------------- 1 | ⍝ grid-size in left argument (e.g., (1024 768)) 2 | ⍝ X-range, Y-range in right argument 3 | 4 | mandelbrot ← { 5 | X ← ⊃⍺ ⍝ e.g., 1024 6 | Y ← ⊃1↓⍺ ⍝ e.g., 768 7 | xRng ← 2↑⍵ 8 | yRng ← 2↓⍵ 9 | dx ← ((xRng[2])-xRng[1]) ÷ X 10 | dy ← ((yRng[2])-yRng[1]) ÷ Y 11 | cx ← 1 Y X ⍴ (xRng[1]) + dx × ⍳X ⍝ real plane 12 | cy ← ⍉ X Y 1 ⍴ (yRng[1]) + dy × ⍳Y ⍝ img plane 13 | mandel1 ← { ⍝ perform one iteration of mandelbrot - vectorized 14 | arg ← 3 Y X ⍴ ⍵ ⍝ 2 planes for iteratively computed z's and 1 plane for the counter 15 | zx ← 1↑arg ⍝ real plane 16 | zy ← 1↑1↓arg ⍝ imaginary plane 17 | count ← 1↑2↓arg ⍝ count plane 18 | zzx ← cx + (zx × zx) - zy × zy 19 | zzy ← cy + (zx × zy) + zx × zy 20 | conv ← 4 > (zzx × zzx) + zzy × zzy 21 | count2 ← count + 1 - conv 22 | zzx ⍪ zzy ⍪ count2 23 | } 24 | planes ← 3 Y X ⍴ 0 25 | N ← 90 ⍝ iterations 26 | res ← (mandel1 ⍣ N) planes 27 | (2↓res) ÷ N ⍝ return normalized count plane 28 | } 29 | 30 | layout ← { 31 | arr ← '$#Oo*=+:- ' 32 | arr[⍵+1] 33 | } 34 | 35 | norm ← { layout¨ ⌈9 × ⍵ } 36 | 37 | mandelWrap ← { 38 | ⎕ ← norm (⌽⍵) ⍴ ⍵ mandelbrot ¯2 0.75 ¯0.75 0.75 39 | } 40 | 41 | mandelWrap 20 12 42 | 43 | 0 -------------------------------------------------------------------------------- /src/flags.sig: -------------------------------------------------------------------------------- 1 | (** Module for parsing commandline argument flags and invoking a general 2 | run function. 3 | *) 4 | 5 | signature FLAGS = sig 6 | type flags = (string * string option) list 7 | 8 | val flag_p : flags -> string -> bool 9 | val flag : flags -> string -> string option 10 | 11 | val runargs : {unaries: string list, 12 | usage: unit -> string, 13 | run: flags * string list -> unit} -> unit 14 | end 15 | 16 | (** 17 | 18 | [type flags] Flags are either nullary or unary. 19 | 20 | [flag_p flags f] returns true if f appears in flags as a nullary 21 | flag. Returns false, otherwise. 22 | 23 | [flag flags f] returns SOME v if f appears in flags as a unary flag 24 | with value v. Returns NONE, otherwise. 25 | 26 | [runargs {unaries,usage,run}] parses the commandline parameters 27 | given to the process. Flags are divided into unary flags (specified 28 | by the unaries argument), each of which take a single argument 29 | (consecutive sequence of non-space printable ascii characters) and 30 | nullary (boolean) flags that take no arguments. Flags are assumed to 31 | start with "-". If an empty sequence of arguments are provided to 32 | the process or if "-h" or "-help" is given as a flag to the process, 33 | the usage function is invoked and the process is 34 | terminated. Otherwise, if parsing of the commandline arguments 35 | succeeds, the runargs function is invoke with the provided flags and 36 | the remaining arguments (non-flags) provided on the commandline. 37 | 38 | *) 39 | -------------------------------------------------------------------------------- /tests/take.apl: -------------------------------------------------------------------------------- 1 | ⍝ --------------------------------------------- 2 | ⍝ Take operations on arrays of different ranks 3 | ⍝ --------------------------------------------- 4 | 5 | ⍝ Normal take 6 | ⎕ ← 3 ↑ 1 2 3 4 ⍝ --> 1 2 3 7 | 8 | ⍝ Normal overtake 9 | ⎕ ← 6 ↑ 1 2 3 4 ⍝ --> 1 2 3 4 0 0 10 | 11 | 12 | ⍝ Multi-dimensional take 13 | X ← 2 ↑ 4 5 ⍴ ⍳ 20 ⍝ --> 1 2 3 4 5 14 | ⍝ 6 7 8 9 10 15 | ⎕ ← 10 - X 16 | 17 | ⍝ Multi-dimensional overtake 18 | ⎕ ← 4 ↑ 2 5 ⍴ ⍳ 8 ⍝ --> 1 2 3 4 5 19 | ⍝ 6 7 8 1 2 20 | ⍝ 0 0 0 0 0 21 | ⍝ 0 0 0 0 0 22 | 23 | ⍝ Test of negative take 24 | ⎕ ← ¯2 ↑ 1 2 3 4 5 ⍝ --> 4 5 25 | 26 | ⎕ ← ¯2 ↑ 4 2 ⍴ ⍳ 8 ⍝ --> 5 6 27 | ⍝ 7 8 28 | 29 | ⍝ Test of undertake 30 | ⎕ ← ¯6 ↑ 1 2 3 4 ⍝ --> 0 0 1 2 3 4 31 | 32 | ⎕ ← ¯6 ↑ 4 2 ⍴ ⍳ 8 ⍝ --> 0 0 33 | ⍝ 0 0 34 | ⍝ 1 2 35 | ⍝ 3 4 36 | ⍝ 5 6 37 | ⍝ 7 8 38 | 39 | ⍝ Take from zilde 40 | 41 | ⎕ ← 3 ↑ ⍬ ⍝ --> [3](0,0,0) 42 | ⎕ ← ¯3 ↑ ⍬ ⍝ --> [3](0,0,0) 43 | 44 | ⍝ zero-takes 45 | 46 | ⎕ ← 0 ↑ 1 2 3 4 ⍝ --> [0]() 47 | ⎕ ← 0 ↑ 4 2 ⍴ ⍳ 8 ⍝ --> [0,2]() 48 | ⎕ ← 0 ↑ ⍬ ⍝ --> [0]() 49 | 50 | ⍝ take from scalars 51 | 52 | ⎕ ← 3 ↑ 23 ⍝ --> [3](23,0,0) 53 | ⎕ ← ¯3 ↑ 23 ⍝ --> [3](0,0,23) 54 | ⎕ ← 1 ↑ 23 ⍝ --> [1](23) 55 | ⎕ ← ¯1 ↑ 23 ⍝ --> [1](23) 56 | ⎕ ← 0 ↑ 23 ⍝ --> [0]() 57 | 58 | 0 -------------------------------------------------------------------------------- /src/util.sig: -------------------------------------------------------------------------------- 1 | (** Utility library for general purpose small useful function. *) 2 | 3 | signature UTIL = sig 4 | (* Functional utilities *) 5 | val curry : ('a * 'b -> 'c) -> 'a -> 'b -> 'c 6 | val uncurry : ('a -> 'b -> 'c) -> ('a * 'b) -> 'c 7 | val $ : ('a -> 'b) * 'a -> 'b 8 | 9 | (* Iteration *) 10 | val iter : (int*'a -> 'a) -> 'a -> int*int -> 'a 11 | 12 | (* Association lists *) 13 | type (''a,'b) alist = (''a * 'b) list 14 | val emptyAlist : unit -> (''a,'b) alist 15 | val extendAlist : (''a,'b) alist -> ''a * 'b -> (''a,'b) alist 16 | val lookupAlist : (''a,'b) alist -> ''a -> 'b option 17 | val plusAlist : (''a,'b) alist * (''a,'b) alist -> (''a,'b) alist 18 | 19 | val listContains : ''a -> ''a list -> bool 20 | 21 | (* Printing *) 22 | val intToCString : Int32.int -> string 23 | val realToCString : real -> string 24 | val realToTailString : real -> string 25 | val quote : string -> string 26 | val prln : string -> unit 27 | val log : bool -> (unit -> string) -> unit 28 | 29 | 30 | (* Minimum and maximum values *) 31 | val minInt : Int32.int 32 | val maxInt : Int32.int 33 | 34 | (* File manipulation *) 35 | val readFile : string -> string 36 | 37 | 38 | end 39 | 40 | (** 41 | 42 | [curry f a b] returns f(a,b). 43 | 44 | [uncurry f (a,b)] returns f a b. 45 | 46 | [f $ a] returns f a. Useful when the right-hand-side is a complex 47 | expression. 48 | 49 | [iter f a (i,j)] returns the result of accumulating the result of 50 | applying f over the interval [i;j]. Identical to 51 | f(j,...f(i+1,f(i,a))...) if i <= j. Returns a if i > j. 52 | 53 | [intToCString i] returns a C syntactic string representation of the 54 | integer i (as a C int). 55 | 56 | [realToCString r] returns a C syntactic string representation of the 57 | real r (as a C double). 58 | 59 | [readfile f] returns the content of the file s. Raises an exception if 60 | the file does not exists or cannot be opened for reading. 61 | 62 | *) 63 | -------------------------------------------------------------------------------- /tests/sierpinski.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 | 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 | 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 | 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 | 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 | 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 | 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 | 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 | 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 | 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 | 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 | 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 | 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 | 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 | 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 | 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 | 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 | 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 21 | 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 22 | 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 23 | 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 24 | 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 25 | 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 26 | 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 27 | 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 28 | 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 29 | 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 30 | 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 31 | 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 32 | 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 33 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 34 | 35 | [](0.0) 36 | -------------------------------------------------------------------------------- /tests/sierpinski0.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 | 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 | 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 | 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 | 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 | 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 | 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 | 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 | 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 | 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 | 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 | 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 | 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 | 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 | 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 | 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 | 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 | 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 21 | 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 22 | 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 23 | 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 24 | 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 25 | 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 26 | 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 27 | 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 28 | 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 29 | 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 30 | 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 31 | 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 32 | 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 33 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 34 | 35 | [](243.0) 36 | -------------------------------------------------------------------------------- /src/util.sml: -------------------------------------------------------------------------------- 1 | 2 | structure Util :> UTIL = struct 3 | 4 | fun curry f a b = f (a,b) 5 | fun uncurry f (a,b) = f a b 6 | 7 | infixr $ 8 | fun f $ e = f e 9 | 10 | fun iter f a (i,j) = 11 | let fun loop a n = if n > j then a 12 | else loop (f (n,a)) (n+1) 13 | in loop a i 14 | end 15 | 16 | (* Association lists *) 17 | type (''a,'b) alist = (''a * 'b) list 18 | fun emptyAlist () = [] 19 | fun extendAlist e (n,v) = (n,v)::e 20 | fun lookupAlist E n = 21 | case List.find (fn (x,_) => x=n) E of 22 | SOME(_,v) => SOME v 23 | | NONE => NONE 24 | fun plusAlist (a1,a2) = a2@a1 25 | 26 | fun listContains s xs = List.exists (curry (op =) s) xs 27 | 28 | (* Printing basic values *) 29 | fun intToCString i = 30 | if i = ~2147483648 then "-2147483648" 31 | else if i < 0 then "-" ^ intToCString (~i) 32 | else Int32.toString i 33 | 34 | fun realToString inf d = 35 | if d < 0.0 then "-" ^ realToString inf (~d) 36 | else 37 | if Real.==(d,Real.posInf) then inf 38 | else 39 | let val s = Real.toString d 40 | val s = String.translate (fn #"~" => "-" 41 | | #"E" => "e" 42 | | c => String.str c) s 43 | in if CharVector.exists (fn c => c = #".") s then s 44 | else if CharVector.exists (fn c => c = #"e") s then s 45 | else s ^ ".0" 46 | end 47 | 48 | fun realToCString d = realToString "HUGE_VAL" d 49 | fun realToTailString d = realToString "inf" d 50 | 51 | (* Add quotes around a string *) 52 | fun quote s = "'" ^ s ^ "'" 53 | 54 | fun prln s = print(s ^ "\n") 55 | fun log verbose f = if verbose then prln(f()) else () 56 | 57 | 58 | (* Minimum and maximum values *) 59 | val minInt = case Int32.minInt of 60 | SOME i => i 61 | | NONE => raise Fail "Util.no minInt" 62 | val maxInt = case Int32.maxInt of 63 | SOME i => i 64 | | NONE => raise Fail "Util.no maxInt" 65 | 66 | 67 | (* File manipulation *) 68 | fun readFile f = 69 | let val is = case f of 70 | "-" => TextIO.stdIn 71 | | _ => TextIO.openIn f 72 | in let val s = TextIO.inputAll is 73 | in TextIO.closeIn is; 74 | s 75 | end handle ? => (TextIO.closeIn is; raise ?) 76 | end 77 | 78 | end 79 | -------------------------------------------------------------------------------- /doc/comp.md: -------------------------------------------------------------------------------- 1 | ## Compiling APL 2 | 3 | Source language 4 | 5 | e ::= i | e1;e2 | e1+e2 | x<-e | x | lam e | x(e) 6 | 7 | Dynamically typed __terms__: 8 | 9 | ```sml 10 | type mi = Int Num m (* Multidimensional integer array *) 11 | 12 | datatype s = (* Terms *) 13 | Is of INT (* integer *) 14 | | Ais of mi (* integer array *) 15 | | Fs of s -> s M (* function in-lining *) 16 | ``` 17 | 18 | Environments (G) map identifiers (variables and symbols) to terms: 19 | 20 | G \in ENV = ID -> s 21 | 22 | Compilation: 23 | 24 | [ _ ] _ _ : AST -> ENV -> (s * ENV -> s M) -> s M 25 | 26 | [i] G k = k (Is(I i),{}) 27 | 28 | [e1; e2] G k = 29 | [e1] G (fn (s1,G1) => 30 | [e2] (G1@G) (fn (s2,G2) => 31 | k (s2,G2@G1))) 32 | 33 | [e1 + e2] G k = 34 | [e2] G (fn (s2,G2) => 35 | [e1] (G2@G) (fn (s1,G1) => 36 | case (s1, s2) of 37 | (Is i1, Is i2) => k(Is(i1+i2),G2@G1) 38 | | (Ais a1, Ais a2) => mmap2 (op +) a1 a2 >>= (fn x => k(Ais x,G2@G1)) 39 | | (Ais a1, Is i2) => k(Ais(mmap(fn x => x+i2)a1),G2@G1) 40 | | (Is i1, Ais a2) => k(Ais(mmap(fn x => i1+x)a2),G2@G1) 41 | | _ => err)) 42 | 43 | [v <- e] G k = 44 | [e] G (fn (s,_) => k(s,{v->s})) 45 | 46 | [a] G k = k (G(a),{}) 47 | 48 | [lam e] G k = 49 | let f x = 50 | let G' = {w -> x} 51 | in [e] (G'@G) (fn (s,_) => ret s) 52 | in k(Fs f,{}) 53 | end 54 | 55 | [a(e)] G k = 56 | case G(a) of 57 | Fs f => 58 | [e] G (fn (s,G') => 59 | f s >>= (fn s' => k(s',G'))) 60 | | _ => err 61 | 62 | ## Compiling into TAIL (simplified) 63 | 64 | opr ::= reduce[1,2] | map[1,1] | transpose[0,1] | out[2,2] 65 | | add[0,2] | mul[0,2] | max[0,2] | min[0,2] 66 | 67 | a ::= 68 | 69 | e ::= a | x | let x = e in e | fun f (x1,...,xn) = e in e 70 | | f(e1,...,en) | opr [f1,...,fn] (e1,...,em) 71 | 72 | [ _ ] _ : AST -> E -> (ML -> E -> ML) -> ML 73 | 74 | [x] E k = k E x 75 | 76 | [a] E k = k E a 77 | 78 | [x<-e] E k = let x = [e] E (fn _ x => x) in k (E+{x->x}) x 79 | 80 | [e1;e2] E k = [e1] E (fn E x => [e2] E k) 81 | 82 | [e1+e2] k = [e2] E (fn E x => [e1] E (fn E y => k E (add[](y,x)))) 83 | 84 | [lam e] E k = 85 | fun f (w) = [e] (E+{w->w}) (fn _ x => x) 86 | in k E f 87 | 88 | [x(e)] E k = [e] E (fn E y => k E (E(x)(y))) 89 | 90 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | 5 | push: 6 | branches: [ master ] 7 | 8 | tags: 9 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 10 | 11 | pull_request: 12 | branches: [ master ] 13 | 14 | # Allows you to run this workflow manually from the Actions tab 15 | workflow_dispatch: 16 | 17 | jobs: 18 | 19 | build-test: 20 | 21 | strategy: 22 | matrix: 23 | os: [ubuntu-20.04, macos-12] 24 | mlcomp: [mlkit, mlton] 25 | # mlcomp: [mlton] 26 | 27 | runs-on: ${{ matrix.os }} 28 | 29 | steps: 30 | 31 | - uses: actions/checkout@v2 32 | 33 | - name: Setup environment 34 | run: | 35 | echo "OS=$(uname -s | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV 36 | echo "RUNHOME=$(echo $HOME)" >> $GITHUB_ENV 37 | 38 | - name: Install MLKit and smlpkg 39 | working-directory: ${{ env.RUNHOME }} 40 | run: | 41 | echo "[OS: $OS, HOME: $RUNHOME]" 42 | wget https://github.com/diku-dk/smlpkg/releases/download/v0.1.4/smlpkg-bin-dist-${{env.OS}}.tgz 43 | tar xzf smlpkg-bin-dist-${{env.OS}}.tgz 44 | echo "$HOME/smlpkg-bin-dist-${{env.OS}}/bin" >> $GITHUB_PATH 45 | wget https://github.com/melsman/mlkit/releases/download/v4.7.11/mlkit-bin-dist-${{env.OS}}.tgz 46 | tar xzf mlkit-bin-dist-${{env.OS}}.tgz 47 | echo "$HOME/mlkit-bin-dist-${{env.OS}}/bin" >> $GITHUB_PATH 48 | mkdir -p .mlkit 49 | echo "SML_LIB $HOME/mlkit-bin-dist-${{env.OS}}/lib/mlkit" > .mlkit/mlb-path-map 50 | 51 | - name: Check 52 | run: | 53 | mlkit --version 54 | smlpkg --version 55 | echo 'github.event_name: ' ${{ github.event_name }} 56 | echo 'github.ref: ' ${{ github.ref }} 57 | 58 | - name: Install MLton (linux) 59 | if: ${{ env.OS == 'linux' && matrix.mlcomp == 'mlton' }} 60 | run: | 61 | sudo apt-get install -y mlton 62 | mlton 63 | 64 | - name: Install MLton (macos) 65 | if: ${{ env.OS == 'darwin' && matrix.mlcomp == 'mlton' }} 66 | run: | 67 | brew install mlton 68 | mlton 69 | 70 | - name: Build 71 | run: MLCOMP=${{ matrix.mlcomp }} make clean all 72 | 73 | - name: Run tests 74 | run: MLCOMP=${{ matrix.mlcomp }} make test 75 | 76 | - name: Make binary distribution 77 | if: ${{ matrix.mlcomp == 'mlton' }} 78 | run: make dist 79 | 80 | - name: Upload release 81 | if: ${{ matrix.mlcomp == 'mlton' && github.event_name == 'push' && contains(github.ref, '/tags/v') }} 82 | uses: svenstaro/upload-release-action@v2 83 | with: 84 | repo_token: ${{ secrets.GITHUB_TOKEN }} 85 | file: dist/apltail-bin-dist-${{ env.OS }}.tgz 86 | tag: ${{ github.ref }} 87 | overwrite: true 88 | -------------------------------------------------------------------------------- /tests/inv.apl: -------------------------------------------------------------------------------- 1 | ⍝ Copyright 2016, Martin Elsman 2 | ⍝ MIT License 3 | ⍝ 4 | ⍝ Matrix inverse 5 | 6 | ⍝ [id n] returns an n×n identity matrix 7 | id ← {(⍳⍵)∘.=⍳⍵} 8 | 9 | else ← {(⍺⍺⍣⍺)(⍵⍵⍣(~⍺))⍵} 10 | 11 | ⍝ [n swap1 m] swaps row n in m with the first row 12 | swap1 ← { 13 | n ← ⍺ 14 | (n = 1) { ⍵ } else { 15 | row ← 1↑(n-1)↓⍵ 16 | fst ← 1↑⍵ 17 | pre ← 1↓(n-1)↑⍵ 18 | suf ← n↓⍵ 19 | row ⍪ pre ⍪ fst ⍪ suf 20 | } ⍵ 21 | } 22 | 23 | swap ← { 24 | x ← ⍺[1] 25 | y ← ⍺[2] 26 | (x=y) { ⍵ } else { 27 | x swap1 (y swap1 (x swap1 ⍵)) 28 | } ⍵ 29 | } 30 | 31 | ⍝ [normVec v] normalizes a vector to have a leading 1 (assumes non-zero first element) 32 | normVec ← { ⍵ ÷ ⊃ ⍵ } 33 | 34 | normFirst ← { 35 | (normVec 1↑⍵) ⍪ 1↓⍵ 36 | } 37 | 38 | normByPivot ← { 39 | v ← ⊃ (⍺-1)↓⍉(⍺-1)↓⍵ 40 | ⍝ v ← (⍵[⍺])[⍺] 41 | pre ← (⍺-1)↑⍵ 42 | rest ← (⍺-1)↓⍵ 43 | row ← 1↑rest 44 | suf ← 1↓rest 45 | pre ⍪ (row ÷ v) ⍪ suf 46 | } 47 | 48 | ⍝ ⎕ ← 'Tests of normByPivot' 49 | ⍝ arg ← 1 ⌽ 5 5 ⍴ ⍳ 8 50 | ⍝ ⎕ ← arg 51 | ⍝ ⎕ ← 2 normByPivot arg 52 | 53 | ⍝ [n maxColIdx m] returns the index of the largest element in column n of m 54 | maxColIdx ← { 55 | c ← ,1↑(⍺-1)↓⍉⍵ 56 | m ← ⌈/c 57 | ⌈/(⍳⊃⍴⍵)×({⍵=m}¨c) 58 | } 59 | 60 | ⍝ ⎕ ← 'Tests of maxColIdx' 61 | ⍝ ⎕ ← 1 maxColIdx 2 ⊖ 3 ⌽ 5 5 ⍴ ⍳ 100 ⍝ => 3 62 | ⍝ ⎕ ← 3 maxColIdx 1 ⊖ 3 ⌽ 5 5 ⍴ ⍳ 100 ⍝ => 4 63 | 64 | ⍝ [n maxColIdxSub m] returns the index of the largest element in the 65 | ⍝ first column of the lower-right sub-matrix of m (indexed by n) 66 | maxColIdxSub ← { 67 | ⍺ maxColIdx (⍺-1)↓⍵ 68 | } 69 | 70 | ⍝ ⎕ ← 'Tests of maxColIdxSub' 71 | ⍝ ⎕ ← 1 maxColIdxSub 2 ⊖ 3 ⌽ 5 5 ⍴ ⍳ 100 ⍝ => 3 72 | ⍝ ⎕ ← 3 maxColIdxSub 1 ⊖ 3 ⌽ 5 5 ⍴ ⍳ 100 ⍝ => 2 73 | ⍝ ⎕ ← 5 maxColIdxSub 1 ⊖ 3 ⌽ 5 5 ⍴ ⍳ 100 ⍝ => 1 74 | 75 | zerofront ← { 76 | v ← ,1↑⍉⍵ 77 | m ← v ∘.× ,⍺ 78 | ⍵ - m 79 | } 80 | 81 | zeroPivot ← { 82 | i ← ⍺ 83 | pre ← (i-1)↑⍵ 84 | rest ← (i-1)↓⍵ 85 | suf ← 1↓rest 86 | r ← 1↑rest 87 | onPart ← { 88 | v ← ,1↑(i-1)↓⍉⍵ 89 | m ← v ∘.× ,r 90 | ⍵ - m 91 | } 92 | (onPart pre) ⍪ r ⍪ onPart suf 93 | } 94 | 95 | inv ← { 96 | n ← ⊃ ⍴ ⍵ 97 | R ← ⍵ , id n 98 | R ← (1 ((⍴R)[2]) ⍴ 1.0) ⍪ R ⍝ Hack to pass the pivot index around 99 | looper ← { 100 | R ← ⍵ 101 | i ← ⌈ ⊃,R ⍝ Extract pivot index 102 | R ← 1↓R ⍝ Extract array 103 | m ← i maxColIdxSub R 104 | R ← (i,m+i-1) swap R 105 | R ← i normByPivot R 106 | R ← i zeroPivot R 107 | R ← (1 ((⍴R)[2]) ⍴ (i+1.0)) ⍪ R ⍝ Increase pivot index 108 | } 109 | R ← (looper ⍣ n) R 110 | R ← 1↓R ⍝ Extract array 111 | ⍉n↓⍉R ⍝ Cut off identity matrix 112 | } 113 | 114 | 115 | ⍝ Examples 116 | A ← 3 3 ⍴ 1 ⌽ ⍉ ⍳ 9 117 | ⎕ ← A 118 | ⎕ ← inv A 119 | 120 | B ← 2 2 ⍴ 4 7 2 6 121 | ⎕ ← B 122 | ⎕ ← inv B 123 | 124 | ⍝ ⎕ ← inv 4 4 ⍴ 4 0 0 0 0 0 2 0 0 1 2 0 1 0 0 1 125 | 126 | 127 | 0 -------------------------------------------------------------------------------- /src/tail/apl.sig: -------------------------------------------------------------------------------- 1 | (** APL style operations on multi-dimensional arrays *) 2 | 3 | (* Scalar-extension and identity items are assumed already to be 4 | * resolved. *) 5 | 6 | signature APL = sig 7 | type 'a APLArray 8 | val scl : 'a -> 'a -> 'a APLArray (* scl default value *) 9 | val unScl : string -> 'a APLArray -> 'a 10 | val vec : 'a -> 'a list -> 'a APLArray 11 | val zilde : 'a -> 'a APLArray 12 | val liftU : 'b -> ('a -> 'b) -> 'a APLArray -> 'b APLArray 13 | val liftB : 'c -> ('a * 'b -> 'c) -> 'a APLArray * 'b APLArray -> 'c APLArray 14 | val map : 'b -> ('a -> 'b) -> 'a APLArray -> 'b APLArray 15 | 16 | val shape : 'a APLArray -> Int32.int APLArray 17 | val reshape : Int32.int APLArray * 'a APLArray -> 'a APLArray 18 | val ravel : 'a APLArray -> 'a APLArray 19 | val iota : Int32.int APLArray -> Int32.int APLArray 20 | val each : 'b -> ('a APLArray -> 'b APLArray) -> 'a APLArray -> 'b APLArray 21 | val power : ('a APLArray -> 'a APLArray) -> Int32.int APLArray -> 'a APLArray -> 'a APLArray 22 | val reduce : ('a APLArray * 'a APLArray -> 'a APLArray) -> 'a APLArray -> 'a APLArray -> 'a APLArray 23 | val scan : ('a APLArray * 'a APLArray -> 'a APLArray) -> 'a APLArray -> 'a APLArray 24 | val gradeUp : ('a * 'a -> bool) -> 'a APLArray -> Int32.int APLArray 25 | val gradeDown : ('a * 'a -> bool) -> 'a APLArray -> Int32.int APLArray 26 | val catenate : 'a APLArray * 'a APLArray -> 'a APLArray 27 | val cons : 'a APLArray * 'a APLArray -> 'a APLArray 28 | val snoc : 'a APLArray * 'a APLArray -> 'a APLArray 29 | (* 30 | val dot : ('c APLArray * 'c APLArray -> 'c APLArray) -> ('a APLArray * 'b APLArray -> 'c APLArray) 31 | -> 'c APLArray -> 'a APLArray -> 'b APLArray -> 'c APLArray 32 | *) 33 | val zipWith : 'c -> ('a APLArray * 'b APLArray -> 'c APLArray) -> 'a APLArray -> 'b APLArray -> 'c APLArray 34 | val transpose : 'a APLArray -> 'a APLArray 35 | val transpose2: Int32.int APLArray * 'a APLArray -> 'a APLArray 36 | val vreverse : 'a APLArray -> 'a APLArray 37 | val vrotate : Int32.int APLArray * 'a APLArray -> 'a APLArray 38 | val reverse : 'a APLArray -> 'a APLArray 39 | val rotate : Int32.int APLArray * 'a APLArray -> 'a APLArray 40 | val drop : Int32.int APLArray * 'a APLArray -> 'a APLArray 41 | val take : Int32.int APLArray * 'a APLArray -> 'a APLArray 42 | val first : 'a APLArray -> 'a APLArray 43 | val iff : bool APLArray * (unit -> 'a APLArray) * (unit -> 'a APLArray) -> 'a APLArray 44 | 45 | val compress : bool APLArray * 'a APLArray -> 'a APLArray 46 | val replicate : Int32.int APLArray * 'a APLArray -> 'a APLArray 47 | val idxassign : Int32.int APLArray * 'a APLArray * 'a -> unit 48 | val idxS : Int32.int APLArray * Int32.int APLArray * 'a APLArray -> 'a APLArray 49 | (* val idx : Int32.int APLArray * Int32.int APLArray * 'a APLArray -> 'a APLArray *) 50 | 51 | val pr : ('a -> string) * string -> 'a APLArray -> string 52 | end 53 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #MLKIT=SML_LIB=/Users/mael/gits/mlkit /Users/mael/gits/mlkit/bin/mlkit 2 | 3 | #MLCOMP ?= mlkit 4 | 5 | MLCOMP ?= mlton 6 | SMLPKG ?= smlpkg 7 | 8 | FILES=src/flags.sml src/flags.mlb src/aplt.sml src/aplt.mlb \ 9 | src/apl2tail.mlb src/Apl2Tail.sml src/Tail2Laila.sml \ 10 | src/util.sig src/util.sml src/util.mlb \ 11 | $(shell ls -1 src/tail/*.sig src/tail/*.sml src/tail/*.mlb) \ 12 | $(shell ls -1 src/il/*.sig src/il/*.sml src/il/*.mlb) \ 13 | $(shell ls -1 src/laila/*.sig src/laila/*.sml src/laila/*.mlb) 14 | 15 | PREFIX ?= . 16 | DESTDIR ?= $(PREFIX)/dist 17 | 18 | GIT_VERSION := $(shell git --no-pager describe --tags --always --dirty) 19 | GIT_DATE := $(firstword $(shell git --no-pager show --date=short --format="%ad" --name-only)) 20 | PLATFORM := $(shell uname -pmrs) 21 | 22 | .PHONY: all 23 | all: aplt 24 | 25 | # Use temp file src/version~ to ensure regeneration of src/version.sml 26 | # whenever (and only when) the git version changes... 27 | .PHONY: force 28 | src/version~: force 29 | @echo '$(GIT_VERSION) $(GIT_DATE)' | cmp -s - $@ || echo '$(GIT_VERSION) $(GIT_DATE)' > $@ 30 | 31 | src/version.sml: src/version~ 32 | @echo "structure Version = struct\n\ 33 | val version = \"$(GIT_VERSION)\"\n\ 34 | val date = \"$(GIT_DATE)\"\n\ 35 | val platform = \"$(PLATFORM)\"\nend" > $@ 36 | @echo Generated file $@ 37 | @echo Git version $(GIT_VERSION) $(GIT_DATE) 38 | 39 | aplt: src/aplt.mlb $(FILES) src/aplt.sml src/version.sml src/lib/github.com/diku-dk/sml-aplparse 40 | $(MLCOMP) -output $@ $< 41 | 42 | .PHONY: install 43 | install: 44 | cp -p aplt $(DESTDIR)/bin/ 45 | 46 | OS=$(shell uname -s | tr '[:upper:]' '[:lower:]') 47 | 48 | DISTNAME=apltail-bin-dist-$(OS) 49 | 50 | .PHONY: dist 51 | dist: aplt 52 | rm -rf dist 53 | mkdir dist 54 | mkdir dist/$(DISTNAME) 55 | mkdir dist/$(DISTNAME)/bin 56 | mkdir -p dist/$(DISTNAME)/lib/apltail 57 | mkdir -p dist/$(DISTNAME)/include/apltail 58 | mkdir -p dist/$(DISTNAME)/share/apltail/tests 59 | mkdir -p dist/$(DISTNAME)/share/apltail/doc 60 | cp -p aplt dist/$(DISTNAME)/bin/ 61 | cp -p lib/prelude.apl dist/$(DISTNAME)/lib/apltail/ 62 | cp -p include/apl.h dist/$(DISTNAME)/include/apltail/ 63 | cp -p tests/Makefile tests/*.out.ok tests/*.apl tests/*.txt dist/$(DISTNAME)/share/apltail/tests/ 64 | cp -p MIT_LICENSE.md dist/$(DISTNAME)/share/apltail/doc/MIT_LICENSE 65 | cp -p doc/README_BIN dist/$(DISTNAME)/share/apltail/doc/README 66 | echo 'PREFIX?=/usr/local' > dist/$(DISTNAME)/Makefile 67 | echo '.PHONY: install' >> dist/$(DISTNAME)/Makefile 68 | echo 'install:' >> dist/$(DISTNAME)/Makefile 69 | echo "\t"'for d in $$$$(find * -type d); do install -d "$$(PREFIX)/$$$$d"; done' \ 70 | >> dist/$(DISTNAME)/Makefile 71 | echo "\t"'for f in $$$$(find * -type f | grep -v Makefile); do install -p "$$$$f" "$$(PREFIX)/$$$$f"; done' \ 72 | >> dist/$(DISTNAME)/Makefile 73 | (cd dist; tar -czf $(DISTNAME).tgz $(DISTNAME)) 74 | 75 | .PHONY: test 76 | test: aplt Makefile 77 | $(MAKE) -C tests test testc 78 | 79 | .PHONY: prepare 80 | prepare: 81 | (cd src; $(SMLPKG) sync) 82 | 83 | .PHONY: clean 84 | clean: Makefile 85 | find . -name '*~' | xargs rm -f 86 | find . -name 'MLB' | xargs rm -rf 87 | find . -name 'run' | xargs rm -f 88 | rm -f aplt src/version.sml 89 | $(MAKE) -C tests clean 90 | 91 | src/lib/github.com/diku-dk/sml-aplparse: 92 | (cd src; $(SMLPKG) sync) 93 | -------------------------------------------------------------------------------- /src/tail/tail_exp.sig: -------------------------------------------------------------------------------- 1 | (** Tail expression terms. This interface exposes the structure of 2 | TAIL expressions. It also provides evaluation and type 3 | checking/inference functionality. 4 | *) 5 | 6 | signature TAIL_EXP = sig 7 | 8 | structure T : TAIL_TYPE 9 | 10 | type rnk = T.rnk 11 | type typ = T.typ 12 | type opr = string 13 | 14 | (* Variables are initially immutable, but if we discover an 15 | index-assignment, we change the variable it is updating to be 16 | mutable. *) 17 | eqtype var 18 | val newVar : unit -> var (* create new immutable variable *) 19 | val mutableVar : var -> bool ref (* get reference to get/set whether this variable is mutable *) 20 | 21 | (* Finite map's keyed by TAIL-variables *) 22 | structure FM : sig 23 | type dom = var 24 | type 'b map 25 | val empty : 'b map 26 | val singleton : dom * 'b -> 'b map 27 | val lookup : 'b map -> dom -> 'b option 28 | val add : dom * 'b * 'b map -> 'b map 29 | val plus : 'a map * 'a map -> 'a map 30 | val merge : ('a * 'a -> 'a) -> 'a map -> 'a map -> 'a map 31 | val map : ('a -> 'b) -> 'a map -> 'b map 32 | val remove : dom * 'a map -> 'a map option 33 | end 34 | 35 | (* TAIL AST *) 36 | datatype uexp = 37 | Var of var * typ 38 | | I of Int32.int 39 | | D of real 40 | | X of real * real 41 | | B of bool 42 | | C of word 43 | | Iff of uexp * uexp * uexp * typ 44 | | Vc of uexp list * typ 45 | | Op of opr * uexp list * typ 46 | | Let of var * typ * uexp * uexp * typ 47 | | Fn of var * typ * uexp * typ 48 | | Tuple of uexp list * typ 49 | | Prj of int * uexp * typ 50 | 51 | (* Type environment *) 52 | type env 53 | val lookup : env -> var -> typ option 54 | val emptyEnv : env 55 | val add : env -> var -> typ -> env 56 | 57 | (* Type-checking *) 58 | datatype 't report = OK of 't | ERR of string 59 | val typeExp : env -> uexp -> typ report 60 | 61 | (* Walk the syntax tree, mark each operator that works on 62 | shape-types (appends "V" to the end of the operation name) *) 63 | val resolveShOpr : uexp -> uexp 64 | 65 | (* Alternative constructors that checks the types upon 66 | construction. May raise Fail. *) 67 | val Iff_e : uexp * uexp * uexp -> uexp 68 | val Vc_e : uexp list -> uexp 69 | val Op_e : opr * uexp list -> uexp 70 | val Let_e : var * typ * uexp * uexp -> uexp 71 | val Fn_e : var * typ * uexp -> uexp 72 | val Tuple_e : uexp list -> uexp 73 | val Prj_e : int * uexp -> uexp 74 | val unTuple : uexp -> uexp list option 75 | 76 | (* Get the type of a TAIL-expression *) 77 | val typeOf : uexp -> typ 78 | 79 | (* Values & Stores *) 80 | type value 81 | type denv 82 | val emptyDEnv : denv 83 | val addDE : denv -> var -> value -> denv 84 | val Dvalue : real -> value 85 | val unDvalue : value -> real 86 | val Xvalue : real * real -> value 87 | val unXvalue : value -> real * real 88 | val Uvalue : value (* = Dvalue 0.0 ? *) 89 | 90 | (* Evaluate an expression in the given environment *) 91 | val eval : denv -> uexp -> value 92 | 93 | (* Pretty printing variables, values and characters *) 94 | val ppVar : var -> string 95 | val pr_value : value -> string 96 | val pr_char : word -> string 97 | end 98 | -------------------------------------------------------------------------------- /src/tail/tail_type.sig: -------------------------------------------------------------------------------- 1 | (** Type structure for TAIL programs. The interface is highly 2 | imperative as types may be unified using operations such as 3 | relateR, relateR2, unifyR, unifyB, unify, and subtype. 4 | 5 | r ::= Ranks 6 | rv rank variable 7 | i immediate rank 8 | k ::= Base types 9 | bv base type variable 10 | bool boolean 11 | int integer 12 | double double 13 | complex complex 14 | char character 15 | t ::= Types 16 | tv type variable 17 | [k]r array type with base type b and rank r 18 | r vector type with base type b and length r (i.e., shape vector) 19 | S_k(r) singleton type of base type b and value r 20 | SV_k(r) singleton one-element vector type containing the value r of type b 21 | t -> t function type 22 | t1*...*tn tuple 23 | *) 24 | 25 | signature TAIL_TYPE = sig 26 | datatype unify_result = SUCCESS | ERROR of string 27 | 28 | (* Ranks (\rho) *) 29 | type rnk 30 | val rnk : int -> rnk 31 | val unRnk : rnk -> int option 32 | val RnkVar : unit -> rnk (* generate new shape variable *) 33 | val RnkVarCon : (int-> unify_result) -> rnk 34 | (* val relateR : (int -> int) * (int -> int) -> rnk -> rnk -> string option *) 35 | (* val relateR2 : {f12: int*int->int,f13:int*int->int,f23:int*int->int} -> *) 36 | (* rnk -> rnk -> rnk -> string option *) 37 | val unifyR : rnk -> rnk -> unify_result (* unify two shape variables. *) 38 | val prRnk : rnk -> string 39 | 40 | (* Base types (\kappa) *) 41 | type bty 42 | val IntB : bty 43 | val BoolB : bty 44 | val DoubleB : bty 45 | val ComplexB : bty 46 | val CharB : bty 47 | val isInt : bty -> bool 48 | val isDouble : bty -> bool 49 | val isComplex: bty -> bool 50 | val isBool : bty -> bool 51 | val isChar : bty -> bool 52 | val TyVarB : unit -> bty (* generate new base type variable *) 53 | val unifyB : bty -> bty -> unify_result (* unify two base type variables *) 54 | val prBty : bty -> string 55 | 56 | (* Types (\tau) *) 57 | type typ 58 | val Arr : bty -> rnk -> typ (* Array type [k]r *) 59 | val Vcc : bty -> rnk -> typ (* Vector type r *) 60 | val S : bty -> rnk -> typ (* singleton *) 61 | val SV : bty -> rnk -> typ (* singleton vector *) 62 | val Fun : typ * typ -> typ 63 | val Tup : typ list -> typ 64 | val prj : int -> typ -> typ (* takes the projection type as argument and returns the type of the tuple as a type variable *) 65 | 66 | (* Type abbreviations *) 67 | val Int : typ 68 | val Bool : typ 69 | val Double : typ 70 | val Complex : typ 71 | val Char : typ 72 | val Scl : bty -> typ (* [bty]0 *) 73 | val VecB : bty -> typ (* [bty]1 *) 74 | val Vec : typ -> typ (* asserts argument is scalar *) 75 | 76 | (* Type deconstructors *) 77 | val unArr : typ -> (bty * rnk) option 78 | val unVcc : typ -> (bty * rnk) option 79 | val unS : typ -> (bty * rnk) option 80 | val unSV : typ -> (bty * rnk) option 81 | val unFun : typ -> (typ * typ) option 82 | val unArr' : typ -> (bty * rnk) option (* also returns values for Vcc,S,SV *) 83 | val unTup : typ -> typ list option 84 | 85 | val TyVar : unit -> typ (* create type variable *) 86 | val subtype : typ -> typ -> unify_result (* is subtype *) 87 | val unify : typ -> typ -> unify_result (* unify two type variables *) 88 | val join : typ -> typ -> typ (* least common supertype; may raise Fail *) 89 | val prType : typ -> string 90 | end 91 | -------------------------------------------------------------------------------- /tests/life.out.ok: -------------------------------------------------------------------------------- 1 | 2 | 0 0 0 0 0 0 0 0 0 0 3 | 0 0 0 0 0 0 0 0 0 0 4 | 0 0 0 0 0 0 0 0 0 0 5 | 0 0 0 0 0 0 0 0 0 0 6 | 0 0 0 0 0 0 0 0 0 0 7 | 0 0 0 0 0 0 0 0 0 0 8 | 0 0 0 0 0 0 0 0 1 0 9 | 0 0 0 0 0 0 0 1 1 0 10 | 0 0 0 0 0 0 0 1 0 1 11 | 0 0 0 0 0 0 0 0 0 0 12 | 13 | 14 | 0 0 0 0 0 0 0 0 0 0 15 | 0 0 0 0 0 0 0 0 0 0 16 | 0 0 0 0 0 0 0 0 0 0 17 | 0 0 0 0 0 0 0 0 0 0 18 | 0 0 0 0 0 0 0 0 0 0 19 | 0 0 0 0 0 0 0 0 0 0 20 | 0 0 0 0 0 0 0 1 1 0 21 | 0 0 0 0 0 0 0 1 0 1 22 | 0 0 0 0 0 0 0 1 0 0 23 | 0 0 0 0 0 0 0 0 0 0 24 | 25 | 26 | 0 0 0 0 0 0 0 0 0 0 27 | 0 0 0 0 0 0 0 0 0 0 28 | 0 0 0 0 0 0 0 0 0 0 29 | 0 0 0 0 0 0 0 0 0 0 30 | 0 0 0 0 0 0 0 0 0 0 31 | 0 0 0 0 0 0 0 0 0 0 32 | 0 0 0 0 0 0 0 1 1 0 33 | 0 0 0 0 0 0 1 1 0 0 34 | 0 0 0 0 0 0 0 0 1 0 35 | 0 0 0 0 0 0 0 0 0 0 36 | 37 | 38 | 0 0 0 0 0 0 0 0 0 0 39 | 0 0 0 0 0 0 0 0 0 0 40 | 0 0 0 0 0 0 0 0 0 0 41 | 0 0 0 0 0 0 0 0 0 0 42 | 0 0 0 0 0 0 0 0 0 0 43 | 0 0 0 0 0 0 0 0 0 0 44 | 0 0 0 0 0 0 1 1 1 0 45 | 0 0 0 0 0 0 1 0 0 0 46 | 0 0 0 0 0 0 0 1 0 0 47 | 0 0 0 0 0 0 0 0 0 0 48 | 49 | 50 | 0 0 0 0 0 0 0 0 0 0 51 | 0 0 0 0 0 0 0 0 0 0 52 | 0 0 0 0 0 0 0 0 0 0 53 | 0 0 0 0 0 0 0 0 0 0 54 | 0 0 0 0 0 0 0 0 0 0 55 | 0 0 0 0 0 0 0 1 0 0 56 | 0 0 0 0 0 0 1 1 0 0 57 | 0 0 0 0 0 0 1 0 1 0 58 | 0 0 0 0 0 0 0 0 0 0 59 | 0 0 0 0 0 0 0 0 0 0 60 | 61 | 62 | 0 0 0 0 0 0 0 0 0 0 63 | 0 0 0 0 0 0 0 0 0 0 64 | 0 0 0 0 0 0 0 0 0 0 65 | 0 0 0 0 0 0 0 0 0 0 66 | 0 0 0 0 0 0 0 0 0 0 67 | 0 0 0 0 0 0 1 1 0 0 68 | 0 0 0 0 0 0 1 0 1 0 69 | 0 0 0 0 0 0 1 0 0 0 70 | 0 0 0 0 0 0 0 0 0 0 71 | 0 0 0 0 0 0 0 0 0 0 72 | 73 | 74 | 0 0 0 0 0 0 0 0 0 0 75 | 0 0 0 0 0 0 0 0 0 0 76 | 0 0 0 0 0 0 0 0 0 0 77 | 0 0 0 0 0 0 0 0 0 0 78 | 0 0 0 0 0 0 0 0 0 0 79 | 0 0 0 0 0 0 1 1 0 0 80 | 0 0 0 0 0 1 1 0 0 0 81 | 0 0 0 0 0 0 0 1 0 0 82 | 0 0 0 0 0 0 0 0 0 0 83 | 0 0 0 0 0 0 0 0 0 0 84 | 85 | 86 | 0 0 0 0 0 0 0 0 0 0 87 | 0 0 0 0 0 0 0 0 0 0 88 | 0 0 0 0 0 0 0 0 0 0 89 | 0 0 0 0 0 0 0 0 0 0 90 | 0 0 0 0 0 0 0 0 0 0 91 | 0 0 0 0 0 1 1 1 0 0 92 | 0 0 0 0 0 1 0 0 0 0 93 | 0 0 0 0 0 0 1 0 0 0 94 | 0 0 0 0 0 0 0 0 0 0 95 | 0 0 0 0 0 0 0 0 0 0 96 | 97 | 98 | 0 0 0 0 0 0 0 0 0 0 99 | 0 0 0 0 0 0 0 0 0 0 100 | 0 0 0 0 0 0 0 0 0 0 101 | 0 0 0 0 0 0 0 0 0 0 102 | 0 0 0 0 0 0 1 0 0 0 103 | 0 0 0 0 0 1 1 0 0 0 104 | 0 0 0 0 0 1 0 1 0 0 105 | 0 0 0 0 0 0 0 0 0 0 106 | 0 0 0 0 0 0 0 0 0 0 107 | 0 0 0 0 0 0 0 0 0 0 108 | 109 | 110 | 0 0 0 0 0 0 0 0 0 0 111 | 0 0 0 0 0 0 0 0 0 0 112 | 0 0 0 0 0 0 0 0 0 0 113 | 0 0 0 0 0 0 0 0 0 0 114 | 0 0 0 0 0 1 1 0 0 0 115 | 0 0 0 0 0 1 0 1 0 0 116 | 0 0 0 0 0 1 0 0 0 0 117 | 0 0 0 0 0 0 0 0 0 0 118 | 0 0 0 0 0 0 0 0 0 0 119 | 0 0 0 0 0 0 0 0 0 0 120 | 121 | 122 | 0 0 0 0 0 0 0 0 0 0 123 | 0 0 0 0 0 0 0 0 0 0 124 | 0 0 0 0 0 0 0 0 0 0 125 | 0 0 0 0 0 0 0 0 0 0 126 | 0 0 0 0 0 1 1 0 0 0 127 | 0 0 0 0 1 1 0 0 0 0 128 | 0 0 0 0 0 0 1 0 0 0 129 | 0 0 0 0 0 0 0 0 0 0 130 | 0 0 0 0 0 0 0 0 0 0 131 | 0 0 0 0 0 0 0 0 0 0 132 | 133 | 134 | 0 0 0 0 0 0 0 0 0 0 135 | 0 0 0 0 0 0 0 0 0 0 136 | 0 0 0 0 0 0 0 0 0 0 137 | 0 0 0 0 0 0 0 0 0 0 138 | 0 0 0 0 1 1 1 0 0 0 139 | 0 0 0 0 1 0 0 0 0 0 140 | 0 0 0 0 0 1 0 0 0 0 141 | 0 0 0 0 0 0 0 0 0 0 142 | 0 0 0 0 0 0 0 0 0 0 143 | 0 0 0 0 0 0 0 0 0 0 144 | 145 | 146 | 0 0 0 0 0 0 0 0 0 0 147 | 0 0 0 0 0 0 0 0 0 0 148 | 0 0 0 0 0 0 0 0 0 0 149 | 0 0 0 0 0 1 0 0 0 0 150 | 0 0 0 0 1 1 0 0 0 0 151 | 0 0 0 0 1 0 1 0 0 0 152 | 0 0 0 0 0 0 0 0 0 0 153 | 0 0 0 0 0 0 0 0 0 0 154 | 0 0 0 0 0 0 0 0 0 0 155 | 0 0 0 0 0 0 0 0 0 0 156 | 157 | 158 | 0 0 0 0 0 0 0 0 0 0 159 | 0 0 0 0 0 0 0 0 0 0 160 | 0 0 0 0 0 0 0 0 0 0 161 | 0 0 0 0 1 1 0 0 0 0 162 | 0 0 0 0 1 0 1 0 0 0 163 | 0 0 0 0 1 0 0 0 0 0 164 | 0 0 0 0 0 0 0 0 0 0 165 | 0 0 0 0 0 0 0 0 0 0 166 | 0 0 0 0 0 0 0 0 0 0 167 | 0 0 0 0 0 0 0 0 0 0 168 | 169 | 170 | 0 0 0 0 0 0 0 0 0 0 171 | 0 0 0 0 0 0 0 0 0 0 172 | 0 0 0 0 0 0 0 0 0 0 173 | 0 0 0 0 1 1 0 0 0 0 174 | 0 0 0 1 1 0 0 0 0 0 175 | 0 0 0 0 0 1 0 0 0 0 176 | 0 0 0 0 0 0 0 0 0 0 177 | 0 0 0 0 0 0 0 0 0 0 178 | 0 0 0 0 0 0 0 0 0 0 179 | 0 0 0 0 0 0 0 0 0 0 180 | 181 | 182 | 0 0 0 0 0 0 0 0 0 0 183 | 0 0 0 0 0 0 0 0 0 0 184 | 0 0 0 0 0 0 0 0 0 0 185 | 0 0 0 1 1 1 0 0 0 0 186 | 0 0 0 1 0 0 0 0 0 0 187 | 0 0 0 0 1 0 0 0 0 0 188 | 0 0 0 0 0 0 0 0 0 0 189 | 0 0 0 0 0 0 0 0 0 0 190 | 0 0 0 0 0 0 0 0 0 0 191 | 0 0 0 0 0 0 0 0 0 0 192 | 193 | 194 | 0 0 0 0 0 0 0 0 0 0 195 | 0 0 0 0 0 0 0 0 0 0 196 | 0 0 0 0 1 0 0 0 0 0 197 | 0 0 0 1 1 0 0 0 0 0 198 | 0 0 0 1 0 1 0 0 0 0 199 | 0 0 0 0 0 0 0 0 0 0 200 | 0 0 0 0 0 0 0 0 0 0 201 | 0 0 0 0 0 0 0 0 0 0 202 | 0 0 0 0 0 0 0 0 0 0 203 | 0 0 0 0 0 0 0 0 0 0 204 | 205 | 206 | 0 0 0 0 0 0 0 0 0 0 207 | 0 0 0 0 0 0 0 0 0 0 208 | 0 0 0 1 1 0 0 0 0 0 209 | 0 0 0 1 0 1 0 0 0 0 210 | 0 0 0 1 0 0 0 0 0 0 211 | 0 0 0 0 0 0 0 0 0 0 212 | 0 0 0 0 0 0 0 0 0 0 213 | 0 0 0 0 0 0 0 0 0 0 214 | 0 0 0 0 0 0 0 0 0 0 215 | 0 0 0 0 0 0 0 0 0 0 216 | 217 | 218 | 0 0 0 0 0 0 0 0 0 0 219 | 0 0 0 0 0 0 0 0 0 0 220 | 0 0 0 1 1 0 0 0 0 0 221 | 0 0 1 1 0 0 0 0 0 0 222 | 0 0 0 0 1 0 0 0 0 0 223 | 0 0 0 0 0 0 0 0 0 0 224 | 0 0 0 0 0 0 0 0 0 0 225 | 0 0 0 0 0 0 0 0 0 0 226 | 0 0 0 0 0 0 0 0 0 0 227 | 0 0 0 0 0 0 0 0 0 0 228 | 229 | 230 | 0 0 0 0 0 0 0 0 0 0 231 | 0 0 0 0 0 0 0 0 0 0 232 | 0 0 1 1 1 0 0 0 0 0 233 | 0 0 1 0 0 0 0 0 0 0 234 | 0 0 0 1 0 0 0 0 0 0 235 | 0 0 0 0 0 0 0 0 0 0 236 | 0 0 0 0 0 0 0 0 0 0 237 | 0 0 0 0 0 0 0 0 0 0 238 | 0 0 0 0 0 0 0 0 0 0 239 | 0 0 0 0 0 0 0 0 0 0 240 | 241 | [](0.0) 242 | -------------------------------------------------------------------------------- /src/laila/laila.sig: -------------------------------------------------------------------------------- 1 | signature LAILA = sig 2 | 3 | include TYPE 4 | 5 | val optimisationLevel : int ref (* -O 2: constant folding on double operations *) 6 | val enableComments : bool ref (* Print comments in generated code *) 7 | val unsafeAsserts : bool ref (* Don't insert asserts for zipWith, etc. *) 8 | val statistics_p : bool ref (* Print statistics *) 9 | val hoist_p : bool ref (* Hoist optimization *) 10 | val loopsplit_p : bool ref (* Loop split optimization *) 11 | 12 | (* Monad encapsulating program construction *) 13 | type 'a M 14 | val >>= : 'a M * ('a -> 'b M) -> 'b M 15 | val ret : 'a -> 'a M 16 | 17 | (* Terms *) 18 | type t 19 | val I : Int32.int -> t 20 | val D : real -> t 21 | val B : bool -> t 22 | val C : word -> t 23 | val i2d : t -> t 24 | val b2i : t -> t 25 | val If : t * t * t -> t 26 | 27 | (* Compiled Programs *) 28 | type prog 29 | val runM : {verbose: bool, optlevel: int} -> T -> t M -> prog 30 | val runF : T * T -> (t -> t M) -> prog 31 | val outprog : string -> prog -> unit 32 | 33 | (* Values and Evaluation *) 34 | type value 35 | val Iv : Int32.int -> value 36 | val unIv : value -> Int32.int (* may fail *) 37 | val Dv : real -> value 38 | val unDv : value -> real (* may fail *) 39 | val Bv : bool -> value 40 | val unBv : value -> bool (* may fail *) 41 | val Vv : value list -> value 42 | val unVv : value -> value list (* may fail *) 43 | val Uv : value 44 | val eval : prog -> value -> value 45 | val pp_prog : prog -> string 46 | val ppV : value -> string 47 | 48 | type INT = t 49 | type DOUBLE = t 50 | type BOOL = t 51 | type CHAR = t 52 | 53 | val assert : string -> BOOL -> 'a M -> 'a M 54 | 55 | val addi : INT * INT -> INT 56 | val subi : INT * INT -> INT 57 | val muli : INT * INT -> INT 58 | val divi : INT * INT -> INT 59 | val resi : INT * INT -> INT 60 | val maxi : INT * INT -> INT 61 | val mini : INT * INT -> INT 62 | val lti : INT * INT -> BOOL 63 | val ltei : INT * INT -> BOOL 64 | val gti : INT * INT -> BOOL 65 | val gtei : INT * INT -> BOOL 66 | val eqi : INT * INT -> BOOL 67 | val neqi : INT * INT -> BOOL 68 | val negi : INT -> INT 69 | val signi : INT -> INT 70 | val absi : INT -> INT 71 | 72 | val ori : INT * INT -> INT 73 | val andi : INT * INT -> INT 74 | val xori : INT * INT -> INT 75 | val shli : INT * INT -> INT 76 | val shri : INT * INT -> INT 77 | val shari : INT * INT -> INT 78 | 79 | val addd : DOUBLE * DOUBLE -> DOUBLE 80 | val subd : DOUBLE * DOUBLE -> DOUBLE 81 | val muld : DOUBLE * DOUBLE -> DOUBLE 82 | val divd : DOUBLE * DOUBLE -> DOUBLE 83 | val resd : DOUBLE * DOUBLE -> DOUBLE 84 | val maxd : DOUBLE * DOUBLE -> DOUBLE 85 | val mind : DOUBLE * DOUBLE -> DOUBLE 86 | val powd : DOUBLE * DOUBLE -> DOUBLE 87 | val ltd : DOUBLE * DOUBLE -> BOOL 88 | val lted : DOUBLE * DOUBLE -> BOOL 89 | val gtd : DOUBLE * DOUBLE -> BOOL 90 | val gted : DOUBLE * DOUBLE -> BOOL 91 | val eqd : DOUBLE * DOUBLE -> BOOL 92 | val neqd : DOUBLE * DOUBLE -> BOOL 93 | val negd : DOUBLE -> DOUBLE 94 | val absd : DOUBLE -> DOUBLE 95 | val expd : DOUBLE -> DOUBLE 96 | val ln : DOUBLE -> DOUBLE 97 | val sin : DOUBLE -> DOUBLE 98 | val cos : DOUBLE -> DOUBLE 99 | val tan : DOUBLE -> DOUBLE 100 | val signd : DOUBLE -> INT 101 | val floor : DOUBLE -> INT 102 | val ceil : DOUBLE -> INT 103 | val pi : DOUBLE 104 | val roll : INT -> DOUBLE (* 0 -> [0;1[ ; n -> [0;n] whole number *) 105 | 106 | val eqc : CHAR * CHAR -> BOOL 107 | 108 | val eqb : BOOL * BOOL -> BOOL 109 | val andb : BOOL * BOOL -> BOOL 110 | val orb : BOOL * BOOL -> BOOL 111 | val xorb : BOOL * BOOL -> BOOL 112 | val notb : BOOL -> BOOL 113 | 114 | (* APL multi-dimensional arrays *) 115 | type m 116 | val zilde : T -> m 117 | val scl : T -> t -> m (* scalar value *) 118 | val enclose : t -> m (* one dimensional vector with one element *) 119 | val iota : INT -> m 120 | val rank : m -> INT 121 | val rav : m -> m M 122 | val dimincr : m -> m (* shape(dimincr(m)) = shape(m)@[1] *) 123 | val each : T -> (t -> t M) -> m -> m 124 | val lett : t -> t M 125 | val letm : m -> m M 126 | val mem : m -> m M 127 | val zipWith : T -> (t * t -> t M) -> m -> m -> m M 128 | val scan : (t * t -> t M) -> m -> m M 129 | val catenate : m -> m -> m M 130 | val take : INT -> m -> m M 131 | val drop : INT -> m -> m M 132 | val first : m -> t M 133 | val rotate : INT -> m -> m (* ok for vectors *) 134 | val vreverse : m -> m M 135 | val vrotate : INT -> m -> m M 136 | val reshape : m -> m -> m M 137 | val shape : m -> m 138 | val reduce : (t * t -> t M) -> t -> m -> (t -> 'b) -> (m -> 'b) -> 'b M 139 | val transpose : m -> m M 140 | val transpose2 : int list -> m -> m M 141 | val compress : m * m -> m M 142 | val replicate : t * m * m -> m M 143 | val power : (m -> m M) -> INT -> m -> m M 144 | val powerScl : (t -> t M) -> INT -> t -> t M 145 | val condScl : (t -> t M) -> BOOL -> t -> t M 146 | val fromListM : T -> t list -> m M 147 | 148 | (* Indexing *) 149 | val idxS : INT -> INT -> m -> (t -> 'b) -> (m -> 'b) -> 'b M 150 | 151 | (* Printing routines *) 152 | val prArr : m -> unit M 153 | val printf : string * t list -> unit M 154 | val sprintf : string * t list -> m M 155 | 156 | (* Time.now *) 157 | val nowi : INT -> INT 158 | 159 | (* Multi-dimensional mutable arrays - used for idxassign *) 160 | type mm 161 | val mk_mm : m -> mm M 162 | val idxassign : m -> mm -> t -> unit M 163 | val mm2m : mm -> m 164 | 165 | (* Reading files *) 166 | val readFile : m -> m M 167 | val readIntVecFile : m -> m M 168 | val readDoubleVecFile : m -> m M 169 | 170 | end 171 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | TESTS=test test1 test2 test3 test4 test5 test6 test7 test9 test10 \ 2 | test11 test12 test13 test14 test15 test16 test19 signal test21 \ 3 | test28 residue mult0 mult sierpinski0 slashbar primes0 compress \ 4 | primes replicate cons boolean innerLegrand5.3 quadassign opr1 \ 5 | opr2 opr3 fun2 take drop vrev vrot rot rotfirst first life \ 6 | powscl pow powmat vec zfunc repl ceilfloormaxmin easter \ 7 | eacheaster else chars shape innerproduct sign ln circ timespi \ 8 | blackscholes pi readfile readintvecfile tax dtransp abcd mean \ 9 | idx tup binaryops fib10 sierpinski idxassign format \ 10 | readdoublevecfile squad expd reduce transpose vowels train0 \ 11 | train trains1 trainatop tally inv inv3 mandelbrot powtup \ 12 | mandelbrotN cmplx compose streak sum35 anagram rav gradeupdown \ 13 | sort athas mandel 14 | 15 | APLFILES=$(TESTS:%=%.apl) 16 | TLFILES=$(APLFILES:%.apl=%.tl) 17 | RESFILES=$(APLFILES:%.apl=%.res) $(APLFILES:%.apl=%.resn) 18 | OUTVFILES=$(APLFILES:%.apl=%.outv) 19 | 20 | PRELUDE?=../lib/prelude.apl 21 | APLT?=../aplt 22 | 23 | .PHONY: all 24 | all: $(TLFILES) test 25 | 26 | %.tl: %.apl Makefile 27 | $(APLT) -s_tail -c -o $@ $(PRELUDE) $< 28 | 29 | %.out: %.apl Makefile 30 | $(APLT) -s_tail -silent $(PRELUDE) $< > $@ 31 | 32 | %.outn: %.apl Makefile 33 | $(APLT) -s_tail -noopt -silent $(PRELUDE) $< > $@ 34 | 35 | %.outv: %.apl Makefile 36 | $(APLT) -s_tail -p_tail -p_types -noopt $(PRELUDE) $< > $@ 37 | 38 | %.res: %.out 39 | @(diff -aq $< $<.ok > /dev/null 2>&1; \ 40 | if [ $$? -eq 0 ]; then \ 41 | echo "Test $*.apl: OK" > $@ \ 42 | ; else \ 43 | if [ -e $<.ok ]; then \ 44 | echo "Test $*.apl: *** ERR: file $< differs from $<.ok ***" > $@ \ 45 | ; else \ 46 | echo "Test $*.apl: *** ERR: file $<.ok does not exist ***" > $@ \ 47 | ; fi \ 48 | ; fi) 49 | 50 | %.resn: %.outn 51 | @(diff -aq $< $*.out.ok > /dev/null 2>&1; \ 52 | if [ $$? -eq 0 ]; then \ 53 | echo "Test $*.apl (no optimization): OK" > $@ \ 54 | ; else \ 55 | if [ -e $*.out.ok ]; then \ 56 | echo "Test $*.apl: *** ERR: file $< differs from $*.out.ok ***" > $@ \ 57 | ; else \ 58 | echo "Test $*.apl: *** ERR: file $*.out.ok does not exist ***" > $@ \ 59 | ; fi \ 60 | ; fi) 61 | 62 | .PHONY: test 63 | test: $(RESFILES) 64 | @cat $(RESFILES) 65 | @echo "-------T E S T --- R E P O R T-------" 66 | @echo "Tests succeeded: `grep "OK" $(RESFILES) | wc -l` /`grep "Test" $(RESFILES) | wc -l`" 67 | @echo "Test errors: `grep "ERR" $(RESFILES) | wc -l` /`grep "Test" $(RESFILES) | wc -l`" 68 | @echo "-------------------------------------" 69 | @exit `grep "ERR" $(RESFILES) | wc -l` 70 | 71 | outv: $(OUTVFILES) 72 | 73 | 74 | clean: 75 | rm -f *.tl *.out *.res *.resn *.outn *~ *.outv *.outc *.resc 76 | rm -f c/*.out c/*.c c/*~ *~ c/*.exe *.time *.dyatime *.comptime *.outd *.outb 77 | 78 | 79 | ################### Testing Laila (C) Backend ################### 80 | 81 | CTESTS=test test1 test2 test3 test4 test5 test6 test7 test9 test10 \ 82 | test11 test12 test13 test14 test15 test16 test19 signal test21 \ 83 | test28 residue mult0 mult slashbar primes0 compress primes \ 84 | cons boolean innerLegrand5.3 quadassign opr1 opr2 opr3 fun2 \ 85 | take drop vrev vrot rot rotfirst first powscl vec zfunc \ 86 | ceilfloormaxmin easter eacheaster else innerproduct sign mean \ 87 | powmat life pow fib10 timespi ln chars repl replicate shape \ 88 | tup circ abcd dtransp tax binaryops pi blackscholes idx \ 89 | idxassign format readintvecfile readdoublevecfile squad expd \ 90 | reduce transpose sierpinski sierpinski0 vowels train0 train \ 91 | trains1 trainatop tally sum35 rav athas 92 | 93 | #anagram 94 | # readfile 95 | 96 | CRESFILES=$(CTESTS:%=%.resc) 97 | 98 | .PHONY: testc 99 | testc: $(CRESFILES) 100 | @cat $(CRESFILES) 101 | @echo "------- C Backend --- T E S T --- R E P O R T-------" 102 | @echo "Tests succeeded: `grep "OK" $(CRESFILES) | wc -l` /`grep "Test" $(CRESFILES) | wc -l`" 103 | @echo "Test errors: `grep "ERR" $(CRESFILES) | wc -l` /`grep "Test" $(CRESFILES) | wc -l`" 104 | @echo "----------------------------------------------------" 105 | cat pi.outc 106 | @echo "----------------------------------------------------" 107 | @exit `grep "ERR" $(CRESFILES) | wc -l` 108 | 109 | c/%.c: %.apl Makefile 110 | # $(APLT) -materialize -opt_hoist -opt_loopsplit -c -O 2 -oc $@ $(PRELUDE) $< 111 | $(APLT) -materialize -opt_loopsplit -c -O 2 -oc $@ $(PRELUDE) $< 112 | 113 | c/%.exe: c/%.c 114 | gcc -I ../include --std=c99 -O3 -o $@ $< -lm 115 | 116 | %.outc: c/%.exe 117 | $< > $@ 118 | 119 | %.resc: %.outc 120 | @(diff -aq $< $*.out.ok > /dev/null 2>&1; \ 121 | if [ $$? -eq 0 ]; then \ 122 | echo "Test $*.apl (c backend): OK" > $@ \ 123 | ; else \ 124 | if [ -e $*.out.ok ]; then \ 125 | echo "Test $*.apl: *** ERR: file $< differs from $*.out.ok ***" > $@ \ 126 | ; else \ 127 | echo "Test $*.apl: *** ERR: file $*.out.ok does not exist ***" > $@ \ 128 | ; fi \ 129 | ; fi) 130 | 131 | ###### Benchmarking the Laila (C) Backend against Dyalog interpreter ###### 132 | # 133 | # This benchmarking assumes that dyalog is installed together with the 134 | # rundyalog script (with IO<-1) being available in the user's PATH. 135 | # 136 | 137 | TIME=/usr/bin/time 138 | #TIME=gtime 139 | 140 | BENCH=pi2 life2 primes2 easter3000 blacksch 141 | 142 | TIMEFILES=$(BENCH:%=%.time) 143 | DYATIMEFILES=$(BENCH:%=%.dyatime) 144 | COMPTIMEFILES=$(BENCH:%=%.comptime) 145 | 146 | .PHONY: bench 147 | bench: $(COMPTIMEFILES) 148 | @echo 149 | @echo "----- B E N C H M A R K --- R E P O R T-----" 150 | @echo 'Benchmark Dyalog Laila' 151 | @cat $(COMPTIMEFILES) 152 | @echo "--------------------------------------------" 153 | 154 | %.time: c/%.exe 155 | $(TIME) -o $@ -f "%Us" $< > $*.outb 156 | 157 | %.dyatime: %.apl 158 | $(TIME) -o $@ -f "%Us" rundyalog $< > $*.outd 159 | 160 | %.comptime: %.dyatime %.time 161 | printf '%-15s %7s %7s\n' "$*.apl" `cat $*.dyatime | tr -d '\n'` `cat $*.time | tr -d '\n'` > $@ 162 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## apltail [![CI](https://github.com/melsman/apltail/workflows/CI/badge.svg)](https://github.com/melsman/apltail/actions) 2 | 3 | An APL Compiler based on a Typed Array Intermediate Language. 4 | 5 | This software implements an APL compiler. The compiler is 6 | based on a [typed array intermediate language](http://elsman.com/pdf/array14_final.pdf) [1]. The 7 | executable also contains an interpreter for TAIL and a compiler from 8 | TAIL into C. 9 | 10 | See the [coverage page](doc/coverage.md) for information about what APL 11 | functionality is supported. 12 | 13 | See also [the compilation scheme](doc/comp.md) if you are curious about how the 14 | compilation works. 15 | 16 | ## An example 17 | 18 | Consider the following program: 19 | 20 | ```apl 21 | f ← {5+⍵} ⍝ Function adding 5 to its argument (⍵) 22 | +/ f ⍳ 30 ⍝ Apply f to the vector 1..30 and 23 | ⍝ sum up the elements in the resulting vector 24 | ``` 25 | 26 | Here is what happens when the program is compiled and executed: 27 | 28 | bash-3.2$ ./aplt -p_tail lib/prelude.apl tests/test.apl 29 | [Reading file: lib/prelude.apl] 30 | [Reading file: tests/test.apl] 31 | Resulting program: 32 | let v0:30 = iotaV(30) in 33 | i2d(reduce(addi,0,eachV(fn v1:[int]0 => addi(5,v1),v0))) 34 | Evaluating 35 | Result is [](615.0) 36 | 37 | ## Another example 38 | 39 | Consider the program 40 | 41 | ```apl 42 | diff ← {1↓⍵−¯1⌽⍵} 43 | signal ← {¯50⌈50⌊50×(diff 0,⍵)÷0.01+⍵} 44 | +/ signal ⍳ 100 45 | ``` 46 | 47 | Here is the result of compiling and evaluating it: 48 | 49 | bash-3.2$ ./aplt -p_tail lib/prelude.apl tests/signal.apl 50 | [Reading file: lib/prelude.apl] 51 | [Reading file: tests/signal.apl] 52 | Resulting program: 53 | let v0:100 = iotaV(100) in 54 | let v3:101 = consV(0,v0) in 55 | 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))))))) 56 | Evaluating 57 | Result is [](258.557340366) 58 | 59 | ## Example demonstrating transpose and a double-reduce 60 | 61 | Consider the following APL program: 62 | 63 | ```apl 64 | a ← 3 2 ⍴ ⍳ 5 65 | a2 ← 3 2 ⍴ ⍳ 4 66 | b ← ⍉ a 67 | c ← b, ⍉ a2 68 | ×/ +/ c 69 | 70 | ⍝ 1 2 1 3 5 1 3 1 -+-> 14 71 | ⍝ 3 4 2 4 1 2 4 2 -+-> 15 72 | ⍝ 5 1 73 | ⍝ --- 74 | ⍝ 210 75 | ``` 76 | 77 | Here is the result of compiling and evaluating it: 78 | 79 | bash-3.2$ ./aplt -p_tail lib/prelude.apl tests/test15.apl 80 | [Reading file: lib/prelude.apl] 81 | [Reading file: tests/test15.apl] 82 | Resulting program: 83 | let v0:[int]2 = reshape([3,2],iotaV(5)) in 84 | let v1:[int]2 = reshape([3,2],iotaV(4)) in 85 | let v2:[int]2 = transp(v0) in 86 | let v3:[int]2 = cat(v2,transp(v1)) in 87 | i2d(reduce(muli,1,reduce(addi,0,v3))) 88 | Evaluating 89 | Result is [](210.0) 90 | 91 | ## Example demonstrating matrix-multiplication 92 | 93 | ```apl 94 | a ← 3 2 ⍴ ⍳ 5 95 | b ← ⍉ a 96 | c ← a +.× b 97 | ×/ +/ c 98 | 99 | ⍝ 1 3 5 100 | ⍝ 2 4 1 101 | ⍝ 102 | ⍝ 1 2 5 11 7 -+-> 23 103 | ⍝ 3 4 11 25 19 -+-> 55 104 | ⍝ 5 1 7 19 26 -+-> 52 105 | ⍝ 65780 106 | ``` 107 | 108 | Here is the result of compiling and evaluating the example using the 109 | [prelude](/prelude.apl) definition of inner product: 110 | 111 | bash-3.2$ ./aplt -p_tail lib/prelude.apl tests/test13.apl 112 | [Reading file: lib/prelude.apl] 113 | [Reading file: tests/test13.apl] 114 | Resulting program: 115 | let v0:[int]2 = reshape([3,2],iotaV(5)) in 116 | let v1:[int]2 = transp(v0) in 117 | let v6:[int]3 = transp2([2,1,3],reshape([3,3,2],v0)) in 118 | let v12:[int]3 = transp2([1,3,2],reshape([3,2,3],v1)) in 119 | let v17:[int]2 = reduce(addi,0,zipWith(muli,v6,v12)) in 120 | i2d(reduce(muli,1,reduce(addi,0,v17))) 121 | Evaluating 122 | Result is [](65780.0) 123 | 124 | Without optimizations, the compilation results in a slightly larger output: 125 | 126 | bash-3.2$ ./aplt -p_tail -noopt lib/prelude.apl tests/test13.apl 127 | [Reading file: lib/prelude.apl] 128 | [Reading file: tests/test13.apl] 129 | Resulting program: 130 | let v0:[int]2 = reshape([3,2],iotaV(5)) in 131 | let v1:[int]2 = transp(v0) in 132 | let v2:3 = catV(dropV(b2iV(tt),shape(v1)),shape(v0)) in 133 | let v3:[int]0 = subi(firstV(shapeV(shape(v0))),b2iV(tt)) in 134 | let v4:3 = iotaV(firstV(shapeV(v2))) in 135 | let v5:3 = catV(rotateV(v3,dropV(~1,v4)),takeV(~1,v4)) in 136 | let v6:[int]3 = transp2(v5,reshape(v2,v0)) in 137 | let v7:3 = catV(dropV(~1,shape(v0)),shape(v1)) in 138 | let v8:S(int,2) = firstV(shapeV(shape(v0))) in 139 | let v9:3 = iotaV(firstV(shapeV(v7))) in 140 | let v10:1 = dropV(negi(v8),rotateV(v8,iotaV(firstV(shapeV(v9))))) in 141 | let v11:3 = catV(dropV(~1,iotaV(v8)),snocV(v10,v8)) in 142 | let v12:[int]3 = transp2(v11,reshape(v7,v1)) in 143 | let v17:[int]2 = reduce(addi,0,zipWith(muli,v6,v12)) in 144 | i2d(reduce(muli,1,reduce(addi,0,v17))) 145 | Evaluating 146 | Result is [](65780.0) 147 | 148 | ## Try it! 149 | 150 | The software makes use of the [sml-unicode](https://github.com/diku-dk/sml-unicode) library for lexing and 151 | the [sml-aplparse](https://github.com/diku-dk/sml-aplparse) library for 152 | 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. 153 | 154 | You also need a Standard ML compiler (e.g., [Mlton](http://www.mlton.org/) or [MLKit](http://melsman.github.io/mlkit)). 155 | 156 | To pull down the dependent libraries and to compile the source, execute the following commands in a shell: 157 | 158 | $ make prepare 159 | $ make all 160 | 161 | These commands will leave an executable `aplt` in the root directory of the repository. 162 | 163 | To run a series of tests, execute `make test` in your shell. 164 | 165 | To get `aplt` to output type instantiation list for the polymorphic 166 | functions, such as `reduce`, `each`, and `take`, you may pass the 167 | option `-p_types` to `aplt`. 168 | 169 | See also the [coverage page](doc/coverage.md). 170 | 171 | To compile with MLKit instead of with MLton, which takes quite some 172 | time, instead of typing `make all` above, type instead `MLCOMP=mlkit make all`. 173 | 174 | ## License 175 | 176 | This software is published under the [MIT License](MIT_LICENSE.md). 177 | 178 | ## References 179 | 180 | [1] Martin Elsman and Martin Dybdal. __Compiling a Subset of APL Into 181 | a Typed Intermediate Language__. In _ACM SIGPLAN International 182 | Workshop on Libraries, Languages and Compilers for Array Programming 183 | (ARRAY'14)_. Edinburgh, UK. June, 184 | 2014. [pdf](http://elsman.com/pdf/array14_final.pdf), 185 | [bibtex](http://elsman.com//pdf/array14_final.bibtex.txt). 186 | -------------------------------------------------------------------------------- /include/apl.h: -------------------------------------------------------------------------------- 1 | // C Runtime system for the APL compiler C backend 2 | // 3 | // Copyright (c) 2015, Martin Elsman 4 | // MIT License 5 | 6 | // ------------------ 7 | // Some abbreviations 8 | // ------------------ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define ori(x,y) (int)(((unsigned int)(x))|((unsigned int)(y))) 19 | #define andi(x,y) (int)(((unsigned int)(x))&((unsigned int)(y))) 20 | #define xori(x,y) (int)(((unsigned int)(x))^((unsigned int)(y))) 21 | #define shli(x,y) (int)(((unsigned int)(x))<<((unsigned int)(y))) 22 | #define shri(x,y) (int)(((unsigned int)(x))>>((unsigned int)(y))) 23 | #define shari(x,y) (int)(((int)(x))>>((unsigned int)(y))) 24 | #define i2d(x) ((double)x) 25 | #define d2i(x) ((int)x) 26 | #define b2i(x) ((x)?1:0) 27 | #define ln(x) (log(x)) 28 | #define true 1 29 | #define false 0 30 | #define bool int 31 | 32 | int maxi(int a, int b) { return (a > b) ? a : b; } 33 | int mini(int a, int b) { return (a < b) ? a : b; } 34 | 35 | double maxd(double a, double b) { return (a > b) ? a : b; } 36 | double mind(double a, double b) { return (a < b) ? a : b; } 37 | 38 | 39 | // ------------------------------ 40 | // Printing of scalars and arrays 41 | // ------------------------------ 42 | 43 | static void prInt(int i) { printf("%d", i); } 44 | 45 | static void prBool(int b) { prInt(b); } 46 | 47 | // [countChar(c,s)] returns the number of occurences of c in s. 48 | static ssize_t countChar(ssize_t c, char *s) { 49 | char *p; 50 | ssize_t count; 51 | 52 | count = 0; 53 | for( p=s; *p != '\0'; p++ ) 54 | { 55 | if( *p == c ) count++; 56 | } 57 | return count; 58 | } 59 | 60 | static void formatD(char* buf, double arg) 61 | { 62 | sprintf(buf, "%.12g", arg); 63 | if( countChar('.', buf) == 0 && countChar('E', buf) == 0 ) 64 | { 65 | strcat(buf, ".0"); 66 | } 67 | } 68 | 69 | static void prDouble(double arg) 70 | { 71 | char buf[64]; 72 | formatD(buf, arg); 73 | printf("%s", buf); 74 | } 75 | 76 | // Print result of program evaluation 77 | 78 | static void prScalarDouble(double arg) 79 | { 80 | printf("[]("); prDouble(arg); printf(")"); 81 | } 82 | 83 | // --------------------------- 84 | // Some mathematical functions 85 | // --------------------------- 86 | 87 | static int resi(int y, int x) // notice the swapped arguments 88 | { 89 | int tmp; 90 | if ( y == 0 ) { return x; } 91 | tmp = x % y; 92 | if (tmp == 0 || (x>0 && y>0) || (x<0 && y<0)) { 93 | return tmp; 94 | } else { 95 | return tmp+y; 96 | } 97 | } 98 | 99 | static int floori(double x) { 100 | return (int)floor(x); 101 | } 102 | 103 | static int ceili(double x) { 104 | return (int)ceil(x); 105 | } 106 | 107 | // ------------------------------ 108 | // Roll function 109 | // ------------------------------ 110 | 111 | static double roll (int x) { 112 | int i = rand(); 113 | double r = ((double)i)/((double)RAND_MAX); 114 | if (x == 0) { 115 | return r; 116 | } 117 | int y = (int)(x * r); 118 | return (double)y; 119 | } 120 | 121 | 122 | // ----------------- 123 | // Now function 124 | // ----------------- 125 | 126 | struct timeval tv_init; 127 | 128 | static void initialize() { 129 | gettimeofday(&tv_init, NULL); 130 | return; 131 | } 132 | 133 | // return time since process start in milliseconds 134 | static int now (int x) { 135 | struct timeval tv_check; 136 | gettimeofday(&tv_check, NULL); 137 | long int usec = tv_check.tv_usec - tv_init.tv_usec; 138 | long int sec = tv_check.tv_sec - tv_init.tv_sec; 139 | long int msec = usec / 1000; 140 | return (int)(sec*1000+msec); 141 | } 142 | 143 | // ----------------- 144 | // Halting execution 145 | // ----------------- 146 | 147 | void halt(char *s) { 148 | printf("Execution halted: %s\n",s); 149 | exit(1); 150 | } 151 | 152 | 153 | /* Buffer size in number of bytes */ 154 | #define INIT_BUFFER_SIZE (4*1024) 155 | 156 | /* Copy values to a new buffer, double the size, free the old buffer. */ 157 | int double_buffersize(int* bufferSize, void** buffer_ptr) { 158 | int newBufferSize = 2*(*bufferSize); 159 | //printf("Doubling the buffer, new buffer size: %d bytes\n", newBufferSize); 160 | int* buffer = *buffer_ptr; 161 | int* newBuffer = malloc (newBufferSize); 162 | if (newBuffer != NULL) { 163 | memcpy(newBuffer, buffer, *bufferSize); 164 | free(buffer); 165 | *buffer_ptr = newBuffer; 166 | *bufferSize = newBufferSize; 167 | return 1; 168 | } else { 169 | return 0; 170 | } 171 | } 172 | 173 | int* read_csv_ints(FILE* handle, int* valuesRead) { 174 | int bufferSize = INIT_BUFFER_SIZE; 175 | //printf("Alloc initial buffer, size: %d bytes\n", bufferSize); 176 | int* buffer_ptr = (int*) malloc (bufferSize); 177 | if (buffer_ptr == NULL) { 178 | return 0; 179 | } 180 | 181 | int i = 0; 182 | char line[1024]; 183 | //printf("Reading first line\n"); 184 | while (fgets(line, 1024, handle)) { 185 | const char* tok; 186 | tok = strtok(line, " ,\n"); 187 | while (tok != NULL) { 188 | buffer_ptr[i] = atoi(tok); 189 | i++; 190 | if (sizeof(int)*i >= bufferSize) { 191 | //printf("Read %d integers, resize buffer\n", i); 192 | if(!double_buffersize(&bufferSize, (void**)&buffer_ptr)) { 193 | return NULL; 194 | } 195 | } 196 | tok = strtok (NULL, " ,\n"); 197 | } 198 | } 199 | *valuesRead = i; 200 | return buffer_ptr; 201 | } 202 | 203 | /* Arg, complete COPY-PASTE of above, just changed to read doubles */ 204 | double* read_csv_doubles(FILE* handle, int* valuesRead) { 205 | int bufferSize = INIT_BUFFER_SIZE; 206 | // printf("Alloc initial buffer, size: %d bytes\n", bufferSize); 207 | double* buffer_ptr = (double*) malloc (bufferSize); 208 | if (buffer_ptr == NULL) { 209 | return NULL; 210 | } 211 | 212 | int i = 0; 213 | char line[1024]; 214 | //printf("Reading first line\n"); 215 | while (fgets(line, 1024, handle)) { 216 | const char* tok; 217 | tok = strtok(line, " ,\n"); 218 | while (tok != NULL) { 219 | buffer_ptr[i] = atof(tok); 220 | i++; 221 | if (sizeof(double)*i >= bufferSize) { 222 | //printf("Read %d integers, resize buffer\n", i); 223 | if(!double_buffersize(&bufferSize, (void**)&buffer_ptr)) { 224 | return NULL; 225 | } 226 | } 227 | tok = strtok (NULL, " ,\n"); 228 | } 229 | } 230 | *valuesRead = i; 231 | return buffer_ptr; 232 | } 233 | 234 | int* readIntVecFile(int* valuesRead, char* filename) { 235 | FILE* file = fopen(filename, "r"); 236 | if (file == NULL) { 237 | fprintf(stderr, "Error reading %s: %d (%s)\n", filename, errno, strerror(errno)); 238 | exit(0); 239 | } 240 | 241 | int* res = read_csv_ints(file, valuesRead); 242 | if (res == NULL) { 243 | printf("readIntVecFile: Error reading file '%s'\n", filename); 244 | fclose(file); 245 | exit(0); 246 | } 247 | fclose(file); 248 | return res; 249 | } 250 | 251 | double* readDoubleVecFile(int* valuesRead, char* filename) { 252 | FILE* file = fopen(filename, "r"); 253 | if (file == NULL) { 254 | fprintf(stderr, "Error reading %s: %d (%s)\n", filename, errno, strerror(errno)); 255 | exit(0); 256 | } 257 | 258 | double* res = read_csv_doubles(file, valuesRead); 259 | if (res == NULL) { 260 | printf("readDoubleVecFile: Error reading file '%s'\n", filename); 261 | fclose(file); 262 | exit(0); 263 | } 264 | fclose(file); 265 | return res; 266 | } 267 | -------------------------------------------------------------------------------- /src/aplt.sml: -------------------------------------------------------------------------------- 1 | structure Apl2Tail = Apl2Tail(Tail) 2 | 3 | type res = (unit, Tail.Double Tail.Num) Tail.prog option 4 | 5 | fun die s = raise Fail ("Apl2Tail." ^ s) 6 | 7 | (* Parsing *) 8 | fun parseFile (flags : Flags.flags) (pe : AplParse.env) (f : string) : AplAst.exp * AplParse.env = 9 | let val verbose_p = Flags.flag_p flags "-v" 10 | val silent_p = Flags.flag_p flags "-silent" 11 | val _ = Util.log (not silent_p) (fn _ => "[Reading file: " ^ f ^ "]") 12 | val s = Util.readFile f 13 | val ts = AplLex.lex f s 14 | val _ = Util.log verbose_p (fn _ => "File lexed:") 15 | val _ = Util.log verbose_p (fn _ => " " ^ AplLex.pr_tokens (map #1 ts)) 16 | val _ = Util.log verbose_p (fn _ => "Parsing tokens...") 17 | val (e,pe') = AplParse.parse pe ts 18 | val _ = Util.log verbose_p (fn _ => "Parse success:\n " ^ AplAst.pr_exp e) 19 | in (e,pe') 20 | end 21 | 22 | fun parseFiles (flags : Flags.flags) (pe0 : AplParse.env) (fs: string list) : AplAst.exp = 23 | let fun mergeExps (NONE,e) = SOME e 24 | | mergeExps (SOME e0,e) = SOME(AplParse.seq(e0,e)) 25 | fun parseFs pe = 26 | fn (nil, NONE) => raise Fail "Expecting at least one file" 27 | | (nil, SOME e) => e 28 | | (f::fs, acc) => 29 | let val (e,pe') = parseFile flags pe f 30 | in parseFs (AplParse.plus(pe,pe')) (fs,mergeExps (acc,e)) 31 | end 32 | in parseFs pe0 (fs,NONE) 33 | end 34 | 35 | (* Compilation *) 36 | (* compileExp : flag list -> AplAst.exp -> (unit, Tail.Double Tail.Num) Tail.prog option *) 37 | fun compileExp (flags : Flags.flags) (e : AplAst.exp) : res = 38 | let (* val compile_only_p = flag_p flags "-c" *) 39 | val verbose_p = Flags.flag_p flags "-v" 40 | val silent_p = Flags.flag_p flags "-silent" 41 | val p_tail = Flags.flag_p flags "-p_tail" 42 | val p_types = Flags.flag_p flags "-p_types" 43 | val optlevel = if Flags.flag_p flags "-noopt" then 0 else 1 44 | val materialize = Flags.flag_p flags "-materialize" 45 | val outfile = Flags.flag flags "-o" 46 | val p = Apl2Tail.compile {verbose=verbose_p, optlevel=optlevel, prtype=p_types, materialize=materialize} e 47 | val () = 48 | case outfile of 49 | SOME ofile => Tail.outprog p_types ofile p 50 | | NONE => 51 | if p_tail andalso not verbose_p then 52 | (if not silent_p then print "TAIL program:\n" else (); 53 | print (Tail.pp_prog p_types p); 54 | print "\n") 55 | else () (* program already printed! *) 56 | in SOME p 57 | end 58 | 59 | fun errHandler (e : exn) : 'a option = 60 | case e of 61 | AplParse.ParseErr (l,msg) => (Util.prln ("Parse Error at " ^ 62 | Region.ppLoc l ^ ": \n " ^ 63 | msg); NONE) 64 | | Fail s => (Util.prln s; NONE) 65 | | _ => raise e 66 | 67 | fun compile flags (fs : string list) : res = 68 | let val s_parse = Flags.flag_p flags "-s_parse" (* stop after parsing *) 69 | val e = parseFiles flags Apl2Tail.initialParseEnv fs 70 | in if s_parse 71 | then (Util.prln "Stopping after parsing."; NONE) 72 | else compileExp flags e 73 | end handle ? => errHandler ? 74 | 75 | 76 | fun compileAndRun (flags,files) = 77 | let val compile_only_p = Flags.flag_p flags "-c" 78 | val verbose_p = Flags.flag_p flags "-v" 79 | val stop_after_tail_p = Flags.flag_p flags "-s_tail" 80 | val print_laila_p = Flags.flag_p flags "-p_laila" 81 | val silent_p = Flags.flag_p flags "-silent" 82 | val () = Laila.unsafeAsserts := Flags.flag_p flags "-unsafe" 83 | val () = Laila.enableComments := Flags.flag_p flags "-comments" 84 | val () = Laila.statistics_p := Flags.flag_p flags "-stat_laila" 85 | val () = Laila.hoist_p := Flags.flag_p flags "-opt_hoist" 86 | val () = Laila.loopsplit_p := Flags.flag_p flags "-opt_loopsplit" 87 | val () = case Flags.flag flags "-O" of 88 | NONE => () 89 | | SOME n => 90 | case Int.fromString n of 91 | SOME n => Tail.optimisationLevel := n 92 | | NONE => die "expecting integer as argument to -O flag" 93 | in if silent_p andalso verbose_p then 94 | Util.prln "Inconsistent use of -silent and -v flags" 95 | else 96 | case compile flags files of 97 | SOME p => 98 | let val () = if compile_only_p then () 99 | else let val () = if not silent_p then Util.prln("Evaluating") 100 | else () 101 | val v = Tail.eval p Tail.Uv 102 | in if silent_p then Util.prln(Tail.ppValue v) 103 | else Util.prln("Result is " ^ Tail.ppValue v) 104 | end 105 | in if stop_after_tail_p then () 106 | else let val lp = Tail2Laila.compile flags p 107 | val ocfile = Flags.flag flags "-oc" 108 | in case ocfile of 109 | SOME ocfile => Laila.outprog ocfile lp 110 | | NONE => 111 | if print_laila_p orelse verbose_p then 112 | (print "LAILA program:\n"; 113 | print (Laila.pp_prog lp); 114 | print "\n") 115 | else () (* program already printed! *) 116 | end 117 | end 118 | | NONE => OS.Process.exit OS.Process.failure 119 | end handle exn as IO.Io {name,function,cause} => 120 | (print ("Uncaught IO exception: Io{name=" ^ name ^ ", function=" ^ function ^ ", cause=" ^ General.exnMessage cause ^ "}\n"); 121 | raise exn) 122 | 123 | 124 | val name = CommandLine.name() 125 | 126 | fun version() = 127 | String.concatWith "\n" 128 | ["APLtail version: " ^ Version.version, 129 | "Version date: " ^ Version.date, 130 | "Platform: " ^ Version.platform] 131 | 132 | fun usage() = 133 | version() ^ "\n\n" ^ 134 | "Usage: " ^ name ^ " [OPTIONS]... file.apl...\n" ^ 135 | " -o file : write TAIL program to file\n" ^ 136 | " -oc file : write LAILA program to file\n" ^ 137 | " -c : compile only (no evaluation)\n" ^ 138 | " -noopt : disable optimizations\n" ^ 139 | " -materialize : enable materialization of arrays\n" ^ 140 | " -p_tail : print TAIL program\n" ^ 141 | " -p_types : print types in TAIL code\n" ^ 142 | " -p_laila : print LAILA code\n" ^ 143 | " -s_parse : stop after parsing\n" ^ 144 | " -s_tail : stop after TAIL generation\n" ^ 145 | " -silent : evaluation output only (unless there are errors)\n" ^ 146 | " -v : verbose\n" ^ 147 | " -O n : optimisation level (n>0 optimises double operations aggresively)\n" ^ 148 | " -comments : write comments in generated C code\n" ^ 149 | " -unsafe : don't include assert code in generated C code for array indexing\n" ^ 150 | " -stat_laila : print statistics for LAILA code generation\n" ^ 151 | " -opt_hoist : enable hoist optimization in LAILA code generation\n" ^ 152 | " -opt_loopsplit : enable loop split optimization in LAILA code generation\n" 153 | 154 | (* Parse command line arguments and pass to compileAndRun *) 155 | val () = Flags.runargs {usage = usage, 156 | run = compileAndRun, 157 | unaries = ["-o","-oc","-O"]} 158 | -------------------------------------------------------------------------------- /src/tail/tail_type.sml: -------------------------------------------------------------------------------- 1 | structure TailType : TAIL_TYPE = struct 2 | type var = string 3 | type opr = string 4 | open URef 5 | type bv = string 6 | type tv = string 7 | type rv = string 8 | 9 | datatype unify_result = SUCCESS | ERROR of string 10 | 11 | datatype r = R of int 12 | | Rv of rv * (int -> unify_result) 13 | withtype rnk = r uref 14 | datatype b = IntT 15 | | DoubleT 16 | | ComplexT 17 | | BoolT 18 | | CharT 19 | | Bv of bv 20 | withtype bty = b uref 21 | datatype t = ArrT of bty * rnk 22 | | VccT of bty * rnk 23 | | ST of bty * rnk 24 | | SVT of bty * rnk 25 | | FunT of typ * typ 26 | | TupT of typ list 27 | | TyvT of tv * prj list option 28 | withtype typ = t uref 29 | and prj = int * t uref 30 | 31 | local 32 | fun newcount s = 33 | let val c = ref 0 34 | in fn () => s ^ Int.toString(!c before c:= !c + 1) 35 | end 36 | in fun RnkVarCon f : rnk = uref(Rv(newcount "'r" (),f)) 37 | fun RnkVar () : rnk = RnkVarCon (fn _ => SUCCESS) 38 | fun TyVarB () : bty = uref(Bv(newcount "'b" ())) 39 | fun TyVar () : typ = uref(TyvT(newcount "'a" (),NONE)) 40 | fun TyVarPrj (i,t) : typ = uref(TyvT(newcount "'t" (),SOME [(i,t)])) 41 | end 42 | 43 | val rnk0 = uref (R 0) 44 | val rnk1 = uref (R 1) 45 | fun rnk 0 = rnk0 46 | | rnk 1 = rnk1 47 | | rnk n = uref (R n) 48 | fun unRnk r = case !!r of R i => SOME i | _ => NONE 49 | 50 | val IntB = uref IntT 51 | val DoubleB = uref DoubleT 52 | val ComplexB = uref ComplexT 53 | val BoolB = uref BoolT 54 | val CharB = uref CharT 55 | 56 | fun Arr bt r = uref(ArrT(bt,r)) 57 | fun Vcc bt r = uref(VccT(bt,r)) 58 | fun S bt r = uref(ST(bt,r)) 59 | fun SV bt r = uref(SVT(bt,r)) 60 | fun Fun (t1,t2) = uref(FunT(t1,t2)) 61 | fun Tup ts = uref(TupT ts) 62 | 63 | fun prj i t = TyVarPrj (i,t) 64 | 65 | fun Scl bt = Arr bt rnk0 66 | fun VecB bt = Arr bt rnk1 67 | val Int = Scl IntB 68 | val Double = Scl DoubleB 69 | val Complex = Scl ComplexB 70 | val Bool = Scl BoolB 71 | val Char = Scl CharB 72 | 73 | val Sh = Vcc IntB 74 | val Si = S IntB 75 | val Vi = SV IntB 76 | 77 | fun prR r = case r of R i => Int.toString i | Rv (rv,_) => rv 78 | and prRnk r = prR (!!r) 79 | and prB b = 80 | case b of 81 | IntT => "int" 82 | | DoubleT => "double" 83 | | ComplexT => "complex" 84 | | BoolT => "bool" 85 | | CharT => "char" 86 | | Bv bv => bv 87 | and prBty bty = prB(!!bty) 88 | and prT t = 89 | case t of 90 | ArrT (bt,r) => "[" ^ prBty bt ^ "]" ^ prRnk r 91 | | VccT (bt, r) => "<" ^ prBty bt ^ ">" ^ prRnk r 92 | | ST (bt,r) => "S(" ^ prBty bt ^ "," ^ prRnk r ^ ")" 93 | | SVT (bt,r) => "SV(" ^ prBty bt ^ "," ^ prRnk r ^ ")" 94 | | FunT (t1,t2) => "(" ^ prType t1 ^ ")->" ^ prType t2 95 | | TupT ts => "(" ^ String.concatWith " * " (List.map prType ts) ^ ")" 96 | | TyvT (tv,_) => tv 97 | and prType t = prT(!!t) 98 | 99 | fun unArr t = case !!t of ArrT p => SOME p | _ => NONE 100 | fun unVcc t = case !!t of VccT p => SOME p | _ => NONE 101 | fun unS t = case !!t of ST p => SOME p | _ => NONE 102 | fun unSV t = case !!t of SVT p => SOME p | _ => NONE 103 | fun unFun t = case !!t of FunT p => SOME p | _ => NONE 104 | fun unTup t = case !!t of TupT p => SOME p | _ => NONE 105 | 106 | fun comb f1 f2 t = case f1 t of SUCCESS => f2 t | x => x 107 | fun check f t = case f t of ERROR s => raise Fail s | SUCCESS => () 108 | 109 | fun isInt bt = case !!bt of IntT => true | _ => false 110 | fun isDouble bt = case !!bt of DoubleT => true | _ => false 111 | fun isComplex bt = case !!bt of ComplexT => true | _ => false 112 | fun isBool bt = case !!bt of BoolT => true | _ => false 113 | fun isChar bt = case !!bt of CharT => true | _ => false 114 | 115 | fun Vec t = 116 | case unArr t of 117 | SOME (bt, r) => 118 | (case unRnk r of 119 | SOME 0 => VecB bt 120 | | _ => raise Fail "Vec assumes a known scalar type argument") 121 | | NONE => case unS t of 122 | SOME (bt,_) => VecB bt 123 | | NONE => raise Fail "Vec assumes a known scalar type argument" 124 | 125 | fun combB (b1,b2) = 126 | case (b1,b2) of 127 | (Bv _, _) => b2 128 | | (_, Bv _) => b1 129 | | (IntT, IntT) => b1 130 | | (DoubleT, DoubleT) => b1 131 | | (ComplexT, ComplexT) => b1 132 | | (BoolT, BoolT) => b1 133 | | (CharT, CharT) => b1 134 | | _ => raise Fail ("cannot unify " ^ prB b1 ^ " and " ^ prB b2) 135 | and unifB b1 b2 = URef.unify combB (b1,b2) 136 | and combT (t1,t2) = 137 | case (t1,t2) of 138 | (TyvT (_,NONE), _) => t2 139 | | (_, TyvT (_,NONE)) => t1 140 | | (TyvT (v1,SOME prjs1), TyvT(_,SOME prjs2)) => TyvT(v1,SOME(unifPrjs prjs1 prjs2)) 141 | | (TyvT (_,SOME prjs), TupT ts) => 142 | (List.app (fn (i,t) => 143 | if i < length ts then unif (List.nth(ts,i)) t 144 | else raise Fail ("cannot project " ^ Int.toString i ^ 145 | "th value from tuple of length " ^ 146 | Int.toString (length ts))) 147 | prjs; 148 | t2) 149 | | (TupT _, TyvT _) => combT (t2,t1) 150 | | (t as ArrT (b1,r1), ArrT (b2,r2)) => (unifB b1 b2; unifR r1 r2; t) 151 | | (t as VccT (b1,r1), VccT (b2,r2)) => (unifB b1 b2; unifR r1 r2; t) 152 | | (t as ST (b1,r1), ST (b2,r2)) => (unifB b1 b2; unifR r1 r2; t) 153 | | (t as SVT (b1,r1), SVT (b2,r2)) => (unifB b1 b2; unifR r1 r2; t) 154 | | (t as FunT (t1,t2), FunT (t1',t2')) => (unif t1 t1'; unif t2 t2'; t) 155 | | (t as TupT ts, t' as TupT ts') => (unifs t t' ts ts'; t) 156 | | _ => raise Fail ("cannot unify " ^ prT t1 ^ " and " ^ prT t2) 157 | and unifPrjs nil prjs2 = prjs2 158 | | unifPrjs ((i1,t1)::prjs1) prjs2 = 159 | (List.app(fn (i2,t2) => if i1=i2 then unif t1 t2 160 | else ()) prjs2; 161 | if List.exists (fn (i2,_) => i1 = i2) prjs2 then 162 | unifPrjs prjs1 prjs2 163 | else unifPrjs prjs1 ((i1,t1)::prjs2)) 164 | 165 | and unif t1 t2 = URef.unify combT (t1,t2) 166 | handle Fail s => raise Fail (s ^ " when trying to unify " ^ prT (URef.!! t1) ^ " and " ^ prT (URef.!! t2)) 167 | and unifs _ _ nil nil = () 168 | | unifs t0 t0' (t::ts) (t'::ts') = (unif t t'; unifs t0 t0' ts ts') 169 | | unifs t0 t0' _ _ = raise Fail ("cannot unify tuple types " ^ prT t0 ^ " and " ^ prT t0') 170 | and combR (r1,r2) = 171 | case (r1,r2) of 172 | (R i1, R i2) => if i1 = i2 then r1 173 | else raise Fail ("cannot unify rank " ^ prR r1 ^ " and rank " ^ prR r2) 174 | | (Rv(rv1,f1), Rv(_,f2)) => Rv(rv1,comb f1 f2) 175 | | (Rv(_,f), R i) => (check f i; r2) 176 | | (R i, Rv(_,f)) => (check f i; r1) 177 | and unifR r1 r2 = URef.unify combR (r1,r2) 178 | 179 | (* fun relateR _ = raise Fail "relateR not implemented" *) 180 | (* fun relateR2 _ = raise Fail "relateR2 not implemented" *) 181 | 182 | (* The applications of unify below should be replaced with conditional unifications *) 183 | 184 | fun unif_btr (bt1,r1) (bt2,r2) = 185 | (unifB bt1 bt2; unifR r1 r2) 186 | 187 | fun subtype t1 t2 = 188 | case unS t1 of 189 | SOME btr1 => (case unS t2 of 190 | SOME btr2 => unif_btr btr1 btr2 191 | | NONE => unif t2 (Scl (#1 btr1)) 192 | ) 193 | | NONE => 194 | case unSV t1 of 195 | SOME btr1 => (case unSV t2 of 196 | SOME btr2 => unif_btr btr1 btr2 197 | | NONE => case unVcc t2 of 198 | SOME (bt2,r2) => (unifB (#1 btr1) bt2; 199 | unifR rnk1 r2) 200 | | NONE => unif t2 (VecB (#1 btr1)) 201 | ) 202 | | NONE => 203 | case unVcc t1 of 204 | SOME btr1 => (case unVcc t2 of 205 | SOME btr2 => unif_btr btr1 btr2 206 | | NONE => unif t2 (VecB (#1 btr1)) 207 | ) 208 | | NONE => 209 | case (unTup t1, unTup t2) of 210 | (SOME ts1, SOME ts2) => 211 | (ListPair.appEq (fn (t1,t2) => subtype t1 t2) (ts1,ts2) 212 | handle ListPair.UnequalLengths => 213 | raise Fail "cannot unify tuple types of different length") 214 | | _ => unif t1 t2 215 | 216 | fun join t1 t2 = 217 | case (unS t1, unS t2) of 218 | (SOME (bt1,r1), SOME (bt2,r2)) => 219 | (unifB bt1 bt2; 220 | case (unRnk r1, unRnk r2) of 221 | (SOME i1, SOME i2) => if i1 = i2 then t1 222 | else Scl bt1 223 | | _ => (unifR r1 r2; t1)) 224 | | (SOME(bt1,_), NONE) => join (Scl bt1) t2 225 | | (NONE, SOME(bt2,_)) => join t1 (Scl bt2) 226 | | (NONE, NONE) => 227 | case (unSV t1, unSV t2) of 228 | (SOME (bt1,r1), SOME (bt2,r2)) => 229 | (unifB bt1 bt2; 230 | case (unRnk r1, unRnk r2) of 231 | (SOME i1, SOME i2) => if i1 = i2 then t1 232 | else Vcc bt1 (rnk 1) 233 | | _ => (unifR r1 r2; t1)) 234 | | (SOME(bt1,_), NONE) => join (Vcc bt1 (rnk 1)) t2 235 | | (NONE, SOME(bt2,_)) => join t1 (Vcc bt2 (rnk 1)) 236 | | (NONE, NONE) => 237 | case (unVcc t1, unVcc t2) of 238 | (SOME (bt1,r1), SOME (bt2,r2)) => 239 | (unifB bt1 bt2; 240 | case (unRnk r1, unRnk r2) of 241 | (SOME i1, SOME i2) => if i1 = i2 then t1 242 | else VecB bt1 243 | | _ => (unifR r1 r2; t1)) 244 | | (SOME(bt1,_), NONE) => join (VecB bt1) t2 245 | | (NONE, SOME(bt2,_)) => join t1 (VecB bt2) 246 | | (NONE, NONE) => 247 | (case (unTup t1, unTup t2) of 248 | (SOME ts1, SOME ts2) => 249 | let val ts = ListPair.map (fn (t1,t2) => join t1 t2) (ts1,ts2) 250 | in Tup ts 251 | end 252 | | _ => (unif t1 t2; t1)) 253 | 254 | fun wrap f x y = (f x y; SUCCESS) handle Fail s => ERROR s 255 | val unify = wrap unif 256 | val subtype = wrap subtype 257 | val unifyR = wrap unifR 258 | val unifyB = wrap unifB 259 | 260 | fun unArr' at = (* return the base type and the rank of an array *) 261 | case unArr at of 262 | SOME p => SOME p 263 | | NONE => case unVcc at of 264 | SOME (bt,_) => SOME (bt, rnk 1) 265 | | NONE => case unSV at of 266 | SOME (bt,_) => SOME (bt, rnk 1) 267 | | NONE => case unS at of 268 | SOME (bt,_) => SOME (bt, rnk 0) 269 | | NONE => NONE 270 | end 271 | -------------------------------------------------------------------------------- /doc/coverage.md: -------------------------------------------------------------------------------- 1 | ## Coverage of the APLT Compiler 2 | 3 | This page documents the functionality of the APLT compiler. 4 | 5 | ### Datatypes 6 | 7 | Supported datatypes include booleans, integers, doubles, and 8 | characters. Strings are represented as character arrays. Nested arrays 9 | are currently not supported, except in a limited fashion for 10 | resembling tuples (see below). 11 | 12 | ### Monadic Functions 13 | 14 | | Expression | Name | Meaning | Notes | 15 | |-----------------|------------------|----------------------|---------------| 16 | | `⍴ A` | Shape | Returns the shape of the array A as a vector of integers. | | 17 | | `⍳ N` | Iota | Returns a vector of length N with values [1,...,N]. | | 18 | | `, A` | Ravel | Returns the vector of values appearing in A in row-major order. | | 19 | | `+ A` | Identity | Returns A. | | 20 | | `- A` | Negation | Returns the array A with all elements negated. | | 21 | | `÷ A` | Reciprocal | Returns the array A with elements being the reciprocal values of the values in A. | | 22 | | `× A` | Sign | Returns the array A with elements being -1 for negative values in A and 1 for positive values in A. | | 23 | | `⌈ A` | Ceil | Returns A with elements ceiled. | The function returns an integer array. | 24 | | `⌊ A` | Floor | Returns A with elements floored. | The function returns an integer array. | 25 | | `⍉ A` | Transpose | Returns the transposed version of A. | | 26 | | `~ A` | Logical negation | Returns A with boolean elements negated. | Assumes A to be of boolean type. | 27 | | `○ A` | Pi times | Returns A with all elements multiplied by pi. | 28 | | `⍟ A` | Log | Returns A with the natural logarithm applied to all elements. | 29 | | `? A` | Random | Returns random values between 0 and 1 (if the argument is 0) and otherwise between 0 and the argument (whole number). | 30 | | `≢ A` | Tally | Returns the size of the outer dimension of A. | 31 | 32 | ### Dyadic Functions 33 | 34 | | Expression | Name | Meaning | Notes | 35 | |---------------|------------------|----------------------|---------------| 36 | | `B ⍴ A` | Reshape | Returns an array with shape B and values taken from ,A (rotated if there are not sufficiently many values in A). | The length of the vector B must be statically decided. | 37 | | `B ⍉ A` | Dyadic transpose | Returns the generalized transposed version of A, according to the dimension index vector B. | B must be an integer vector of the same length as A. | 38 | | `B + A` | Addition | Pair-wise addition of elements in B and A. | Scalar expansion supported: Arrays A and B must be of the same shape unless one of the arrays is a scalar value in which case the array is extended to match the shape of the other array. | 39 | | `B - A` | Subtraction | Pair-wise subtraction of elements in B and A. | Scalar expansion supported. | 40 | | `B ÷ A` | Division | Pair-wise division of elements in B and A. | Scalar expansion supported. | 41 | | `B × A` | Multiplication | Pair-wise multiplication of elements in B and A. | Scalar expansion supported. | 42 | | `B ⌈ A` | Maximum | Pair-wise maximum of elements in B and A. | Scalar expansion supported. | 43 | | `B ⌊ A` | Minimum | Pair-wise minimum of elements in B and A. | Scalar expansion supported. | 44 | | `N ↑ A` | Take | Returns the vector resulting from taking N elements from A (row-major order). | When N is negative, values are taken from the right. | 45 | | `N ↓ A` | Drop | Returns the vector resulting from dropping N elements from A (row-major order). | When N is negative, values are dropped from the right. | 46 | | `N ⌽ A` | Rotate | Returns the vector resulting from rotating values in A to the left N steps (row-major order). | When N is negative, values are right-rotated. | 47 | | `N ⊖ A` | Rotate last | Returns the vector resulting from rotating values (in A) N steps along the last axis (column-major order). | When N is negative, values are rotated in the opposite directions. | 48 | | `B , A` | Catenate | Returns the vector resulting from catenating elements in B with elements in A (row-major order). | | 49 | | `B ⍪ A` | Catenate last | Returns the vector resulting from catenating elements in B with elements in A (column-major order). | | 50 | | `B ∨ A` | Boolean or | Returns the logical disjunction of B and A. | Scalar expansion supported. | 51 | | `B ∧ A` | Boolean and | Returns the logical conjunction of B and A. | Scalar expansion supported. | 52 | | `B ⍱ A` | Boolean nor | Returns the negation of the logical disjunction of B and A. | Scalar expansion supported. | 53 | | `B ⍲ A` | Boolean nand | Returns the negation of the logical conjunction of B and A. | Scalar expansion supported. | 54 | | `B = A` | Equality | Pair-wise equality of elements in B and A. | Scalar expansion supported. | 55 | | `B ≠ A` | Not equal | Pair-wise inequality of elements in B and A. | Scalar expansion supported. | 56 | | `B < A` | Less than | Pair-wise less than comparison of elements in B and A. | Scalar expansion supported. | 57 | | `B ≤ A` | Less than or equal| Pair-wise less than or equal comparison of elements in B and A. | Scalar expansion supported. | 58 | | `B > A` | Greater than | Pair-wise greater than comparison of elements in B and A. | Scalar expansion supported. | 59 | | `B ≥ A` | Greater than or equal|Pair-wise greater that or equal comparison of elements in B and A. | Scalar expansion supported. | 60 | | `B / A` | Compress | Returns the elements in A (as a vector) for which the corresponding elements in the boolean vector B are true. | Assumes A to be a vector of the same length as the boolean vector B. | 61 | | `B / A` | Replicate | Returns repeated elements from A (as a vector) with the repetition controlled by the corresponding elements in the integer vector B. | Assumes A to be a vector of the same length as the integer vector B. | 62 | | `B ○ A` | Circ | Returns the trigonometric function on A dependent on the integer value B; 1:sin, 2:cos, 3:tan. | The value of B has to be statically determined. | 63 | 64 | ### Monadic Operators 65 | 66 | | Expression | Name | Meaning | Notes | 67 | |---------------|------------------|----------------------|---------------| 68 | | `f /` | Reduce | Returns a monadic function that reduces (using f) its argument array along the first axis. The argument to the operator must be a dyadic function. | Certain limitations apply. | 69 | | `f ⌿` | Reduce last axis | Returns a monadic function that reduces (using f) its argument array along the last axis. The argument to the operator must be a dyadic function. | Certain limitations apply. | 70 | | `f ¨` | Each | Returns a monadic function that maps (using f) over its argument array. The argument to the operator must be a monadic function. | | 71 | | `∘. f` | Outer product | Returns a dyadic function that applies f to all elements (pairs) from the cartesian product of the array arguments. | | 72 | 73 | ### Dyadic Operators 74 | 75 | | Expression | Name | Meaning | Notes | 76 | |---------------|------------------|----------------------|---------------| 77 | | `f . g` | Inner product | Returns a dyadic function that performs the inner product of its arguments (using f and g). The arguments to the operator must be a dyadic function. | Certain limitations apply. | 78 | | `f ⍣ n` | Power | Returns a monadic function that iteratively applies f to its argument n times. | Parentheses may be needed to separate n from the argument to the resulting function. The function f may take (and produce) a vector of arrays, which may be indexed in the body of f using array indexing. | 79 | 80 | ### Scalar extensions 81 | 82 | Scalar extensions are supported. 83 | 84 | 85 | ### Identity items 86 | For certain built-in functions, identity items are supported: 87 | 88 | | Function | Left-identity | Right-identity | 89 | |---------------|------------------|----------------| 90 | | `+` | 0 | 0 | 91 | | `-` | | 0 | 92 | | `×` | 1 | 1 | 93 | | `÷` | | 1 | 94 | | `|` | 0 | | 95 | | `=`,`≥`,`≤` | 1 | 1 | 96 | | `≠`,`>`,`<` | 0 | 0 | 97 | | `∨` | | 0 | 98 | | `∧` | | 1 | 99 | | `⌈` | -inf | -inf | 100 | | `⌊` | inf | inf | 101 | 102 | ### Quad Assignment (output) 103 | 104 | Intermediate arrays may be printed using assignment to the quad-character: 105 | 106 | ```apl 107 | ⎕ ← A 108 | ``` 109 | 110 | Arrays of rank 2 are printed as matrices. Other arrays are printed 111 | using a flat representation, specifying both the shape vector and the 112 | underlying values. 113 | 114 | ### Trains (points-free notation) 115 | 116 | APLT supports writing expressions in points-free (also called tacit) notation. For instance, the APL code 117 | 118 | ```apl 119 | mean ← +/÷≢ 120 | ⎕ ← mean 2 37 4 1 121 | ``` 122 | results in the output `11`. APLT support both monadic and dyadic _Agh_ trains and monadic and dyadic _fgh_ trains. 123 | 124 | ### Tuples of arrays 125 | 126 | APLT supports having tuples of arrays of different ranks and 127 | types. For instance, a tuple `c` of a vector, a pair (of two vectors), and 128 | a scalar, may be constructed as 129 | 130 | ```apl 131 | a ← 1 2 4 3 132 | b ← 'hello' 133 | c ← a (b a) 4 134 | ``` 135 | 136 | Tuples, such as `c`, may be passed to functions and deconstructed using index notation: 137 | 138 | ```apl 139 | f ← { 140 | a1 ← +/⍵[1] 141 | a2 ← ⊃⍴(⍵[2])[1] 142 | a1 + a2 + ⍵[3] 143 | } 144 | ⎕ ← f c ⍝ --> [](19) 145 | ``` 146 | 147 | A particular use of this feature is in conjunction with the power 148 | operator. See the [powtup.apl](https://github.com/melsman/apltail/blob/master/tests/powtup.apl) test example. 149 | 150 | ### System Functions 151 | 152 | | Expression | Name | Meaning | Notes | 153 | |------------------|------------------|----------------------|---------------| 154 | | `⎕ReadFile file` | READ FILE | Takes a filepath as parameter and returns a vector of characters | Fails in case the file cannot be read. | 155 | | `⎕ReadIntVecFile file` | READ INT VECTOR FROM FILE | Takes a filepath as parameter and returns a vector of integers | Fails in case the input file cannot be read or does not contain a sequence of integers separated by space characters. | 156 | 157 | 158 | ### Using APLT 159 | 160 | Here is the output from executing `aplt` on the command-line: 161 | 162 | bash-3.2$ aplt 163 | Usage: ../apltail/aplt [OPTIONS]... file.apl... 164 | -o file : write TAIL program to file 165 | -oc file : write LAILA program to file 166 | -c : compile only (no evaluation) 167 | -noopt : disable optimizations 168 | -materialize : disable materialization of arrays 169 | -p_tail : print TAIL program 170 | -p_types : print types in TAIL code 171 | -p_laila : print LAILA code 172 | -s_parse : stop after parsing 173 | -s_tail : stop after TAIL generation 174 | -silent : evaluation output only (unless there are errors) 175 | -v : verbose 176 | -O n : optimisation level (n>0 optimises double operations aggresively) 177 | -comments : write comments in generated C code 178 | -unsafe : don't include assert code in generated C code for array indexing 179 | -stat_laila : print statistics for LAILA code generation 180 | -opt_hoist : enable hoist optimization in LAILA code generation 181 | -opt_loopsplit : enable loop split optimization in LAILA code generation 182 | -------------------------------------------------------------------------------- /tests/pricer.apl: -------------------------------------------------------------------------------- 1 | bb_data ← 3 5 ⍴ 2.2372928847280580 1.0960951589853829 0.7075902730592357 0.8166828043492210 0.7075902730592357 0.0000000000000000 0.5998905309250137 0.4993160054719562 0.6669708029197080 0.5006839945280438 0.0000000000000000 0.4001094690749863 0.5006839945280438 0.3330291970802919 0.4993160054719562 2 | bb_ind ← 3 5 ⍴ 5 2 1 3 4 0 0 0 2 3 0 5 2 5 5 3 | md_c ← 3 3 ⍴ 1.0000000 0.6000000 0.8000000 0.6000000 0.8000000 0.1500000 0.8000000 0.1500000 0.5809475 4 | 5 | md_disc ← 0.9797862861805930 0.9505748482484491 0.9214621679912968 0.8906693055891434 0.8588567633110704 6 | 7 | md_drifts ← 5 3 ⍴ ¯0.0283491736871803 0.0178771081725381 0.0043096808044729 ¯0.0183841413744211 ¯0.0044530897672834 0.0024263805987983 ¯0.0172686581005089 0.0125638544546015 0.0094452810918001 ¯0.0144179417871814 0.0157411263968213 0.0125315353728014 ¯0.0121497422218761 0.0182904634062437 0.0151125070556484 8 | 9 | md_starts ← 3758.0500000000001819 11840.0000000000000000 1200.0000000000000000 10 | 11 | md_vols ← 5 3 ⍴ 0.1900000 0.1900000 0.1500000 0.1900000 0.1900000 0.1500000 0.1900000 0.1900000 0.1500000 0.1900000 0.1900000 0.1500000 0.1900000 0.1900000 0.1500000 12 | 13 | 14 | dv ← 536870912 268435456 134217728 67108864 15 | dv ← dv, 33554432 16777216 8388608 4194304 2097152 1048576 524288 16 | dv ← dv, 262144 131072 65536 32768 16384 8192 4096 2048 1024 512 17 | dv ← dv, 256 128 64 32 16 8 4 2 1 536870912 805306368 18 | dv ← dv, 671088640 1006632960 570425344 855638016 713031680 1069547520 19 | dv ← dv, 538968064 808452096 673710080 1010565120 572653568 858980352 20 | dv ← dv, 715816960 1073725440 536879104 805318656 671098880 1006648320 21 | dv ← dv, 570434048 855651072 713042560 1069563840 538976288 808464432 22 | dv ← dv, 673720360 1010580540 572662306 858993459 536870912 23 | dv ← dv, 805306368 402653184 603979776 973078528 385875968 595591168 24 | dv ← dv, 826277888 438304768 657457152 999817216 358875136 538574848 25 | dv ← dv, 807862272 406552576 605372416 975183872 389033984 597170176 26 | dv ← dv, 828646400 437926400 656873216 1002152832 357921088 536885792 27 | dv ← dv, 805312304 402662296 603992420 973085210 385885991 28 | dv ← dv, 536870912 805306368 939524096 335544320 234881024 721420288 29 | dv ← dv, 411041792 616562688 920649728 1062207488 381157376 258736128 30 | dv ← dv, 771883008 453181440 545488896 817971200 954261504 340963328 31 | dv ← dv, 238651392 732843008 417426944 609285376 909831040 1068349120 32 | dv ← dv, 383778848 256901168 783810616 460062740 537001998 805503019 33 | dv ← dv, 536870912 805306368 402653184 1006632960 167772160 285212672 34 | dv ← dv, 713031680 566231040 853540864 489684992 952631296 208928768 35 | dv ← dv, 316801024 758317056 550076416 813154304 417505280 1009913856 36 | dv ← dv, 172697600 297131008 704744960 553894656 847291520 499194688 37 | dv ← dv, 954376224 204607536 306915352 766893116 536972810 805552913 38 | dv ← dv, 536870912 805306368 402653184 469762048 301989888 721420288 39 | dv ← dv, 92274688 264241152 941621248 741343232 169345024 924581888 40 | dv ← dv, 395444224 619380736 1034256384 603963392 838868992 452997120 41 | dv ← dv, 494934016 331357184 706744832 120597248 261621120 953946048 42 | dv ← dv, 800208928 148581424 935168536 350484252 630339474 1072370923 43 | dv ← dv, 536870912 805306368 134217728 1006632960 503316480 754974720 44 | dv ← dv, 629145600 440401920 94371840 711983104 229113856 374079488 45 | dv ← dv, 330694656 996212736 907247616 557531136 867573760 190918656 46 | dv ← dv, 1041467392 490437632 766918144 643898624 462663040 125527616 47 | dv ← dv, 672545696 202454896 373006376 288845836 1000351766 930090001 48 | dv ← dv, 536870912 268435456 402653184 872415232 838860800 956301312 49 | dv ← dv, 612368384 717225984 211812352 386924544 302514176 688128000 50 | dv ← dv, 1015414784 516751360 1051492352 773734400 914432000 63877120 51 | dv ← dv, 807741440 165200896 748683776 118489344 168296832 486802240 52 | dv ← dv, 243663648 667747216 439124552 81674924 975249610 350138737 53 | dv ← dv, 536870912 268435456 671088640 469762048 973078528 1023410176 54 | dv ← dv, 713031680 339738624 912261120 797966336 176685056 71565312 55 | dv ← dv, 510263296 865533952 814120960 961232896 887136256 668078080 56 | dv ← dv, 116070400 382772224 1047134720 597098752 411468416 625689024 57 | dv ← dv, 249602976 449975248 745216680 43033924 134873446 201786361 58 | dv ← dv, 536870912 268435456 402653184 67108864 704643072 385875968 59 | dv ← dv, 696254464 205520896 920649728 946864128 359137280 859045888 60 | dv ← dv, 302907392 50659328 462192640 524599296 895541248 590794752 61 | dv ← dv, 168810496 118033408 831447552 138662144 485185920 796511296 62 | dv ← dv, 1021313184 1064304752 619184920 997458052 250479054 745865975 63 | dv ← dv, 536870912 268435456 939524096 1006632960 838860800 64 | dv ← dv, 889192448 645922816 46137344 476053504 584056832 210239488 65 | dv ← dv, 465829888 820903936 689897472 73695232 249118720 110075904 66 | dv ← dv, 315338752 610637824 517665792 1049494016 785318144 376210304 67 | dv ← dv, 735921088 402760480 738505552 168368744 151499820 344957894 68 | dv ← dv, 936096557 536870912 805306368 939524096 1006632960 69 | dv ← dv, 503316480 922746880 41943040 423624704 228589568 651165696 70 | dv ← dv, 195559424 500957184 791019520 261292032 1040285696 118407168 71 | dv ← dv, 982065152 625250304 329533440 298984448 153690624 76845824 72 | dv ← dv, 579619712 692987840 900670432 450334832 363187112 719119956 73 | dv ← dv, 765461306 382730781 536870912 805306368 402653184 74 | dv ← dv, 603979776 838860800 117440512 478150656 658505728 752877568 75 | dv ← dv, 1060110336 141033472 209453056 244187136 272957440 678068224 76 | dv ← dv, 1014546432 377724928 876875776 443160576 998185984 168665600 77 | dv ← dv, 318837504 914397568 71818816 40763680 527762288 939688008 78 | dv ← dv, 335855668 705536494 587273091 536870912 268435456 79 | dv ← dv, 671088640 738197504 637534208 150994944 813694976 943718400 80 | dv ← dv, 77594624 179306496 798490624 967049216 134348800 1006698496 81 | dv ← dv, 235044864 620937216 377643008 826314752 874711040 854819840 82 | dv ← dv, 725109248 856992512 664336768 94804544 100663328 419430416 83 | dv ← dv, 411041832 339738668 580911142 61865993 536870912 805306368 84 | dv ← dv, 939524096 603979776 100663296 452984832 998244352 188743680 85 | dv ← dv, 866123776 389021696 287834112 172228608 824836096 977731584 86 | dv ← dv, 153714688 507854848 254402560 88403968 883578880 235160576 87 | dv ← dv, 118055424 422917888 371224704 326210368 654926368 691353392 88 | dv ← dv, 773877944 930190180 554263078 842348331 89 | 90 | dirVec ← 15 30 ⍴ dv 91 | 92 | 93 | contract ← 2 94 | ⍝ num_mc_it ← 1048576 95 | num_mc_it ← 100000 96 | num_dates ← 5 97 | num_under ← 3 98 | num_models ← 1 99 | num_bits ← 30 100 | 101 | testBit ← { 0≠⍵ ⎕INT32AND 1 ⎕INT32SHL (⍺-1) } 102 | grayCode ← { ⍵ ⎕INT32XOR ⍵ ⎕INT32SHR 1 } 103 | 104 | 105 | ⍝ Sobol sequences using inductive approach 106 | sobolIndI ← { 107 | dirVec ← ⍵ 108 | n ← ⍺ 109 | bitsNum ← (⍴dirVec)[⊃⍴⍴dirVec] 110 | bits ← ⍳bitsNum 111 | is ← n ∘.{⍵ testBit (grayCode ⍺)} bits 112 | is ⎕INT32XOR.× ⍉dirVec 113 | } 114 | 115 | sobolIndR ← { 116 | arri ← ⍺ sobolIndI ⍵ 117 | bitsNum ← (⍴⍵)[⊃⍴⍴⍵] 118 | arri÷2*bitsNum 119 | } 120 | 121 | ⍝ TODO: implement approach by Mike Giles et al. 122 | 123 | ⍝ Implement normal distribution using the method used in R: 124 | ⍝ https://svn.r-project.org/R/trunk/src/nmath/qnorm.c 125 | ⍝ Algorithm 111 and 241 (available at JSTOR) 126 | small_as ← 3.387132872796366608 133.14166789178437745 1971.5909503065514427 13731.693765509461125 127 | small_as ← small_as, 45921.953931549871457 67265.770927008700853 33430.575583588128105 2509.0809287301226727 128 | 129 | small_bs ← 1.0 42.313330701600911252 687.1870074920579083 5394.1960214247511077 130 | small_bs ← small_bs , 21213.794301586595867 39307.89580009271061 28729.085735721942674 5226.495278852854561 131 | 132 | interm_as ← 1.42343711074968357734 4.6303378461565452959 5.7694972214606914055 3.64784832476320460504 133 | interm_as ← interm_as , 1.27045825245236838258 0.24178072517745061177 0.0227238449892691845833 (7.7454501427834140764 × 10*¯4) 134 | 135 | interm_bs ← 1.0 2.05319162663775882187 1.6763848301838038494 0.68976733498510000455 136 | interm_bs ← interm_bs , 0.14810397642748007459 0.0151986665636164571966 (5.475938084995344946 × 10*¯4) (1.05075007164441684324 × 10*¯9) 137 | 138 | tail_as ← 6.6579046435011037772 5.4637849111641143699 1.7848265399172913358 0.29656057182850489123 139 | tail_as ← tail_as , 0.026532189526576123093 0.0012426609473880784386 (2.71155556874348757815 × 10*¯4) (2.01033439929228813265 × 10*¯7) 140 | 141 | tail_bs ← 1.0 0.59983220655588793769 0.13692988092273580531 0.0148753612908506148525 142 | tail_bs ← tail_bs , (7.868691311456132591 × 10*¯4) (1.8463183175100546818 × 10*¯5) (1.4215117583164458887 × 10*¯7) (2.04426310338993978564 × 10*¯15) 143 | 144 | 145 | appr ← { (⍺×(⍺×(⍺×(⍺×(⍺×(⍺×(⍺×⍵[8]+⍵[7])+⍵[6])+⍵[5])+⍵[4])+⍵[3])+⍵[2])+⍵[1]) } 146 | 147 | smallcase ← { 148 | x ← 0.180625 - ⍵×⍵ 149 | ⍵ × (x appr small_as) ÷ (x appr small_bs) 150 | } 151 | 152 | intermediate ← { 153 | x ← ⍵ - 1.6 154 | (x appr interm_as) ÷ (x appr interm_bs) 155 | } 156 | 157 | tail ← { 158 | x ← ⍵ - 5.0 159 | (x appr tail_as) ÷ (x appr tail_bs) 160 | } 161 | 162 | else ← {(⍺⍺⍣⍺)(⍵⍵⍣(~⍺))⍵} 163 | 164 | ugaussianEl ← { 165 | dp ← ⍵ - 0.5 166 | 167 | ⍝ case 1 168 | R1 ← smallcase dp 169 | 170 | ⍝ case 2 171 | pp ← 0.5 + dp×-×dp 172 | r ← (-⍟pp)*0.5 173 | x ← ((intermediate r) × r≤5.0) + (tail r) × r>5.0 174 | R2 ← x × ×dp 175 | 176 | ⍝ conditional 177 | (R2 × (1 - 0.425≥|dp)) + R1 × (0.425≥|dp) 178 | } 179 | 180 | ugaussian ← { ugaussianEl ¨ ⍵ } 181 | 182 | brownianBridge ← { 183 | num_under ← ⍵[1] 184 | num_dates ← ⍵[2] 185 | bb_ind ← ⍵[3] 186 | bb_data ← ⍵[4] 187 | gauss ← ⍵[5] 188 | 189 | bb_bi ← bb_ind[1;] 190 | bb_li ← bb_ind[2;] 191 | bb_ri ← bb_ind[3;] 192 | bb_sd ← bb_data[1;] 193 | bb_lw ← bb_data[2;] 194 | bb_rw ← bb_data[3;] 195 | gauss2Dt ← (num_dates num_under)⍴gauss 196 | sz ← (⍉(num_under num_dates)⍴bb_sd) × gauss2Dt 197 | bbrow ← ((num_dates+1) num_under)⍴0.0 198 | 199 | step ← { 200 | next ← (bb_lw[⍵]×bbrow[bb_li[⍵]+1;]) + sz[⍵;] + (bb_rw[⍵]×bbrow[bb_ri[⍵]+1;]) 201 | k ← bb_bi[⍵]+1 202 | iter ← { 203 | bbrow[k;⍵] ← next[⍵] 204 | ⍵+1 205 | } 206 | v ← (iter ⍣ num_under) 1 207 | ⍵+1 208 | } 209 | 210 | variable_not_used ← (step ⍣ num_dates) 1 211 | (1↓bbrow) - num_dates↑bbrow 212 | } 213 | 214 | ⍝ Sets the values in the upper triangle to zero 215 | clearUpperTriangle ← { 216 | n ← ⊃1↑⍴ ⍵ 217 | ⍵ × (⍳n)∘.≥⍳n 218 | } 219 | 220 | ⍝ Black-Scholes 221 | ⍝ Currently num_under must be a constant, should be given as argument 222 | correlateDeltas ← { 223 | md_c ← ⍺ 224 | bb_arr ← ⍵ 225 | ⍝ Clear upper triangle - why are the numbers there when we don't use them? 226 | bb_arr +.× ⍉ clearUpperTriangle md_c 227 | } 228 | 229 | combineVs ← { 230 | n_row ← ⍵[1] 231 | vol_row ← ⍵[2] 232 | dr_row ← ⍵[3] 233 | dr_row + n_row × vol_row 234 | } 235 | 236 | mkPrices ← { 237 | md_starts ← ⍵[1] 238 | md_vols ← ⍵[2] 239 | md_drifts ← ⍵[3] 240 | noises ← ⍵[4] 241 | e_rows ← *combineVs noises md_vols md_drifts 242 | 243 | 1↓⍉×\md_starts , ⍉ e_rows 244 | } 245 | 246 | blackScholes ← { 247 | num_under ← ⍵[1] 248 | md_c ← ⍵[2] 249 | md_vols ← ⍵[3] 250 | md_drifts ← ⍵[4] 251 | md_starts ← ⍵[5] 252 | bb_arr ← ⍵[6] 253 | noises ← md_c correlateDeltas bb_arr 254 | mkPrices (md_starts md_vols md_drifts noises) 255 | } 256 | 257 | payoff2 ← { 258 | md_disc ← ⍺ 259 | xss ← ⍵ 260 | mins ← ⌊/xss × (⍴xss)⍴ ÷ 3758.05 11840.0 1200.0 261 | 262 | bools ← (mins ≥ 1), (mins[5] ≥ 0.75), 1 263 | X ← 1000.0 × md_disc[5] 264 | results ← (md_disc × 1000 + 150 × ⍳5), X, mins[5] × X 265 | 266 | (bools/results)[1] 267 | } 268 | 269 | compute ← { 270 | n ← ⍵ 271 | payoffs ← 0 272 | 273 | sobol_mat ← (⍳⍵) sobolIndR dirVec 274 | gauss_mat ← ugaussian sobol_mat 275 | 276 | compute1 ← { 277 | bb_mat ← brownianBridge (num_under num_dates bb_ind bb_data (gauss_mat[⍵;])) 278 | bs_mat ← blackScholes (num_under md_c md_vols md_drifts md_starts bb_mat) 279 | 280 | md_disc payoff2 bs_mat 281 | } 282 | 283 | (+/compute1¨⍳n)÷n 284 | } 285 | 286 | compute num_mc_it 287 | -------------------------------------------------------------------------------- /src/tail/tail.sig: -------------------------------------------------------------------------------- 1 | (** This signature specifies operations for constructing, 2 | pretty-printing, and evaluating TAIL programs. TAIL is an acronym 3 | for "Typed Array Intermediate Language". 4 | *) 5 | 6 | signature TAIL = sig 7 | 8 | val optimisationLevel : int ref 9 | 10 | structure Exp : TAIL_EXP 11 | 12 | (* Types (phantom types) *) 13 | eqtype Int and Double and Complex and 'a Num (* numeric types *) 14 | and Bool (* booleans *) 15 | and Char (* characters *) 16 | and 'a Vec (* vectors *) 17 | 18 | (* TAIL types (= TAIL_TYPE.typ) *) 19 | type 'a T (* Type constructors *) 20 | val Int : Int Num T 21 | val Double : Double Num T 22 | val Complex : Complex Num T 23 | val Bool : Bool T 24 | val Char : Char T 25 | val Vec : 'a T -> 'a Vec T 26 | val prType : 'a T -> string 27 | 28 | (* Monadic encapsulation of program construction. Allows for 29 | introducing target-language let-constructs using the lett and 30 | letm combinators below. 31 | *) 32 | type 'a M 33 | val >>= : 'a M * ('a -> 'b M) -> 'b M 34 | val ret : 'a -> 'a M 35 | 36 | (* Terms *) 37 | type 'a exp 38 | type 'a tvector = 'a Vec exp (* vector terms *) 39 | val typeOf : 'a exp -> Exp.typ 40 | 41 | (* TAIL terms w. added phantom types *) 42 | type 'a NUM = 'a Num exp (* basic term types *) 43 | type INT = Int NUM 44 | type DOUBLE = Double NUM 45 | type COMPLEX = Complex NUM 46 | type BOOL = Bool exp 47 | type CHAR = Char exp 48 | 49 | val I : Int32.int -> INT 50 | val D : real -> DOUBLE 51 | val X : real*real -> COMPLEX 52 | val B : bool -> BOOL 53 | val C : word -> CHAR 54 | val % : INT * INT -> INT 55 | val d2x : DOUBLE -> COMPLEX 56 | val i2d : INT -> DOUBLE 57 | val b2i : BOOL -> INT 58 | val If : BOOL * 'a exp * 'a exp -> 'a exp 59 | val fromList : 'a T -> 'a exp list -> 'a tvector 60 | val fromChars : word list -> Char tvector 61 | 62 | (* Compiled Programs 63 | 'a - the input type of the expression (often just "unit") 64 | 'b - the return type of the expression *) 65 | type ('a,'b) prog 66 | 67 | (* [runM flags t0 c] Runs the monadic expression c, type checks it 68 | and optimizes it. 69 | 70 | Prints type errors and intermediate representations if the 71 | 'verbose' flag (-v) is set. 72 | 73 | The expression is expected to return a value of type 't0'. 74 | *) 75 | val runM : {verbose: bool, optlevel: int, prtype: bool, materialize: bool} 76 | -> 'b T -> 'b exp M -> (unit,'b) prog 77 | 78 | (* Run the monadic expression, the function will be given a variable 79 | where to store the final result *) 80 | val runF : 'a T * 'b T -> ('a exp -> 'b exp M) -> ('a,'b) prog 81 | 82 | (* [outprog prtype filename c] 83 | 'prtype' indicates whether the output should include instance lists. *) 84 | val outprog : bool -> string -> ('a,'b) prog -> unit 85 | val runHack : 'a M -> 'a option 86 | val toExp : (unit,'b) prog -> 'b exp 87 | 88 | (* Values and Evaluation *) 89 | type 'a value 90 | val Iv : Int32.int -> Int Num value 91 | val unIv : Int Num value -> Int32.int 92 | val Dv : real -> Double Num value 93 | val unDv : Double Num value -> real 94 | val Xv : real*real -> Complex Num value 95 | val unXv : Complex Num value -> real*real 96 | val Bv : bool -> Bool value 97 | val unBv : Bool value -> bool 98 | val Vv : 'a value list -> 'a Vec value 99 | val unVv : 'a Vec value -> 'a value list 100 | val Uv : unit value 101 | 102 | (* Evaluate TAIL expression to a value *) 103 | val eval : ('a,'b) prog -> 'a value -> 'b value 104 | 105 | (* Pretty printing *) 106 | val pp_prog : bool -> ('a,'b) prog -> string 107 | val pp_exp : bool -> 'a exp -> string 108 | val ppValue : 'a value -> string 109 | 110 | type 'a ndarray (* APL multi-dimensional arrays *) 111 | 112 | (* TAIL built-in operations *) 113 | val ceil : DOUBLE -> INT 114 | val floor : DOUBLE -> INT 115 | val ln : DOUBLE -> DOUBLE 116 | val cos : DOUBLE -> DOUBLE 117 | val sin : DOUBLE -> DOUBLE 118 | val tan : DOUBLE -> DOUBLE 119 | val acos : DOUBLE -> DOUBLE 120 | val asin : DOUBLE -> DOUBLE 121 | val atan : DOUBLE -> DOUBLE 122 | val cosh : DOUBLE -> DOUBLE 123 | val sinh : DOUBLE -> DOUBLE 124 | val tanh : DOUBLE -> DOUBLE 125 | val pi : unit -> DOUBLE 126 | val addi : INT * INT -> INT 127 | val subi : INT * INT -> INT 128 | val muli : INT * INT -> INT 129 | val divi : INT * INT -> INT 130 | val resi : INT * INT -> INT 131 | val lti : INT * INT -> BOOL 132 | val ltei : INT * INT -> BOOL 133 | val gti : INT * INT -> BOOL 134 | val gtei : INT * INT -> BOOL 135 | val eqi : INT * INT -> BOOL 136 | val neqi : INT * INT -> BOOL 137 | val maxi : INT -> INT -> INT 138 | val mini : INT -> INT -> INT 139 | val negi : INT -> INT 140 | val absi : INT -> INT 141 | val signi : INT -> INT 142 | val addd : DOUBLE * DOUBLE -> DOUBLE 143 | val subd : DOUBLE * DOUBLE -> DOUBLE 144 | val muld : DOUBLE * DOUBLE -> DOUBLE 145 | val divd : DOUBLE * DOUBLE -> DOUBLE 146 | val resd : DOUBLE * DOUBLE -> DOUBLE 147 | val powd : DOUBLE * DOUBLE -> DOUBLE 148 | val ltd : DOUBLE * DOUBLE -> BOOL 149 | val lted : DOUBLE * DOUBLE -> BOOL 150 | val gtd : DOUBLE * DOUBLE -> BOOL 151 | val gted : DOUBLE * DOUBLE -> BOOL 152 | val eqd : DOUBLE * DOUBLE -> BOOL 153 | val neqd : DOUBLE * DOUBLE -> BOOL 154 | val maxd : DOUBLE -> DOUBLE -> DOUBLE 155 | val mind : DOUBLE -> DOUBLE -> DOUBLE 156 | val negd : DOUBLE -> DOUBLE 157 | val absd : DOUBLE -> DOUBLE 158 | val expd : DOUBLE -> DOUBLE 159 | val signd : DOUBLE -> INT 160 | 161 | val andb : BOOL * BOOL -> BOOL 162 | val orb : BOOL * BOOL -> BOOL 163 | val xorb : BOOL * BOOL -> BOOL 164 | val eqb : BOOL * BOOL -> BOOL 165 | val nandb : BOOL * BOOL -> BOOL 166 | val norb : BOOL * BOOL -> BOOL 167 | val notb : BOOL -> BOOL 168 | 169 | val addx : COMPLEX * COMPLEX -> COMPLEX 170 | val subx : COMPLEX * COMPLEX -> COMPLEX 171 | val mulx : COMPLEX * COMPLEX -> COMPLEX 172 | val rex : COMPLEX -> DOUBLE 173 | val imx : COMPLEX -> DOUBLE 174 | val injx : DOUBLE * DOUBLE -> COMPLEX 175 | val expx : COMPLEX -> COMPLEX 176 | 177 | val roll : INT -> DOUBLE 178 | 179 | val ltc : CHAR * CHAR -> BOOL 180 | val ltec : CHAR * CHAR -> BOOL 181 | val gtc : CHAR * CHAR -> BOOL 182 | val gtec : CHAR * CHAR -> BOOL 183 | val eqc : CHAR * CHAR -> BOOL 184 | val neqc : CHAR * CHAR -> BOOL 185 | 186 | val zilde : unit -> 'a ndarray 187 | val scl : 'a exp -> 'a ndarray (* identity! *) 188 | val scalar : 'a exp -> 'a ndarray 189 | val vec : 'a tvector -> 'a ndarray 190 | val iota : INT -> Int Num ndarray 191 | val iota' : Int Num ndarray -> Int Num ndarray 192 | 193 | val siz : 'a ndarray -> INT 194 | val dim : 'a ndarray -> INT 195 | 196 | (* Ravel *) 197 | val rav : 'a ndarray -> 'a ndarray 198 | val rav0 : 'a ndarray -> 'a tvector 199 | 200 | (* val index : Int Num tvector -> 'a m -> 'a m M *) 201 | val each : ('a exp -> 'b exp M) -> 'a ndarray -> 'b ndarray 202 | 203 | val red : ('a exp * 'b exp -> 'b exp) -> 'b exp -> 'a ndarray -> 'b exp 204 | 205 | val mif : BOOL * 'a ndarray * 'a ndarray -> 'a ndarray 206 | val lett : 'a exp -> 'a exp M 207 | val letm : 'a ndarray -> 'a ndarray M 208 | 209 | val zipWith : ('a exp * 'b exp -> 'c exp M) -> 'a ndarray -> 'b ndarray -> 'c ndarray 210 | 211 | val scan : ('a exp * 'b exp -> 'a exp M) -> 'a exp -> 'b ndarray -> 'a ndarray 212 | 213 | val catenate : 'a ndarray -> 'a ndarray -> 'a ndarray 214 | val catenate_first : 'a ndarray -> 'a ndarray -> 'a ndarray 215 | 216 | val take : INT -> 'a ndarray -> 'a ndarray 217 | val drop : INT -> 'a ndarray -> 'a ndarray 218 | 219 | val first : 'a ndarray -> 'a exp 220 | 221 | (* Memoize *) 222 | val mem : 'a ndarray -> 'a ndarray 223 | val memScl : 'a exp -> 'a exp 224 | 225 | val rotate : INT -> 'a ndarray -> 'a ndarray 226 | val reverse : 'a ndarray -> 'a ndarray 227 | val vreverse : 'a ndarray -> 'a ndarray 228 | val vrotate : INT -> 'a ndarray -> 'a ndarray 229 | val reshape : Int Num tvector -> 'a ndarray -> 'a ndarray 230 | val shape : 'a ndarray -> Int Num tvector 231 | val gradeUp : 'a ndarray -> Int Num ndarray 232 | val gradeDown : 'a ndarray -> Int Num ndarray 233 | 234 | val reduce : ('a exp * 'a exp -> 'a exp M) -> 'a exp -> 'a ndarray -> ('a exp -> 'b) -> ('a ndarray -> 'b) -> 'b 235 | 236 | val compress : Bool ndarray -> 'a ndarray -> 'a ndarray 237 | val replicate : 'a exp -> Int Num ndarray -> 'a ndarray -> 'a ndarray 238 | 239 | val power : ('a ndarray -> 'a ndarray M) -> INT -> 'a ndarray -> 'a ndarray 240 | val powerScl : ('a exp -> 'a exp M) -> INT -> 'a exp -> 'a exp 241 | val condScl : ('a exp -> 'a exp M) -> BOOL -> 'a exp -> 'a exp 242 | 243 | type 'a tuple 244 | type nil 245 | type ('a,'e) tupleIdx 246 | val powerN : ('a tuple -> 'a tuple M) -> INT -> 'a tuple -> 'a tuple 247 | val empTuple : nil tuple 248 | val consTuple : 'a ndarray -> 'b tuple -> ('a->'b)tuple 249 | val Zero : unit -> ('a->'b,'a)tupleIdx 250 | val Succ : ('a,'e)tupleIdx -> ('a->'b,'e)tupleIdx (* Succ(Zero()) : ('a->'b->'c,'b)tupleIdx *) 251 | val prjTuple : ('a,'e)tupleIdx -> 'a tuple -> 'e ndarray 252 | 253 | structure Unsafe : sig 254 | type utuple 255 | type uexp 256 | val letUtuple : utuple -> utuple M 257 | val upowerN : (utuple -> utuple M) -> INT -> utuple -> utuple 258 | val empUtuple : utuple 259 | val consUtuple : uexp -> utuple -> utuple 260 | val prjUtuple : int -> utuple -> uexp (* zero-indexed *) 261 | val toUexp : 'a exp -> uexp 262 | val toUexpA : 'a ndarray -> uexp 263 | val fromUexp : uexp -> 'a exp 264 | val fromUexpA : uexp -> 'a ndarray 265 | end 266 | 267 | val transpose : 'a ndarray -> 'a ndarray 268 | val transpose2 : Int Num tvector -> 'a ndarray -> 'a ndarray 269 | 270 | val idxS : Int32.int -> INT -> 'a ndarray -> ('a exp -> 'b) -> ('a ndarray -> 'b) -> 'b 271 | val idx : Int32.int -> Int Num ndarray -> 'a ndarray -> 'a ndarray 272 | 273 | val idxassign : Int Num ndarray -> 'a ndarray -> 'a exp -> BOOL 274 | 275 | (* Printing routines *) 276 | val prArrI : Int Num ndarray -> Int Num ndarray 277 | val prArrB : Bool ndarray -> Bool ndarray 278 | val prArrD : Double Num ndarray -> Double Num ndarray 279 | val prArrX : Complex Num ndarray -> Complex Num ndarray 280 | val prArrC : Char ndarray -> Char ndarray 281 | val prSclI : INT -> INT 282 | val prSclB : BOOL -> BOOL 283 | val prSclD : DOUBLE -> DOUBLE 284 | val prSclX : COMPLEX -> COMPLEX 285 | val prSclC : CHAR -> CHAR 286 | val formatI : INT -> Char ndarray 287 | val formatD : DOUBLE -> Char ndarray 288 | val formatX : COMPLEX -> Char ndarray 289 | 290 | (* File access *) 291 | val readFile : Char ndarray -> Char ndarray 292 | val readIntVecFile : Char ndarray -> Int Num ndarray 293 | val readDoubleVecFile : Char ndarray -> Double Num ndarray 294 | 295 | (* Int32 binary operations *) 296 | val andi : INT * INT -> INT 297 | val ori : INT * INT -> INT 298 | val shri : INT * INT -> INT 299 | val shari : INT * INT -> INT 300 | val shli : INT * INT -> INT 301 | val xori : INT * INT -> INT 302 | val noti : INT -> INT 303 | 304 | (* Time.now *) 305 | val nowi : INT -> INT (* nowi 0 returns time in milliseconds since process start *) 306 | 307 | val bench : ('a exp -> 'a exp M) -> INT -> 'a exp -> 'a exp (* as powerScl, but for benchmarking *) 308 | 309 | end 310 | --------------------------------------------------------------------------------