better presentation

This commit is contained in:
Yann Esposito (Yogsototh) 2013-10-07 15:56:31 +02:00
parent 282012720d
commit 87ae01adc8
25 changed files with 561 additions and 106 deletions

View file

@ -108,15 +108,23 @@
</blockquote>
</section>
<section class="slide">
<h2 id="parsecs">Parsec(s)</h2>
<p>In reality there is many choices:</p>
<pre><code>- attoparsec: fast
- Bytestring-lexing: fast
- Parsec 3: powerful, nice error reporting</code></pre>
</section>
<section class="slide">
<h2 id="a-parsec-example">A Parsec Example</h2>
<pre class="sourceCode haskell"><code class="sourceCode haskell">whitespaces <span class="fu">=</span> many (oneOf <span class="st">&quot;\t &quot;</span>)
number <span class="fu">=</span> many1 digit</code></pre>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="dt">Right</span> <span class="st">&quot; \t &quot;</span> <span class="co">-- whitespaces on &quot; \t &quot;</span>
<span class="dt">Right</span> <span class="st">&quot;&quot;</span> <span class="co">-- whitespaces on &quot;32&quot;</span>
<span class="dt">Right</span> <span class="st">&quot;32&quot;</span> <span class="co">-- number on &quot;32&quot;</span>
number <span class="fu">=</span> many1 digit
symbol <span class="fu">=</span> oneOf <span class="st">&quot;!#$%<span class="and">&amp;</span>|*+-/:&lt;=&gt;?@^_~&quot;</span></code></pre>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="st">&quot; \t &quot;</span> <span class="co">-- whitespaces on &quot; \t &quot;</span>
<span class="st">&quot;&quot;</span> <span class="co">-- whitespaces on &quot;32&quot;</span>
<span class="st">&quot;32&quot;</span> <span class="co">-- number on &quot;32&quot;</span>
<span class="co">-- number on &quot; \t 32 &quot;</span>
<span class="dt">Left</span> <span class="st">&quot;number&quot;</span> (line <span class="dv">1</span>, column <span class="dv">1</span>)<span class="fu">:</span>
<span class="st">&quot;number&quot;</span> (line <span class="dv">1</span>, column <span class="dv">1</span>)<span class="fu">:</span>
unexpected <span class="st">&quot; &quot;</span>
expecting digit</code></pre>
</section>
@ -128,19 +136,93 @@ number <span class="fu">=</span> many1 digit
<span class="ot">number&#39; ::</span> <span class="dt">Parser</span> <span class="dt">Int</span>
number&#39; <span class="fu">=</span> <span class="kw">do</span>
string_of_number <span class="ot">&lt;-</span> many1 digit
return (read string_of_number)</code></pre>
<span class="fu">return</span> (<span class="fu">read</span> string_of_number)</code></pre>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="st">&quot;32&quot;</span><span class="ot"> ::</span> [<span class="dt">Char</span>] <span class="co">-- number on &quot;32&quot;</span>
<span class="dv">32</span><span class="ot"> ::</span> <span class="dt">Int</span> <span class="co">-- number&#39; on &quot;32&quot;</span></code></pre>
</section>
<section class="slide">
<h2 id="monadic-style">Monadic style</h2>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">isolatedNumber ::</span> <span class="dt">Parser</span> <span class="dt">String</span>
isolatedNumber <span class="fu">=</span> <span class="kw">do</span>
_ <span class="ot">&lt;-</span> whitespaces
n <span class="ot">&lt;-</span> number
_ <span class="ot">&lt;-</span> whitespaces
return n</code></pre>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="dt">Right</span> <span class="st">&quot;32&quot;</span> <span class="co">-- isolatedNumber on &quot; \t 32 &quot;</span></code></pre>
<h2 id="combining-monadic-style">Combining Monadic style</h2>
<p><br /><span class="math"><em>S</em>=<em>a</em><em>S</em><em>b</em><em>ε</em></span><br /></p>
<pre class="sourceCode haskell"><code class="sourceCode haskell">s <span class="fu">=</span> (<span class="kw">do</span>
a <span class="ot">&lt;-</span> char <span class="ch">&#39;a&#39;</span>
mid <span class="ot">&lt;-</span> <span class="dt">S</span>
b <span class="ot">&lt;-</span> char <span class="ch">&#39;b&#39;</span>
<span class="fu">return</span> (a<span class="fu">:</span>mid) <span class="fu">++</span> b<span class="fu">:</span>[])
<span class="fu">&lt;|&gt;</span> string <span class="st">&quot;&quot;</span></code></pre>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="st">&quot;&quot;</span> <span class="co">-- s on &quot;&quot;</span>
<span class="st">&quot;aaabbb&quot;</span> <span class="co">-- s on &quot;aaabbb&quot;</span>
<span class="st">&quot;aabb&quot;</span> <span class="co">-- s on &quot;aabbb&quot;</span>
<span class="co">-- s on &quot;aaabb&quot;</span>
<span class="dt">S</span> (line1 <span class="dv">1</span>, column <span class="dv">4</span>)<span class="fu">:</span>
unexpected end <span class="kw">of</span> input
expecting <span class="st">&quot;b&quot;</span></code></pre>
</section>
<section class="slide">
<h2 id="applicative-style">Applicative style</h2>
<p><br /><span class="math"><em>S</em>=<em>a</em><em>S</em><em>b</em><em>ε</em></span><br /></p>
<pre class="sourceCode haskell"><code class="sourceCode haskell">s <span class="fu">=</span> concat3 <span class="fu">&lt;$&gt;</span> string <span class="st">&quot;a&quot;</span> <span class="fu">&lt;*&gt;</span> s <span class="fu">&lt;*&gt;</span> char <span class="st">&quot;b&quot;</span>
<span class="fu">&lt;|&gt;</span> string <span class="st">&quot;&quot;</span>
<span class="kw">where</span>
concat3 x y z <span class="fu">=</span> x <span class="fu">++</span> y <span class="fu">++</span> z</code></pre>
</section>
<section class="slide">
<h2 id="applicative-style-usefull-with-data-types">Applicative Style usefull with Data types</h2>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">IP</span> <span class="fu">=</span> <span class="dt">IP</span> <span class="dt">Int</span> <span class="dt">Int</span> <span class="dt">Int</span> <span class="dt">Int</span>
parseIP <span class="fu">=</span> <span class="dt">IP</span> <span class="fu">&lt;$&gt;</span>
number <span class="fu">&lt;*</span> char <span class="ch">&#39;.&#39;</span> <span class="fu">&lt;*&gt;</span>
number <span class="fu">&lt;*</span> char <span class="ch">&#39;.&#39;</span> <span class="fu">&lt;*&gt;</span>
number <span class="fu">&lt;*</span> char <span class="ch">&#39;.&#39;</span> <span class="fu">&lt;*&gt;</span>
number
monadicParseIP <span class="fu">=</span> <span class="kw">do</span>
d1 <span class="ot">&lt;-</span> number
char <span class="ch">&#39;.&#39;</span>
d2 <span class="ot">&lt;-</span> number
char <span class="ch">&#39;.&#39;</span>
d3 <span class="ot">&lt;-</span> number
char <span class="ch">&#39;.&#39;</span>
d4 <span class="ot">&lt;-</span> number
<span class="fu">return</span> (<span class="dt">IP</span> d1 d2 d3 d4)</code></pre>
</section>
<section class="slide">
<h2 id="write-number-correctly">Write number correctly</h2>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">number ::</span> <span class="dt">Parser</span> <span class="dt">Int</span>
number <span class="fu">=</span> <span class="kw">do</span>
x <span class="ot">&lt;-</span> <span class="fu">read</span> <span class="fu">&lt;$&gt;</span> many1 digit
guard (<span class="dv">0</span> <span class="fu">&lt;=</span> x <span class="fu"><span class="and">&amp;</span><span class="and">&amp;</span></span> x <span class="fu">&lt;</span> <span class="dv">256</span>) <span class="fu">&lt;?&gt;</span>
<span class="st">&quot;Number between 0 and 255 (here &quot;</span> <span class="fu">++</span> <span class="fu">show</span> x <span class="fu">++</span> <span class="st">&quot;)&quot;</span>
<span class="fu">return</span> (<span class="fu">fromIntegral</span> x)</code></pre>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="fu">&gt;&gt;&gt;</span> test parseIP <span class="st">&quot;parseIP&quot;</span> <span class="st">&quot;823.32.80.113&quot;</span>
<span class="st">&quot;parseIP&quot;</span> (line <span class="dv">1</span>, column <span class="dv">4</span>)<span class="fu">:</span>
unexpected <span class="st">&quot;.&quot;</span>
expecting digit <span class="fu">or</span> <span class="dt">Number</span> between <span class="dv">0</span> <span class="fu">and</span> <span class="dv">255</span> (here <span class="dv">823</span>)</code></pre>
</section>
<section class="slide">
<h2 id="so">So</h2>
<ul>
<li>combination of simple parsers</li>
<li>error messages with <code>(&lt;?&gt;)</code></li>
<li>embed result in data type using Applicative style</li>
<li>Not shown, use another monad with the parser</li>
</ul>
<p>Time to do something cool</p>
</section>
<section class="slide">
<h2 id="a-simple-dsl">A Simple DSL</h2>
<p>Let's write a minimal DSL</p>
</section>
<section class="slide">
<h2 id="useful-definitions">Useful definitions</h2>
<p><code>try</code> tries to parse and backtracks if it fails.</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell">(<span class="fu">&lt;||&gt;</span>) parser1 parser2 <span class="fu">=</span> try parser1 <span class="fu">&lt;|&gt;</span> parser2</code></pre>
<p><code>lexeme</code>, just skip spaces.</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell">lexeme parser <span class="fu">=</span> whitespaces <span class="fu">*&gt;</span> parser <span class="fu">&lt;*</span> whitespaces</code></pre>
</section>
<section class="slide">
<h2 id="data-structure">Data Structure</h2>
<p>Remember from text to data structure</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">Tree</span> <span class="fu">=</span> <span class="dt">Node</span> <span class="dt">Element</span> [<span class="dt">Tree</span>]</code></pre>
</section>
<!-- End slides. -->

Binary file not shown.

View file

@ -0,0 +1,147 @@
## Parsing
Latin pars (ōrātiōnis), meaning part (of speech).
- **analysing a string of symbols**
- **formal grammar**.
## Parsing Example (1)
From String:
``` haskell
(1+3)*(1+5+9)
```
To data structure:
![AST](parsec/img/mp/AST.png)\
## Parsec
> Parsec lets you construct parsers by combining high-order Combinators
> to create larger expressions.
>
> Combinator parsers are written and used within the same programming language
> as the rest of the program.
>
> The parsers are first-class citizens of the languages [...]"
## Parsec(s)
In reality there is many choices:
- attoparsec: fast
- Bytestring-lexing: fast
- Parsec 3: powerful, nice error reporting
## A Parsec Example
``` haskell
whitespaces = many (oneOf "\t ")
number = many1 digit
symbol = oneOf "!#$%&|*+-/:<=>?@^_~"
```
``` haskell
" \t " -- whitespaces on " \t "
"" -- whitespaces on "32"
"32" -- number on "32"
-- number on " \t 32 "
"number" (line 1, column 1):
unexpected " "
expecting digit
```
## Monadic style
``` haskell
number :: Parser String
number = many1 digit
number' :: Parser Int
number' = do
string_of_number <- many1 digit
return (read string_of_number)
```
``` haskell
"32" :: [Char] -- number on "32"
32 :: Int -- number' on "32"
```
## Combining Monadic style
$$ S = aSb | ε $$
``` haskell
s = (do
a <- char 'a'
mid <- S
b <- char 'b'
return (a:mid) ++ b:[])
<|> string ""
```
``` haskell
"" -- s on ""
"aaabbb" -- s on "aaabbb"
"aabb" -- s on "aabbb"
-- s on "aaabb"
S (line1 1, column 4):
unexpected end of input
expecting "b"
```
## Applicative style
$$ S = aSb | ε $$
``` haskell
s = concat3 <$> string "a" <*> s <*> char "b"
<|> string ""
where
concat3 x y z = x ++ y ++ z
```
## Applicative Style usefull with Data types
``` haskell
data IP = IP Int Int Int Int
parseIP = IP <$>
number <* char '.' <*>
number <* char '.' <*>
number <* char '.' <*>
number
monadicParseIP = do
d1 <- number
char '.'
d2 <- number
char '.'
d3 <- number
char '.'
d4 <- number
return (IP d1 d2 d3 d4)
```
## Write number correctly
``` haskell
number :: Parser Int
number = do
x <- read <$> many1 digit
guard (0 <= x && x < 256) <?>
"Number between 0 and 255 (here " ++ show x ++ ")"
return (fromIntegral x)
```
``` haskell
>>> test parseIP "parseIP" "823.32.80.113"
"parseIP" (line 1, column 4):
unexpected "."
expecting digit or Number between 0 and 255 (here 823)
```

View file

@ -0,0 +1,34 @@
## So
- combination of simple parsers
- error messages with `(<?>)`
- embed result in data type using Applicative style
- Not shown, use another monad with the parser
Time to do something cool
## A Simple DSL
Let's write a minimal DSL
## Useful definitions
`try` tries to parse and backtracks if it fails.
``` haskell
(<||>) parser1 parser2 = try parser1 <|> parser2
```
`lexeme`, just skip spaces.
``` haskell
lexeme parser = whitespaces *> parser <* whitespaces
```
## Data Structure
Remember from text to data structure
``` haskell
data Tree = Node Element [Tree]
```

View file

@ -1,19 +0,0 @@
## [Write Yourself a Scheme in 48 Hours](https://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/First_Steps)
~~~ {.haskell}
import Text.Parsec
type Parser a = Parsec String () a
~~~
~~~ {.haskell}
symbol :: Parser Char
symbol = oneOf "!#$%&|*+-/:<=>?@^_~"
~~~
~~~ {.haskell}
readExpr :: String -> String
readExpr input = case parse symbol "lisp" input of
Left err -> "No match: " ++ show err
Right val -> "Found: " ++ show val
~~~

View file

@ -1,14 +0,0 @@
## Monadic style
``` haskell
isolatedNumber :: Parser String
isolatedNumber = do
_ <- whitespaces
n <- number
_ <- whitespaces
return n
```
``` haskell
Right "32" -- isolatedNumber on " \t 32 "
```

View file

@ -1,7 +1,7 @@
## Parsing
Latin pars (ōrātiōnis), meaning part (of speech).
- **analysing a string of symbols**
- **formal grammar**.

View file

@ -9,3 +9,4 @@ From String:
To data structure:
![AST](parsec/img/mp/AST.png)\

View file

@ -7,3 +7,4 @@
> as the rest of the program.
>
> The parsers are first-class citizens of the languages [...]"

View file

@ -0,0 +1,8 @@
## Parsec(s)
In reality there is many choices:
- attoparsec: fast
- Bytestring-lexing: fast
- Parsec 3: powerful, nice error reporting

View file

@ -3,15 +3,17 @@
``` haskell
whitespaces = many (oneOf "\t ")
number = many1 digit
symbol = oneOf "!#$%&|*+-/:<=>?@^_~"
```
``` haskell
Right " \t " -- whitespaces on " \t "
Right "" -- whitespaces on "32"
Right "32" -- number on "32"
" \t " -- whitespaces on " \t "
"" -- whitespaces on "32"
"32" -- number on "32"
-- number on " \t 32 "
Left "number" (line 1, column 1):
"number" (line 1, column 1):
unexpected " "
expecting digit
```

View file

@ -14,3 +14,4 @@ number' = do
"32" :: [Char] -- number on "32"
32 :: Int -- number' on "32"
```

View file

@ -0,0 +1,24 @@
## Combining Monadic style
$$ S = aSb | ε $$
``` haskell
s = (do
a <- char 'a'
mid <- S
b <- char 'b'
return (a:mid) ++ b:[])
<|> string ""
```
``` haskell
"" -- s on ""
"aaabbb" -- s on "aaabbb"
"aabb" -- s on "aabbb"
-- s on "aaabb"
S (line1 1, column 4):
unexpected end of input
expecting "b"
```

View file

@ -0,0 +1,11 @@
## Applicative style
$$ S = aSb | ε $$
``` haskell
s = concat3 <$> string "a" <*> s <*> char "b"
<|> string ""
where
concat3 x y z = x ++ y ++ z
```

View file

@ -0,0 +1,22 @@
## Applicative Style usefull with Data types
``` haskell
data IP = IP Int Int Int Int
parseIP = IP <$>
number <* char '.' <*>
number <* char '.' <*>
number <* char '.' <*>
number
monadicParseIP = do
d1 <- number
char '.'
d2 <- number
char '.'
d3 <- number
char '.'
d4 <- number
return (IP d1 d2 d3 d4)
```

View file

@ -0,0 +1,17 @@
## Write number correctly
``` haskell
number :: Parser Int
number = do
x <- read <$> many1 digit
guard (0 <= x && x < 256) <?>
"Number between 0 and 255 (here " ++ show x ++ ")"
return (fromIntegral x)
```
``` haskell
>>> test parseIP "parseIP" "823.32.80.113"
"parseIP" (line 1, column 4):
unexpected "."
expecting digit or Number between 0 and 255 (here 823)
```

View file

@ -0,0 +1,9 @@
## So
- combination of simple parsers
- error messages with `(<?>)`
- embed result in data type using Applicative style
- Not shown, use another monad with the parser
Time to do something cool

View file

@ -0,0 +1,4 @@
## A Simple DSL
Let's write a minimal DSL

View file

@ -0,0 +1,14 @@
## Useful definitions
`try` tries to parse and backtracks if it fails.
``` haskell
(<||>) parser1 parser2 = try parser1 <|> parser2
```
`lexeme`, just skip spaces.
``` haskell
lexeme parser = whitespaces *> parser <* whitespaces
```

View file

@ -0,0 +1,7 @@
## Data Structure
Remember from text to data structure
``` haskell
data Tree = Node Element [Tree]
```

46
parsec/examples/03.hs Normal file
View file

@ -0,0 +1,46 @@
import Control.Applicative hiding (many, (<|>))
import Text.Parsec
import Data.Typeable
type Parser a = Parsec String () a
sa :: Parser String
sa = concat3 <$> string "a" <*> sa <*> string "b" <|> string ""
where
concat3 x y z = x ++ y ++ z
s :: Parser String
s = s' <|> epsilon
epsilon = string ""
s' :: Parser String
s' = do
a <- string "a"
mid <- s
b <- string "b"
return (a ++ mid ++ b)
main :: IO ()
main = do
test s "S" "aaabbb"
test s "S" "aabbb"
test s "S" "aab"
test s "S" ""
test sa "S'" "aaabbb"
test sa "S'" "aabbb"
test sa "S'" "aab"
test sa "S'" ""
test parseIP "parseIP" "123.32.80.113"
test parseIP "parseIP" "823.32.80.113"
test :: (Typeable a, Show a) => Parser a -> String -> String -> IO ()
test parser description string = do
putStrLn $ "-- " ++ description ++ " on '" ++ string ++ "'"
let res = parse parser description string
putStr $ show res
case res of
Left err -> return ()
Right value -> putStr $ " :: " ++ show (typeOf value)
putStrLn ""

View file

@ -0,0 +1,38 @@
{-# LANGUAGE DeriveDataTypeable #-}
import Control.Applicative hiding (many, (<|>))
import Text.Parsec
import Data.Typeable
import Control.Monad (guard)
type Parser a = Parsec String () a
data IP = IP Int Int Int Int deriving (Show,Typeable)
parseIP :: Parser IP
parseIP = IP <$>
number <* char '.' <*>
number <* char '.' <*>
number <* char '.' <*>
number
number :: Parser Int
number = do
x <- read <$> many1 digit
guard (0 <= x && x < 256) <?> "Number between 0 and 255 (here " ++ show x ++ ")"
return (fromIntegral x)
main :: IO ()
main = do
test parseIP "parseIP" "123.32.80.113"
test parseIP "parseIP" "823.32.80.113"
test :: (Typeable a, Show a) => Parser a -> String -> String -> IO ()
test parser description string = do
putStrLn $ "-- " ++ description ++ " on '" ++ string ++ "'"
let res = parse parser description string
putStr $ show res
case res of
Left err -> return ()
Right value -> putStr $ " :: " ++ show (typeOf value)
putStrLn ""

View file

@ -10,14 +10,31 @@ fi
cd $scriptdir
htmldir="_html"
tmpdir="_tmp"
[[ -e $htmldir ]] && \rm -rf $htmldir
[[ -e $tmpdir ]] && \rm -rf $tmpdir
mkdir -p $htmldir
# split a markdown file on ##
splitMarkdown() {
dstdir=$tmpdir/${1:h}
mdfic=$tmpdir/${1:r}
[[ ! -d $dstdir ]] && mkdir -p $dstdir
awk '/^## /{ dest=sprintf("'$mdfic'-%03d.md",n); print dest; n++ } { print $0 > dest}' $1
}
# Convert all slides from markdown
for slide in **/*.{md,html}(.N); do
dst="$htmldir/${slide:r}.html"
[[ ! -e ${dst:h} ]] && mkdir -p ${dst:h}
case ${slide:e} in
md) pandoc -f markdown -t html $slide > $dst;;
md) i=0
for tmpfic in $(splitMarkdown $slide); do
((i++))
print "Split $tmpfic"
dst="$( print -- ${tmpfic:r}.html | sed 's#'$tmpdir'#'$htmldir'#' )"
pandoc -f markdown -t html $tmpfic > $dst
done ;;
html) cp $slide $dst;;
esac
done

View file

@ -1,55 +1,3 @@
#!/usr/bin/env zsh
error(){print -- $* >&2; exit 1}
(($#<2)) && error "usage: ${0:t} [once] cmd dirs..."
ONCE=0
[[ $1 = "once" ]] && { ONCE=1; shift }
(($#<2)) && error "usage: ${0:t} [once] cmd dirs..."
cmd="$1"
shift
typeset -a listDir
listDir=( $@ )
isRecentlyModified() {
local fic="$1"
local mtime=0
currenttime=$(date +"%s")
case $(uname) in
Darwin) mtime=$(stat -f %m $fic);;
Linux) mtime=$(stat --printf %Y $fic);;
*) mtime=$(stat --printf %Y $fic);;
esac
(( $currenttime - $mtime < 2 ))
}
checkfile=".last_watched"
((ONCE == 0)) && \
[[ -e $checkfile ]] && \
isRecentlyModified $checkfile && \
error "Wait at least 2 second if you killed the process"
execIfChanged() {
isRecentlyModified $1 && { print -- "$cmd $1"; eval "$cmd $1"}
}
typeset -A listFic
while true; do
listFic=()
for d in $listDir; do
if [[ -d $d ]]; then
for fic in $d/**/*(.); do
execIfChanged $fic
done
else
execIfChanged $d
fi
done
((ONCE == 1)) && break
touch $checkfile
sleep 2
done
./watch ./gen *.html 10_Introduction

55
parsec/watch Executable file
View file

@ -0,0 +1,55 @@
#!/usr/bin/env zsh
error(){print -- $* >&2; exit 1}
(($#<2)) && error "usage: ${0:t} [once] cmd dirs..."
ONCE=0
[[ $1 = "once" ]] && { ONCE=1; shift }
(($#<2)) && error "usage: ${0:t} [once] cmd dirs..."
cmd="$1"
shift
typeset -a listDir
listDir=( $@ )
isRecentlyModified() {
local fic="$1"
local mtime=0
currenttime=$(date +"%s")
case $(uname) in
Darwin) mtime=$(stat -f %m $fic);;
Linux) mtime=$(stat --printf %Y $fic);;
*) mtime=$(stat --printf %Y $fic);;
esac
(( $currenttime - $mtime < 2 ))
}
checkfile=".last_watched"
((ONCE == 0)) && \
[[ -e $checkfile ]] && \
isRecentlyModified $checkfile && \
error "Wait at least 2 second if you killed the process"
execIfChanged() {
isRecentlyModified $1 && { print -- "$cmd $1"; eval "$cmd $1"}
}
typeset -A listFic
while true; do
listFic=()
for d in $listDir; do
if [[ -d $d ]]; then
for fic in $d/**/*(.); do
execIfChanged $fic
done
else
execIfChanged $d
fi
done
((ONCE == 1)) && break
touch $checkfile
sleep 2
done