+++ /dev/null
-implementation module GenPrint\r
-\r
-import StdGeneric, StdEnv, StdMaybe\r
-\r
-//-------------------------------------------------------------------------------------\r
-\r
-:: *StringOutput = {so_str :: !*String, so_pos :: !Int}\r
-\r
-\r
-instance PrintOutput StringOutput where\r
- printOutput ch s=:{so_str, so_pos} \r
- #! new_str = realloc_if_needed so_pos so_str \r
- = {s & so_str = {new_str & [so_pos] = ch}, so_pos = inc so_pos}\r
- where\r
- realloc_if_needed :: Int u:String -> v:String, [u <= v]\r
- realloc_if_needed pos str\r
- #! size_str = size str\r
- | pos == size_str\r
- #! new_str = createArray ((size_str + 1) * 3 /2) '\0'\r
- #! (new_str, str) = fill 0 size_str new_str str\r
- = new_str\r
- | otherwise \r
- = str \r
- fill i n new_str str \r
- | i == n\r
- = (new_str, str)\r
- | otherwise \r
- #! (ch, str) = str![i] \r
- = fill (inc i) n {new_str & [i] = ch} str \r
- \r
-instance PrintOutput File where\r
- printOutput x s\r
- = fwritec x s\r
-\r
-\r
-//-------------------------------------------------------------------------------------\r
-\r
-\r
-($) infixl 9\r
-($) x y = y o x\r
-\r
-(@) infix 8 \r
-(@) x y = x y\r
-\r
-mapSt f [] st = ([], st)\r
-mapSt f [x:xs] st\r
- # (y, st) = f x st\r
- # (ys, st) = mapSt f xs st\r
- = ([y:ys], st)\r
-\r
-foldSt f [] = id \r
-foldSt f [x:xs] = foldSt f xs o f x\r
-\r
-//-------------------------------------------------------------------------------------\r
-:: PrintState s =\r
- { ps_output :: !s\r
- , ps_context :: !Context\r
- }\r
-:: Context \r
- = CtxNone // initial env\r
- | CtxNullary // nullary constructor\r
- | CtxRecord // record constructor \r
- | CtxTuple // tuple constructor\r
- | CtxNonfix // normal nonfix constructor\r
- | CtxInfix // infix constructor\r
- String // name\r
- GenConsAssoc // constructor's associativity \r
- Prio // constructors priority \r
- GenConsAssoc // left or right argument\r
-:: Prio :== Int\r
- \r
-instance == GenConsAssoc where\r
- (==) GenConsAssocNone GenConsAssocNone = True\r
- (==) GenConsAssocLeft GenConsAssocLeft = True\r
- (==) GenConsAssocRight GenConsAssocRight = True\r
- (==) _ _ = False\r
-\r
-mkContext :: GenericConsDescriptor -> Context\r
-mkContext {gcd_prio=GenConsNoPrio, gcd_fields, gcd_name, gcd_arity}\r
- | isEmpty gcd_fields \r
- | gcd_arity == 0\r
- = CtxNullary\r
- | is_tuple gcd_name\r
- = CtxTuple\r
- | otherwise\r
- = CtxNonfix\r
- | otherwise \r
- = CtxRecord \r
-where\r
- is_tuple name \r
- #! size_name = size name\r
- = (size_name == 7 || size_name == 8)\r
- && name.[0] == '_'\r
- && name.[1] == 'T'\r
- && name.[2] == 'u'\r
- && name.[3] == 'p'\r
- && name.[4] == 'l'\r
- && name.[5] == 'e'\r
- && isDigit name.[6]\r
- && (size_name == 7 || isDigit name.[7])\r
- \r
-mkContext {gcd_prio=GenConsPrio assoc prio, gcd_name} \r
- = CtxInfix gcd_name assoc prio GenConsAssocNone\r
-\r
-needParenthesis :: Context Context -> Bool\r
-needParenthesis CtxNone outer_ctx = abort "needParenthesis: this_ctx = CtxNone"\r
-needParenthesis this_ctx CtxNullary = abort "needParenthesis: outer_ctx = CtxNullary"\r
-needParenthesis CtxNullary outer_ctx = False\r
-needParenthesis CtxTuple outer_ctx = True // the tuple parenthesis\r
-needParenthesis CtxRecord outer_ctx = False\r
-needParenthesis CtxNonfix CtxNone = False\r
-needParenthesis CtxNonfix CtxTuple = False\r
-needParenthesis CtxNonfix CtxRecord = False\r
-needParenthesis CtxNonfix CtxNonfix = True\r
-needParenthesis CtxNonfix (CtxInfix _ _ _ _) = False\r
-needParenthesis (CtxInfix _ _ _ _) CtxNone = False\r
-needParenthesis (CtxInfix _ _ _ _) CtxNullary = True\r
-needParenthesis (CtxInfix _ _ _ _) CtxTuple = False\r
-needParenthesis (CtxInfix _ _ _ _) CtxRecord = False\r
-needParenthesis (CtxInfix _ _ _ _) CtxNonfix = True // False // PK\r
-needParenthesis (CtxInfix _ this_assoc this_prio _) (CtxInfix _ outer_assoc outer_prio branch) \r
- = outer_prio > this_prio \r
- || (outer_prio == this_prio && not (this_assoc == outer_assoc && this_assoc == branch))\r
-\r
-//derive bimap PrintState\r
-\r
-//-------------------------------------------------------------------------------------\r
-\r
-\r
-printChar :: Char (PrintState *s) -> (PrintState *s) | PrintOutput s \r
-printChar ch s=:{ps_output}\r
- # ps_output = printOutput ch ps_output\r
- = {s & ps_output = ps_output}\r
-\r
-printCharLiteral '\\' = printChar '\\' $ printChar '\\'\r
-printCharLiteral '\n' = printChar '\\' $ printChar '\n'\r
-printCharLiteral '\t' = printChar '\\' $ printChar '\t'\r
-printCharLiteral '\b' = printChar '\\' $ printChar '\b'\r
-printCharLiteral '\'' = printChar '\\' $ printChar '\''\r
-printCharLiteral '\"' = printChar '\\' $ printChar '\"'\r
-printCharLiteral '\0' = printChar '\\' $ printChar '\0'\r
-printCharLiteral c = printChar c\r
-\r
-printString str\r
- #! size_str = size str\r
- = do_it 0 size_str str\r
-where\r
- do_it i n str\r
- | i == n\r
- = id\r
- = printChar str.[i]\r
- $ do_it (inc i) n str \r
-\r
-printStringLiteral str\r
- #! size_str = size str\r
- = do_it 0 size_str str\r
-where\r
- do_it i n str\r
- | i == n\r
- = id\r
- = printCharLiteral str.[i]\r
- $ do_it (inc i) n str \r
-\r
-\r
-printList f xs ps=:{ps_context}\r
- = { print_list f xs { ps & ps_context = CtxNone} \r
- & ps_context = ps_context \r
- }\r
-where\r
- print_list f [] = id\r
- print_list f [x] = f x\r
- print_list f [x:xs] \r
- = f x \r
- $ printString ", "\r
- $ print_list f xs \r
-\r
-//-------------------------------------------------------------------------------------\r
-generic gPrint a :: a (PrintState *s) -> (PrintState *s) | PrintOutput s\r
-gPrint{|Int|} x st \r
- = printString (toString x) st\r
-gPrint{|Real|} x st \r
- # str = toString x\r
- | all isDigit [c\\c<-:str] // add .0 if needed\r
- = printString (str +++ ".0") st \r
- | str.[0] == '.'\r
- = printString ("0" +++ str) st\r
- | otherwise \r
- = printString str st\r
-gPrint{|Bool|} x st \r
- = printString (toString x) st\r
-gPrint{|Char|} x st \r
- = printChar '\'' $ printCharLiteral x $ printChar '\'' @ st \r
-gPrint{|String|} x st \r
- = printChar '"'\r
- $ printStringLiteral x \r
- $ printChar '"'\r
- @ st\r
-gPrint{|UNIT|} x st \r
- = st\r
- \r
-gPrint{|EITHER|} fl fr (LEFT x) st = fl x st\r
-gPrint{|EITHER|} fl fr (RIGHT x) st = fr x st\r
-\r
-gPrint{|PAIR|} fx fy (PAIR x y) st=:{ps_context = CtxNone}\r
- = abort "gOutput{|PAIR|}: CtxNone\n" \r
-gPrint{|PAIR|} fx fy (PAIR x y) st=:{ps_context = CtxNullary}\r
- = abort "gOutput{|PAIR|}: CtxNullary\n" \r
-gPrint{|PAIR|} fx fy (PAIR x y) st=:{ps_context = CtxTuple}\r
- = fx x $ printString ", " $ fy y @ st\r
-gPrint{|PAIR|} fx fy (PAIR x y) st=:{ps_context = CtxRecord}\r
- = fx x $ printString ", " $ fy y @ st\r
-gPrint{|PAIR|} fx fy (PAIR x y) st=:{ps_context = CtxNonfix}\r
- = fx x $ printChar ' ' $ fy y @ st \r
-gPrint{|PAIR|} fx fy (PAIR x y) st=:{ps_context = CtxInfix name assoc prio branch} \r
- # st = fx x {st & ps_context = CtxInfix name assoc prio GenConsAssocLeft} \r
- # st = printChar ' ' $ printStringLiteral name $ printChar ' ' @ st\r
- # st = fy y {st & ps_context = CtxInfix name assoc prio GenConsAssocRight} \r
- = {st & ps_context = CtxInfix name assoc prio branch} \r
-\r
-gPrint{|CONS of d|} print_arg (CONS x) st=:{ps_context}\r
- #! ctx = mkContext d\r
- #! st = { st & ps_context = ctx }\r
- | needParenthesis ctx ps_context\r
- = { printChar '(' \r
- $ print print_arg ctx \r
- $ printChar ')' \r
- @ st \r
- & ps_context = ps_context \r
- }\r
- | otherwise\r
- = { print print_arg ctx st & ps_context = ps_context }\r
-where\r
- print print_arg CtxNone \r
- = abort "gOutput{|CONS|}: CtxNone\n"\r
- print print_arg CtxNullary \r
- = printStringLiteral d.gcd_name \r
- print print_arg CtxTuple\r
- = print_arg x\r
- print print_arg CtxRecord \r
- = printString "{ " \r
- $ foldSt printChar (tl [c\\c<-:d.gcd_name]) //printStringLiteral d.gcd_name \r
- $ printString " | "\r
- $ print_arg x\r
- $ printString " }"\r
- print print_arg CtxNonfix \r
- = printStringLiteral d.gcd_name\r
- $ printChar ' '\r
- $ print_arg x \r
- print print_arg (CtxInfix _ _ _ _) \r
- = print_arg x\r
-\r
-gPrint{|FIELD of d|} f (FIELD x) st\r
- = printStringLiteral d.gfd_name\r
- $ printString " = " \r
- $ f x \r
- @ st\r
-gPrint{|OBJECT|} f (OBJECT x) st\r
- = f x st \r
- \r
-gPrint{|[]|} f xs st\r
- = printChar '['\r
- $ printList f xs \r
- $ printChar ']'\r
- @ st\r
-\r
-gPrint{|{}|} f xs st\r
- = printChar '{'\r
- $ printList f [ x \\ x <-: xs] \r
- $ printChar '}'\r
- @ st\r
-\r
-gPrint{|{!}|} f xs st\r
- = printChar '{'\r
- $ printList f [ x \\ x <-: xs] \r
- $ printChar '}'\r
- @ st\r
-\r
-//derive gOutput (,), (,,), (,,,), (,,,,), (,,,,,), (,,,,,,), (,,,,,,,)\r
- \r
-//-------------------------------------------------------------------------------------\r
-(<<-) infixl 0 :: (PrintState *s) a -> *(PrintState *s) | gPrint{|*|} a & PrintOutput s\r
-(<<-) s x = gPrint{|*|} x s\r
-\r
-mkPrintState :: *s -> PrintState *s | PrintOutput s\r
-mkPrintState s =\r
- { ps_output = s\r
- , ps_context = CtxNone\r
- } \r
-\r
-mkStringPrintState :: PrintState StringOutput\r
-mkStringPrintState = mkPrintState {so_pos = 0, so_str = createArray 16 '\0'}\r
-\r
-openFilePrintState :: String *fs -> (Maybe (PrintState *File), *fs) | FileSystem fs\r
-openFilePrintState name fs \r
- # (ok, file, fs) = fopen name FWriteText fs\r
- | ok = (Just (mkPrintState file), fs)\r
- = (Nothing, fs)\r
-\r
-printToString :: a -> String | gPrint{|*|} a\r
-printToString x\r
- # string_output = (mkStringPrintState <<- x).ps_output\r
- = string_output.so_str % (0,string_output.so_pos-1)\r
-\r
-//-------------------------------------------------------------------------------------\r
-\r
-//Start = 1
\ No newline at end of file