From afccbeed9b074bfe37434bbb9651aeb445d53d5b Mon Sep 17 00:00:00 2001 From: "hiroyuki.nagata" Date: Mon, 24 Jan 2022 22:50:24 +0900 Subject: [PATCH] Update AST classes as simple, use list instead of vector. Fix bison action of list. --- source/src/BNFC/Backend/C/CFtoBisonC.hs | 9 +- source/src/BNFC/Backend/CPP/Common.hs | 9 - source/src/BNFC/Backend/CPP/PrettyPrinter.hs | 40 +--- source/src/BNFC/Backend/CPP/STL.hs | 128 +++++------ source/src/BNFC/Backend/CPP/STL/CFtoSTLAbs.hs | 212 +++++++----------- 5 files changed, 158 insertions(+), 240 deletions(-) diff --git a/source/src/BNFC/Backend/C/CFtoBisonC.hs b/source/src/BNFC/Backend/C/CFtoBisonC.hs index ee5fe1e8..5da087aa 100644 --- a/source/src/BNFC/Backend/C/CFtoBisonC.hs +++ b/source/src/BNFC/Backend/C/CFtoBisonC.hs @@ -150,8 +150,7 @@ header mode cf = unlines $ concat [ , "%defines \"" ++ ("Bison" <.> hExt) ++ "\"" ] , when (beyondAnsi mode) - [ "%define parse.trace" - , "%define api.namespace {" ++ ns ++ "}" + [ "%define api.namespace {" ++ ns ++ "}" , "/* Specify the namespace for the C++ parser class. */"] , whenJust (parserPackage mode) $ \ ns -> [ "%name-prefix = \"" ++ ns ++ "\"" @@ -596,7 +595,7 @@ generateActionSTLBeyondAnsi rp inPackage nt f b mbs = reverses ++ if | isCoercion f -> concat ["$$ = ", unwords ms, ";", loc] | isNilFun f -> concat ["$$ = ", "std::make_shared<", scope, nt, ">();"] | isOneFun f -> concat ["$$ = ", "std::make_shared<", scope, nt, ">(); $$->cons(", head ms, ");"] - | isConsFun f -> concat [lst, "->cons(", el, ");"] + | isConsFun f -> concat [lst, "->cons(", el, "); $$ = ", lst, ";"] | isDefinedRule f -> concat ["$$ = ", scope, sanitizeCpp (funName f), "(", intercalate ", " ms, ");" ] | otherwise -> concat ["$$ = ", "std::make_shared<", scope, funName f, ">(", (intercalate ", " ms), ");", loc] where @@ -609,9 +608,7 @@ generateActionSTLBeyondAnsi rp inPackage nt f b mbs = reverses ++ = " $$->line_number = @$.first_line; $$->char_number = @$.first_column;" | otherwise = "" - -- TODO: temporary commented reverse() - -- reverses = unwords [m ++"->reverse();" | (m, True) <- mbs] - reverses = unwords ["/*" ++m++ "->reverse(); */" | (m, True) <- mbs] + reverses = unwords [m ++"->reverse();" | (m, True) <- mbs] scope = nsScope inPackage diff --git a/source/src/BNFC/Backend/CPP/Common.hs b/source/src/BNFC/Backend/CPP/Common.hs index c098c000..0719534b 100644 --- a/source/src/BNFC/Backend/CPP/Common.hs +++ b/source/src/BNFC/Backend/CPP/Common.hs @@ -80,17 +80,8 @@ data CppStdMode wrapPointerIf :: Bool -> String -> String wrapPointerIf b v = if b then "*" ++ v else v -wrapUniquePtrIf :: Bool -> String -> String -wrapUniquePtrIf b v = if b then "std::unique_ptr<" ++v++">" else v - -wrapUniquePtr :: String -> String -wrapUniquePtr v = "std::unique_ptr<" ++v++">" - wrapSharedPtrIf :: Bool -> String -> String wrapSharedPtrIf b v = if b then "std::shared_ptr<" ++v++">" else v wrapSharedPtr :: String -> String wrapSharedPtr v = "std::shared_ptr<" ++v++">" - -wrapMoveIf :: Bool -> String -> String -wrapMoveIf b v = if b then "std::move(" ++v++")" else v diff --git a/source/src/BNFC/Backend/CPP/PrettyPrinter.hs b/source/src/BNFC/Backend/CPP/PrettyPrinter.hs index c8564d9c..297867b5 100644 --- a/source/src/BNFC/Backend/CPP/PrettyPrinter.hs +++ b/source/src/BNFC/Backend/CPP/PrettyPrinter.hs @@ -31,7 +31,7 @@ import BNFC.Utils import BNFC.Backend.Common import BNFC.Backend.Common.NamedVariables import BNFC.Backend.Common.StrUtils (renderCharOrString) -import BNFC.Backend.CPP.Common ( CppStdMode(..), wrapUniquePtr, wrapSharedPtrIf, wrapPointerIf ) +import BNFC.Backend.CPP.Common (CppStdMode(..)) import BNFC.Backend.CPP.STL.STLUtils import BNFC.PrettyPrint @@ -199,7 +199,6 @@ prDataH mode useSTL (cat, rules) CppStdBeyondAnsi _ -> True CppStdAnsi _ -> False cl = identCat (normCat cat) - vararg = if beyondAnsi then "p" else "*p" prRuleH = if beyondAnsi then prRuleHBeyondAnsi else prRuleHAnsi itty = concat [ cl, "::", "const_iterator" ] abstract = case lookupRule (noPosition $ catToStr cat) rules of @@ -393,7 +392,7 @@ prPrintData True mode _ _ (cat@(ListCat _), rules) = render $ genPrintVisitorList (mode, cat, rules) prPrintData False mode _ _ (cat@(ListCat _), rules) = genPrintVisitorListNoStl (mode, cat, rules) -prPrintData _ mode _inPackage cf (TokenCat cat, _rules) | +prPrintData _ _ _inPackage cf (TokenCat cat, _rules) | isPositionCat cf cat = genPositionToken cat prPrintData _ mode inPackage _cf (cat, rules) = abstract ++ concatMap (prPrintRule beyondAnsi inPackage) rules @@ -402,7 +401,6 @@ prPrintData _ mode inPackage _cf (cat, rules) = CppStdBeyondAnsi _ -> True CppStdAnsi _ -> False cl = identCat (normCat cat) - vararg = "*p" abstract = case lookupRule (noPosition $ catToStr cat) rules of Just _ -> "" Nothing -> "void PrintAbsyn::visit" ++ cl ++ "(" ++ cl +++ "*p) {} //abstract class\n\n" @@ -410,7 +408,7 @@ prPrintData _ mode inPackage _cf (cat, rules) = -- | Generate pretty printer visitor for a list category (STL version). -- genPrintVisitorList :: (CppStdMode, Cat, [Rule]) -> Doc -genPrintVisitorList (mode, cat@(ListCat _), rules) = vcat +genPrintVisitorList (_, cat@(ListCat _), rules) = vcat [ "void PrintAbsyn::visit" <> lty <> parens (ltyarg <> "*" <+> varg) , codeblock 2 [ "iter" <> lty <> parens (vname <> "->begin()" <> comma <+> vname <> "->end()") <> semi ] @@ -427,7 +425,7 @@ genPrintVisitorList (mode, cat@(ListCat _), rules) = vcat , "else" ] , unless (null docs1) - [ "if (i == j-1)" + [ "if (i == std::prev(j, 1))" , "{ /* last */" , nest 2 $ vcat docs1 , "}" @@ -442,9 +440,6 @@ genPrintVisitorList (mode, cat@(ListCat _), rules) = vcat , "" ] where - beyondAnsi = case mode of - CppStdBeyondAnsi _ -> True - CppStdAnsi _ -> False cl = identCat (normCat cat) lty = text cl -- List type ltyarg = text cl -- List type arg @@ -480,7 +475,7 @@ prListRule_ (Rule _ _ items _) = for items $ \case Left c | Just{} <- maybeTokenCat c -> "visit" <> dat <> "(*i);" - | isList c -> "iter" <> dat <> "(i+1, j);" + | isList c -> "iter" <> dat <> "(std::next(i,1), j);" | otherwise -> "(*i)->accept(this);" where dat = text $ identCat $ normCat c @@ -489,7 +484,7 @@ prListRule_ (Rule _ _ items _) = for items $ \case -- between the versions with and without STL. -- The present version has been adapted from CFtoCPrinter. genPrintVisitorListNoStl :: (CppStdMode, Cat, [Rule]) -> String -genPrintVisitorListNoStl (mode, cat@(ListCat _), rules) = unlines $ concat +genPrintVisitorListNoStl (_, cat@(ListCat _), rules) = unlines $ concat [ [ "void PrintAbsyn::visit" ++ cl ++ "("++ cl ++ " *" ++ vname ++ ")" , "{" , " if (" ++ vname +++ "== 0)" @@ -515,12 +510,8 @@ genPrintVisitorListNoStl (mode, cat@(ListCat _), rules) = unlines $ concat ] ] where - beyondAnsi = case mode of - CppStdBeyondAnsi _ -> True - CppStdAnsi _ -> False cl = identCat (normCat cat) vname = map toLower cl - varg = map toLower cl pre = vname ++ "->" prules = sortRulesByPrecedence rules swRules f = switchByPrecedence "_i_" $ @@ -531,7 +522,7 @@ genPrintVisitorListNoStl _ = error "genPrintVisitorListNoStl expects a ListCat" --Pretty Printer methods for a rule. prPrintRule :: Bool -> Maybe String -> Rule -> String -prPrintRule beyondAnsi inPackage r@(Rule fun _ _ _) | isProperLabel fun = unlines $ concat +prPrintRule _ inPackage r@(Rule fun _ _ _) | isProperLabel fun = unlines $ concat [ [ "void PrintAbsyn::visit" ++ visitFunName ++ "(" ++ vararg +++ fnm ++ ")" , "{" , " int oldi = _i_;" @@ -573,7 +564,7 @@ prPrintItem pre (Left (c, nt)) --This prints the functions for Abstract Syntax tree printing. prShowData :: Bool -> CppStdMode -> (Cat, [Rule]) -> String -prShowData True mode (cat@(ListCat c), _) = unlines +prShowData True _ (cat@(ListCat c), _) = unlines [ "void ShowAbsyn::visit" ++ cl ++ "("++ cl ++ " *" ++ vname ++ ")", "{", @@ -583,20 +574,16 @@ prShowData True mode (cat@(ListCat c), _) = unlines if isTokenCat c then " visit" ++ baseName cl ++ "(*i) ;" else " (*i)->accept(this);", - " if (i != " ++ vname ++ "->end() - 1) bufAppend(\", \");", + " if (i != std::prev(" ++ vname ++ "->end(), 1)) bufAppend(\", \");", " }", "}", "" ] where - beyondAnsi = case mode of - CppStdBeyondAnsi _ -> True - CppStdAnsi _ -> False cl = identCat (normCat cat) vname = map toLower cl - varg = vname -prShowData False mode (cat@(ListCat c), _) = +prShowData False _ (cat@(ListCat c), _) = unlines [ "void ShowAbsyn::visit" ++ cl ++ "("++ cl ++ " *" ++ vname ++ ")", @@ -619,13 +606,9 @@ prShowData False mode (cat@(ListCat c), _) = "" ] where - beyondAnsi = case mode of - CppStdBeyondAnsi _ -> True - CppStdAnsi _ -> False cl = identCat (normCat cat) ecl = identCat (normCatOfList cat) vname = map toLower cl - varg = vname member = map toLower ecl ++ "_" visitMember | Just t <- maybeTokenCat c = @@ -640,14 +623,13 @@ prShowData _ mode (cat, rules) = --Not a list: CppStdBeyondAnsi _ -> True CppStdAnsi _ -> False cl = identCat (normCat cat) - varg = "p" abstract = case lookupRule (noPosition $ catToStr cat) rules of Just _ -> "" Nothing -> "void ShowAbsyn::visit" ++ cl ++ "(" ++ cl ++ " *p) {} //abstract class\n\n" --This prints all the methods for Abstract Syntax tree rules. prShowRule :: IsFun f => Rul f -> Bool -> String -prShowRule (Rule f _ cats _) beyondAnsi | isProperLabel f = concat +prShowRule (Rule f _ cats _) _ | isProperLabel f = concat [ "void ShowAbsyn::visit" ++ fun ++ "(" ++ vararg +++ fnm ++ ")\n", "{\n", diff --git a/source/src/BNFC/Backend/CPP/STL.hs b/source/src/BNFC/Backend/CPP/STL.hs index 13c8e37f..19fbe72f 100644 --- a/source/src/BNFC/Backend/CPP/STL.hs +++ b/source/src/BNFC/Backend/CPP/STL.hs @@ -22,7 +22,7 @@ import BNFC.Backend.Base import BNFC.Backend.C ( bufferH, bufferC, comment, testfileHeader ) import BNFC.Backend.C.CFtoBisonC ( cf2Bison, unionBuiltinTokens, positionCats, varName ) import BNFC.Backend.C.CFtoFlexC ( cf2flex, ParserMode(..), beyondAnsi, parserPackage, parserName, stlParser ) -import BNFC.Backend.CPP.Common ( commentWithEmacsModeHint, wrapSharedPtr, CppStdMode(..) ) +import BNFC.Backend.CPP.Common ( commentWithEmacsModeHint, wrapSharedPtr ) import BNFC.Backend.CPP.Makefile import BNFC.Backend.CPP.STL.CFtoSTLAbs import BNFC.Backend.CPP.STL.CFtoCVisitSkelSTL @@ -120,6 +120,7 @@ cpptest mode inPackage cf hExt = unlines $ concat , if beyondAnsi mode then unlines [ "#include " + , "#include " , "#include \"Driver" ++hExt++ "\"" ] else @@ -137,43 +138,68 @@ cpptest mode inPackage cf hExt = unlines $ concat , "}" , "" , "int main(int argc, char ** argv)" - , "{" - , " FILE *input;" - , " int quiet = 0;" - , " char *filename = NULL;" - , "" - , " if (argc > 1) {" - , " if (strcmp(argv[1], \"-s\") == 0) {" - , " quiet = 1;" - , " if (argc > 2) {" - , " filename = argv[2];" - , " } else {" - , " input = stdin;" - , " }" - , " } else {" - , " filename = argv[1];" - , " }" - , " }" - , "" - , " if (filename) {" - , " input = fopen(filename, \"r\");" - , " if (!input) {" - , " usage();" - , " exit(1);" - , " }" - , " } else input = stdin;" - , "" , if beyondAnsi mode then unlines [ - " /* The default entry point is used. For other options see Parser.H */" + "{" + , " int quiet = 0;" + , " char *filename = NULL;" + , "" + , " if (argc > 1) {" + , " if (strcmp(argv[1], \"-s\") == 0) {" + , " quiet = 1;" + , " if (argc > 2) {" + , " filename = argv[2];" + , " }" + , " } else {" + , " filename = argv[1];" + , " }" + , " }" + , "" + , " /* The default entry point is used. For other options see Parser.H */" , " " ++ (wrapSharedPtr $ scope ++ dat) ++ " parse_tree = nullptr;" , " try { " + , "" , " auto driver = std::make_unique<" ++ns++ "::" ++camelCaseName++ "Driver>();" - , " parse_tree = driver->p" ++ def ++ "(filename);" + , " if (filename) {" + , " std::ifstream input(filename);" + , " if ( ! input.good() ) {" + , " usage();" + , " exit(1);" + , " }" + , " parse_tree = driver->p" ++ def ++ "(input);" + , " } else {" + , " parse_tree = driver->p" ++ def ++ "(std::cin);" + , " }" ] else unlines [ - " /* The default entry point is used. For other options see Parser.H */" + "{" + , " FILE *input;" + , " int quiet = 0;" + , " char *filename = NULL;" + , "" + , " if (argc > 1) {" + , " if (strcmp(argv[1], \"-s\") == 0) {" + , " quiet = 1;" + , " if (argc > 2) {" + , " filename = argv[2];" + , " } else {" + , " input = stdin;" + , " }" + , " } else {" + , " filename = argv[1];" + , " }" + , " }" + , "" + , " if (filename) {" + , " input = fopen(filename, \"r\");" + , " if (!input) {" + , " usage();" + , " exit(1);" + , " }" + , " } else input = stdin;" + , "" + , " /* The default entry point is used. For other options see Parser.H */" , " " ++ scope ++ dat ++ " *parse_tree = NULL;" , " try { " ," parse_tree = " ++ scope ++ "p" ++ def ++ "(input);" @@ -223,7 +249,7 @@ cpptest mode inPackage cf hExt = unlines $ concat camelCaseName = camelCase_ name ns = fromMaybe camelCaseName (parserPackage mode) - +mkHeaderFile :: String -> Maybe String -> CF -> [Cat] -> [Cat] -> [String] -> String mkHeaderFile hExt inPackage _cf _cats eps _env = unlines $ concat [ [ "#ifndef " ++ hdef , "#define " ++ hdef @@ -245,9 +271,7 @@ mkHeaderFile hExt inPackage _cf _cats eps _env = unlines $ concat where hdef = nsDefine inPackage "PARSER_HEADER_FILE" mkFuncs s = - [ identCat (normCat s) ++ "*" +++ "p" ++ identCat s ++ "(FILE *inp);" - , identCat (normCat s) ++ "*" +++ "ps" ++ identCat s ++ "(const char *str);" - ] + [ identCat (normCat s) ++ "*" +++ "p" ++ identCat s ++ "(std::istream &stream);" ] -- | C++ lexer/parser driver @@ -280,8 +304,7 @@ driverH mode cf cats = unlines -- user defined tokens , unlines [ prettyShow (" std::shared_ptr<" ++ identCat tok ++ ">"+++ varName tok ++";") | tok <- normCats ] , "" - , unlines [ mkFileEntry ep | ep <- entryPoints ] - , unlines [ mkStringEntry ep | ep <- entryPoints ] + , unlines [ mkStreamEntry ep | ep <- entryPoints ] , "" , " /**" , " * parse - parse from a file" @@ -320,16 +343,14 @@ driverH mode cf cats = unlines ns = fromMaybe camelCaseName (parserPackage mode) normCats = nub (map normCat cats) entryPoints = toList (allEntryPoints cf) - mkFileEntry s = - " " ++ (wrapSharedPtr $ identCat (normCat s)) +++ "p" ++ identCat s ++ "(const char *filename);" - mkStringEntry s = - " " ++ (wrapSharedPtr $ identCat (normCat s)) +++ "ps" ++ identCat s ++ "(std::istream &stream);" + mkStreamEntry s = + " " ++ (wrapSharedPtr $ identCat (normCat s)) +++ "p" ++ identCat s ++ "(std::istream &stream);" -- | C++ lexer/parser driver driverC :: ParserMode -> CF -> String -> String -driverC mode cf driverH = unlines +driverC mode cf _ = unlines [ "#include " , "#include " , "#include " @@ -406,37 +427,18 @@ driverC mode cf driverH = unlines , " return;" , "}" , "" - , unlines [ mkFileEntry ep | ep <- entryPoints ] - , unlines [ mkStringEntry ep | ep <- entryPoints ] + , unlines [ mkStreamEntry ep | ep <- entryPoints ] ] where name = parserName mode camelCaseName = camelCase_ name ns = fromMaybe camelCaseName (parserPackage mode) entryPoints = toList (allEntryPoints cf) - mkFileEntry s = - unlines [ - (wrapSharedPtr $ identCat (normCat s)) - , ns++ "::" ++camelCaseName++ "Driver::p" ++ identCat s ++ "(const char *filename)" - , "{" - , " assert( filename != nullptr );" - , " std::ifstream in_file( filename );" - , " if( ! in_file.good() )" - , " {" - , " exit( EXIT_FAILURE );" - , " }" - , " parse_helper( in_file );" - , " return this->" ++ varName s++ ";" - , "}" - ] - mkStringEntry s = + mkStreamEntry s = unlines [ (wrapSharedPtr $ identCat (normCat s)) - , ns++ "::" ++camelCaseName++ "Driver::ps" ++ identCat s ++ "(std::istream &stream)" + , ns++ "::" ++camelCaseName++ "Driver::p" ++ identCat s ++ "(std::istream &stream)" , "{" - , " if( ! stream.good() && stream.eof() ) {" - , " return nullptr;" - , " }" , " parse_helper( stream );" , " return this->" ++ varName s++ ";" , "}" diff --git a/source/src/BNFC/Backend/CPP/STL/CFtoSTLAbs.hs b/source/src/BNFC/Backend/CPP/STL/CFtoSTLAbs.hs index ec76e4a8..c4385f75 100644 --- a/source/src/BNFC/Backend/CPP/STL/CFtoSTLAbs.hs +++ b/source/src/BNFC/Backend/CPP/STL/CFtoSTLAbs.hs @@ -24,7 +24,7 @@ import Data.Char ( toLower ) import BNFC.Backend.Common.OOAbstract import BNFC.CF -import BNFC.Options ( RecordPositions(..), Ansi(..) ) +import BNFC.Options ( RecordPositions(..) ) import BNFC.TypeChecker ( ListConstructors(..) ) import BNFC.Utils ( (+++), applyWhen ) @@ -56,7 +56,7 @@ mkHFile rp mode inPackage cabs cf = unlines "#include "]; CppStdBeyondAnsi _ -> unlines [ "#include ", - "#include ", + "#include ", "#include ", "#include "]; }, @@ -90,7 +90,7 @@ mkHFile rp mode inPackage cabs cf = unlines }, "", "/******************** Visitor Interfaces ********************/", - prVisitor mode cabs, + prVisitor cabs, "", prVisitable, "", @@ -119,22 +119,22 @@ prVisitable = unlines [ "{", " public:", -- all classes with virtual methods require a virtual destructor - " virtual ~Visitable() {}", - " virtual void accept(Visitor *v) = 0;", + " virtual ~Visitable() {}", + " virtual void accept(Visitor *v) = 0;", "};" ] -prVisitor :: CppStdMode -> CAbs -> String -prVisitor mode cf = unlines [ +prVisitor :: CAbs -> String +prVisitor cf = unlines [ "class Visitor", "{", "public:", - " virtual ~Visitor() {}", + " virtual ~Visitor() {}", unlines - [" virtual void visit"++c++"("++ c +++ vararg ++") = 0;" | c <- allClasses cf, notElem c (defineds cf)], + [" virtual void visit"++c++"("++ c +++ vararg ++") = 0;" | c <- allClasses cf, notElem c (defineds cf)], "", unlines - [" virtual void visit"++c++"("++c++" x) = 0;" | c <- allNonClasses cf], + [" virtual void visit"++c++"("++c++" x) = 0;" | c <- allNonClasses cf], "};" ] where @@ -147,16 +147,16 @@ prAbs mode rp c = "class " ++ c ++ " : public Visitable", "{", "public:", - " virtual " ++ c ++ " *clone() const = 0;", - if rp == RecordPositions then " int line_number, char_number;" else "", + " virtual " ++ c ++ " *clone() const = 0;", + if rp == RecordPositions then " int line_number, char_number;" else "", "};" ]; CppStdBeyondAnsi _ -> unlines [ "class " ++ c ++ " : public Visitable", "{", "public:", - " virtual" +++ wrapSharedPtr c +++ "clone() const = 0;", - if rp == RecordPositions then " int line_number, char_number;" else "", + " virtual" +++ wrapSharedPtr c +++ "clone() const = 0;", + if rp == RecordPositions then " int line_number, char_number;" else "", "};" ]; } @@ -169,31 +169,37 @@ prCon mode (c,(f,cs)) = "{", "public:", unlines - [" "++ typ +++ pointerIf st var ++ ";" | (typ,st,var) <- cs], - " " ++ f ++ "(const " ++ f ++ " &);", - " " ++ f ++ " &operator=(const " ++f++ " &);", - " " ++ f ++ "(" ++ conargs ++ ");", + [" "++ typ +++ pointerIf st var ++ ";" | (typ,st,var) <- cs], + " " ++ f ++ "(const " ++ f ++ " &);", + " " ++ f ++ " &operator=(const " ++f++ " &);", + " " ++ f ++ "(" ++ conargs ++ ");", -- Typ *p1, PIdent *p2, ListStm *p3); - " ~" ++f ++ "();", - " virtual void accept(Visitor *v);", - " virtual " ++f++ " *clone() const;", - " void swap(" ++f++ " &);", + " ~" ++f ++ "();", + " virtual void accept(Visitor *v) override;", + " virtual " ++f++ " *clone() const;", + " void swap(" ++f++ " &);", "};" ]; CppStdBeyondAnsi _ -> unlines [ "class " ++f++ " : public " ++ c, "{", "public:", - unlines [" " ++ wrapSharedPtrIf isClass typ +++ var ++ ";" | (typ,isClass,var) <- cs], - -- "right-hand side" operations; for move - " " ++ f ++ "(" ++ f ++ "&& rhs);", - " " ++ f ++ "& operator=(" ++ f ++ "&& rhs);", - " " ++ f ++ "(const" +++ f ++ "& rhs);", - " " ++ f ++ "& operator=(const" +++ f ++ "& rhs);", - " " ++ f ++ "(" ++ conargs ++ ");", - " ~" ++f ++ "();", - " virtual void accept(Visitor *v);", - " " ++ wrapSharedPtr c +++ " clone() const override;", + unlines [" " ++ wrapSharedPtrIf isClass typ +++ var ++ ";" | (typ,isClass,var) <- cs], + if length cs > 0 then + -- Generate following initiliazer; + -- + -- Prog(std::shared_ptr p1) + -- : Program(), liststatement_{p1} {}; + unlines + [ " " ++f++ "(" ++ conargs ++ ")", + " :" +++ c ++ "(), " ++ intercalate ", " [var ++ "{p" ++ show i ++ "}" | ((_,_,var),i) <- zip cs [(1::Integer)..]], + " {};" + ] + else + " " ++f++ "(" ++ conargs ++ "):" +++ c +++ "(){};", + "", + " virtual void accept(Visitor *v) override;", + " " ++ wrapSharedPtr c +++ " clone() const override;", "};" ]; } @@ -202,11 +208,10 @@ prCon mode (c,(f,cs)) = case mode of { CppStdAnsi _ -> concat $ intersperse ", " - [x +++ pointerIf st ("p" ++ show i) | ((x,st,_),i) <- zip cs [1..]] + [x +++ pointerIf st ("p" ++ show i) | ((x,st,_),i) <- zip cs [(1::Integer)..]] ; CppStdBeyondAnsi _ -> - concat $ intersperse ", " - [wrapSharedPtrIf isClass x ++ "& p" ++ show i | ((x,isClass,_),i) <- zip cs [1..]] + intercalate ", " [wrapSharedPtrIf isClass x ++ " p" ++ show i | ((x,isClass,_),i) <- zip cs [(1::Integer)..]] ; } @@ -216,8 +221,8 @@ prList mode (c, b) = case mode of { "class " ++c++ " : public Visitable, public std::vector<" ++bas++ ">" , "{" , "public:" - , " virtual void accept(Visitor *v);" - , " virtual " ++ c ++ " *clone() const;" + , " virtual void accept(Visitor *v);" + , " virtual " ++ c ++ " *clone() const;" , "};" , "" -- cons for this list type @@ -227,28 +232,24 @@ prList mode (c, b) = case mode of { "class " ++c++ " : public Visitable" , "{" , "public:" - , " std::vector<" ++ wrapSharedPtr childClass++ ">" +++ childClassVarName ++ ";" + , " " ++c++ "() : " ++childClassVarName++ "{}" + , " {}" + , "" + , " std::list<" ++ wrapSharedPtr childClass++ ">" +++ childClassVarName ++ ";" , "" -- ref: https://stackoverflow.com/questions/51148797/how-can-i-define-iterator-and-const-iterator-in-my-class-while-i-uses-stdvecto - , " // define iterator and const_iterator, expose it" - , " using iterator = typename std::vector<" ++ wrapSharedPtr childClass ++ ">::iterator;" - , " using const_iterator = typename std::vector<" ++ wrapSharedPtr childClass++ ">::const_iterator;" - , " auto begin() const { return " ++childClassVarName++ ".begin(); }" - , " auto begin() { return " ++childClassVarName++ ".begin(); }" - , " auto end() const { return " ++childClassVarName++ ".end(); }" - , " auto end() { return " ++childClassVarName++ ".end(); }" + , " // define iterator and const_iterator, expose it" + , " using iterator = typename std::list<" ++ wrapSharedPtr childClass ++ ">::iterator;" + , " using const_iterator = typename std::list<" ++ wrapSharedPtr childClass++ ">::const_iterator;" + , " auto begin() const { return " ++childClassVarName++ ".begin(); }" + , " auto begin() { return " ++childClassVarName++ ".begin(); }" + , " auto end() const { return " ++childClassVarName++ ".end(); }" + , " auto end() { return " ++childClassVarName++ ".end(); }" , "" - -- "right-hand side" operations; for move - , " " ++ c ++ "(" ++ c ++ "&& rhs);" - , " " ++ c ++ "& operator=(" ++ c ++ "&& rhs);" - , " " ++ c ++ "(const" +++ c ++ "& rhs);" - , " " ++ c ++ "& operator=(const" +++ c ++ "& rhs);" - , " " ++ c ++ "();" - , " ~" ++ c ++ "();" - , " virtual void accept(Visitor *v);" - , " " ++ wrapSharedPtr c +++ " clone() const;" - , " void cons(" ++ wrapSharedPtr childClass ++ ");" - , " void reverse();" + , " virtual void accept(Visitor *v);" + , " " ++ wrapSharedPtr c +++ " clone() const;" + , " void cons(" ++ wrapSharedPtr childClass ++ ");" + , " void reverse();" , "};" , "" ]; @@ -297,42 +298,10 @@ prConC mode c fcs@(f,_) = unlines [ prListC :: CppStdMode -> (String,Bool) -> String prListC mode (c,b) = unlines [ "/******************** " ++ c ++ " ********************/" - , case mode of { - CppStdAnsi _ -> [] - ; - CppStdBeyondAnsi _ -> unlines [ - c ++ "::" ++ c ++ "(" ++ c ++ "&& rhs) = default;", - "", - c ++ "&" +++ c ++ "::operator=(" ++ c ++ "&& rhs) = default;", - "", - c ++ "::" ++ c ++ "(const" +++ c ++ "& rhs)", - "{", - " for (const auto& e : rhs." ++inner++ ")", - " {", - " " ++inner++".push_back(e->clone());", - " }", - "}", - "", - c ++ "&" +++ c ++ "::operator=(const" +++ c ++ "& rhs)", - "{", - " for (const auto& e : rhs." ++inner++ ")", - " {", - " " ++inner++".push_back(e->clone());", - " }", - " return *this;", - "}", - "", - c ++ "::" ++ c ++"() = default;", - c ++ "::~" ++ c ++"() = default;", - ""]; - } , prAcceptC mode c , prCloneC mode c c , prConsC mode c b ] - where - inner = map toLower c ++ "_" - --The standard accept function for the Visitor pattern prAcceptC :: CppStdMode -> String -> String @@ -340,13 +309,13 @@ prAcceptC mode ty = case mode of { CppStdAnsi _ -> unlines [ "void " ++ ty ++ "::accept(Visitor *v)", "{", - " v->visit" ++ ty ++ "(this);", + " v->visit" ++ ty ++ "(this);", "}" ]; CppStdBeyondAnsi _ -> unlines [ "void " ++ty++ "::accept(Visitor *v)", "{", - " v->visit" ++ ty ++ "(this);", + " v->visit" ++ ty ++ "(this);", "}" ]; } @@ -357,13 +326,13 @@ prCloneC mode f c = case mode of { CppStdAnsi _ -> unlines [ c +++ "*" ++ c ++ "::clone() const", "{", - " return new" +++ c ++ "(*this);", + " return new" +++ c ++ "(*this);", "}" ]; CppStdBeyondAnsi _ -> unlines [ wrapSharedPtr f +++ c ++ "::clone() const ", "{", - " return std::make_shared<" ++ c ++ ">(*this);", + " return std::make_shared<" ++ c ++ ">(*this);", "}" ]; } @@ -373,17 +342,17 @@ prConsC :: CppStdMode -> String -> Bool -> String prConsC mode c b = case mode of { CppStdAnsi _ -> unlines [ concat [ c, "* ", "cons", c, "(", bas, " x, ", c, "* xs) {" ] - , " xs->insert(xs->begin(), x);" - , " return xs;" + , " xs->insert(xs->begin(), x);" + , " return xs;" , "}" ]; CppStdBeyondAnsi _ -> unlines [ concat [ "void ", c, "::cons(", wrapSharedPtr bas, " x) {" ] - , " " ++inner++ ".insert(" ++inner++ ".begin(), x);" + , " " ++inner++ ".push_front(x);" , "}" , "" , "void" +++ c ++ "::reverse() {" - , " std::reverse(" ++inner++ ".begin(), " ++inner++ ".end());" + , " std::reverse(" ++inner++ ".begin(), " ++inner++ ".end());" , "}" ]; } @@ -400,27 +369,22 @@ prConstructorC mode (f,cs) = case mode of { CppStdAnsi _ -> unlines [ f ++ "::" ++ f ++ "(" ++ conargs ++ ")", "{", - unlines [" " ++ c ++ " = " ++ p ++ ";" | (c,p) <- zip cvs pvs], + unlines [" " ++ c ++ " = " ++ p ++ ";" | (c,p) <- zip cvs pvs], "}" ]; CppStdBeyondAnsi _ -> unlines [ - f ++ "::" ++ f ++ "(" ++ conargs ++ ")", - "{", - unlines [" " ++ c ++ " = " ++ wrapMoveIf isClass p ++ ";" | (c,isClass,p) <- zip3 cvs isClasses pvs], - "}" ]; } where cvs = [c | (_,_,c) <- cs] - isClasses = [isClass | (_,isClass,_) <- cs] - pvs = ['p' : show i | ((_,_,_),i) <- zip cs [1..]] + pvs = ['p' : show i | ((_,_,_),i) <- zip cs [(1::Integer)..]] conargs = case mode of { CppStdAnsi _ -> - intercalate ", " [x +++ pointerIf isClass v | ((x,isClass,_),v) <- zip cs pvs] + intercalate ", " [x +++ pointerIf isClass v | ((x,isClass,_),v) <- zip cs pvs] ; CppStdBeyondAnsi _ -> - intercalate ", " [wrapSharedPtrIf isClass x ++ "&" +++ v | ((x,isClass,_),v) <- zip cs pvs] + "" ; } @@ -431,40 +395,23 @@ prCopyC mode (c,cs) = case mode of { CppStdAnsi _ -> unlines [ c ++ "::" ++ c ++ "(const" +++ c +++ "& other)", "{", - unlines [" " ++ cv ++ " = other." ++ cloneIf st cv ++ ";" | (_,st,cv) <- cs], + unlines [" " ++ cv ++ " = other." ++ cloneIf st cv ++ ";" | (_,st,cv) <- cs], "}", "", c +++ "&" ++ c ++ "::" ++ "operator=(const" +++ c +++ "& other)", "{", - " " ++ c +++ "tmp(other);", - " swap(tmp);", - " return *this;", + " " ++ c +++ "tmp(other);", + " swap(tmp);", + " return *this;", "}", "", "void" +++ c ++ "::swap(" ++ c +++ "& other)", "{", - unlines [" std::swap(" ++ cv ++ ", other." ++ cv ++ ");" | (_,_,cv) <- cs], + unlines [" std::swap(" ++ cv ++ ", other." ++ cv ++ ");" | (_,_,cv) <- cs], "}" ]; - CppStdBeyondAnsi _ -> unlines [ - -- "right-hand side" operations; for move - c ++ "::" ++ c ++ "(" ++ c ++ "&& rhs) = default;", - "", - c ++ "&" +++ c ++ "::operator=(" ++ c ++ "&& rhs) = default;", - "", - c ++ "::" ++ c ++ "(const" +++ c ++ "& rhs)", - "{", - unlines [" " ++ pointerIf isClass c ++ " = " ++ pointerIf isClass "rhs" ++ "." ++ c ++ ";" | (_,isClass,c) <- cs], - "}", - "", - c ++ "&" +++ c ++ "::operator=(const" +++ c ++ "& rhs)", - "{", - unlines [" " ++ pointerIf isClass c ++ " = " ++ pointerIf isClass "rhs" ++ "." ++ c ++ ";" | (_,isClass,c) <- cs], - " return *this;", - "}", - "" - ]; - } + CppStdBeyondAnsi _ -> "" + } where cloneIf st cv = if st then (cv ++ "->clone()") else cv @@ -474,10 +421,9 @@ prDestructorC mode (c,cs) = case mode of { CppStdAnsi _ -> unlines [ c ++ "::~" ++ c ++"()", "{", - unlines [" delete(" ++ cv ++ ");" | (_,isPointer,cv) <- cs, isPointer], + unlines [" delete(" ++ cv ++ ");" | (_,isPointer,cv) <- cs, isPointer], "}" ]; - CppStdBeyondAnsi _ -> unlines [ - c ++ "::~" ++ c ++"() = default;" - ]; + CppStdBeyondAnsi _ -> "" + ; }