Commit aa4d8686 authored by Michael Hanus's avatar Michael Hanus
Browse files

Curry preprocessor integrated into one executable and support mixture of...

Curry preprocessor integrated into one executable and support mixture of integrated code and default rules
parent 04db7557
# Makefile for default rules preprocessor
# source modules of the default rules preprocessor:
DEPS = *.curry
TOOL=Transform
.PHONY: all compile install clean uninstall
all: install
install: $(TOOL)
clean:
$(CLEANCURRY) -r
uninstall: clean
rm -f $(TOOL)
# generate executable for Curry Browser:
Transform: $(DEPS)
$(REPL) $(REPL_OPTS) :set -time :load Transform :save :quit
......@@ -4,15 +4,9 @@ Default Rules Preprocessor
This directory contains the implementation of a preprocessor
for Curry programs in order to implement default rules.
A default rule for a function `f` processed by this preprocessor
must be defined as a rule defining `default_f` (see the examples
in the directory Examples).
must be defined as a rule defining the operation `f'default`.
The preprocessor can be called with the following parameters:
The preprocessor can be called by the Curry preprocessor `currypp`
with the option `defaultrules` (provided as a CYMAKE option,
see the example programs in the directory Examples).
... <input> : translate <input> program and show translated program
... -r <input> : translate <input> program and load the translated program
into the Curry system
... <org> <infile> <outfile> : "preprocessor mode", i.e., translate
<infile> to <outfile> where <org> is the original program
......@@ -66,7 +66,7 @@ main = do
[mname] -> transMain tparam (stripCurrySuffix mname)
(orgfile:infile:outfile:opts) ->
maybe (printError args)
(\vl -> transPP vl orgfile infile outfile)
(\vl -> transDefaultRules vl orgfile infile outfile)
(processOptions opts)
_ -> printError args
......@@ -120,11 +120,11 @@ compileAcyFcy quiet progname = do
callFrontendWithParams FCY params progname
------------------------------------------------------------------------
-- Start sequentializer in "preprocessor mode":
transPP :: Int -> String -> String -> String -> IO ()
transPP verb orgfile infile outfile = do
-- Start default rules transformation in "preprocessor mode":
transDefaultRules :: Int -> String -> String -> String -> IO ()
transDefaultRules verb orgfile infile outfile = do
when (verb>0) $ putStr banner
let savefile = orgfile++".SAVE"
let savefile = orgfile++".SAVEDEFRULES"
modname = stripCurrySuffix orgfile
renameFile orgfile savefile
starttime <- getCPUTime
......@@ -134,8 +134,9 @@ transPP verb orgfile infile outfile = do
let (detfuncnames,newprog) = translateProg inputProg
writeFile outfile (showCProg newprog)
stoptime <- getCPUTime
when (verb>0) $ putStrLn
("Total transformation time: " ++ show (stoptime-starttime) ++ " ms")
when (verb>1) $ putStrLn
("Default rules transformation time: " ++
show (stoptime-starttime) ++ " ms")
printProofObligation detfuncnames
where
tryReadUntypedCurry mn savefile =
......
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=--foreigncode #-}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=foreigncode #-}
------------------------------------------------------------------------------
--- This program contains some examples for integrated code to format strings.
......
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=--foreigncode #-}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=foreigncode #-}
------------------------------------------------------------------------------
--- This program contains examples for integrated code to support
......
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=--foreigncode #-}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=foreigncode #-}
------------------------------------------------------------------------------
--- This program contains some examples for using different kinds of
......
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=--foreigncode --optF=-o #-}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=foreigncode #-}
------------------------------------------------------------------------------
-- Example for CGI programming in Curry:
......
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=--foreigncode --optF=-o #-}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=foreigncode --optF=-o #-}
------------------------------------------------------------------------------
--- This program contains examples for integrated code to support
......
......@@ -7,26 +7,39 @@
--- is supported (option --foreigncode, see module `Translator`).
---
--- @author Michael Hanus
--- @version February 2015
--- @version November 2015
------------------------------------------------------------------------------
import Char(isDigit,digitToInt)
import Directory(copyFile,renameFile)
import Distribution(installDir)
import List(delete)
import System
import Translator(translateFile)
import TransDefRules(transDefaultRules)
import TransSeqRules(transSequentialRules)
cppBanner :: String
cppBanner = unlines [bannerLine,bannerText,bannerLine]
where
bannerText = "Curry Preprocessor (version of 21/08/2015)"
bannerText = "Curry Preprocessor (version of 13/11/2015)"
bannerLine = take (length bannerText) (repeat '=')
--- Preprocessor targets:
data PPTarget = ForeignCode | SequentialRules | DefaultRules
parseTarget :: String -> Maybe PPTarget
parseTarget t | t=="foreigncode" = Just ForeignCode
| t=="defaultrules" = Just DefaultRules
| t=="seqrules" = Just SequentialRules
| otherwise = Nothing
--- Preprocessor options:
data PPOpts = PPOpts { optHelp :: Bool
, optSave :: Bool
, optVerb :: Int
, optTgts :: [String]
, optTgts :: [PPTarget]
}
initOpts :: PPOpts
......@@ -45,11 +58,16 @@ main = do
maybe (showUsage args)
(\opts ->
if optHelp opts
then putStrLn (cppBanner ++ usageText)
then putStrLn (cppBanner ++ usageText) >> exitWith 1
else do
when (optVerb opts > 0) $ putStr cppBanner
when (optVerb opts > 2) $ do
putStrLn ("Original file name: " ++ orgSourceFile)
putStrLn ("Input file name: " ++ inFile)
putStrLn ("Output file name: " ++ outFile)
preprocess opts orgSourceFile inFile outFile
when (optSave opts) $ saveFile orgSourceFile outFile )
when (optSave opts) $ saveFile orgSourceFile outFile
when (optVerb opts > 3) (readFile outFile >>= putStrLn) )
(processOptions initOpts options)
_ -> maybe (showUsage args)
(\opts -> if optHelp opts
......@@ -66,16 +84,18 @@ main = do
(['-','v',vl]:os) -> if isDigit vl
then processOptions opts { optVerb = digitToInt vl } os
else Nothing
(('-':'-':ts):os) -> if ts `elem` ["foreigncode","seqrules","default"]
then processOptions opts {optTgts = ts:optTgts opts} os
else Nothing
(ts:os) -> if ts `elem` ["foreigncode","seqrules","defaultrules"]
then processOptions opts {optTgts = ts:optTgts opts} os
else Nothing
(('-':'-':ts):os) -> maybe Nothing
(\t -> processOptions
opts {optTgts = t : optTgts opts} os)
(parseTarget ts)
(ts:os) -> maybe Nothing
(\t -> processOptions
opts {optTgts = t : optTgts opts} os)
(parseTarget ts)
saveFile orgSourceFile outFile = do
let sFile = orgSourceFile++".CURRYPP"
system $ "cp "++outFile++" "++sFile
copyFile outFile sFile
putStrLn $ "Translated Curry file written to '"++sFile++"'"
showUsage args = do
......@@ -97,25 +117,44 @@ usageText =
"\nand optional settings:\n" ++
"-o : store output also in file <OrgFileName>.CURRYPP\n" ++
"-v : show preprocessor version on stdout\n" ++
"-v<n> : show more information about the preprocessor:\n" ++
" <n>=1 : show version\n" ++
" <n>=2 : show timing\n" ++
" <n>=3 : show used file names\n" ++
" <n>=4 : show transformed Curry program\n" ++
"-h|-? : show help message and quit\n"
-- Start the Curry preprocessor:
preprocess :: PPOpts -> String -> String -> String -> IO ()
preprocess opts orgSourceFile infile outfile
preprocess opts orgfile infile outfile
| null pptargets = do
putStr cppBanner
putStrLn "ERROR: no preprocessing target (e.g., --foreigncode) specified!\n"
putStrLn usageText
exitWith 1
| "foreigncode" `elem` pptargets = translateFile infile outfile
| "seqrules" `elem` pptargets =
system (unwords [installDir++"/currytools/currypp/SequentialRules/Main",
orgSourceFile,infile,outfile]) >> done
| "defaultrules" `elem` pptargets =
system
(unwords $ [installDir++"/currytools/currypp/DefaultRules/Transform",
orgSourceFile,infile,outfile] ++
(if verb==0 then [] else ["-v"++show verb])) >> done
| SequentialRules `elem` pptargets && DefaultRules `elem` pptargets
= do putStr cppBanner
putStrLn "ERROR: cannot use 'defaultrules' together with 'seqrules'!\n"
exitWith 1
| ForeignCode `elem` pptargets
= do starttime <- getCPUTime
translateFile orgfile infile outfile
stoptime <- getCPUTime
when (verb>1) $ putStrLn
("Foreign code transformation time: " ++
show (stoptime-starttime) ++ " ms")
let rpptargets = delete ForeignCode pptargets
unless (null rpptargets) $ do
let savefile = orgfile ++ ".SAVEORGPP"
renameFile orgfile savefile
copyFile outfile orgfile
copyFile orgfile infile
preprocess opts{optTgts = rpptargets} orgfile infile outfile
renameFile savefile orgfile
| SequentialRules `elem` pptargets
= transSequentialRules verb orgfile infile outfile
| DefaultRules `elem` pptargets
= transDefaultRules verb orgfile infile outfile
| otherwise = error "currypp: internal error"
where
pptargets = optTgts opts
......
......@@ -6,18 +6,23 @@
# Jasper Sikorra - jsi@informatik.uni-kiel.de
#
#****************************************************************************
#----------------------------------
# Input and output dirs
#----------------------------------
# Makefile for Curry preprocessor
#****************************************************************************
# Tool binary
TOOL = $(BINDIR)/currypp
# Source filepaths
SRCDIR = $(CURDIR)
PARSEDIR = $(SRCDIR)/Parser
MLDIR = $(PARSEDIR)/ML
SRCDIR = $(CURDIR)
PARSEDIR = $(SRCDIR)/Parser
MLDIR = $(PARSEDIR)/ML
SEQRULESDIR = $(CURDIR)/SequentialRules
DEFRULESDIR = $(CURDIR)/DefaultRules
# preprocessor input path and dependencies:
PPPATH = $(SRCDIR):$(PARSEDIR):$(MLDIR):$(SEQRULESDIR):$(DEFRULESDIR)
DEPS = $(SRCDIR)/*.curry $(PARSEDIR)/*.curry $(MLDIR)/*.curry \
$(SEQRULESDIR)/*.curry $(DEFRULESDIR)/*.curry
.PHONY: all compile install clean uninstall
......@@ -28,22 +33,14 @@ compile: Main
install: compile
rm -f $(TOOL)
ln -s $(CURDIR)/Main $(TOOL)
cd SequentialRules && $(MAKE) install
cd DefaultRules && $(MAKE) install
clean:
$(CLEANCURRY) -r
rm -f Translator
cd SequentialRules && $(MAKE) clean
cd DefaultRules && $(MAKE) clean
uninstall: clean
rm -f $(TOOL)
cd SequentialRules && $(MAKE) uninstall
cd DefaultRules && $(MAKE) uninstall
# generate executable of currypp translator:
Main: $(SRCDIR)/*.curry $(PARSEDIR)/*.curry $(MLDIR)/*.curry
@echo Compiling Curry Integrated Code Translator ...
$(REPL) $(REPL_OPTS) :set path $(SRCDIR):$(PARSEDIR):$(MLDIR) \
:load Main :save :quit
Main: $(DEPS)
@echo Compiling Curry Preprocessor...
$(REPL) $(REPL_OPTS) :set path $(PPPATH) :load Main :save :quit
......@@ -13,7 +13,7 @@ If the pre-processor is installed (see Makefile) as the binary `currypp`,
Curry source files containing integrated code can be translated
by running `currypp` as follows:
currypp org-filename input-file output-file --foreigncode [-o]
currypp <org-filename> <input-file> <output-file> foreigncode [-o]
The parameters are:
......
# Makefile for sequential rules preprocessor
# source modules of the seqeuential rules preprocessor:
DEPS = *.curry
.PHONY: all compile install clean uninstall
all: install
install: Main
clean:
$(CLEANCURRY) -r
rm -f Main
uninstall: clean
rm -f $(TOOL)
# generate executable for Curry Browser:
Main: $(DEPS)
$(REPL) $(REPL_OPTS) :set -time :load Main :save :quit
......@@ -10,11 +10,6 @@ rule ordering.
The ideas of this transformation are described in the
[WFLP 2014 paper](http://ceur-ws.org/Vol-1335/wflp2014_paper5.pdf).
The preprocessor can be called with the following parameters:
... <input> : translate <input> program and show translated program
... <input> <output> : translate <input> program into <output> program
... <org> <infile> <outfile> : "preprocessor mode", i.e., translate
<infile> to <outfile> where <org> is the original program
The preprocessor can be called by the Curry preprocessor `currypp`
with the option `seqrules` (provided as a CYMAKE option,
see the example programs in the directory Examples).
......@@ -36,7 +36,7 @@ main = do
[srcmod] -> applySequential (stripCurrySuffix srcmod) Nothing
[srcmod,trgmod] -> applySequential (stripCurrySuffix srcmod)
(Just (stripCurrySuffix trgmod))
[orgfile,infile,outfile] -> ppSequential orgfile infile outfile
[orgfile,infile,outfile] -> transSequentialRules 1 orgfile infile outfile
_ -> do putStrLn $ "Illegal arguments: "++unwords args
putStrLn "Usage: ... <sourcemodule> <targetmodule>"
......@@ -48,17 +48,20 @@ applySequential sourcemodname mbtarget = do
(maybe putStr (\fn -> writeFile (fn++".curry")) mbtarget) targetprog
-- Start sequentializer in "preprocessor mode":
ppSequential :: String -> String -> String -> IO ()
ppSequential orgfile infile outfile = do
--print (orgfile,infile,outfile)
let savefile = orgfile++".SAVE"
transSequentialRules :: Int -> String -> String -> String -> IO ()
transSequentialRules verb orgfile infile outfile = do
let savefile = orgfile++".SAVESEQRULES"
modname = stripCurrySuffix orgfile
renameFile orgfile savefile
starttime <- getCPUTime
readFile infile >>= writeFile orgfile . replaceOptionsLine
inputProg <- tryReadCurry modname savefile
--putStr (showCProg (translate inputProg modname))
renameFile savefile orgfile
writeFile outfile (showCProg (translate inputProg modname))
stoptime <- getCPUTime
when (verb>1) $ putStrLn
("Sequential rules transformation time: " ++
show (stoptime-starttime) ++ " ms")
where
tryReadCurry mn savefile =
catch (readCurry mn)
......
......@@ -93,21 +93,21 @@ formatWarnings ws@((p,_):_) = "\nWARNINGS in " ++ getFilename p ++ ":"
++ " | " ++ getWarnMsg w
--- Translates a file with Curry with Integrated Code to a file with Curry Code.
--- @param in_fp - The filepath to the input file
--- @param out_fp - The filepath to the output file
translateFile :: String -> String -> IO ()
translateFile in_fp out_fp =
do in_st <- readFile in_fp
out_st <- translateString in_fp in_st
writeFile out_fp out_st
--- Translates a string with Curry with Integrated Code to a string with Curry
--- Code.
--- @param orgfile - The file path to the original Curry file
--- @param infile - The file path to the input file
--- @param outfile - The file path to the output file
translateFile :: String -> String -> String -> IO ()
translateFile orgfile infile outfile =
readFile infile >>= translateString orgfile >>= writeFile outfile
--- Translates a string containing a Curry program with Integrated Code
--- into a string with pure Curry code.
--- @param fname - The name of the original Curry file
--- @param s - The string that should be translated
--- @return The translated string
translateString :: String -> String -> IO String
translateString name s =
do stw <- concatAllIOPM $ applyLangParsers $ ciparser name s
translateString fname s =
do stw <- concatAllIOPM $ applyLangParsers $ ciparser fname s
putStr (formatWarnings (getWarnings stw))
escapePR (discardWarnings stw) errfun
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment