1 {-# LANGUAGE FlexibleInstances #-}
3 {-# LANGUAGE NoMonomorphismRestriction #-}
4 {-# LANGUAGE OverloadedStrings #-}
5 {-# LANGUAGE TypeFamilies #-}
6 {-# LANGUAGE UndecidableInstances #-}
7 module Language.Symantic.Typing.Syntax where
9 import Data.Text (Text)
10 import qualified Data.Text as Text
11 import qualified Data.List as List
16 ast_lexem :: node -> Lexem node
17 ast_nodes :: node -> [node]
20 -- | Attach a location.
24 instance Functor (At ast) where
25 fmap f (At ast a) = At ast (f a)
28 = Error_Syntax_more_arguments_needed (At ast Int)
29 -- ^ Total minimal number of arguments.
30 | Error_Syntax_read (At ast Text)
33 class Lift_Error_Syntax err where
34 lift_error_syntax :: Error_Syntax ast -> err ast
37 :: ( AST ast, Lexem ast ~ Text
38 , Read ty, Lift_Error_Syntax err )
40 -> (ty -> Either (err ast) ret)
41 -> Either (err ast) ret
42 from_lex msg ast_x k =
43 from_ast0 ast_x $ \lex_x as ->
44 case reads $ Text.unpack lex_x of
45 [(x, "")] | null as -> k x
46 _ -> Left $ lift_error_syntax $
51 -> (Lexem ast -> [ast] -> Either (err ast) ret)
52 -> Either (err ast) ret
55 as -> k (ast_lexem ast) as
57 :: (AST ast, Lift_Error_Syntax err) => ast
58 -> (ast -> [ast] -> Either (err ast) ret)
59 -> Either (err ast) ret
63 Left $ lift_error_syntax $
64 Error_Syntax_more_arguments_needed $
68 :: (AST ast, Lift_Error_Syntax err) => ast
69 -> (ast -> ast -> [ast] -> Either (err ast) ret)
70 -> Either (err ast) ret
73 a1:a2:as -> k a1 a2 as
75 Left $ lift_error_syntax $
76 Error_Syntax_more_arguments_needed $
79 :: (AST ast, Lift_Error_Syntax err) => ast
80 -> (ast -> ast -> ast -> [ast] -> Either (err ast) ret)
81 -> Either (err ast) ret
84 a1:a2:a3:as -> k a1 a2 a3 as
86 Left $ lift_error_syntax $
87 Error_Syntax_more_arguments_needed $
94 instance AST (Syntax a) where
95 type Lexem (Syntax a) = a
96 ast_lexem (Syntax x _) = x
97 ast_nodes (Syntax _ ns) = ns
99 -- | Custom 'Show' instance a little bit more readable
100 -- than the automatically derived one.
101 instance Show (Syntax Text) where
102 showsPrec p ast@(Syntax name args) =
103 let n = Text.unpack name in
105 Syntax _ [] -> showString n
107 showParen (p <= prec_arrow) $
108 showString (""++n++" ") .
109 showsPrec prec_arrow a
110 Syntax "(->)" [a, b] ->
111 showParen (p <= prec_arrow) $
112 showsPrec prec_arrow a .
113 showString (" -> ") .
114 showsPrec (prec_arrow + 1) b
115 Syntax "\\" [var, ty, body] ->
116 showParen (p <= prec_lambda) $
118 showsPrec prec_lambda var .
120 showsPrec prec_lambda ty .
121 showString (") -> ") .
122 showsPrec prec_lambda body
123 Syntax " " [fun, arg] ->
124 showParen (p <= prec_app) $
125 showsPrec prec_dollar fun .
127 showsPrec prec_dollar arg
128 Syntax "$" [fun, arg] ->
129 showParen (p <= prec_dollar) $
130 showsPrec prec_dollar fun .
132 showsPrec prec_dollar arg
134 showParen (p <= prec_app) $
137 showString (List.unwords $ show <$> args)