MatrixAI / Architect

Programming Language for Type Safe Composition of Distributed Infrastructure
Apache License 2.0
1 stars 0 forks source link

Reserved identifiers #17

Open CMCDragonkai opened 6 years ago

CMCDragonkai commented 6 years ago

Parsing reserved identifiers follows a standard pattern.

Basically to parse an identifier, you always check if the identifier is a reserved identifier, and if so you disallow.

A reserved identifier is always a keyword then a conditional. That conditional can be a whitelist or blacklist. It can either say, that these are the things allowed after the keyword, or it can say these things are not allowed after the keyword.

The point is to disambiguate between let from letx.

Hnix uses:

reservedEnd :: Char -> Bool
reservedEnd x = isSpace x ||
    x == '{' || x == '(' || x == '[' ||
    x == '}' || x == ')' || x == ']' ||
    x == ';' || x == ':' || x == '.' ||
    x == '"' || x == '\'' || x == ','

reserved :: Text -> Parser ()
reserved n = lexeme $ try $
    string n *> lookAhead (void (satisfy reservedEnd) <|> eof)

I decided to simplify to just:

reserved :: Text -> Parser ()
reserved i = (lexeme . MP.try) $
  MPC.string i *> MP.lookAhead reservedAfter
  where
    reservedAfter = MPC.space1 <|> lineComment <|> blockComment <|> MP.eof

This ensures that a reserved identifier is a keyword with some sort of space \t \v ... etc the comments and EOF.

Hopefully the above works.