| 1 | {-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances -cpp #-} |
|---|
| 2 | {-! global : YAML_Pos, Perl6Class, MooseClass !-} |
|---|
| 3 | |
|---|
| 4 | {-| Capture-enabled "new" Pugs AST |
|---|
| 5 | -} |
|---|
| 6 | |
|---|
| 7 | module Pugs.Exp where |
|---|
| 8 | |
|---|
| 9 | import Pugs.Pretty |
|---|
| 10 | import Text.PrettyPrint |
|---|
| 11 | import Pugs.Internals |
|---|
| 12 | import Pugs.Val |
|---|
| 13 | import Pugs.Types (Var) |
|---|
| 14 | import qualified Pugs.AST.Internals (Exp) |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | type ExpVar = Var |
|---|
| 18 | type ExpVal = Val |
|---|
| 19 | type ExpCapt = Capt Exp |
|---|
| 20 | |
|---|
| 21 | newtype ExpEmeritus = MkExpEmeritus { ee :: Pugs.AST.Internals.Exp } |
|---|
| 22 | |
|---|
| 23 | instance Eq ExpEmeritus where _ == _ = True |
|---|
| 24 | instance Ord ExpEmeritus where compare _ _ = EQ |
|---|
| 25 | instance Show ExpEmeritus where show _ = "<Exp.Emeritus>" |
|---|
| 26 | |
|---|
| 27 | -- | AST for an expression. |
|---|
| 28 | data Exp |
|---|
| 29 | = ENoop -- ^ No-op |
|---|
| 30 | | EVar ExpVar -- ^ Variable |
|---|
| 31 | | EVal ExpVal -- ^ Value |
|---|
| 32 | | EDeref ExpVar -- ^ Dereference |
|---|
| 33 | | EBind Exp Exp -- ^ Bind, i.e., := |
|---|
| 34 | | EAssign Exp Exp -- ^ Assignment, = |
|---|
| 35 | | EControl ExpControl -- ^ Control structure, e.g. if, while |
|---|
| 36 | | EFlatten [Exp] -- ^ Wrapper for expressions forced into |
|---|
| 37 | -- slurpy context |
|---|
| 38 | | EE ExpEmeritus |
|---|
| 39 | deriving (Show, Eq, Ord, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 40 | |
|---|
| 41 | prettyExp :: Exp -> Doc |
|---|
| 42 | prettyExp (EE e) = formatQuite (ee e) |
|---|
| 43 | prettyExp exp = text (show exp) |
|---|
| 44 | |
|---|
| 45 | |
|---|
| 46 | -- | Control statement, such as "if". |
|---|
| 47 | data ExpControl |
|---|
| 48 | = CCall ID ExpCapt -- ^ lookup a routine, call it |
|---|
| 49 | | CCallDyn Exp ExpCapt -- ^ call with a dynamically calculated name |
|---|
| 50 | | CApply Exp ExpCapt -- ^ apply a Code without lookup |
|---|
| 51 | | CCond Exp Code -- ^ 2 if 1 |
|---|
| 52 | | CTrenaryCond Exp Code Code -- ^ 1 ?? 2 !! 3 |
|---|
| 53 | | CCondBlock (Exp, Code) [(Exp, Code)] (Maybe Code) |
|---|
| 54 | -- ^ if 1 { 2 } else { 3 } or in general, |
|---|
| 55 | -- if 1 { 2 } elsif 3 { 4 } elsif 5 { 6 } 7 |
|---|
| 56 | -- ^ &statement_control:<if> |
|---|
| 57 | | CGoto ID -- ^ &statement_control:<goto> |
|---|
| 58 | | CWhile Exp Code -- ^ &statement_control:<while> |
|---|
| 59 | | CGiven Exp Code -- ^ given |
|---|
| 60 | | CWhen Exp Code -- ^ when |
|---|
| 61 | | CForeign -- ^ &statement_control:<mycontrol> |
|---|
| 62 | deriving (Show, Eq, Ord, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 63 | |
|---|
| 64 | -- | AST for a statement. The top level of an AST is a list of Stmt. |
|---|
| 65 | data Stmt = MkStmt |
|---|
| 66 | { label :: Maybe ID |
|---|
| 67 | , pragmas :: Table |
|---|
| 68 | , expression :: Exp |
|---|
| 69 | } deriving (Show, Eq, Ord, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 70 | |
|---|
| 71 | -- | Carry over last pragmas and create a new statement out of an expression |
|---|
| 72 | nextStmt :: Stmt -> Exp -> Stmt |
|---|
| 73 | nextStmt MkStmt{ pragmas=prag } exp = MkStmt{ label=Nothing, pragmas=prag, expression=exp } |
|---|