Skip to content

Commit 8a70729

Browse files
committed
wip
1 parent e1a7fe8 commit 8a70729

File tree

4 files changed

+100
-72
lines changed

4 files changed

+100
-72
lines changed

plutus-core/plutus-core/src/PlutusCore/Parser/Builtin.hs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import Data.Text qualified as T
2525
import Data.Text.Internal.Read (hexDigitToInt)
2626
import Data.Vector.Strict (Vector)
2727
import Data.Vector.Strict qualified as Vector
28-
import Text.Megaparsec (customFailure, getSourcePos, takeWhileP)
28+
import Debug.Trace
29+
import Text.Megaparsec (customFailure, getSourcePos, label, takeWhileP)
2930
import Text.Megaparsec.Char (char, hexDigitChar, string)
3031
import Text.Megaparsec.Char.Lexer qualified as Lex
3132

@@ -185,12 +186,15 @@ constantOf expectParens uni =
185186
constant :: Parser (Some (ValueOf DefaultUni))
186187
constant = do
187188
-- Parse the type tag.
189+
-- Provide a clearer error message when the type name is invalid.
190+
-- After 'con', a type name is expected (e.g., 'bool', 'integer', 'bytestring').
188191
SomeTypeIn (Kinded uni) <- defaultUni
189192
-- Check it's of kind @*@, because a constant that we're about to parse can only be of type of
190193
-- kind @*@.
191194
Refl <- reoption $ checkStar uni
192195
-- Parse the constant of the type represented by the type tag.
193-
someValueOf uni <$> constantOf ExpectParensYes uni
196+
x <- someValueOf uni <$> constantOf ExpectParensYes uni
197+
return x
194198

195199
data ExpectParens
196200
= ExpectParensYes

plutus-core/plutus-core/src/PlutusCore/Parser/Type.hs

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ import Control.Monad
2424
import Data.ByteString (ByteString)
2525
import Data.Text (Text)
2626
import Data.Vector.Strict qualified as Strict
27+
import Debug.Trace
28+
import Text.Megaparsec (getOffset, getSourcePos, registerFancyFailure)
2729
import Text.Megaparsec hiding (ParseError, State, many, parse, some)
30+
import Text.Megaparsec.Error (ErrorFancy (ErrorFail), ErrorItem (Tokens))
2831

2932
{-| A PLC @Type@ to be parsed. ATM the parser only works
3033
for types in the @DefaultUni@ with @DefaultFun@. -}
@@ -135,25 +138,24 @@ i.e. parse into @Tree Text@ and do the kind checking afterwards, but given that
135138
to do the kind checking of builtins regardless (even for UPLC), we don't win much by deferring
136139
doing it. -}
137140
defaultUni :: Parser (SomeTypeIn (Kinded DefaultUni))
138-
defaultUni =
139-
choice $
140-
map
141-
try
142-
[ trailingWhitespace (inParens defaultUniApplication)
143-
, someType @_ @Integer <$ symbol "integer"
144-
, someType @_ @ByteString <$ symbol "bytestring"
145-
, someType @_ @Text <$ symbol "string"
146-
, someType @_ @() <$ symbol "unit"
147-
, someType @_ @Bool <$ symbol "bool"
148-
, someType @_ @[] <$ symbol "list"
149-
, someType @_ @Strict.Vector <$ symbol "array"
150-
, someType @_ @(,) <$ symbol "pair"
151-
, someType @_ @Data <$ symbol "data"
152-
, someType @_ @BLS12_381.G1.Element <$ symbol "bls12_381_G1_element"
153-
, someType @_ @BLS12_381.G2.Element <$ symbol "bls12_381_G2_element"
154-
, someType @_ @BLS12_381.Pairing.MlResult <$ symbol "bls12_381_mlresult"
155-
, someType @_ @Value <$ symbol "value"
156-
]
141+
defaultUni = do
142+
choice
143+
[ try $ trailingWhitespace (inParens defaultUniApplication)
144+
, try $ someType @_ @Integer <$ symbol "integer"
145+
, try $ someType @_ @ByteString <$ symbol "bytestring"
146+
, try $ someType @_ @Text <$ symbol "string"
147+
, try $ someType @_ @() <$ symbol "unit"
148+
, try $ someType @_ @Bool <$ symbol "bool"
149+
, try $ someType @_ @[] <$ symbol "list"
150+
, try $ someType @_ @Strict.Vector <$ symbol "array"
151+
, try $ someType @_ @(,) <$ symbol "pair"
152+
, try $ someType @_ @Data <$ symbol "data"
153+
, try $ someType @_ @BLS12_381.G1.Element <$ symbol "bls12_381_G1_element"
154+
, try $ someType @_ @BLS12_381.G2.Element <$ symbol "bls12_381_G2_element"
155+
, try $ someType @_ @BLS12_381.Pairing.MlResult <$ symbol "bls12_381_mlresult"
156+
, try $ someType @_ @Value <$ symbol "value"
157+
, fail "Unknown type, expected one of: bool, integer, bytestring, string, unit, list, array, pair, data, value, bls12_381_G1_element, bls12_381_G2_element, bls12_381_mlresult, or a type application in parens"
158+
]
157159

158160
tyName :: Parser TyName
159161
tyName = TyName <$> name

plutus-core/untyped-plutus-core/src/UntypedPlutusCore/Parser.hs

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -42,50 +42,50 @@ import PlutusCore.Version
4242
-- | A parsable UPLC term.
4343
type PTerm = UPLC.Term PLC.Name PLC.DefaultUni PLC.DefaultFun SrcSpan
4444

45-
conTerm :: Parser PTerm
46-
conTerm = withSpan $ \sp ->
45+
conTerm :: SrcSpan -> Parser PTerm
46+
conTerm sp =
4747
UPLC.Constant sp <$> constant
4848

49-
builtinTerm :: Parser PTerm
50-
builtinTerm = withSpan $ \sp ->
49+
builtinTerm :: SrcSpan -> Parser PTerm
50+
builtinTerm sp =
5151
UPLC.Builtin sp <$> builtinFunction
5252

5353
varTerm :: Parser PTerm
54-
varTerm = withSpan $ \sp ->
55-
UPLC.Var sp <$> name
54+
varTerm =
55+
withSpan $ \sp -> UPLC.Var sp <$> name
5656

57-
lamTerm :: Parser PTerm
58-
lamTerm = withSpan $ \sp ->
57+
lamTerm :: SrcSpan -> Parser PTerm
58+
lamTerm sp =
5959
UPLC.LamAbs sp <$> (trailingWhitespace name) <*> term
6060

61-
appTerm :: Parser PTerm
62-
appTerm = withSpan $ \sp ->
61+
appTerm :: SrcSpan -> Parser PTerm
62+
appTerm sp =
6363
-- TODO: should not use the same `sp` for all arguments.
6464
mkIterApp <$> term <*> (fmap (sp,) <$> some term)
6565

66-
delayTerm :: Parser PTerm
67-
delayTerm = withSpan $ \sp ->
66+
delayTerm :: SrcSpan -> Parser PTerm
67+
delayTerm sp =
6868
UPLC.Delay sp <$> term
6969

70-
forceTerm :: Parser PTerm
71-
forceTerm = withSpan $ \sp ->
70+
forceTerm :: SrcSpan -> Parser PTerm
71+
forceTerm sp =
7272
UPLC.Force sp <$> term
7373

74-
errorTerm :: Parser PTerm
75-
errorTerm = withSpan $ \sp ->
74+
errorTerm :: SrcSpan -> Parser PTerm
75+
errorTerm sp =
7676
return (UPLC.Error sp)
7777

78-
constrTerm :: Parser PTerm
79-
constrTerm = withSpan $ \sp -> do
78+
constrTerm :: SrcSpan -> Parser PTerm
79+
constrTerm sp = do
8080
let maxTag = fromIntegral (maxBound :: Word64)
8181
tag :: Integer <- lexeme Lex.decimal
8282
args <- many term
8383
whenVersion (\v -> v < plcVersion110) $ fail "'constr' is not allowed before version 1.1.0"
8484
when (tag > maxTag) $ fail "constr tag too large: must be a legal Word64 value"
8585
pure $ UPLC.Constr sp (fromIntegral tag) args
8686

87-
caseTerm :: Parser PTerm
88-
caseTerm = withSpan $ \sp -> do
87+
caseTerm :: SrcSpan -> Parser PTerm
88+
caseTerm sp = do
8989
res <- UPLC.Case sp <$> term <*> (V.fromList <$> many term)
9090
whenVersion (\v -> v < plcVersion110) $ fail "'case' is not allowed before version 1.1.0"
9191
pure res
@@ -102,28 +102,30 @@ term =
102102
where
103103
tryAppTerm :: Parser PTerm
104104
tryAppTerm = do
105-
_ <- try (symbol "[")
106-
t <- appTerm
107-
_ <- char ']'
108-
return t
105+
withSpan $ \sp -> do
106+
_ <- try (symbol "[")
107+
t <- appTerm sp
108+
_ <- symbol "]"
109+
return t
109110

110111
tryTermInParens :: Parser PTerm
111-
tryTermInParens = do
112-
_ <- try (symbol "(")
113-
t <-
114-
choice
115-
[ try (symbol "builtin") *> builtinTerm
116-
, try (symbol "lam") *> lamTerm
117-
, try (symbol "constr") *> constrTerm -- "constr" must come before "con"
118-
, try (symbol "con") *> conTerm
119-
, try (symbol "delay") *> delayTerm
120-
, try (symbol "force") *> forceTerm
121-
, try (symbol "error") *> errorTerm
122-
, try (symbol "constr") *> constrTerm
123-
, try (symbol "case") *> caseTerm
124-
]
125-
_ <- char ')'
126-
return t
112+
tryTermInParens =
113+
withSpan $ \sp -> do
114+
_ <- try (symbol "(")
115+
t <-
116+
choice
117+
[ try (symbol "builtin") *> builtinTerm sp
118+
, try (symbol "lam") *> lamTerm sp
119+
, try (symbol "constr") *> constrTerm sp -- "constr" must come before "con"
120+
, try (symbol "con") *> conTerm sp
121+
, try (symbol "delay") *> delayTerm sp
122+
, try (symbol "force") *> forceTerm sp
123+
, try (symbol "error") *> errorTerm sp
124+
, try (symbol "constr") *> constrTerm sp
125+
, try (symbol "case") *> caseTerm sp
126+
]
127+
_ <- symbol ")"
128+
return t
127129

128130
-- | Parser for UPLC programs.
129131
program :: Parser (UPLC.Program PLC.Name PLC.DefaultUni PLC.DefaultFun SrcSpan)

plutus-core/untyped-plutus-core/testlib/Generators/Spec.hs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import Control.Lens (view)
1111
import Control.Monad (unless)
1212
import Data.Text (Text)
1313
import Data.Text qualified as T
14-
import Hedgehog (annotate, annotateShow, failure, property, tripping, (===))
14+
import Debug.Trace
15+
import Hedgehog (Gen, Property, annotate, annotateShow, failure, property, tripping, (===))
1516
import Hedgehog.Gen qualified as Gen
1617
import Hedgehog.Range qualified as Range
1718
import PlutusCore (Name)
@@ -58,20 +59,39 @@ propTermSrcSpan = testPropertyNamed
5859
"propTermSrcSpan"
5960
. property
6061
$ do
61-
code <-
62+
code <- genRandomCode
63+
annotateShow code
64+
let (endingLine, endingCol) = getCodeEndingLineAndCol code
65+
result <- parseTermWithTrailingSpace code
66+
case result of
67+
Right term -> do
68+
let (endingLine', endingCol') = getTermEndingLineAndCol term
69+
annotateShow (endingLine', endingCol', "asdasdasdasdasdasdasdasdasdasdasd")
70+
(endingLine', endingCol') === (endingLine, endingCol + 1)
71+
Left err ->
72+
handleParseError err
73+
where
74+
genRandomCode =
6275
display
6376
<$> forAllPretty
6477
( view progTerm
6578
<$> runAstGen (regenConstantsUntil isSerialisable =<< genProgram @DefaultFun)
6679
)
67-
annotateShow code
68-
let (endingLine, endingCol) = length &&& T.length . last $ T.lines code
69-
trailingSpaces <- forAllPretty $ Gen.text (Range.linear 0 10) (Gen.element [' ', '\n'])
70-
case runQuoteT . parseTerm $ code <> trailingSpaces of
71-
Right parsed ->
72-
let sp = termAnn parsed
73-
in (srcSpanELine sp, srcSpanECol sp) === (endingLine, endingCol)
74-
Left err -> annotate (display err) >> failure
80+
81+
getCodeEndingLineAndCol code = (length &&& T.length . last) (T.lines code)
82+
83+
parseTermWithTrailingSpace code = do
84+
trailingSpaces <- genTrailingSpaces
85+
return $ runQuoteT $ parseTerm (code <> trailingSpaces)
86+
87+
genTrailingSpaces = forAllPretty $ Gen.text (Range.linear 0 10) (Gen.element [' ', '\n'])
88+
89+
getTermEndingLineAndCol term = do
90+
let sp = termAnn term
91+
let x = (srcSpanELine sp, srcSpanECol sp)
92+
traceShow (term, sp, x) $ x
93+
94+
handleParseError err = annotate (display err) >> failure
7595

7696
propUnit :: TestTree
7797
propUnit =
@@ -153,7 +173,7 @@ propTypeNameTypoErrorLocation =
153173
, "[ (builtin integerToByteString) (con boot True) (con integer 0) (con integer 712372356934756347862573452345342345) ]"
154174
, ")"
155175
]
156-
expectedErrorParts = ["unexpected", "expecting", "bool"]
176+
expectedErrorParts = ["Unknown type", "expected", "bool"]
157177
case runQuoteT (parseProgram code) of
158178
Right _ -> error "Expected parse error, but parsing succeeded"
159179
Left (ParseErrorB errBundle) -> do

0 commit comments

Comments
 (0)