Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
gargantext-ihaskell
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
gargantext-ihaskell
Commits
10991eb1
Commit
10991eb1
authored
Dec 16, 2014
by
Razzi Abuissa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement pragma handling
parent
1c3d12c5
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
88 additions
and
46 deletions
+88
-46
Parser.hs
ghc-parser/generic-src/Language/Haskell/GHC/Parser.hs
+35
-26
Evaluate.hs
src/IHaskell/Eval/Evaluate.hs
+6
-3
Parser.hs
src/IHaskell/Eval/Parser.hs
+42
-12
Util.hs
src/IHaskell/Eval/Util.hs
+5
-5
No files found.
ghc-parser/generic-src/Language/Haskell/GHC/Parser.hs
View file @
10991eb1
...
...
@@ -67,7 +67,7 @@ data ParseOutput a
-- | Store locations along with a value.
data
Located
a
=
Located
{
line
::
LineNumber
,
-- Where this element is located.
unloc
::
a
-- Located element.
unloc
::
a
-- Located element.
}
deriving
(
Eq
,
Show
,
Functor
)
...
...
@@ -101,17 +101,17 @@ runParser flags (Parser parserType parser) str =
toParseOut
$
unP
parser
parseState
where
toParseOut
::
ParseResult
a
->
ParseOutput
a
toParseOut
(
PFailed
span
@
(
RealSrcSpan
realSpan
)
err
)
=
toParseOut
(
PFailed
span
@
(
RealSrcSpan
realSpan
)
err
)
=
let
errMsg
=
printErrorBag
$
unitBag
$
mkPlainErrMsg
flags
span
err
line
=
srcLocLine
$
realSrcSpanStart
realSpan
col
=
srcLocCol
$
realSrcSpanStart
realSpan
in
Failure
errMsg
$
Loc
line
col
toParseOut
(
PFailed
span
err
)
=
toParseOut
(
PFailed
span
err
)
=
let
errMsg
=
printErrorBag
$
unitBag
$
mkPlainErrMsg
flags
span
err
in
Failure
errMsg
$
Loc
0
0
toParseOut
(
POk
parseState
result
)
=
toParseOut
(
POk
parseState
result
)
=
let
parseEnd
=
realSrcSpanStart
$
last_loc
parseState
endLine
=
srcLocLine
parseEnd
endCol
=
srcLocCol
parseEnd
...
...
@@ -126,7 +126,7 @@ runParser flags (Parser parserType parser) str =
-- | Split a string at a given line and column. The column is included in
-- the second part of the split.
splitAtLoc
::
LineNumber
->
ColumnNumber
->
String
->
(
String
,
String
)
splitAtLoc
line
col
string
=
splitAtLoc
line
col
string
=
if
line
>
length
(
lines
string
)
then
(
string
,
""
)
else
(
before
,
after
)
...
...
@@ -145,7 +145,7 @@ joinLines = intercalate "\n"
-- | Split an input string into chunks based on indentation.
-- A chunk is a line and all lines immediately following that are indented
-- beyond the indentation of the first line. This parses Haskell layout
-- rules properly, and allows using multiline expressions via indentation.
-- rules properly, and allows using multiline expressions via indentation.
layoutChunks
::
String
->
[
Located
String
]
layoutChunks
=
go
1
where
...
...
@@ -164,16 +164,16 @@ layoutChunks = go 1
layoutLines
_
[]
=
[]
-- Use the indent of the first line to find the end of the first block.
layoutLines
lineIdx
all
@
(
firstLine
:
rest
)
=
layoutLines
lineIdx
all
@
(
firstLine
:
rest
)
=
let
firstIndent
=
indentLevel
firstLine
blockEnded
line
=
indentLevel
line
<=
firstIndent
in
case
findIndex
blockEnded
rest
of
-- If the first block doesn't end, return the whole string, since
-- that just means the block takes up the entire string.
-- that just means the block takes up the entire string.
Nothing
->
[
Located
lineIdx
$
intercalate
"
\n
"
all
]
-- We found the end of the block. Split this bit out and recurse.
Just
idx
->
Just
idx
->
let
(
before
,
after
)
=
splitAt
idx
rest
in
Located
lineIdx
(
joinLines
$
firstLine
:
before
)
:
go
(
lineIdx
+
idx
+
1
)
(
joinLines
after
)
...
...
@@ -183,7 +183,7 @@ layoutChunks = go 1
-- Count a tab as two spaces.
indentLevel
(
'
\t
'
:
str
)
=
2
+
indentLevel
str
-- Count empty lines as a large indent level, so they're always with the previous expression.
indentLevel
""
=
100000
...
...
@@ -192,7 +192,7 @@ layoutChunks = go 1
-- | Drop comments from Haskell source.
-- Simply gets rid of them, does not replace them in any way.
removeComments
::
String
->
String
removeComments
=
removeOneLineComments
.
removeMultilineComments
0
removeComments
=
removeOneLineComments
.
removeMultilineComments
0
0
where
removeOneLineComments
str
=
case
str
of
...
...
@@ -200,7 +200,7 @@ removeComments = removeOneLineComments . removeMultilineComments 0
':'
:
'!'
:
remaining
->
":!"
++
takeLine
remaining
++
dropLine
remaining
-- Handle strings.
'"'
:
remaining
->
'"'
:
remaining
->
let
quoted
=
takeString
remaining
len
=
length
quoted
in
'"'
:
quoted
++
removeOneLineComments
(
drop
len
remaining
)
...
...
@@ -211,31 +211,40 @@ removeComments = removeOneLineComments . removeMultilineComments 0
where
dropLine
=
removeOneLineComments
.
dropWhile
(
/=
'
\n
'
)
removeMultilineComments
nesting
str
=
removeMultilineComments
nesting
pragmaNesting
str
=
case
str
of
-- Don't remove comments after cmd directives
':'
:
'!'
:
remaining
->
":!"
++
takeLine
remaining
++
removeMultilineComments
nesting
(
dropWhile
(
/=
'
\n
'
)
remaining
)
removeMultilineComments
nesting
pragmaNesting
(
dropWhile
(
/=
'
\n
'
)
remaining
)
-- Handle strings.
'"'
:
remaining
->
'"'
:
remaining
->
if
nesting
==
0
then
then
let
quoted
=
takeString
remaining
len
=
length
quoted
in
'"'
:
quoted
++
removeMultilineComments
nesting
(
drop
len
remaining
)
'"'
:
quoted
++
removeMultilineComments
nesting
pragmaNesting
(
drop
len
remaining
)
else
removeMultilineComments
nesting
remaining
'{'
:
'-'
:
remaining
->
removeMultilineComments
(
nesting
+
1
)
remaining
'-'
:
'}'
:
remaining
->
removeMultilineComments
nesting
pragmaNesting
remaining
'{'
:
'-'
:
'#'
:
remaining
->
if
nesting
==
0
then
"{-#"
++
removeMultilineComments
nesting
(
pragmaNesting
+
1
)
remaining
else
removeMultilineComments
nesting
pragmaNesting
remaining
'#'
:
'-'
:
'}'
:
remaining
->
if
nesting
==
0
then
if
pragmaNesting
>
0
then
'#'
:
'-'
:
'}'
:
removeMultilineComments
nesting
(
pragmaNesting
-
1
)
remaining
else
'#'
:
'-'
:
'}'
:
removeMultilineComments
nesting
pragmaNesting
remaining
else
removeMultilineComments
nesting
pragmaNesting
remaining
'{'
:
'-'
:
remaining
->
removeMultilineComments
(
nesting
+
1
)
pragmaNesting
remaining
'-'
:
'}'
:
remaining
->
if
nesting
>
0
then
removeMultilineComments
(
nesting
-
1
)
remaining
else
'-'
:
'}'
:
removeMultilineComments
nesting
remaining
x
:
xs
->
then
removeMultilineComments
(
nesting
-
1
)
pragmaNesting
remaining
else
'-'
:
'}'
:
removeMultilineComments
nesting
pragmaNesting
remaining
x
:
xs
->
if
nesting
>
0
then
removeMultilineComments
nesting
xs
else
x
:
removeMultilineComments
nesting
xs
then
removeMultilineComments
nesting
pragmaNesting
xs
else
x
:
removeMultilineComments
nesting
pragmaNesting
xs
[]
->
[]
takeLine
=
takeWhile
(
/=
'
\n
'
)
...
...
src/IHaskell/Eval/Evaluate.hs
View file @
10991eb1
...
...
@@ -259,7 +259,7 @@ evaluate kernelState code output = do
-- Merge them with normal display outputs.
dispsIO
<-
extractValue
"IHaskell.Display.displayFromChan"
dispsMay
<-
liftIO
dispsIO
let
result
=
let
result
=
case
dispsMay
of
Nothing
->
evalResult
evalOut
Just
disps
->
evalResult
evalOut
<>
disps
...
...
@@ -416,7 +416,7 @@ evalCommand output (Directive SetDynFlag flags) state =
-- For -XNoImplicitPrelude, remove the Prelude import.
-- For -XImplicitPrelude, add it back in.
case
flag
of
"-XNoImplicitPrelude"
->
"-XNoImplicitPrelude"
->
evalImport
"import qualified Prelude as Prelude"
"-XImplicitPrelude"
->
do
importDecl
<-
parseImportDecl
"import Prelude"
...
...
@@ -882,6 +882,9 @@ evalCommand _ (ParseError loc err) state = do
evalComms
=
[]
}
evalCommand
output
(
Pragma
pragmas
)
state
=
do
write
$
"Got pragmas "
++
show
pragmas
evalCommand
output
(
Directive
SetExtension
$
unwords
pragmas
)
state
hoogleResults
::
KernelState
->
[
Hoogle
.
HoogleResult
]
->
EvalOut
hoogleResults
state
results
=
EvalOut
{
...
...
@@ -987,7 +990,7 @@ keepingItVariable act = do
var
name
=
name
++
rand
goStmt
s
=
runStmt
s
RunToCompletion
itVariable
=
var
"it_var_temp_"
goStmt
$
printf
"let %s = it"
itVariable
val
<-
act
goStmt
$
printf
"let it = %s"
itVariable
...
...
src/IHaskell/Eval/Parser.hs
View file @
10991eb1
...
...
@@ -48,6 +48,7 @@ data CodeBlock
|
Directive
DirectiveType
String
-- ^ An IHaskell directive.
|
Module
String
-- ^ A full Haskell module, to be compiled and loaded.
|
ParseError
StringLoc
ErrMsg
-- ^ An error indicating that parsing the code block failed.
|
Pragma
[
String
]
-- ^ A list of GHC pragmas (from a {-# LANGUAGE ... #-} block)
deriving
(
Show
,
Eq
)
-- | Directive types. Each directive is associated with a string in the
...
...
@@ -86,10 +87,11 @@ parseString codeString = do
return
result
where
parseChunk
::
GhcMonad
m
=>
String
->
LineNumber
->
m
(
Located
CodeBlock
)
parseChunk
chunk
line
=
Located
line
<$>
if
isDirective
chunk
then
return
$
parseDirective
chunk
line
else
parseCodeChunk
chunk
line
parseChunk
chunk
line
|
isDirective
chunk
=
return
$
Located
line
$
parseDirective
chunk
line
|
isPragma
chunk
=
return
$
Located
line
$
parsePragma
chunk
line
|
otherwise
=
Located
line
<$>
parseCodeChunk
chunk
line
processChunks
::
GhcMonad
m
=>
[
Located
CodeBlock
]
->
[
Located
String
]
->
m
[
Located
CodeBlock
]
processChunks
accum
remaining
=
...
...
@@ -100,25 +102,39 @@ parseString codeString = do
-- If we have more remaining, parse the current chunk and recurse.
Located
line
chunk
:
remaining
->
do
block
<-
parseChunk
chunk
line
activate
Parsing
Extensions
$
unloc
block
activateExtensions
$
unloc
block
processChunks
(
block
:
accum
)
remaining
-- Test w
i
ther a given chunk is a directive.
-- Test w
he
ther a given chunk is a directive.
isDirective
::
String
->
Bool
isDirective
=
startswith
":"
.
strip
-- Test if a chunk is a pragma.
isPragma
::
String
->
Bool
isPragma
=
startswith
"{-#"
.
strip
-- Number of lines in this string.
nlines
::
String
->
Int
nlines
=
length
.
lines
activate
Parsing
Extensions
::
GhcMonad
m
=>
CodeBlock
->
m
()
activate
Parsing
Extensions
(
Directive
SetExtension
ext
)
=
void
$
setExtension
ext
activate
Parsing
Extensions
(
Directive
SetDynFlag
flags
)
=
activateExtensions
::
GhcMonad
m
=>
CodeBlock
->
m
()
activateExtensions
(
Directive
SetExtension
ext
)
=
void
$
setExtension
ext
activateExtensions
(
Directive
SetDynFlag
flags
)
=
case
stripPrefix
"-X"
flags
of
Just
ext
->
void
$
setExtension
ext
Nothing
->
return
()
activateParsingExtensions
_
=
return
()
activateExtensions
(
Pragma
extensions
)
=
void
$
setAll
extensions
where
setAll
::
GhcMonad
m
=>
[
String
]
->
m
(
Maybe
String
)
setAll
(
ext
:
extensions
)
=
do
err
<-
setExtension
ext
case
err
of
Nothing
->
setAll
extensions
Just
err
->
return
$
Just
err
setAll
[]
=
return
Nothing
activateExtensions
_
=
return
()
-- | Parse a single chunk of code, as indicated by the layout of the code.
parseCodeChunk
::
GhcMonad
m
=>
String
->
LineNumber
->
m
CodeBlock
parseCodeChunk
code
startLine
=
do
...
...
@@ -191,11 +207,11 @@ parseCodeChunk code startLine = do
-- signature, which is also joined with the subsequent declarations.
joinFunctions
::
[
Located
CodeBlock
]
->
[
Located
CodeBlock
]
joinFunctions
[]
=
[]
joinFunctions
blocks
=
joinFunctions
blocks
=
if
signatureOrDecl
$
unloc
$
head
blocks
then
Located
lnum
(
conjoin
$
map
unloc
decls
)
:
joinFunctions
rest
else
head
blocks
:
joinFunctions
(
tail
blocks
)
where
where
decls
=
takeWhile
(
signatureOrDecl
.
unloc
)
blocks
rest
=
drop
(
length
decls
)
blocks
lnum
=
line
$
head
decls
...
...
@@ -211,6 +227,20 @@ joinFunctions blocks =
conjoin
::
[
CodeBlock
]
->
CodeBlock
conjoin
=
Declaration
.
intercalate
"
\n
"
.
map
str
-- | Parse a pragma of the form {-# LANGUAGE ... #-}
parsePragma
::
String
-- ^ Pragma string.
->
Int
-- ^ Line number at which the directive appears.
->
CodeBlock
-- ^ Pragma code block or a parse error.
parsePragma
(
'{'
:
'-'
:
'#'
:
pragma
)
line
=
Pragma
$
extractPragma
pragma
where
extractPragma
::
String
->
[
String
]
-- | After removing commas, extract words until a # is reached
extractPragma
pragmas
=
case
(
words
$
takeWhile
(
/=
'#'
)
$
filter
(
/=
','
)
pragmas
)
of
[]
->
[]
x
:
xs
->
xs
-- remove the first word (such as LANGUAGE)
-- | Parse a directive of the form :directiveName.
parseDirective
::
String
-- ^ Directive string.
->
Int
-- ^ Line number at which the directive appears.
...
...
src/IHaskell/Eval/Util.hs
View file @
10991eb1
...
...
@@ -52,7 +52,7 @@ data ExtFlag
-- If no such extension exist, yield @Nothing@.
extensionFlag
::
String
-- Extension name, such as @"DataKinds"@
->
Maybe
ExtFlag
extensionFlag
ext
=
extensionFlag
ext
=
case
find
(
flagMatches
ext
)
xFlags
of
Just
(
_
,
flag
,
_
)
->
Just
$
SetFlag
flag
-- If it doesn't match an extension name, try matching against
...
...
@@ -68,7 +68,7 @@ extensionFlag ext =
-- Check if a FlagSpec matches "No<ExtensionName>".
-- In that case, we disable the extension.
flagMatchesNo
ext
(
name
,
_
,
_
)
=
ext
==
"No"
++
name
flagMatchesNo
ext
(
name
,
_
,
_
)
=
ext
==
"No"
++
name
-- | Set an extension and update flags.
-- Return @Nothing@ on success. On failure, return an error message.
...
...
@@ -78,7 +78,7 @@ setExtension ext = do
case
extensionFlag
ext
of
Nothing
->
return
$
Just
$
"Could not parse extension name: "
++
ext
Just
flag
->
do
setSessionDynFlags
$
setSessionDynFlags
$
case
flag
of
SetFlag
ghcFlag
->
xopt_set
flags
ghcFlag
UnsetFlag
ghcFlag
->
xopt_unset
flags
ghcFlag
...
...
@@ -101,7 +101,7 @@ setFlags ext = do
-- Create the parse errors.
let
noParseErrs
=
map
((
"Could not parse: "
++
)
.
unLoc
)
unrecognized
allWarns
=
map
unLoc
warnings
++
allWarns
=
map
unLoc
warnings
++
[
"-package not supported yet"
|
packageFlags
flags
/=
packageFlags
flags'
]
warnErrs
=
map
(
"Warning: "
++
)
allWarns
return
$
noParseErrs
++
warnErrs
...
...
@@ -178,7 +178,7 @@ evalImport imports = do
-- Check whether an import is the same as another import (same module).
importOf
::
ImportDecl
RdrName
->
InteractiveImport
->
Bool
importOf
_
(
IIModule
_
)
=
False
importOf
imp
(
IIDecl
decl
)
=
importOf
imp
(
IIDecl
decl
)
=
((
==
)
`
on
`
(
unLoc
.
ideclName
))
decl
imp
&&
not
(
ideclQualified
decl
)
-- Check whether an import is an *implicit* import of something.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment