Skip to content

Commit

Permalink
[ refactor ] S-Exp protocols to depend on fewer Idris modules (#3060)
Browse files Browse the repository at this point in the history
  • Loading branch information
ohad authored Aug 31, 2023
1 parent e321458 commit d3dc9b7
Show file tree
Hide file tree
Showing 7 changed files with 307 additions and 186 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ idris2docs_venv
/docs/build

/libs/**/build
/ipkg/build

/tests/**/build
/tests/**/output*
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@

* Fixed a bug that caused `f` to sometimes be replaced by `fx` after matching `fx = f x`.

* Refactor the idris2protocols package to depend on fewer Idris2 modules.
We can now export the package independently.
To avoid confusing tooling about which `.ipkg` to use, the
package file is under the newly added `ipkg` sub-directory.

### Library changes

#### Prelude
Expand Down
1 change: 1 addition & 0 deletions idris2api.ipkg
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ modules =
Parser.Package,
Parser.Source,
Parser.Support,
Parser.Support.Escaping,
Parser.Unlit,

Parser.Lexer.Common,
Expand Down
30 changes: 17 additions & 13 deletions idris2protocols.ipkg.hide → ipkg/idris2protocols.ipkg
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,37 @@ version = 0.0.1

modules
= Protocol.Hex
-- , Protocol.IDE
, Protocol.IDE
, Protocol.IDE.Command
, Protocol.IDE.Decoration
, Protocol.SExp
-- TODO: want to add this module, but the parser library introduces
-- dependencies on core idris
-- , Protocol.SExp.Parser
, Libraries.Data.Span
, Libraries.Text.Lexer
, Libraries.Control.Delayed
, Libraries.Text.Bounded
, Libraries.Text.Lexer.Core
, Libraries.Text.Quantity
, Libraries.Text.Token
, Libraries.Text.Lexer.Tokenizer
, Libraries.Text.Lexer
, Parser.Lexer.Common
, Libraries.Data.Span
, Libraries.Data.String.Extra
, Libraries.Text.PrettyPrint.Prettyprinter.Doc
, Libraries.Text.PrettyPrint.Prettyprinter.Symbols
, Libraries.Text.PrettyPrint.Prettyprinter.Util
, Libraries.Text.PrettyPrint.Prettyprinter.Render.String
, Libraries.Text.PrettyPrint.Prettyprinter
, Libraries.Text.Lexer.Tokenizer
, Libraries.Text.Parser.Core
, Libraries.Text.Parser
, Parser.Rule.Source
-- , Protocol.IDE.FileContext
-- , Protocol.IDE.Formatting
-- , Protocol.IDE.Holes
-- , Protocol.IDE.Result
-- , Protocol.IDE.Highlight
, Parser.Support.Escaping
, Protocol.SExp.Parser
, Protocol.IDE.Decoration
, Protocol.IDE.Command
, Protocol.Hex
, Protocol.IDE.FileContext
, Protocol.IDE.Formatting
, Protocol.IDE.Holes
, Protocol.IDE.Result
, Protocol.IDE.Highlight

--depends =

Expand Down
141 changes: 1 addition & 140 deletions src/Parser/Support.idr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Core.TT
import Core.Core
import Data.List
import Parser.Unlit
import public Parser.Support.Escaping

%default total

Expand Down Expand Up @@ -39,146 +40,6 @@ fromParsingErrors origin = ParseFail . (map fromError)
else MkFC origin start end
in (fc, msg +> '.')

export
hex : Char -> Maybe Int
hex '0' = Just 0
hex '1' = Just 1
hex '2' = Just 2
hex '3' = Just 3
hex '4' = Just 4
hex '5' = Just 5
hex '6' = Just 6
hex '7' = Just 7
hex '8' = Just 8
hex '9' = Just 9
hex 'a' = Just 10
hex 'b' = Just 11
hex 'c' = Just 12
hex 'd' = Just 13
hex 'e' = Just 14
hex 'f' = Just 15
hex _ = Nothing

export
dec : Char -> Maybe Int
dec '0' = Just 0
dec '1' = Just 1
dec '2' = Just 2
dec '3' = Just 3
dec '4' = Just 4
dec '5' = Just 5
dec '6' = Just 6
dec '7' = Just 7
dec '8' = Just 8
dec '9' = Just 9
dec _ = Nothing

export
oct : Char -> Maybe Int
oct '0' = Just 0
oct '1' = Just 1
oct '2' = Just 2
oct '3' = Just 3
oct '4' = Just 4
oct '5' = Just 5
oct '6' = Just 6
oct '7' = Just 7
oct _ = Nothing

export
getEsc : String -> Maybe Char
getEsc "NUL" = Just '\NUL'
getEsc "SOH" = Just '\SOH'
getEsc "STX" = Just '\STX'
getEsc "ETX" = Just '\ETX'
getEsc "EOT" = Just '\EOT'
getEsc "ENQ" = Just '\ENQ'
getEsc "ACK" = Just '\ACK'
getEsc "BEL" = Just '\BEL'
getEsc "BS" = Just '\BS'
getEsc "HT" = Just '\HT'
getEsc "LF" = Just '\LF'
getEsc "VT" = Just '\VT'
getEsc "FF" = Just '\FF'
getEsc "CR" = Just '\CR'
getEsc "SO" = Just '\SO'
getEsc "SI" = Just '\SI'
getEsc "DLE" = Just '\DLE'
getEsc "DC1" = Just '\DC1'
getEsc "DC2" = Just '\DC2'
getEsc "DC3" = Just '\DC3'
getEsc "DC4" = Just '\DC4'
getEsc "NAK" = Just '\NAK'
getEsc "SYN" = Just '\SYN'
getEsc "ETB" = Just '\ETB'
getEsc "CAN" = Just '\CAN'
getEsc "EM" = Just '\EM'
getEsc "SUB" = Just '\SUB'
getEsc "ESC" = Just '\ESC'
getEsc "FS" = Just '\FS'
getEsc "GS" = Just '\GS'
getEsc "RS" = Just '\RS'
getEsc "US" = Just '\US'
getEsc "SP" = Just '\SP'
getEsc "DEL" = Just '\DEL'
getEsc str = Nothing

unescape' : List Char -> List Char -> Maybe (List Char)
unescape' _ [] = pure []
unescape' escapeChars (x::xs)
= assert_total $ if escapeChars `isPrefixOf` (x::xs)
then case drop (length escapeChars) (x::xs) of
('\\' :: xs) => pure $ '\\' :: !(unescape' escapeChars xs)
('\n' :: xs) => pure !(unescape' escapeChars xs)
('&' :: xs) => pure !(unescape' escapeChars xs)
('a' :: xs) => pure $ '\a' :: !(unescape' escapeChars xs)
('b' :: xs) => pure $ '\b' :: !(unescape' escapeChars xs)
('f' :: xs) => pure $ '\f' :: !(unescape' escapeChars xs)
('n' :: xs) => pure $ '\n' :: !(unescape' escapeChars xs)
('r' :: xs) => pure $ '\r' :: !(unescape' escapeChars xs)
('t' :: xs) => pure $ '\t' :: !(unescape' escapeChars xs)
('v' :: xs) => pure $ '\v' :: !(unescape' escapeChars xs)
('\'' :: xs) => pure $ '\'' :: !(unescape' escapeChars xs)
('"' :: xs) => pure $ '"' :: !(unescape' escapeChars xs)
('x' :: xs) => case span isHexDigit xs of
([], rest) => unescape' escapeChars rest
(ds, rest) => pure $ cast !(toHex 1 (reverse ds)) ::
!(unescape' escapeChars rest)
('o' :: xs) => case span isOctDigit xs of
([], rest) => unescape' escapeChars rest
(ds, rest) => pure $ cast !(toOct 1 (reverse ds)) ::
!(unescape' escapeChars rest)
xs => case span isDigit xs of
([], (a :: b :: c :: rest)) =>
case getEsc (fastPack [a, b, c]) of
Just v => Just (v :: !(unescape' escapeChars rest))
Nothing => case getEsc (fastPack [a, b]) of
Just v => Just (v :: !(unescape' escapeChars (c :: rest)))
Nothing => unescape' escapeChars xs
([], (a :: b :: [])) =>
case getEsc (fastPack [a, b]) of
Just v => Just (v :: [])
Nothing => unescape' escapeChars xs
([], rest) => unescape' escapeChars rest
(ds, rest) => Just $ cast (cast {to=Int} (fastPack ds)) ::
!(unescape' escapeChars rest)
else Just $ x :: !(unescape' escapeChars xs)
where
toHex : Int -> List Char -> Maybe Int
toHex _ [] = Just 0
toHex m (d :: ds)
= pure $ !(hex (toLower d)) * m + !(toHex (m*16) ds)

toOct : Int -> List Char -> Maybe Int
toOct _ [] = Just 0
toOct m (d :: ds)
= pure $ !(oct (toLower d)) * m + !(toOct (m*8) ds)

export
unescape : Nat -> String -> Maybe String
unescape hashtag x = let escapeChars = '\\' :: replicate hashtag '#' in
fastPack <$> (unescape' escapeChars (unpack x))

export
getCharLit : String -> Maybe Char
getCharLit str
Expand Down
144 changes: 144 additions & 0 deletions src/Parser/Support/Escaping.idr
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
module Parser.Support.Escaping

import Libraries.Data.String.Extra
import Data.List

export
hex : Char -> Maybe Int
hex '0' = Just 0
hex '1' = Just 1
hex '2' = Just 2
hex '3' = Just 3
hex '4' = Just 4
hex '5' = Just 5
hex '6' = Just 6
hex '7' = Just 7
hex '8' = Just 8
hex '9' = Just 9
hex 'a' = Just 10
hex 'b' = Just 11
hex 'c' = Just 12
hex 'd' = Just 13
hex 'e' = Just 14
hex 'f' = Just 15
hex _ = Nothing

export
dec : Char -> Maybe Int
dec '0' = Just 0
dec '1' = Just 1
dec '2' = Just 2
dec '3' = Just 3
dec '4' = Just 4
dec '5' = Just 5
dec '6' = Just 6
dec '7' = Just 7
dec '8' = Just 8
dec '9' = Just 9
dec _ = Nothing

export
oct : Char -> Maybe Int
oct '0' = Just 0
oct '1' = Just 1
oct '2' = Just 2
oct '3' = Just 3
oct '4' = Just 4
oct '5' = Just 5
oct '6' = Just 6
oct '7' = Just 7
oct _ = Nothing

export
getEsc : String -> Maybe Char
getEsc "NUL" = Just '\NUL'
getEsc "SOH" = Just '\SOH'
getEsc "STX" = Just '\STX'
getEsc "ETX" = Just '\ETX'
getEsc "EOT" = Just '\EOT'
getEsc "ENQ" = Just '\ENQ'
getEsc "ACK" = Just '\ACK'
getEsc "BEL" = Just '\BEL'
getEsc "BS" = Just '\BS'
getEsc "HT" = Just '\HT'
getEsc "LF" = Just '\LF'
getEsc "VT" = Just '\VT'
getEsc "FF" = Just '\FF'
getEsc "CR" = Just '\CR'
getEsc "SO" = Just '\SO'
getEsc "SI" = Just '\SI'
getEsc "DLE" = Just '\DLE'
getEsc "DC1" = Just '\DC1'
getEsc "DC2" = Just '\DC2'
getEsc "DC3" = Just '\DC3'
getEsc "DC4" = Just '\DC4'
getEsc "NAK" = Just '\NAK'
getEsc "SYN" = Just '\SYN'
getEsc "ETB" = Just '\ETB'
getEsc "CAN" = Just '\CAN'
getEsc "EM" = Just '\EM'
getEsc "SUB" = Just '\SUB'
getEsc "ESC" = Just '\ESC'
getEsc "FS" = Just '\FS'
getEsc "GS" = Just '\GS'
getEsc "RS" = Just '\RS'
getEsc "US" = Just '\US'
getEsc "SP" = Just '\SP'
getEsc "DEL" = Just '\DEL'
getEsc str = Nothing

unescape' : List Char -> List Char -> Maybe (List Char)
unescape' _ [] = pure []
unescape' escapeChars (x::xs)
= assert_total $ if escapeChars `isPrefixOf` (x::xs)
then case drop (length escapeChars) (x::xs) of
('\\' :: xs) => pure $ '\\' :: !(unescape' escapeChars xs)
('\n' :: xs) => pure !(unescape' escapeChars xs)
('&' :: xs) => pure !(unescape' escapeChars xs)
('a' :: xs) => pure $ '\a' :: !(unescape' escapeChars xs)
('b' :: xs) => pure $ '\b' :: !(unescape' escapeChars xs)
('f' :: xs) => pure $ '\f' :: !(unescape' escapeChars xs)
('n' :: xs) => pure $ '\n' :: !(unescape' escapeChars xs)
('r' :: xs) => pure $ '\r' :: !(unescape' escapeChars xs)
('t' :: xs) => pure $ '\t' :: !(unescape' escapeChars xs)
('v' :: xs) => pure $ '\v' :: !(unescape' escapeChars xs)
('\'' :: xs) => pure $ '\'' :: !(unescape' escapeChars xs)
('"' :: xs) => pure $ '"' :: !(unescape' escapeChars xs)
('x' :: xs) => case span isHexDigit xs of
([], rest) => unescape' escapeChars rest
(ds, rest) => pure $ cast !(toHex 1 (reverse ds)) ::
!(unescape' escapeChars rest)
('o' :: xs) => case span isOctDigit xs of
([], rest) => unescape' escapeChars rest
(ds, rest) => pure $ cast !(toOct 1 (reverse ds)) ::
!(unescape' escapeChars rest)
xs => case span isDigit xs of
([], (a :: b :: c :: rest)) =>
case getEsc (fastPack [a, b, c]) of
Just v => Just (v :: !(unescape' escapeChars rest))
Nothing => case getEsc (fastPack [a, b]) of
Just v => Just (v :: !(unescape' escapeChars (c :: rest)))
Nothing => unescape' escapeChars xs
([], (a :: b :: [])) =>
case getEsc (fastPack [a, b]) of
Just v => Just (v :: [])
Nothing => unescape' escapeChars xs
([], rest) => unescape' escapeChars rest
(ds, rest) => Just $ cast (cast {to=Int} (fastPack ds)) ::
!(unescape' escapeChars rest)
else Just $ x :: !(unescape' escapeChars xs)
where
toHex : Int -> List Char -> Maybe Int
toHex _ [] = Just 0
toHex m (d :: ds)
= pure $ !(hex (toLower d)) * m + !(toHex (m*16) ds)

toOct : Int -> List Char -> Maybe Int
toOct _ [] = Just 0
toOct m (d :: ds)
= pure $ !(oct (toLower d)) * m + !(toOct (m*8) ds)

export
unescape : Nat -> String -> Maybe String
unescape hashtag x = let escapeChars = '\\' :: replicate hashtag '#' in
fastPack <$> (unescape' escapeChars (unpack x))
Loading

0 comments on commit d3dc9b7

Please sign in to comment.