{-
    BNF Converter: C++ Main file
    Copyright (C) 2004  Author:  Markus Forsberg, Michael Pellauer
    Copyright (C) 2020  Andreas Abel

    Modified from CPPTop to BNFC.Backend.CPP.STL 2006 by Aarne Ranta.

-}

module BNFC.Backend.CPP.STL (makeCppStl,) where

import Data.Char
import Data.Foldable (toList)
import qualified Data.List as List
import qualified Data.Map as Map

import BNFC.Utils
import BNFC.CF
import BNFC.Options
import BNFC.Backend.Base
import BNFC.Backend.C            (bufferH, bufferC)
import BNFC.Backend.C.CFtoBisonC (unionBuiltinTokens)
import BNFC.Backend.CPP.Makefile
import BNFC.Backend.CPP.STL.CFtoSTLAbs
import BNFC.Backend.CPP.NoSTL.CFtoFlex
import BNFC.Backend.CPP.STL.CFtoBisonSTL
import BNFC.Backend.CPP.STL.CFtoCVisitSkelSTL
import BNFC.Backend.CPP.PrettyPrinter
import BNFC.Backend.CPP.STL.STLUtils
import qualified BNFC.Backend.Common.Makefile as Makefile

makeCppStl :: SharedOptions -> CF -> MkFiles ()
makeCppStl :: SharedOptions -> CF -> MkFiles ()
makeCppStl SharedOptions
opts CF
cf = do
    let ([Char]
hfile, [Char]
cfile) = RecordPositions -> Maybe [Char] -> [Char] -> CF -> ([Char], [Char])
cf2CPPAbs (SharedOptions -> RecordPositions
linenumbers SharedOptions
opts) (SharedOptions -> Maybe [Char]
inPackage SharedOptions
opts) [Char]
name CF
cf
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"Absyn.H" [Char]
hfile
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"Absyn.C" [Char]
cfile
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"Buffer.H" [Char]
bufferH
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"Buffer.C" ([Char] -> MkFiles ()) -> [Char] -> MkFiles ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char]
bufferC [Char]
"Buffer.H"
    let ([Char]
flex, SymMap
env) = Maybe [Char] -> [Char] -> CF -> ([Char], SymMap)
cf2flex (SharedOptions -> Maybe [Char]
inPackage SharedOptions
opts) [Char]
name CF
cf
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile ([Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".l") [Char]
flex
    let bison :: [Char]
bison = RecordPositions -> Maybe [Char] -> [Char] -> CF -> SymMap -> [Char]
cf2Bison (SharedOptions -> RecordPositions
linenumbers SharedOptions
opts) (SharedOptions -> Maybe [Char]
inPackage SharedOptions
opts) [Char]
name CF
cf SymMap
env
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile ([Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".y") [Char]
bison
    let header :: [Char]
header = Maybe [Char] -> CF -> [Cat] -> [Cat] -> [[Char]] -> [Char]
forall {t :: * -> *} {f}.
Foldable t =>
Maybe [Char] -> CFG f -> [Cat] -> t Cat -> [[Char]] -> [Char]
mkHeaderFile (SharedOptions -> Maybe [Char]
inPackage SharedOptions
opts) CF
cf (CF -> [Cat]
forall f. CFG f -> [Cat]
allParserCats CF
cf) (NonEmpty Cat -> [Cat]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (NonEmpty Cat -> [Cat]) -> NonEmpty Cat -> [Cat]
forall a b. (a -> b) -> a -> b
$ CF -> NonEmpty Cat
forall f. CFG f -> NonEmpty Cat
allEntryPoints CF
cf) (SymMap -> [[Char]]
forall k a. Map k a -> [a]
Map.elems SymMap
env)
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"Parser.H" [Char]
header
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"ParserError.H" ([Char] -> MkFiles ()) -> [Char] -> MkFiles ()
forall a b. (a -> b) -> a -> b
$ Maybe [Char] -> [Char]
printParseErrHeader (SharedOptions -> Maybe [Char]
inPackage SharedOptions
opts)
    let ([Char]
skelH, [Char]
skelC) = Bool -> Maybe [Char] -> CF -> ([Char], [Char])
cf2CVisitSkel Bool
True (SharedOptions -> Maybe [Char]
inPackage SharedOptions
opts) CF
cf
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"Skeleton.H" [Char]
skelH
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"Skeleton.C" [Char]
skelC
    let ([Char]
prinH, [Char]
prinC) = Bool -> Maybe [Char] -> CF -> ([Char], [Char])
cf2CPPPrinter Bool
True (SharedOptions -> Maybe [Char]
inPackage SharedOptions
opts) CF
cf
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"Printer.H" [Char]
prinH
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"Printer.C" [Char]
prinC
    [Char] -> [Char] -> MkFiles ()
forall c. FileContent c => [Char] -> c -> MkFiles ()
mkfile [Char]
"Test.C" (Maybe [Char] -> CF -> [Char]
cpptest (SharedOptions -> Maybe [Char]
inPackage SharedOptions
opts) CF
cf)
    SharedOptions -> ([Char] -> Doc) -> MkFiles ()
Makefile.mkMakefile SharedOptions
opts (([Char] -> Doc) -> MkFiles ()) -> ([Char] -> Doc) -> MkFiles ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> Doc
makefile [Char]
name
  where name :: [Char]
name = SharedOptions -> [Char]
lang SharedOptions
opts

printParseErrHeader :: Maybe String -> String
printParseErrHeader :: Maybe [Char] -> [Char]
printParseErrHeader Maybe [Char]
inPackage =
  [[Char]] -> [Char]
unlines
  [
     [Char]
" #pragma once "
     , [Char]
" #include <string>"
     , [Char]
" #include <stdexcept>"
     , [Char]
""
     , Maybe [Char] -> [Char]
nsStart Maybe [Char]
inPackage
     , [Char]
" class parse_error : public std::runtime_error"
     , [Char]
" {"
     , [Char]
" public:"
     , [Char]
"     parse_error(int line, std::string str)"
     , [Char]
"         : std::runtime_error(str)"
     , [Char]
"         , m_line(line) {}"
     , [Char]
"     int getLine() {"
     , [Char]
"         return m_line;"
     , [Char]
"     } "
     , [Char]
" private:"
     , [Char]
"     int m_line;"
     , [Char]
" }; "
     , Maybe [Char] -> [Char]
nsEnd Maybe [Char]
inPackage
     ]

cpptest :: Maybe String -> CF -> String
cpptest :: Maybe [Char] -> CF -> [Char]
cpptest Maybe [Char]
inPackage CF
cf =
  [[Char]] -> [Char]
unlines
   [
    [Char]
"/*** Compiler Front-End Test automatically generated by the BNF Converter ***/",
    [Char]
"/*                                                                          */",
    [Char]
"/* This test will parse a file, print the abstract syntax tree, and then    */",
    [Char]
"/* pretty-print the result.                                                 */",
    [Char]
"/*                                                                          */",
    [Char]
"/****************************************************************************/",
    [Char]
"#include <cstdio>",
    [Char]
"#include <string>",
    [Char]
"#include <iostream>",
    [Char]
"#include \"Parser.H\"",
    [Char]
"#include \"Printer.H\"",
    [Char]
"#include \"Absyn.H\"",
    [Char]
"#include \"ParserError.H\"",
    [Char]
"",
    [Char]
"void usage() {",
    [Char]
"  printf(\"usage: Call with one of the following argument " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
      [Char]
"combinations:\\n\");",
    [Char]
"  printf(\"\\t--help\\t\\tDisplay this help message.\\n\");",
    [Char]
"  printf(\"\\t(no arguments)\\tParse stdin verbosely.\\n\");",
    [Char]
"  printf(\"\\t(files)\\t\\tParse content of files verbosely.\\n\");",
    [Char]
"  printf(\"\\t-s (files)\\tSilent mode. Parse content of files " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
      [Char]
"silently.\\n\");",
    [Char]
"}",
    [Char]
"",
    [Char]
"int main(int argc, char ** argv)",
    [Char]
"{",
    [Char]
"  FILE *input;",
    [Char]
"  int quiet = 0;",
    [Char]
"  char *filename = NULL;",
    [Char]
"",
    [Char]
"  if (argc > 1) {",
    [Char]
"    if (strcmp(argv[1], \"-s\") == 0) {",
    [Char]
"      quiet = 1;",
    [Char]
"      if (argc > 2) {",
    [Char]
"        filename = argv[2];",
    [Char]
"      } else {",
    [Char]
"        input = stdin;",
    [Char]
"      }",
    [Char]
"    } else {",
    [Char]
"      filename = argv[1];",
    [Char]
"    }",
    [Char]
"  }",
    [Char]
"",
    [Char]
"  if (filename) {",
    [Char]
"    input = fopen(filename, \"r\");",
    [Char]
"    if (!input) {",
    [Char]
"      usage();",
    [Char]
"      exit(1);",
    [Char]
"    }",
    [Char]
"  } else input = stdin;",
    [Char]
"  /* The default entry point is used. For other options see Parser.H */",
    [Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
scope [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
dat [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" *parse_tree = NULL;",
    [Char]
"  try { ",
    [Char]
"  parse_tree = " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
scope [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"p" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
def [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(input);",
    [Char]
"  } catch( " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
scope [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"parse_error &e) {",
    [Char]
"     std::cerr << \"Parse error on line \" << e.getLine() << \"\\n\"; ",
    [Char]
"  }",
    [Char]
"  if (parse_tree)",
    [Char]
"  {",
    [Char]
"    printf(\"\\nParse Successful!\\n\");",
    [Char]
"    if (!quiet) {",
    [Char]
"      printf(\"\\n[Abstract Syntax]\\n\");",
    [Char]
"      " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
scope [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"ShowAbsyn *s = new " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
scope [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"ShowAbsyn();",
    [Char]
"      printf(\"%s\\n\\n\", s->show(parse_tree));",
    [Char]
"      printf(\"[Linearized Tree]\\n\");",
    [Char]
"      " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
scope [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"PrintAbsyn *p = new " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
scope [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"PrintAbsyn();",
    [Char]
"      printf(\"%s\\n\\n\", p->print(parse_tree));",
    [Char]
"    }",
    [Char]
"    return 0;",
    [Char]
"  }",
    [Char]
"  return 1;",
    [Char]
"}",
    [Char]
""
   ]
  where
   cat :: Cat
cat = CF -> Cat
firstEntry CF
cf
   dat :: [Char]
dat = Cat -> [Char]
identCat (Cat -> [Char]) -> Cat -> [Char]
forall a b. (a -> b) -> a -> b
$ Cat -> Cat
normCat Cat
cat
   def :: [Char]
def = Cat -> [Char]
identCat Cat
cat
   scope :: [Char]
scope = Maybe [Char] -> [Char]
nsScope Maybe [Char]
inPackage

mkHeaderFile :: Maybe [Char] -> CFG f -> [Cat] -> t Cat -> [[Char]] -> [Char]
mkHeaderFile Maybe [Char]
inPackage CFG f
cf [Cat]
cats t Cat
eps [[Char]]
env = [[Char]] -> [Char]
unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ [[[Char]]] -> [[Char]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
  [ [ [Char]
"#ifndef " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
hdef
    , [Char]
"#define " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
hdef
    , [Char]
""
    , [Char]
"#include<vector>"
    , [Char]
"#include<string>"
    , [Char]
""
    , Maybe [Char] -> [Char]
nsStart Maybe [Char]
inPackage
    ]
  , (Cat -> [Char]) -> [Cat] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map Cat -> [Char]
mkForwardDec ([Cat] -> [[Char]]) -> [Cat] -> [[Char]]
forall a b. (a -> b) -> a -> b
$ [Cat] -> [Cat]
forall a. Eq a => [a] -> [a]
List.nub ([Cat] -> [Cat]) -> [Cat] -> [Cat]
forall a b. (a -> b) -> a -> b
$ (Cat -> Cat) -> [Cat] -> [Cat]
forall a b. (a -> b) -> [a] -> [b]
map Cat -> Cat
normCat [Cat]
cats
  , [ [Char]
"typedef union"
    , [Char]
"{"
    ]
  , ([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++) [[Char]]
unionBuiltinTokens
  , (Cat -> [[Char]]) -> [Cat] -> [[Char]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Cat -> [[Char]]
mkVar [Cat]
cats
  , [ [Char]
"} YYSTYPE;"
    , [Char]
""
    ]
  , (Cat -> [[Char]]) -> t Cat -> [[Char]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Cat -> [[Char]]
mkFuncs t Cat
eps
  , [ Maybe [Char] -> [Char]
nsEnd Maybe [Char]
inPackage
    , [Char]
""
    , [Char]
"#define " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char] -> [Char]
nsDefine Maybe [Char]
inPackage [Char]
"_ERROR_" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" 258"
    , Int -> [[Char]] -> [Char]
forall {t}. (Show t, Num t) => t -> [[Char]] -> [Char]
mkDefines (Int
259 :: Int) [[Char]]
env
    , [Char]
"extern " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
nsScope Maybe [Char]
inPackage [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"YYSTYPE " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
nsString Maybe [Char]
inPackage [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"yylval;"
    , [Char]
""
    , [Char]
"#endif"
    ]
  ]
  where
  hdef :: [Char]
hdef = Maybe [Char] -> [Char] -> [Char]
nsDefine Maybe [Char]
inPackage [Char]
"PARSER_HEADER_FILE"
  mkForwardDec :: Cat -> [Char]
mkForwardDec Cat
s = [Char]
"class " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
identCat Cat
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
";"
  mkVar :: Cat -> [[Char]]
mkVar Cat
s | Cat -> Cat
normCat Cat
s Cat -> Cat -> Bool
forall a. Eq a => a -> a -> Bool
== Cat
s = [ [Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
identCat Cat
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"*" [Char] -> [Char] -> [Char]
+++ (Char -> Char) -> [Char] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower (Cat -> [Char]
identCat Cat
s) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"_;" ]
  mkVar Cat
_ = []
  mkDefines :: t -> [[Char]] -> [Char]
mkDefines t
n [] = t -> [Char]
forall {a}. (Show a, Num a) => a -> [Char]
mkString t
n
  mkDefines t
n ([Char]
s:[[Char]]
ss) = [Char]
"#define " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s [Char] -> [Char] -> [Char]
+++ t -> [Char]
forall a. Show a => a -> [Char]
show t
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ t -> [[Char]] -> [Char]
mkDefines (t
nt -> t -> t
forall a. Num a => a -> a -> a
+t
1) [[Char]]
ss -- "nsDefine inPackage s" not needed (see cf2flex::makeSymEnv)
  mkString :: a -> [Char]
mkString a
n =  if CFG f -> Cat -> Bool
forall f. CFG f -> Cat -> Bool
isUsedCat CFG f
cf ([Char] -> Cat
TokenCat [Char]
catString)
   then ([Char]
"#define " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char] -> [Char]
nsDefine Maybe [Char]
inPackage [Char]
"_STRING_ " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\n") [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall {a}. (Show a, Num a) => a -> [Char]
mkChar (a
na -> a -> a
forall a. Num a => a -> a -> a
+a
1)
   else a -> [Char]
forall {a}. (Show a, Num a) => a -> [Char]
mkChar a
n
  mkChar :: a -> [Char]
mkChar a
n =  if CFG f -> Cat -> Bool
forall f. CFG f -> Cat -> Bool
isUsedCat CFG f
cf ([Char] -> Cat
TokenCat [Char]
catChar)
   then ([Char]
"#define " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char] -> [Char]
nsDefine Maybe [Char]
inPackage [Char]
"_CHAR_ " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\n") [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall {a}. (Show a, Num a) => a -> [Char]
mkInteger (a
na -> a -> a
forall a. Num a => a -> a -> a
+a
1)
   else a -> [Char]
forall {a}. (Show a, Num a) => a -> [Char]
mkInteger a
n
  mkInteger :: a -> [Char]
mkInteger a
n =  if CFG f -> Cat -> Bool
forall f. CFG f -> Cat -> Bool
isUsedCat CFG f
cf ([Char] -> Cat
TokenCat [Char]
catInteger)
   then ([Char]
"#define " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char] -> [Char]
nsDefine Maybe [Char]
inPackage [Char]
"_INTEGER_ " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\n") [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall {a}. (Show a, Num a) => a -> [Char]
mkDouble (a
na -> a -> a
forall a. Num a => a -> a -> a
+a
1)
   else a -> [Char]
forall {a}. (Show a, Num a) => a -> [Char]
mkDouble a
n
  mkDouble :: a -> [Char]
mkDouble a
n =  if CFG f -> Cat -> Bool
forall f. CFG f -> Cat -> Bool
isUsedCat CFG f
cf ([Char] -> Cat
TokenCat [Char]
catDouble)
   then ([Char]
"#define " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char] -> [Char]
nsDefine Maybe [Char]
inPackage [Char]
"_DOUBLE_ " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\n") [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
mkIdent(a
na -> a -> a
forall a. Num a => a -> a -> a
+a
1)
   else a -> [Char]
forall a. Show a => a -> [Char]
mkIdent a
n
  mkIdent :: a -> [Char]
mkIdent a
n =  if CFG f -> Cat -> Bool
forall f. CFG f -> Cat -> Bool
isUsedCat CFG f
cf ([Char] -> Cat
TokenCat [Char]
catIdent)
   then [Char]
"#define " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char] -> [Char]
nsDefine Maybe [Char]
inPackage [Char]
"_IDENT_ " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\n"
   else [Char]
""
  mkFuncs :: Cat -> [[Char]]
mkFuncs Cat
s =
    [ Cat -> [Char]
identCat (Cat -> Cat
normCat Cat
s) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"*" [Char] -> [Char] -> [Char]
+++ [Char]
"p" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
identCat Cat
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(FILE *inp);"
    , Cat -> [Char]
identCat (Cat -> Cat
normCat Cat
s) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"*" [Char] -> [Char] -> [Char]
+++ [Char]
"p" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
identCat Cat
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(const char *str);"
    ]