| 1 | {-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances -fno-warn-missing-methods -cpp #-} |
|---|
| 2 | {-| |
|---|
| 3 | Perl 6 Values. |
|---|
| 4 | |
|---|
| 5 | > There beryl, pearl, and opal pale, |
|---|
| 6 | > And metal wrought like fishes' mail, |
|---|
| 7 | > Buckler and corslet, axe and sword, |
|---|
| 8 | > And shining spears were laid in hoard... |
|---|
| 9 | -} |
|---|
| 10 | |
|---|
| 11 | module Pugs.Val ( |
|---|
| 12 | module Pugs.Val, |
|---|
| 13 | module Pugs.Val.Code, |
|---|
| 14 | module Pugs.Val.Capture, |
|---|
| 15 | Val, Call, |
|---|
| 16 | ) where |
|---|
| 17 | import Pugs.Class |
|---|
| 18 | import Pugs.Val.Base () |
|---|
| 19 | import Pugs.Val.Code |
|---|
| 20 | import Pugs.Val.Capture |
|---|
| 21 | import Pugs.Internals |
|---|
| 22 | import Text.PrettyPrint |
|---|
| 23 | |
|---|
| 24 | asStr :: Val -> Eval PureStr |
|---|
| 25 | asStr (MkInvocant x _) = return (cast (show x)) |
|---|
| 26 | asBit :: Val -> Eval PureBit |
|---|
| 27 | asBit _ = return (cast True) |
|---|
| 28 | asInt :: Val -> Eval PureInt |
|---|
| 29 | asInt _ = return (cast (0 :: Int)) |
|---|
| 30 | asNum :: Val -> Eval PureNum |
|---|
| 31 | asNum _ = return (cast (0 :: Double)) |
|---|
| 32 | listVal :: Val -> Eval PureList |
|---|
| 33 | listVal = return . (:[]) |
|---|
| 34 | itemVal :: Val -> Eval Val |
|---|
| 35 | itemVal = return |
|---|
| 36 | |
|---|
| 37 | valMeta :: Val -> PureStr |
|---|
| 38 | valMeta _ = cast "Object" |
|---|
| 39 | |
|---|
| 40 | valShow :: Val -> PureStr |
|---|
| 41 | valShow _ = cast "<opaque>" |
|---|
| 42 | |
|---|
| 43 | formatVal :: Val -> Doc |
|---|
| 44 | formatVal (MkInvocant x _) = text (show x) |
|---|
| 45 | |
|---|
| 46 | castVal :: forall a m . (Monad m, Typeable a) => Val -> m a |
|---|
| 47 | castVal (MkInvocant v _) = fromTypeable v |
|---|
| 48 | |
|---|
| 49 | instance ((:>:) PureNum) Rational where cast = NRational |
|---|
| 50 | instance ((:<:) PureNum) Rational where |
|---|
| 51 | castBack (NDouble x) = toRational x |
|---|
| 52 | castBack (NRational x) = x |
|---|
| 53 | instance ((:>:) PureNum) Double where cast = NDouble |
|---|
| 54 | instance ((:<:) PureNum) Double where |
|---|
| 55 | castBack (NDouble x) = x |
|---|
| 56 | castBack (NRational x) = fromRational x |
|---|
| 57 | |
|---|
| 58 | instance ((:>:) PureInt) Integer where cast = IFinite |
|---|
| 59 | instance ((:<:) PureInt) Integer where |
|---|
| 60 | castBack (IFinite i) = i |
|---|
| 61 | castBack INotANumber = error "NaN" |
|---|
| 62 | castBack (IInfinite SPositive) = error "+Infinity" |
|---|
| 63 | castBack (IInfinite SNegative) = error "-Infinity" |
|---|
| 64 | |
|---|
| 65 | instance ((:>:) PureInt) Int where cast = IFinite . toInteger |
|---|
| 66 | instance ((:<:) PureInt) Int where |
|---|
| 67 | castBack (IFinite i) = fromInteger i |
|---|
| 68 | castBack INotANumber = error "NaN" |
|---|
| 69 | castBack (IInfinite SPositive) = error "+Infinity" |
|---|
| 70 | castBack (IInfinite SNegative) = error "-Infinity" |
|---|
| 71 | type PureList = [Val] -- Seq (Either PureSeq PureRange) -- XXX - *very bogus* |
|---|
| 72 | |
|---|
| 73 | newtype PureBit = MkBit Bool |
|---|
| 74 | deriving (Typeable, Show, Eq, Ord, Data, (:>:) Bool, (:<:) Bool) |
|---|
| 75 | |
|---|
| 76 | type PureStr = ByteString |
|---|
| 77 | |
|---|
| 78 | data PureInt |
|---|
| 79 | = IFinite !Integer |
|---|
| 80 | | IInfinite !Sign |
|---|
| 81 | | INotANumber |
|---|
| 82 | deriving (Typeable, Show, Eq, Ord, Data) |
|---|
| 83 | |
|---|
| 84 | data PureNum |
|---|
| 85 | = NDouble !Double -- change to "!NativeDouble" |
|---|
| 86 | | NRational !Rational |
|---|
| 87 | deriving (Typeable, Show, Eq, Ord, Data) |
|---|
| 88 | |
|---|
| 89 | data Sign |
|---|
| 90 | = SPositive |
|---|
| 91 | | SNegative |
|---|
| 92 | deriving (Show, Eq, Ord, Data, Typeable) |
|---|
| 93 | |
|---|
| 94 | -- | L<S02/"Undefined types"> |
|---|
| 95 | data ValUndef |
|---|
| 96 | = UUndef -- ^ "my $x" |
|---|
| 97 | | UWhatever -- ^ "my $x = *" |
|---|
| 98 | | UFailure { f_err :: !ID } -- ^ "my $x = fail 'oops'" |
|---|
| 99 | | UProto { p_meta :: !ID } -- ^ "my $x = Dog" |
|---|
| 100 | deriving (Show, Eq, Ord, Data, Typeable) |
|---|
| 101 | |
|---|
| 102 | instance Boxable ValUndef |
|---|
| 103 | instance Boxable PureInt |
|---|
| 104 | instance Boxable PureNum |
|---|
| 105 | instance Boxable PureSig |
|---|
| 106 | instance Boxable PureBit |
|---|
| 107 | instance Boxable ValCapt |
|---|
| 108 | |
|---|
| 109 | instance Boxable Int |
|---|
| 110 | {- |
|---|
| 111 | module Pugs.Val ( |
|---|
| 112 | IValue(..), Val(..), ValUndef(..), ValNative, P, |
|---|
| 113 | ICoercible(..), WHICH, castVal, formatVal, |
|---|
| 114 | PureBit, PureBool, PureInt, PureNum, PureStr, PureList, itemVal, listVal, |
|---|
| 115 | |
|---|
| 116 | Table, Var(..), |
|---|
| 117 | |
|---|
| 118 | -- From Code |
|---|
| 119 | Sig(..), SigParam(..), ParamAccess(..), ParamDefault(..), |
|---|
| 120 | Capt(..), Feed(..), emptyFeed, Code(..), |
|---|
| 121 | ValCapt, ValFeed, |
|---|
| 122 | ) where |
|---|
| 123 | import Pugs.Internals |
|---|
| 124 | import Pugs.Class |
|---|
| 125 | import GHC.Exts |
|---|
| 126 | import Data.Generics.Basics hiding (cast) |
|---|
| 127 | import qualified Data.Typeable as Typeable |
|---|
| 128 | import qualified Data.ByteString as Buf |
|---|
| 129 | import qualified Data.Map as Map |
|---|
| 130 | import qualified Data.Set as Set |
|---|
| 131 | import Data.Monoid |
|---|
| 132 | |
|---|
| 133 | import Pugs.AST.SIO |
|---|
| 134 | import Pugs.Val.Base |
|---|
| 135 | --import Pugs.Val.Sig |
|---|
| 136 | --import Pugs.Val.Code |
|---|
| 137 | --import Pugs.Exp |
|---|
| 138 | import {-# SOURCE #-} Pugs.Exp |
|---|
| 139 | import qualified Pugs.Types as Types |
|---|
| 140 | import Pugs.Types (Var(..)) |
|---|
| 141 | |
|---|
| 142 | import Text.PrettyPrint -- move to Pugs.Val.Pretty? |
|---|
| 143 | |
|---|
| 144 | -- XXX - Once GHC 6.6 is released with bindists, change #include to .hs-boot! |
|---|
| 145 | #include "Val/Code.hs" |
|---|
| 146 | |
|---|
| 147 | {-| |
|---|
| 148 | |
|---|
| 149 | This module contains the definition of the five variants for a Perl 6 value. |
|---|
| 150 | However, the actual constructors for each variant are abstract, and this module |
|---|
| 151 | does not provide concrete data type definitions beyond those five. |
|---|
| 152 | |
|---|
| 153 | -} |
|---|
| 154 | |
|---|
| 155 | -- | 'Val' represents what an unconstrained scalar container can hold. |
|---|
| 156 | data Val |
|---|
| 157 | = VUndef !ValUndef -- ^ Values that are false on .defined (WHICH = undef) |
|---|
| 158 | | VNative !ValNative -- ^ Values that can fit into an UArray (WHICH = impl.dep.) |
|---|
| 159 | | forall a. Pure a => VPure !a -- ^ Values that are immutable (WHICH = pureId) |
|---|
| 160 | | forall a. Mut a => VMut !a -- ^ In-memory mutable structures (WHICH = memory addr) |
|---|
| 161 | | forall a. Ext a => VExt !a -- ^ Input/Ouput handles (WHICH = memory addr) |
|---|
| 162 | deriving (Typeable) |
|---|
| 163 | |
|---|
| 164 | castVal :: forall a m . (Monad m, Typeable a) => Val -> m a |
|---|
| 165 | --castVal = gmapQi 0 fromTypeable -- when we have 6.6, and can make all Val in Data. |
|---|
| 166 | castVal (VUndef v) = fromTypeable v |
|---|
| 167 | castVal (VNative v) = fromTypeable v |
|---|
| 168 | castVal (VPure v) = fromTypeable v |
|---|
| 169 | castVal (VMut v) = fromTypeable v |
|---|
| 170 | castVal (VExt v) = fromTypeable v |
|---|
| 171 | |
|---|
| 172 | -- | Value view. Contains methods for inspecting values: getting |
|---|
| 173 | -- their metaclass, ids, stringification and so on. |
|---|
| 174 | class ICoercible m a => IValue m a where |
|---|
| 175 | -- | lift an ASTish leaf type to a value. Using this convenience method |
|---|
| 176 | -- you can say "val (NInt 42)" instead of "Val (VNative (NInt 42))". |
|---|
| 177 | val :: a -> Val |
|---|
| 178 | -- | retrieve metaclass instance of a value. |
|---|
| 179 | valMeta :: a -> Class |
|---|
| 180 | valMeta = cast . takeTypeName "" . reverse . show . typeOf |
|---|
| 181 | where |
|---|
| 182 | -- Here we intuit "Str" from "Pugs.Val.Str.PureStr". |
|---|
| 183 | takeTypeName acc [] = acc |
|---|
| 184 | takeTypeName acc (x:xs) |
|---|
| 185 | | isLower x = takeTypeName (x:acc) xs |
|---|
| 186 | | otherwise = x:acc |
|---|
| 187 | -- | Stringification of arbitrary values. |
|---|
| 188 | valShow :: a -> PureStr |
|---|
| 189 | valShow _ = cast "<opaque>" |
|---|
| 190 | -- | Identity. |
|---|
| 191 | valId :: a -> WHICH |
|---|
| 192 | valId x = cast (NUint (W# (unsafeCoerce# x))) |
|---|
| 193 | -- | Comparison. |
|---|
| 194 | valCompare :: a -> a -> Ordering |
|---|
| 195 | valCompare x y = valId x `compare` valId y |
|---|
| 196 | |
|---|
| 197 | instance ICoercible SIO Val where |
|---|
| 198 | -- XXX - have to invent a generic map somehow -- DrIFT anyone? |
|---|
| 199 | asBit VUndef{} = cast False |
|---|
| 200 | asBit (VNative x) = cast $ asBit x |
|---|
| 201 | asBit (VPure x) = cast $ asBit x |
|---|
| 202 | asBit (VMut x) = cast $ asBit x |
|---|
| 203 | asInt (VPure x) = cast $ asInt x |
|---|
| 204 | asNum (VPure x) = cast $ asNum x |
|---|
| 205 | asStr (VPure x) = cast $ asStr x |
|---|
| 206 | asItem = Just . itemVal |
|---|
| 207 | asList = Just . listVal |
|---|
| 208 | asNative (VPure x) = cast $ asNative x |
|---|
| 209 | |
|---|
| 210 | -- evaluate a Val in Item context, a.k.a. rvalue, a.k.a. "is readonly" |
|---|
| 211 | itemVal :: Val -> SIO Val |
|---|
| 212 | itemVal v@(VPure x) = f v x asItem |
|---|
| 213 | itemVal v@(VMut x) = f v x asItem |
|---|
| 214 | itemVal v@(VExt x) = f v x asItem |
|---|
| 215 | itemVal v = return v |
|---|
| 216 | |
|---|
| 217 | -- evaluate a Val in List context, a.k.a. flattening, a.k.a. "is slurpy" |
|---|
| 218 | listVal :: Val -> SIO PureList |
|---|
| 219 | listVal v@(VPure x) = f v x asList |
|---|
| 220 | listVal v@(VMut x) = f v x asList |
|---|
| 221 | listVal v@(VExt x) = f v x asList |
|---|
| 222 | listVal v = cast v |
|---|
| 223 | |
|---|
| 224 | f v x g = maybe (cast v) cast (g x) |
|---|
| 225 | |
|---|
| 226 | instance ((:>:) PureList) Val where |
|---|
| 227 | cast = singleton -- . Left . singleton |
|---|
| 228 | |
|---|
| 229 | instance IValue SIO Val where |
|---|
| 230 | val = id |
|---|
| 231 | valId VUndef{} = cast (NBit False) |
|---|
| 232 | valId (VNative x) = Just x |
|---|
| 233 | valId (VPure x) = valId x |
|---|
| 234 | valId (VMut x) = valId x |
|---|
| 235 | valId (VExt x) = valId x |
|---|
| 236 | valCompare = compare |
|---|
| 237 | valMeta (VUndef x) = cast . show . typeOf $ x |
|---|
| 238 | valMeta (VNative x) = valMeta x |
|---|
| 239 | valMeta (VPure x) = valMeta x |
|---|
| 240 | valMeta (VMut x) = valMeta x |
|---|
| 241 | valMeta (VExt x) = valMeta x |
|---|
| 242 | valShow = cast . show |
|---|
| 243 | |
|---|
| 244 | -- instance Pure PureStr where |
|---|
| 245 | -- pureId x = cast (cast x :: ByteString) |
|---|
| 246 | |
|---|
| 247 | instance ((:>:) WHICH) NativeBuf where |
|---|
| 248 | cast = cast . NBuf |
|---|
| 249 | |
|---|
| 250 | instance ICoercible P ValNative where |
|---|
| 251 | asNative = return . id |
|---|
| 252 | |
|---|
| 253 | instance IValue P ValNative where |
|---|
| 254 | val = VNative |
|---|
| 255 | valMeta NBit{} = cast "bit" |
|---|
| 256 | valMeta NInt{} = cast "int" |
|---|
| 257 | valMeta NUint{} = cast "uint" |
|---|
| 258 | valMeta NBuf{} = cast "buf" |
|---|
| 259 | valMeta NNum{} = cast "num" |
|---|
| 260 | valMeta NComplex{} = cast "complex" |
|---|
| 261 | valCompare = compare |
|---|
| 262 | valShow = cast . show |
|---|
| 263 | valId x = cast x |
|---|
| 264 | |
|---|
| 265 | -- | 'WHICH' is an unique ID that distinguishes two @Val@s of the same type from each other. |
|---|
| 266 | type WHICH = Maybe ValNative |
|---|
| 267 | |
|---|
| 268 | instance ((:>:) WHICH) ValNative where |
|---|
| 269 | cast = Just |
|---|
| 270 | |
|---|
| 271 | -------------------------------------------------------------------------------------- |
|---|
| 272 | |
|---|
| 273 | -- | L<S02/"Undefined types"> |
|---|
| 274 | data ValUndef |
|---|
| 275 | = UUndef -- ^ "my $x" |
|---|
| 276 | | UWhatever -- ^ "my $x = *" |
|---|
| 277 | | UFailure { f_err :: !WHICH } -- ^ "my $x = fail 'oops'" |
|---|
| 278 | | UProto { p_meta :: !WHICH } -- ^ "my $x = Dog" |
|---|
| 279 | deriving (Show, Eq, Ord, Data, Typeable) |
|---|
| 280 | |
|---|
| 281 | -------------------------------------------------------------------------------------- |
|---|
| 282 | -- | Unboxed values. |
|---|
| 283 | data ValNative |
|---|
| 284 | = NBit !NativeBit -- ^ 0 |
|---|
| 285 | | NInt !NativeInt -- ^ -3 |
|---|
| 286 | | NUint !NativeUint -- ^ 7 |
|---|
| 287 | | NBuf !NativeBuf -- ^ (a raw chunk of ints or uints) |
|---|
| 288 | | NNum !NativeNum -- ^ 4.2 |
|---|
| 289 | | NComplex !NativeComplex -- ^ (45 - 9i) |
|---|
| 290 | deriving (Show, Eq, Ord, Data, Typeable) |
|---|
| 291 | |
|---|
| 292 | type NativeBit = Bool |
|---|
| 293 | type NativeInt = Int |
|---|
| 294 | type NativeUint = Word |
|---|
| 295 | type NativeBuf = ByteString |
|---|
| 296 | type NativeNum = Float |
|---|
| 297 | |
|---|
| 298 | -- Haskell's Complex type does not instantiate Ord and Data. |
|---|
| 299 | newtype NativeComplex = MkNComplex { unComplex :: Complex NativeNum } |
|---|
| 300 | deriving (Show, Eq, Typeable) |
|---|
| 301 | instance Ord NativeComplex where |
|---|
| 302 | compare = error "NativeComplex numbers cannot be ordered" |
|---|
| 303 | instance Data NativeComplex where |
|---|
| 304 | -- gunfold = error "gunfold NativeComplex" |
|---|
| 305 | toConstr = error "toConstr NativeComplex" |
|---|
| 306 | dataTypeOf = error "dataTypeOf NativeComplex" |
|---|
| 307 | |
|---|
| 308 | -------------------------------------------------------------------------------------- |
|---|
| 309 | |
|---|
| 310 | -- | L<S02/"Immutable types"> |
|---|
| 311 | |
|---|
| 312 | -- | Pure values need not be in a monad, but we put them in the trivial |
|---|
| 313 | -- Identity so that they are at the same monadic depth as Mut and Ext. |
|---|
| 314 | type P = Identity |
|---|
| 315 | instance Typeable1 P |
|---|
| 316 | |
|---|
| 317 | class (ICoercible P a, Ord a, Show a) => Pure a where |
|---|
| 318 | purePretty :: a -> Doc |
|---|
| 319 | purePretty = text . show |
|---|
| 320 | |
|---|
| 321 | instance (ICoercible P a, Ord a, Show a) => Pure a where {} |
|---|
| 322 | |
|---|
| 323 | liftP :: Monad m => P a -> m a |
|---|
| 324 | liftP = return . runIdentity |
|---|
| 325 | |
|---|
| 326 | instance Pure a => IValue P a where |
|---|
| 327 | val = VPure |
|---|
| 328 | valId = liftP . asNative |
|---|
| 329 | valShow = cast . show |
|---|
| 330 | valCompare = compare |
|---|
| 331 | |
|---|
| 332 | instance Mut a => IValue STM a where |
|---|
| 333 | val = VMut |
|---|
| 334 | |
|---|
| 335 | instance Ext a => IValue SIO a where |
|---|
| 336 | val = VExt |
|---|
| 337 | |
|---|
| 338 | class ICoercible STM a => Mut a where {} |
|---|
| 339 | instance ICoercible STM a => Mut a where {} |
|---|
| 340 | |
|---|
| 341 | class ICoercible SIO a => Ext a where {} |
|---|
| 342 | instance ICoercible SIO a => Ext a where {} |
|---|
| 343 | |
|---|
| 344 | -- type Class = PureStr -- XXX - Wrong |
|---|
| 345 | |
|---|
| 346 | dynEq :: (Typeable a, Typeable b, Eq a) => a -> b -> Bool |
|---|
| 347 | dynEq x y = case Typeable.cast y of |
|---|
| 348 | Just y' -> x == y' |
|---|
| 349 | Nothing -> False |
|---|
| 350 | |
|---|
| 351 | dynCompare :: forall a b ma mb. (IValue ma a, IValue mb b) => a -> b -> Ordering |
|---|
| 352 | dynCompare x y = case Typeable.cast y of |
|---|
| 353 | Just y' -> valCompare x y' |
|---|
| 354 | Nothing -> compare (show $ typeOf x) (show $ typeOf y) |
|---|
| 355 | |
|---|
| 356 | {- |
|---|
| 357 | = PBit !PureBit |
|---|
| 358 | | PInt !PureInt |
|---|
| 359 | | PStr !PureStr |
|---|
| 360 | | PNum !PureNum |
|---|
| 361 | | PComplex !PureComplex |
|---|
| 362 | | PBool !PureBool |
|---|
| 363 | | PException !PureException -- XXX |
|---|
| 364 | | PCode !PureCode |
|---|
| 365 | | PBlock !PureCode -- XXX: or more primitive type? |
|---|
| 366 | | PList !PureList |
|---|
| 367 | | PSeq !PureSeq |
|---|
| 368 | | PRange !PureRange |
|---|
| 369 | | PSet !PureSet |
|---|
| 370 | | PJunc !PureJunc |
|---|
| 371 | | PPair !PurePair |
|---|
| 372 | | PMap !PureMap |
|---|
| 373 | | PSig !PureSig |
|---|
| 374 | | PCap !PureCap |
|---|
| 375 | deriving (Show, Eq, Ord, Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 376 | |
|---|
| 377 | -} |
|---|
| 378 | type PureBool = Bool |
|---|
| 379 | type PureException = () -- XXX *very* bogus |
|---|
| 380 | type PureCode = () -- XXX *very* bogus |
|---|
| 381 | type PureCap = () |
|---|
| 382 | type PureSet = Set Val |
|---|
| 383 | type PureSeq = Seq Val |
|---|
| 384 | type PureComplex = () |
|---|
| 385 | type PureRange = () |
|---|
| 386 | type PureJunc = () |
|---|
| 387 | type PurePair = () |
|---|
| 388 | type PureMap = () |
|---|
| 389 | |
|---|
| 390 | {- |
|---|
| 391 | -------------------------------------------------------------------------------------- |
|---|
| 392 | -- | L<S02/"Mutable types"> minus IO types |
|---|
| 393 | -- Computations on these types take place in the STM monad. |
|---|
| 394 | data ValMut |
|---|
| 395 | = MScalar !MutScalar |
|---|
| 396 | | MArray !MutArray |
|---|
| 397 | | MHash !MutHash |
|---|
| 398 | | MBuf !MutBuf |
|---|
| 399 | | MRoutine !MutRoutine |
|---|
| 400 | | MSub !MutRoutine -- ? |
|---|
| 401 | | MMethod !MutRoutine -- ? |
|---|
| 402 | | MSubmethod !MutRoutine -- ? |
|---|
| 403 | | MMacro -- ??? |
|---|
| 404 | | MRegex !MutVRule -- XXX: maybe move to pure |
|---|
| 405 | | MMatch !MutVMatch |
|---|
| 406 | | MPackage !MutPackage |
|---|
| 407 | | MModule !MutModule |
|---|
| 408 | | MClass !MutClass |
|---|
| 409 | | MRole !MutRole |
|---|
| 410 | | MGrammar !MutGrammar |
|---|
| 411 | | MObject !MutObject -- ? or ObjectId? |
|---|
| 412 | | MForeign !MutDynamic -- ...? |
|---|
| 413 | deriving (Show, Eq, Ord, Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 414 | -} |
|---|
| 415 | |
|---|
| 416 | -------------------------------------------------------------------------------------- |
|---|
| 417 | {- |
|---|
| 418 | -- | Obviously side-effectual types such as file handles. |
|---|
| 419 | -- Computations on these types must take place in the IO monad. |
|---|
| 420 | data ValExt |
|---|
| 421 | = IFile !ExtFile -- ^ File handle |
|---|
| 422 | | ISocket !ExtSocket -- ^ Socket handle |
|---|
| 423 | | IThread !ExtThread -- ^ Thread handle |
|---|
| 424 | | IProcess !ExtProcess -- ^ Process handle |
|---|
| 425 | deriving (Show, Eq, Ord, Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 426 | -} |
|---|
| 427 | |
|---|
| 428 | type ExtFile = () |
|---|
| 429 | type ExtSocket = () |
|---|
| 430 | type ExtThread = () |
|---|
| 431 | type ExtProcess = () |
|---|
| 432 | |
|---|
| 433 | -------------------------------------------------------------------------------------- |
|---|
| 434 | |
|---|
| 435 | -- | General purpose mapping from identifiers to values. |
|---|
| 436 | type Table = Map.Map ID Val |
|---|
| 437 | |
|---|
| 438 | |
|---|
| 439 | {- Pad -} |
|---|
| 440 | {-| |
|---|
| 441 | A 'Pad' keeps track of the names of all currently-bound symbols, and |
|---|
| 442 | associates them with the things they actually represent. |
|---|
| 443 | |
|---|
| 444 | It is represented as a mapping from names to /lists/ of bound items. |
|---|
| 445 | This is to allow for multi subs, because we will need to keep |
|---|
| 446 | /multiple/ subs associated with one symbol. In other cases, the list |
|---|
| 447 | should just contain a single value. See 'Pugs.AST.genSym' and 'Pugs.AST.genMultiSym' for |
|---|
| 448 | more details. |
|---|
| 449 | |
|---|
| 450 | @TVar@ indicates that the mapped-to items are STM transactional variables. |
|---|
| 451 | |
|---|
| 452 | Pads are stored in the current 'Code', and lexical lookups proceed through |
|---|
| 453 | progressively outer scopes until an item is found. For dynamic variables |
|---|
| 454 | (e.g., "our"), the pad holding the items is located in the package. |
|---|
| 455 | -} |
|---|
| 456 | |
|---|
| 457 | newtype Pad = MkPad { padEntries :: Map.Map Var PadEntry } |
|---|
| 458 | deriving (Show, Eq, Ord, Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 459 | |
|---|
| 460 | newtype EntryStorage = MkStorage { s_cell :: TVar Val } |
|---|
| 461 | deriving (Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 462 | instance Show EntryStorage where |
|---|
| 463 | show _ = error "can't show EntryStorage" |
|---|
| 464 | instance Ord EntryStorage where |
|---|
| 465 | compare _ = error "can't compare EntryStorage" |
|---|
| 466 | instance Eq EntryStorage where |
|---|
| 467 | (==) = error "can't equate EntryStorage" |
|---|
| 468 | |
|---|
| 469 | data EntryDeclarator |
|---|
| 470 | = DeclMy |
|---|
| 471 | | DeclOur |
|---|
| 472 | | DeclHas |
|---|
| 473 | | DeclState |
|---|
| 474 | | DeclConstant |
|---|
| 475 | deriving (Show, Eq, Ord, Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 476 | |
|---|
| 477 | data PadEntry = MkEntry |
|---|
| 478 | { e_declarator :: EntryDeclarator -- ^ my etc. |
|---|
| 479 | , e_storage :: EntryStorage -- ^ stored value |
|---|
| 480 | } |
|---|
| 481 | deriving (Show, Eq, Ord, Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 482 | |
|---|
| 483 | -------------------------------------------------------------------------------------- |
|---|
| 484 | |
|---|
| 485 | -- type Var = Types.Var |
|---|
| 486 | {- Variable specification. This belongs in an AST .hs file, not here but until |
|---|
| 487 | - it finds its home we will give it boarding. |
|---|
| 488 | - XXX - Augment Pugs.Types.Var to reason about caller/outer, not here! -} |
|---|
| 489 | |
|---|
| 490 | {- |
|---|
| 491 | data Var |
|---|
| 492 | = VarLexical |
|---|
| 493 | { v_name :: ID |
|---|
| 494 | , v_callerCount :: Int |
|---|
| 495 | , v_outerCount :: Int |
|---|
| 496 | } |
|---|
| 497 | | VarDynamic |
|---|
| 498 | { v_name :: ID |
|---|
| 499 | , v_packageName :: [ID] |
|---|
| 500 | } |
|---|
| 501 | | VarMagic |
|---|
| 502 | { v_magic :: Magic |
|---|
| 503 | } |
|---|
| 504 | deriving (Show, Eq, Ord, Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 505 | -} |
|---|
| 506 | |
|---|
| 507 | data Magic |
|---|
| 508 | = MOS -- ^ $?OS Which os am I compiled for? |
|---|
| 509 | | MOSVer -- ^ $?OSVER Which os version am I compiled for? |
|---|
| 510 | | MPerlVer -- ^ $?PERLVER Which Perl version am I compiled for? |
|---|
| 511 | | MFile -- ^ $?FILE Which file am I in? |
|---|
| 512 | | MLine -- ^ $?LINE Which line am I at? |
|---|
| 513 | | MScalarPackage -- ^ $?PACKAGE Which package am I in? |
|---|
| 514 | | MArrayPackages -- ^ @?PACKAGE Which packages am I in? |
|---|
| 515 | | MScalarModule -- ^ $?MODULE Which module am I in? |
|---|
| 516 | | MArrayModules -- ^ @?MODULE Which modules am I in? |
|---|
| 517 | | MScalarClass -- ^ $?CLASS Which class am I in? (as variable) |
|---|
| 518 | | MArrayClasses -- ^ @?CLASS Which classes am I in? |
|---|
| 519 | | MScalarRole -- ^ $?ROLE Which role am I in? (as variable) |
|---|
| 520 | | MArrayRoles -- ^ @?ROLE Which roles am I in? |
|---|
| 521 | | MScalarGrammar -- ^ $?GRAMMAR Which grammar am I in? |
|---|
| 522 | | MArrayGrammars -- ^ @?GRAMMAR Which grammars am I in? |
|---|
| 523 | | MParser -- ^ $?PARSER Which Perl grammar was used to |
|---|
| 524 | -- ^ parse this statement? |
|---|
| 525 | | MScalarRoutine -- ^ &?ROUTINE Which routine am I in? |
|---|
| 526 | | MArrayRoutines -- ^ @?ROUTINE Which routines am I in? |
|---|
| 527 | | MScalarBlock -- ^ &?BLOCK Which block am I in? |
|---|
| 528 | | MArrayBlocks -- ^ @?BLOCK Which blocks am I in? |
|---|
| 529 | deriving (Show, Eq, Ord, Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} |
|---|
| 530 | |
|---|
| 531 | -------------------------------------------------------------------------------------- |
|---|
| 532 | formatVal :: Val -> Doc |
|---|
| 533 | formatVal (VUndef v) = text $ case v of |
|---|
| 534 | (UUndef) -> "undef" |
|---|
| 535 | (UWhatever) -> "{whatever}" |
|---|
| 536 | (UFailure x) -> "{failure:" ++ (show x) ++ "}" -- what we really want is to port Pretty to fps |
|---|
| 537 | (UProto x) -> "{proto:" ++ (show x) ++ "}" |
|---|
| 538 | formatVal (VNative v) = text $ case v of |
|---|
| 539 | (NBit x) -> if x then "True" else "False" |
|---|
| 540 | (NInt x) -> show x |
|---|
| 541 | (NUint x) -> show x |
|---|
| 542 | (NBuf _) -> "{Buf}" |
|---|
| 543 | (NNum x) -> show x |
|---|
| 544 | (NComplex (MkNComplex x)) -> (show "(") ++ (show $ realPart x) ++ " " ++ |
|---|
| 545 | (if (0 >) (imagPart x) then "- " ++ (show $ 0 - imagPart x) else "+ " ++ (show $ imagPart x)) ++ "*Math::i)" |
|---|
| 546 | formatVal (VPure v) = purePretty v |
|---|
| 547 | formatVal x = text $ show x |
|---|
| 548 | |
|---|
| 549 | -- (NComplex r i(s@i')) -> "(" ++ (show r) ++ " " ++ |
|---|
| 550 | -- (if s == '-' then ("- " ++ show i') else ("+ " ++ show i)) ++ "*i)" |
|---|
| 551 | --formatVal (VPure v) = runIdentity |
|---|
| 552 | -------------------------------------------------------------------------------------- |
|---|
| 553 | |
|---|
| 554 | {-* Generated by DrIFT : Look, but Don't Touch. *-} |
|---|
| 555 | instance Show Val where |
|---|
| 556 | showsPrec d (VUndef aa) = showParen (d >= 10) |
|---|
| 557 | (showString "VUndef" . showChar ' ' . showsPrec 10 aa) |
|---|
| 558 | showsPrec d (VNative aa) = showParen (d >= 10) |
|---|
| 559 | (showString "VNative" . showChar ' ' . showsPrec 10 aa) |
|---|
| 560 | showsPrec d (VPure aa) = showParen (d >= 10) |
|---|
| 561 | (showString "VPure (" . showsPrec 10 aa . showChar ')') |
|---|
| 562 | showsPrec d (VMut aa) = showParen (d >= 10) |
|---|
| 563 | (showString "VMut (" . (cast(valShow aa) ++) . showChar ')') |
|---|
| 564 | showsPrec d (VExt aa) = showParen (d >= 10) |
|---|
| 565 | (showString "VExt (" . (cast(valShow aa) ++) . showChar ')') |
|---|
| 566 | |
|---|
| 567 | instance Eq Val where |
|---|
| 568 | (VUndef aa) == (VUndef aa') = aa == aa' |
|---|
| 569 | (VNative aa) == (VNative aa') = aa == aa' |
|---|
| 570 | (VPure aa) == (VPure aa') = dynEq aa aa' |
|---|
| 571 | (VMut aa) == (VMut aa') = valId aa == valId aa' |
|---|
| 572 | (VExt aa) == (VExt aa') = valId aa == valId aa' |
|---|
| 573 | _ == _ = False |
|---|
| 574 | |
|---|
| 575 | instance Ord Val where |
|---|
| 576 | compare (VUndef aa) (VUndef aa') = compare aa aa' |
|---|
| 577 | compare (VUndef _) (VNative _) = LT |
|---|
| 578 | compare (VUndef _) (VPure _) = LT |
|---|
| 579 | compare (VUndef _) (VMut _) = LT |
|---|
| 580 | compare (VUndef _) (VExt _) = LT |
|---|
| 581 | compare (VNative _) (VUndef _) = GT |
|---|
| 582 | compare (VNative aa) (VNative aa') = compare aa aa' |
|---|
| 583 | compare (VNative _) (VPure _) = LT |
|---|
| 584 | compare (VNative _) (VMut _) = LT |
|---|
| 585 | compare (VNative _) (VExt _) = LT |
|---|
| 586 | compare (VPure _) (VUndef _) = GT |
|---|
| 587 | compare (VPure _) (VNative _) = GT |
|---|
| 588 | compare (VPure aa) (VPure aa') = dynCompare aa aa' |
|---|
| 589 | compare (VPure _) (VMut _) = LT |
|---|
| 590 | compare (VPure _) (VExt _) = LT |
|---|
| 591 | compare (VMut _) (VUndef _) = GT |
|---|
| 592 | compare (VMut _) (VNative _) = GT |
|---|
| 593 | compare (VMut _) (VPure _) = GT |
|---|
| 594 | compare (VMut aa) (VMut aa') = dynCompare aa aa' |
|---|
| 595 | compare (VMut _) (VExt _) = LT |
|---|
| 596 | compare (VExt _) (VUndef _) = GT |
|---|
| 597 | compare (VExt _) (VNative _) = GT |
|---|
| 598 | compare (VExt _) (VPure _) = GT |
|---|
| 599 | compare (VExt _) (VMut _) = GT |
|---|
| 600 | compare (VExt aa) (VExt aa') = dynCompare aa aa' |
|---|
| 601 | |
|---|
| 602 | |
|---|
| 603 | -} |
|---|