Skip to content
This repository has been archived by the owner on Apr 26, 2021. It is now read-only.

Populate values at parser level #27

Merged
merged 21 commits into from
May 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"purescript-spec": "f98fd4f62e4a64741be7adc867033ab352451962",
"purescript-node-fs-aff": "~0.5.0",
"purescript-unsafe-coerce": "~0.1.0",
"purescript-words-lines": "^0.0.2"
"purescript-words-lines": "^0.0.2",
"purescript-free": "^0.9.1"
},
"resolutions": {
"purescript-transformers": "~0.8.4",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "neodoc",
"version": "0.0.15",
"version": "0.1.0",
"description": "Docopt implementation for node",
"main": "index.js",
"directories": {
Expand Down
11 changes: 5 additions & 6 deletions src/Docopt/Docopt.purs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import Data.Array as A
import Data.Bifunctor (lmap)
import Data.List.WordsLines (lines, unlines)


import Language.Docopt (parseDocopt, applyDocopt)
import Language.Docopt (parseDocopt, evalDocopt)
import Language.Docopt.Value (Value())
import Language.Docopt as D
import Language.Docopt.Env (Env())

Expand Down Expand Up @@ -76,15 +76,14 @@ defaultOptions = {
run :: forall e
. String
-> Options
-> Eff (DocoptEff e) (StrMap D.Value)
-> Eff (DocoptEff e) (StrMap Value)
run d o = do
argv <- maybe (A.drop 2 <$> Process.argv) (return <<< id) o.argv
env <- maybe Process.getEnv (return <<< id) o.env
either onError return
do
either onError return do
{ specification, usage } <- parseDocopt d o.smartOptions
lmap ((help usage) ++ _) do
applyDocopt specification env argv o.optionsFirst
evalDocopt specification env argv o.optionsFirst

where
onError e = do
Expand Down
19 changes: 11 additions & 8 deletions src/Language/Docopt.purs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
module Language.Docopt (
runDocopt
, parseDocopt
, applyDocopt
, module D
, evalDocopt
) where

import Prelude ((<<<), bind, return, ($), (<$>))
Expand All @@ -26,12 +25,11 @@ import Language.Docopt.Errors (Argv, DocoptError(..), SolveError(..),
developerErrorMessage, prettyPrintDocoptError
) as D
import Language.Docopt.Value (Value(..)) as D
import Language.Docopt.ParserGen as G
import Language.Docopt.Trans as T
import Language.Docopt.ParserGen as G
import Language.Docopt.Trans.Flat as T

import Language.Docopt.Scanner as Scanner
import Language.Docopt.Solver as Solver
-- import Language.Docopt.Solver2 as Solver
import Language.Docopt.Parser.Usage as Usage
import Language.Docopt.Parser.Desc as Desc

Expand All @@ -40,6 +38,11 @@ type Docopt = {
, specification :: List D.Usage
}

data Origin
= Argv
| Environment
| Default

-- |
-- | Parse the docopt text and produce a parser
-- | that can be applied to user input.
Expand All @@ -57,12 +60,12 @@ parseDocopt docopt smartOpts = do
-- |
-- | Apply the generated docopt parser to user input.
-- |
applyDocopt :: List D.Usage -- ^ The program specification
evalDocopt :: List D.Usage -- ^ The program specification
-> StrMap String -- ^ The environment
-> Array String -- ^ The user input
-> Boolean -- ^ Enable "options-first"
-> Either String (StrMap D.Value)
applyDocopt prg env argv optsFirst = do
evalDocopt prg env argv optsFirst = do
vs <- toUserParseErr argv $ G.runParser env argv (G.genParser prg optsFirst)
return $ uncurry (T.reduce prg env) vs

Expand All @@ -78,7 +81,7 @@ runDocopt :: String -- ^ The docopt text
-> Either String (StrMap D.Value)
runDocopt docopt env argv optsFirst smartOpts = do
{ specification } <- parseDocopt docopt smartOpts
applyDocopt specification env argv optsFirst
evalDocopt specification env argv optsFirst

toScanErr :: forall a. Either P.ParseError a -> Either String a
toScanErr = lmap (D.prettyPrintDocoptError <<< D.DocoptScanError)
Expand Down
34 changes: 34 additions & 0 deletions src/Language/Docopt/Origin.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Language.Docopt.Origin (
Origin(..)
) where

import Prelude
import Data.Function (on)

data Origin
= Argv
| Environment
| Default
| Empty

weight :: Origin -> Int
weight Argv = 3
weight Environment = 2
weight Default = 1
weight Empty = 0

instance showOrigin :: Show Origin where
show Argv = "Argv"
show Environment = "Environment"
show Default = "Default"
show Empty = "Empty"

instance eqOrigin :: Eq Origin where
eq Argv Argv = true
eq Environment Environment = true
eq Default Default = true
eq Empty Empty = true
eq _ _ = false

instance ordOrigin :: Ord Origin where
compare = compare `on` weight
7 changes: 4 additions & 3 deletions src/Language/Docopt/ParserGen.purs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ import Language.Docopt.Env (Env) as D
import Language.Docopt.ParserGen.Token (PositionedToken(..), Token(..),
getSource, prettyPrintToken,
unPositionedToken) as G
import Language.Docopt.ParserGen.Parser (Parser, genUsageParser) as G
import Language.Docopt.ParserGen.Parser (Parser, genUsageParser,
RichValue(..), unRichValue,
from, initialState, ValueMapping()) as G
import Language.Docopt.ParserGen.Lexer (lex) as G
import Language.Docopt.ParserGen.ValueMapping (ValueMapping) as G

type Result = Tuple D.Branch (List G.ValueMapping)

Expand All @@ -40,7 +41,7 @@ runParser :: D.Env -- ^ the user input
-> Either P.ParseError Result -- ^ the parsed output
runParser env argv p = do
toks <- G.lex (toList argv)
evalState (runReaderT (go toks p) env) 0
evalState (runReaderT (go toks p) env) G.initialState
where go i = P.runParserT (P.PState { input: i
, position: P.initialPos
})
Expand Down
Loading