module pascal /* The Triangle of Pascal. The result of this program is a real triangle of Pascal of height Height, not just a list representing such a triangle: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 etc. Run the program using the "Basic Values Only" option (Application options). Use a non-proportional font for the output (e.g. Monaco 9). */ import _SystemArray (+) infixl 6 :: !Int !Int -> Int (+) a b = code inline { addI } (-) infixl 6 :: !Int !Int -> Int (-) a b = code inline { subI } (/) infixl 7 :: !Int !Int -> Int (/) a b = code inline { divI } inc :: !Int -> Int inc a = a + 1 take :: Int [a] -> [a] take 0 _ = [] take n [x:xs] = [x:take (n-1) xs] (+++) infixr 5 :: !{#Char} !{#Char} -> {#Char} (+++) a b = code inline { .d 2 0 jsr catAC .o 1 0 } repeat :: a -> [a] repeat x = cons where cons = [x:cons] repeatn :: !.Int a -> [a] repeatn n x = take n (repeat x) spaces :: !.Int -> [Char] spaces n = repeatn n ' ' class toString a :: !a -> String instance toString [Char] where toString a = {c \\ c <- a} instance toString Int where toString a = code inline { .d 0 1 i jsr ItoAC .o 1 0 } //import StdEnv /* A row of the triangle is represented by a list of integers, the triangle as a list of rows: */ ::Row :== [Int] ::Triangle :== [Row] // Some constants NrRows :== 18 // Number of rows to be shown. Middle :== 40 // The middle of a 80 character line. // Miscellaneous functions NrOfDigits:: Int -> Int NrOfDigits 0 = 0 NrOfDigits n = NrOfDigits (n / 10) + 1 // Calculating the Triangle. Pascal::Triangle Pascal = p where p = [[1] : [Next a \\ a <- p]] Next x = AddRows [0:x] x AddRows::Row Row -> Row AddRows [a:x] [b:y] = [a + b : AddRows x y] AddRows [a] [] = [a] AddRows [] [] = [] // Formatting the list representing the triangle as a real triangle. FormatRows::Triangle -> [String] FormatRows [f:r] = [ FormatRow f +++ "\n" : FormatRows r] where FormatRow::Row -> String FormatRow row = toString (spaces (Middle - Length_new row/2 )) +++ FormatElems row FormatElems::Row -> String FormatElems [f:r] = " " +++ toString f +++ FormatElems r FormatElems [] = "" Length_new::Row -> Int Length_new [f:r] = NrOfDigits f + Length_new r + 1 Length_new [] = -1 FormatRows [] = [] /* The Start rule: The first NrRows rows of the (infinite) triangle returned by Pascal are taken and shown on the screen as a triangle by means of FormatRows. */ Start::[String] Start = FormatRows (take NrRows Pascal)