{-# LANGUAGE TupleSections #-}

{-
    BNF Converter: C++ abstract syntax generator
    Copyright (C) 2004  Author:  Michael Pellauer

    Description   : This module generates the C++ Abstract Syntax
                    tree classes. It generates both a Header file
                    and an Implementation file, and uses the Visitor
                    design pattern. It uses STL (Standard Template Library).

    Author        : Michael Pellauer
    Created       : 4 August, 2003
    Modified      : 22 May, 2004 / Antti-Juhani Kaijanaho
                    29 August, 2006 / Aarne Ranta

-}

module BNFC.Backend.CPP.STL.CFtoSTLAbs (cf2CPPAbs) where

import Data.List        ( intercalate, intersperse )

import BNFC.Backend.Common.OOAbstract
import BNFC.CF
import BNFC.Options     ( RecordPositions(..) )
import BNFC.TypeChecker ( ListConstructors(..) )
import BNFC.Utils       ( (+++), applyWhen )

import BNFC.Backend.CPP.Common
import BNFC.Backend.CPP.STL.STLUtils

--The result is two files (.H file, .C file)

cf2CPPAbs :: RecordPositions -> Maybe String -> String -> CF -> (String, String)
cf2CPPAbs :: RecordPositions -> Maybe [Char] -> [Char] -> CF -> ([Char], [Char])
cf2CPPAbs RecordPositions
rp Maybe [Char]
inPackage [Char]
_ CF
cf = (RecordPositions -> Maybe [Char] -> CAbs -> CF -> [Char]
mkHFile RecordPositions
rp Maybe [Char]
inPackage CAbs
cab CF
cf, Maybe [Char] -> CAbs -> CF -> [Char]
mkCFile Maybe [Char]
inPackage CAbs
cab CF
cf)
  where
    cab :: CAbs
cab = CF -> CAbs
cf2cabs CF
cf


-- **** Header (.H) File Functions **** --

--Makes the Header file.
mkHFile :: RecordPositions -> Maybe String -> CAbs -> CF -> String
mkHFile :: RecordPositions -> Maybe [Char] -> CAbs -> CF -> [Char]
mkHFile RecordPositions
rp Maybe [Char]
inPackage CAbs
cabs CF
cf = [[Char]] -> [Char]
unlines
 [
  [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<string>",
  [Char]
"#include<vector>",
  [Char]
"",
  [Char]
"//C++ Abstract Syntax Interface.",
  Maybe [Char] -> [Char]
nsStart Maybe [Char]
inPackage,
  [Char]
"/********************   TypeDef Section    ********************/",
  [Char]
"",
  [[Char]] -> [Char]
unlines [[Char]
"typedef " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
d [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
";" | ([Char]
c,[Char]
d) <- [([Char], [Char])]
basetypes],
  [Char]
"",
  [[Char]] -> [Char]
unlines [[Char]
"typedef std::string " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
";" | [Char]
s <- CAbs -> [[Char]]
tokentypes CAbs
cabs],
  [Char]
"",
  [Char]
"/********************   Forward Declarations    ********************/",
  [Char]
"",
  [[Char]] -> [Char]
unlines [[Char]
"class " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
";" | [Char]
c <- [[Char]]
classes, [Char] -> [[Char]] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
notElem [Char]
c (CAbs -> [[Char]]
defineds CAbs
cabs)],
  [Char]
"",
  [Char]
"/********************   Visitor Interfaces    ********************/",
  CAbs -> [Char]
prVisitor CAbs
cabs,
  [Char]
"",
  [Char]
prVisitable,
  [Char]
"",
  [Char]
"/********************   Abstract Syntax Classes    ********************/",
  [Char]
"",
  [[Char]] -> [Char]
unlines [RecordPositions -> [Char] -> [Char]
prAbs RecordPositions
rp [Char]
c | [Char]
c <- CAbs -> [[Char]]
absclasses CAbs
cabs],
  [Char]
"",
  [[Char]] -> [Char]
unlines [([Char], CAbsRule) -> [Char]
prCon ([Char]
c,CAbsRule
r) | ([Char]
c,[CAbsRule]
rs) <- CAbs -> [([Char], [CAbsRule])]
signatures CAbs
cabs, CAbsRule
r <- [CAbsRule]
rs],
  [Char]
"",
  [[Char]] -> [Char]
unlines [([Char], Bool) -> [Char]
prList ([Char], Bool)
c | ([Char], Bool)
c <- CAbs -> [([Char], Bool)]
listtypes CAbs
cabs],
  [Char]
"",
  Maybe ListConstructors -> CF -> [Char] -> [Char]
definedRules Maybe ListConstructors
forall a. Maybe a
Nothing CF
cf
  [Char]
"/********************   Defined Constructors    ********************/",
  Maybe [Char] -> [Char]
nsEnd Maybe [Char]
inPackage,
  [Char]
"#endif"
 ]
 where
  classes :: [[Char]]
classes = CAbs -> [[Char]]
allClasses CAbs
cabs
  hdef :: [Char]
hdef = Maybe [Char] -> [Char] -> [Char]
nsDefine Maybe [Char]
inPackage [Char]
"ABSYN_HEADER"

-- auxiliaries

prVisitable :: String
prVisitable :: [Char]
prVisitable = [[Char]] -> [Char]
unlines [
  [Char]
"class Visitable",
  [Char]
"{",
  [Char]
" public:",
  -- all classes with virtual methods require a virtual destructor
  [Char]
"  virtual ~Visitable() {}",
  [Char]
"  virtual void accept(Visitor *v) = 0;",
  [Char]
"};"
  ]

prVisitor :: CAbs -> String
prVisitor :: CAbs -> [Char]
prVisitor CAbs
cf = [[Char]] -> [Char]
unlines [
  [Char]
"class Visitor",
  [Char]
"{",
  [Char]
"public:",
  [Char]
"  virtual ~Visitor() {}",
  [[Char]] -> [Char]
unlines
    [[Char]
"  virtual void visit"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
c[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"("[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
c[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
" *p) = 0;" | [Char]
c <- CAbs -> [[Char]]
allClasses CAbs
cf,
                                                      [Char] -> [[Char]] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
notElem [Char]
c (CAbs -> [[Char]]
defineds CAbs
cf)],
  [Char]
"",
  [[Char]] -> [Char]
unlines
    [[Char]
"  virtual void visit"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
c[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
c[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
" x) = 0;" | [Char]
c <- CAbs -> [[Char]]
allNonClasses CAbs
cf],
  [Char]
"};"
 ]

prAbs :: RecordPositions -> String -> String
prAbs :: RecordPositions -> [Char] -> [Char]
prAbs RecordPositions
rp [Char]
c = [[Char]] -> [Char]
unlines [
  [Char]
"class " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" : public Visitable",
  [Char]
"{",
  [Char]
"public:",
  [Char]
"  virtual " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" *clone() const = 0;",
  if RecordPositions
rp RecordPositions -> RecordPositions -> Bool
forall a. Eq a => a -> a -> Bool
== RecordPositions
RecordPositions then [Char]
"  int line_number;" else [Char]
"",
  [Char]
"};"
  ]

prCon :: (String, CAbsRule) -> String
prCon :: ([Char], CAbsRule) -> [Char]
prCon ([Char]
c,([Char]
f,[([Char], Bool, [Char])]
cs)) = [[Char]] -> [Char]
unlines [
  [Char]
"class " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
f[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" : public " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c,
  [Char]
"{",
  [Char]
"public:",
  [[Char]] -> [Char]
unlines
    [[Char]
"  "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
typ [Char] -> [Char] -> [Char]
+++ Bool -> [Char] -> [Char]
pointerIf Bool
st [Char]
var [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
";" | ([Char]
typ,Bool
st,[Char]
var) <- [([Char], Bool, [Char])]
cs],
  [Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
f [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(const " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
f [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" &);",
  [Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
f [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" &operator=(const " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
f[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" &);",
  [Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
f [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
conargs [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
");",
    -- Typ *p1, PIdent *p2, ListStm *p3);
  [Char]
"  ~" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
f [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"();",
  [Char]
"  virtual void accept(Visitor *v);",
  [Char]
"  virtual " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
f[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" *clone() const;",
  [Char]
"  void swap(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
f[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" &);",
  [Char]
"};"
  ]
 where
   conargs :: [Char]
conargs = [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
intersperse [Char]
", "
     [[Char]
x [Char] -> [Char] -> [Char]
+++ Bool -> [Char] -> [Char]
pointerIf Bool
st ([Char]
"p" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Integer -> [Char]
forall a. Show a => a -> [Char]
show Integer
i) | (([Char]
x,Bool
st,[Char]
_),Integer
i) <- [([Char], Bool, [Char])]
-> [Integer] -> [(([Char], Bool, [Char]), Integer)]
forall a b. [a] -> [b] -> [(a, b)]
zip [([Char], Bool, [Char])]
cs [Integer
1..]]

prList :: (String, Bool) -> String
prList :: ([Char], Bool) -> [Char]
prList ([Char]
c, Bool
b) = [[Char]] -> [Char]
unlines
  [ [Char]
"class " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
c[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" : public Visitable, public std::vector<" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
bas[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
">"
  , [Char]
"{"
  , [Char]
"public:"
  , [Char]
"  virtual void accept(Visitor *v);"
  , [Char]
"  virtual " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" *clone() const;"
  , [Char]
"};"
  , [Char]
""
    -- cons for this list type
  , [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ [Char]
c, [Char]
"* ", [Char]
"cons", [Char]
c, [Char]
"(", [Char]
bas, [Char]
" x, ", [Char]
c, [Char]
"* xs);" ]
  ]
  where
  bas :: [Char]
bas = Bool -> ([Char] -> [Char]) -> [Char] -> [Char]
forall a. Bool -> (a -> a) -> a -> a
applyWhen Bool
b ([Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"*") ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
forall a. Int -> [a] -> [a]
drop Int
4 [Char]
c {- drop "List" -}


-- **** Implementation (.C) File Functions **** --

mkCFile :: Maybe String -> CAbs -> CF -> String
mkCFile :: Maybe [Char] -> CAbs -> CF -> [Char]
mkCFile Maybe [Char]
inPackage CAbs
cabs CF
cf = [[Char]] -> [Char]
unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ [
  [Char]
"//C++ Abstract Syntax Implementation.",
  [Char]
"#include <algorithm>",
  [Char]
"#include <string>",
  [Char]
"#include <vector>",
  [Char]
"#include \"Absyn.H\"",
  Maybe [Char] -> [Char]
nsStart Maybe [Char]
inPackage,
  [[Char]] -> [Char]
unlines [CAbsRule -> [Char]
prConC  CAbsRule
r | ([Char]
_,[CAbsRule]
rs) <- CAbs -> [([Char], [CAbsRule])]
signatures CAbs
cabs, CAbsRule
r <- [CAbsRule]
rs],
  [[Char]] -> [Char]
unlines [([Char], Bool) -> [Char]
prListC ([Char], Bool)
l | ([Char], Bool)
l <- CAbs -> [([Char], Bool)]
listtypes CAbs
cabs],
  Maybe ListConstructors -> CF -> [Char] -> [Char]
definedRules (ListConstructors -> Maybe ListConstructors
forall a. a -> Maybe a
Just (ListConstructors -> Maybe ListConstructors)
-> ListConstructors -> Maybe ListConstructors
forall a b. (a -> b) -> a -> b
$ (Base -> ([Char], Type))
-> (Base -> ([Char], Type)) -> ListConstructors
LC Base -> ([Char], Type)
nil Base -> ([Char], Type)
cons) CF
cf
  [Char]
"/********************   Defined Constructors    ********************/",
  Maybe [Char] -> [Char]
nsEnd Maybe [Char]
inPackage
  ]
  where
  nil :: Base -> ([Char], Type)
nil  Base
t = (,Type
dummyType) ([Char] -> ([Char], Type)) -> [Char] -> ([Char], Type)
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ [Char]
"new List", Base -> [Char]
identType Base
t, [Char]
"()" ]
  cons :: Base -> ([Char], Type)
cons Base
t = (,Type
dummyType) ([Char] -> ([Char], Type)) -> [Char] -> ([Char], Type)
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ [Char]
"consList", Base -> [Char]
identType Base
t ]


prConC :: CAbsRule -> String
prConC :: CAbsRule -> [Char]
prConC fcs :: CAbsRule
fcs@([Char]
f,[([Char], Bool, [Char])]
_) = [[Char]] -> [Char]
unlines [
  [Char]
"/********************   " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
f [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"    ********************/",
  CAbsRule -> [Char]
prConstructorC CAbsRule
fcs,
  CAbsRule -> [Char]
prCopyC CAbsRule
fcs,
  CAbsRule -> [Char]
prDestructorC CAbsRule
fcs,
  [Char] -> [Char]
prAcceptC [Char]
f,
  [Char] -> [Char]
prCloneC [Char]
f,
  [Char]
""
 ]

prListC :: (String,Bool) -> String
prListC :: ([Char], Bool) -> [Char]
prListC ([Char]
c,Bool
b) = [[Char]] -> [Char]
unlines
  [ [Char]
"/********************   " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"    ********************/"
  , [Char]
""
  , [Char] -> [Char]
prAcceptC [Char]
c
  , [Char] -> [Char]
prCloneC [Char]
c
  , [Char] -> Bool -> [Char]
prConsC [Char]
c Bool
b
  ]


--The standard accept function for the Visitor pattern
prAcceptC :: String -> String
prAcceptC :: [Char] -> [Char]
prAcceptC [Char]
ty = [[Char]] -> [Char]
unlines [
  [Char]
"void " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
ty [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"::accept(Visitor *v)",
  [Char]
"{",
  [Char]
"  v->visit" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
ty [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(this);",
  [Char]
"}"
  ]

--The cloner makes a new deep copy of the object
prCloneC :: String -> String
prCloneC :: [Char] -> [Char]
prCloneC [Char]
c = [[Char]] -> [Char]
unlines [
  [Char]
c [Char] -> [Char] -> [Char]
+++ [Char]
"*" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"::clone() const",
  [Char]
"{",
  [Char]
"  return new" [Char] -> [Char] -> [Char]
+++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(*this);",
  [Char]
"}"
  ]

-- | Make a list constructor definition.
prConsC :: String -> Bool -> String
prConsC :: [Char] -> Bool -> [Char]
prConsC [Char]
c Bool
b = [[Char]] -> [Char]
unlines
  [ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ [Char]
c, [Char]
"* ", [Char]
"cons", [Char]
c, [Char]
"(", [Char]
bas, [Char]
" x, ", [Char]
c, [Char]
"* xs) {" ]
  , [Char]
"  xs->insert(xs->begin(), x);"
  , [Char]
"  return xs;"
  , [Char]
"}"
  ]
  where
  bas :: [Char]
bas = Bool -> ([Char] -> [Char]) -> [Char] -> [Char]
forall a. Bool -> (a -> a) -> a -> a
applyWhen Bool
b ([Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"*") ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
forall a. Int -> [a] -> [a]
drop Int
4 [Char]
c {- drop "List" -}

--The constructor assigns the parameters to the corresponding instance variables.
prConstructorC :: CAbsRule -> String
prConstructorC :: CAbsRule -> [Char]
prConstructorC ([Char]
f,[([Char], Bool, [Char])]
cs) = [[Char]] -> [Char]
unlines [
  [Char]
f [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"::" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
f [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
conargs [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")",
  [Char]
"{",
  [[Char]] -> [Char]
unlines [[Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" = " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
p [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
";" | ([Char]
c,[Char]
p) <- [[Char]] -> [[Char]] -> [([Char], [Char])]
forall a b. [a] -> [b] -> [(a, b)]
zip [[Char]]
cvs [[Char]]
pvs],
  [Char]
"}"
  ]
 where
   cvs :: [[Char]]
cvs = [[Char]
c | ([Char]
_,Bool
_,[Char]
c) <- [([Char], Bool, [Char])]
cs]
   pvs :: [[Char]]
pvs = [Char
'p' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Integer -> [Char]
forall a. Show a => a -> [Char]
show Integer
i | (([Char]
_,Bool
_,[Char]
_),Integer
i) <- [([Char], Bool, [Char])]
-> [Integer] -> [(([Char], Bool, [Char]), Integer)]
forall a b. [a] -> [b] -> [(a, b)]
zip [([Char], Bool, [Char])]
cs [Integer
1..]]
   conargs :: [Char]
conargs = [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
", "
     [[Char]
x [Char] -> [Char] -> [Char]
+++ Bool -> [Char] -> [Char]
pointerIf Bool
st [Char]
v | (([Char]
x,Bool
st,[Char]
_),[Char]
v) <- [([Char], Bool, [Char])]
-> [[Char]] -> [(([Char], Bool, [Char]), [Char])]
forall a b. [a] -> [b] -> [(a, b)]
zip [([Char], Bool, [Char])]
cs [[Char]]
pvs]


--Copy constructor and copy assignment
prCopyC :: CAbsRule -> String
prCopyC :: CAbsRule -> [Char]
prCopyC ([Char]
c,[([Char], Bool, [Char])]
cs) = [[Char]] -> [Char]
unlines [
  [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"::" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(const" [Char] -> [Char] -> [Char]
+++ [Char]
c [Char] -> [Char] -> [Char]
+++ [Char]
"& other)",
  [Char]
"{",
  [[Char]] -> [Char]
unlines [[Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
cv [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" = other." [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Bool -> [Char] -> [Char]
cloneIf Bool
st [Char]
cv [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
";" | ([Char]
_,Bool
st,[Char]
cv) <- [([Char], Bool, [Char])]
cs],
  [Char]
"}",
  [Char]
"",
  [Char]
c [Char] -> [Char] -> [Char]
+++ [Char]
"&" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"::" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"operator=(const" [Char] -> [Char] -> [Char]
+++ [Char]
c [Char] -> [Char] -> [Char]
+++ [Char]
"& other)",
  [Char]
"{",
  [Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
+++ [Char]
"tmp(other);",
  [Char]
"  swap(tmp);",
  [Char]
"  return *this;",
  [Char]
"}",
  [Char]
"",
  [Char]
"void" [Char] -> [Char] -> [Char]
+++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"::swap(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
+++ [Char]
"& other)",
  [Char]
"{",
  [[Char]] -> [Char]
unlines [[Char]
"  std::swap(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
cv [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
", other." [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
cv [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
");" | ([Char]
_,Bool
_,[Char]
cv) <- [([Char], Bool, [Char])]
cs],
  [Char]
"}"
  ]
 where
   cloneIf :: Bool -> [Char] -> [Char]
cloneIf Bool
st [Char]
cv = if Bool
st then ([Char]
cv [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"->clone()") else [Char]
cv

--The destructor deletes all a class's members.
prDestructorC :: CAbsRule -> String
prDestructorC :: CAbsRule -> [Char]
prDestructorC ([Char]
c,[([Char], Bool, [Char])]
cs) = [[Char]] -> [Char]
unlines [
  [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"::~" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
c [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"()",
  [Char]
"{",
  [[Char]] -> [Char]
unlines [[Char]
"  delete(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
cv [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
");" | ([Char]
_,Bool
isPointer,[Char]
cv) <- [([Char], Bool, [Char])]
cs, Bool
isPointer],
  [Char]
"}"
  ]