Skip to content

Commit

Permalink
Fail on name clashes with units and functions, fixes #29
Browse files Browse the repository at this point in the history
  • Loading branch information
sharkdp committed Mar 22, 2017
1 parent 5580021 commit bc90b9b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
23 changes: 19 additions & 4 deletions src/Insect/Parser.purs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ import Quantities (DerivedUnit, atto, bit, byte, centi, day, deci, degree, exa,
mole, kelvin, candela)

import Data.Array (some, fromFoldable)
import Data.Either (Either)
import Data.Either (Either(..))
import Data.Foldable (foldr)
import Data.Foldable as F
import Data.List (List, many, init, last)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.NonEmpty (NonEmpty, (:|), foldl1)
import Data.String (fromCharArray, singleton)
import Data.Tuple (Tuple(..))
import Global (readFloat, isFinite)

import Text.Parsing.Parser (ParserT, Parser, ParseError, runParser, fail)
Expand Down Expand Up @@ -368,19 +369,33 @@ command =
) <* eof

-- | Parse a variable assignment like `x = 3m*pi`
assignment P Statement
assignment P (Tuple String Expression)
assignment = do
whiteSpace
var ← token.identifier
reservedOp "="
value ← expression
pure $ Assignment var value
pure $ Tuple var value

-- | Try to parse the identifier as a unit, and fail if it succeeds.
checkIdentifier Tuple String Expression P Statement
checkIdentifier (Tuple var value) =
case runParser var (derivedUnit <* eof) of
Right _ →
fail $ "The identifier '" <> var <> "' is reserved for a physical unit"
Left _ →
case runParser var (funcName <* eof) of
Right _ →
fail $ "The identifier '" <> var <> "' is reserved for a " <>
"mathematical function"
Left _ →
pure $ Assignment var value

-- | Parse a statement in the Insect language.
statement P Statement
statement =
(Command <$> command)
<|> try assignment
<|> (try assignment >>= checkIdentifier)
<|> (Expression <$> fullExpression)

-- | Run the Insect-parser on a `String` input.
Expand Down
8 changes: 7 additions & 1 deletion test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import Quantities ((./), (.*), milli, nano, meter, inch, hour, minute, kilo,
mile, gram, second, deci, tera, hertz, degree, radian)

import Insect.Language (Func(..), BinOp(..), Expression(..), Statement(..))
import Insect.Parser (Dictionary(..), DictEntry(..), (==>), siPrefixDict,
import Insect.Parser (Dictionary(..), DictEntry, (==>), siPrefixDict,
normalUnitDict, imperialUnitDict, parseInsect)
import Insect.Environment (Environment, initialEnvironment)
import Insect (repl)
Expand Down Expand Up @@ -514,6 +514,12 @@ main = runTest do
shouldFail "3=5"
shouldFail "x="

test "Reserved names" do
shouldFail "m=2" -- 'm' is reserved unit
shouldFail "meter=2" -- 'meter' is a reserved unit
shouldFail "list=4" -- 'list' is a reserved keyword
shouldFail "sin=3" -- 'sin is a reserved keyword

let expectOutput' = expectOutput initialEnvironment

suite "Integration" do
Expand Down

0 comments on commit bc90b9b

Please sign in to comment.