Commit 3c418b99 authored by Kenton Varda's avatar Kenton Varda

Max field number warning.

parent 897276d9
...@@ -93,6 +93,7 @@ token = keyword ...@@ -93,6 +93,7 @@ token = keyword
<|> liftM (const Period) (symbol ".") <|> liftM (const Period) (symbol ".")
<|> liftM (const EqualsSign) (symbol "=") <|> liftM (const EqualsSign) (symbol "=")
<|> liftM (const MinusSign) (symbol "-") <|> liftM (const MinusSign) (symbol "-")
<|> liftM (const ExclamationPoint) (symbol "!")
<?> "token" <?> "token"
locatedToken = located token locatedToken = located token
......
...@@ -24,8 +24,11 @@ ...@@ -24,8 +24,11 @@
module Parser (parseFile) where module Parser (parseFile) where
import Text.Parsec hiding (tokens) import Text.Parsec hiding (tokens)
import Text.Parsec.Error(newErrorMessage, Message(Message))
import Text.Printf(printf)
import Token import Token
import Grammar import Grammar
import Semantics(maxFieldNumber, maxMethodNumber)
import Lexer (lexer) import Lexer (lexer)
import Control.Monad.Identity import Control.Monad.Identity
...@@ -43,6 +46,7 @@ tokenErrorString Colon = "\":\"" ...@@ -43,6 +46,7 @@ tokenErrorString Colon = "\":\""
tokenErrorString Period = "\".\"" tokenErrorString Period = "\".\""
tokenErrorString EqualsSign = "\"=\"" tokenErrorString EqualsSign = "\"=\""
tokenErrorString MinusSign = "\"-\"" tokenErrorString MinusSign = "\"-\""
tokenErrorString ExclamationPoint = "\"!\""
tokenErrorString InKeyword = "keyword \"in\"" tokenErrorString InKeyword = "keyword \"in\""
tokenErrorString OfKeyword = "keyword \"of\"" tokenErrorString OfKeyword = "keyword \"of\""
tokenErrorString AsKeyword = "keyword \"as\"" tokenErrorString AsKeyword = "keyword \"as\""
...@@ -84,6 +88,7 @@ colon = tokenParser (matchSimpleToken Colon) <?> "\":\"" ...@@ -84,6 +88,7 @@ colon = tokenParser (matchSimpleToken Colon) <?> "\":\""
period = tokenParser (matchSimpleToken Period) <?> "\".\"" period = tokenParser (matchSimpleToken Period) <?> "\".\""
equalsSign = tokenParser (matchSimpleToken EqualsSign) <?> "\"=\"" equalsSign = tokenParser (matchSimpleToken EqualsSign) <?> "\"=\""
minusSign = tokenParser (matchSimpleToken MinusSign) <?> "\"=\"" minusSign = tokenParser (matchSimpleToken MinusSign) <?> "\"=\""
exclamationPoint = tokenParser (matchSimpleToken ExclamationPoint) <?> "\"!\""
inKeyword = tokenParser (matchSimpleToken InKeyword) <?> "\"in\"" inKeyword = tokenParser (matchSimpleToken InKeyword) <?> "\"in\""
importKeyword = tokenParser (matchSimpleToken ImportKeyword) <?> "\"import\"" importKeyword = tokenParser (matchSimpleToken ImportKeyword) <?> "\"import\""
usingKeyword = tokenParser (matchSimpleToken UsingKeyword) <?> "\"using\"" usingKeyword = tokenParser (matchSimpleToken UsingKeyword) <?> "\"using\""
...@@ -118,11 +123,21 @@ typeExpression = do ...@@ -118,11 +123,21 @@ typeExpression = do
suffixes <- option [] (parenthesizedList typeExpression) suffixes <- option [] (parenthesizedList typeExpression)
return (TypeExpression name suffixes) return (TypeExpression name suffixes)
nameWithOrdinal :: TokenParser (Located String, Located Integer) nameWithOrdinal :: Integer -> TokenParser (Located String, Located Integer)
nameWithOrdinal = do nameWithOrdinal maxNumber = do
name <- located identifier name <- located identifier
atSign atSign
ordinal <- located literalInt ordinal <- located literalInt
if locatedValue ordinal > maxNumber - 32
then exclamationPoint
<|> failNonFatal (locatedPos ordinal)
(printf "%d is nearing maximum of %d. Be sure to plan for future extensibility \
\before you run out of numbers, e.g. by declaring a new nested type which \
\can hold future declarations. To acknowledge this warning, add an \
\exclamation point after the number, i.e.: %s@%d!"
(locatedValue ordinal) maxNumber (locatedValue name)
(locatedValue ordinal))
else optional exclamationPoint
return (name, ordinal) return (name, ordinal)
topLine :: Maybe [Located Statement] -> TokenParser Declaration topLine :: Maybe [Located Statement] -> TokenParser Declaration
...@@ -182,7 +197,7 @@ structLine (Just statements) = typeDecl statements <|> unionDecl statements <|> ...@@ -182,7 +197,7 @@ structLine (Just statements) = typeDecl statements <|> unionDecl statements <|>
unionDecl statements = do unionDecl statements = do
unionKeyword unionKeyword
(name, ordinal) <- nameWithOrdinal (name, ordinal) <- nameWithOrdinal maxFieldNumber
children <- parseBlock unionLine statements children <- parseBlock unionLine statements
return (UnionDecl name ordinal children) return (UnionDecl name ordinal children)
...@@ -191,7 +206,7 @@ unionLine Nothing = optionDecl <|> fieldDecl [] ...@@ -191,7 +206,7 @@ unionLine Nothing = optionDecl <|> fieldDecl []
unionLine (Just statements) = fieldDecl statements unionLine (Just statements) = fieldDecl statements
fieldDecl statements = do fieldDecl statements = do
(name, ordinal) <- nameWithOrdinal (name, ordinal) <- nameWithOrdinal maxFieldNumber
union <- optionMaybe (inKeyword >> located identifier) union <- optionMaybe (inKeyword >> located identifier)
colon colon
t <- typeExpression t <- typeExpression
...@@ -232,7 +247,7 @@ interfaceLine Nothing = optionDecl <|> constantDecl <|> methodDecl [] ...@@ -232,7 +247,7 @@ interfaceLine Nothing = optionDecl <|> constantDecl <|> methodDecl []
interfaceLine (Just statements) = typeDecl statements <|> methodDecl statements interfaceLine (Just statements) = typeDecl statements <|> methodDecl statements
methodDecl statements = do methodDecl statements = do
(name, ordinal) <- nameWithOrdinal (name, ordinal) <- nameWithOrdinal maxMethodNumber
params <- parenthesizedList paramDecl params <- parenthesizedList paramDecl
colon colon
t <- typeExpression t <- typeExpression
...@@ -261,6 +276,10 @@ extractErrors :: Either ParseError (a, [ParseError]) -> [ParseError] ...@@ -261,6 +276,10 @@ extractErrors :: Either ParseError (a, [ParseError]) -> [ParseError]
extractErrors (Left err) = [err] extractErrors (Left err) = [err]
extractErrors (Right (_, errors)) = errors extractErrors (Right (_, errors)) = errors
failNonFatal :: SourcePos -> String -> TokenParser ()
failNonFatal pos msg = modifyState (newError:) where
newError = newErrorMessage (Message msg) pos
parseList parser items = finish where parseList parser items = finish where
results = map (parseCollectingErrors parser) items results = map (parseCollectingErrors parser) items
finish = do finish = do
......
...@@ -33,7 +33,8 @@ import Text.Printf(printf) ...@@ -33,7 +33,8 @@ import Text.Printf(printf)
import Control.Monad(join) import Control.Monad(join)
import Util(delimit) import Util(delimit)
maxFieldNumber = 255 maxFieldNumber = 255 :: Integer
maxMethodNumber = 65535 :: Integer
type ByteString = [Word8] type ByteString = [Word8]
......
...@@ -48,6 +48,7 @@ data Token = Identifier String ...@@ -48,6 +48,7 @@ data Token = Identifier String
| Period | Period
| EqualsSign | EqualsSign
| MinusSign | MinusSign
| ExclamationPoint
| InKeyword | InKeyword
| OfKeyword | OfKeyword
| AsKeyword | AsKeyword
......
Markdown is supported
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