root/src/Pugs/Val.hs

Revision 15501, 20.6 kB (checked in by gaal, 21 months ago)

* use UUndef instead of () for undefined Vals

  • Property svn:mime-type set to text/plain; charset=UTF-8
  • Property svn:eol-style set to native
Line 
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
11module Pugs.Val (
12    module Pugs.Val,
13    module Pugs.Val.Code,
14    module Pugs.Val.Capture,
15    Val, Call,
16) where
17import Pugs.Class
18import Pugs.Val.Base ()
19import Pugs.Val.Code
20import Pugs.Val.Capture
21import Pugs.Internals
22import Text.PrettyPrint
23
24asStr :: Val -> Eval PureStr
25asStr (MkInvocant x _) = return (cast (show x))
26asBit :: Val -> Eval PureBit
27asBit _ = return (cast True)
28asInt :: Val -> Eval PureInt
29asInt _ = return (cast (0 :: Int))
30asNum :: Val -> Eval PureNum
31asNum _ = return (cast (0 :: Double))
32listVal :: Val -> Eval PureList
33listVal = return . (:[])
34itemVal :: Val -> Eval Val
35itemVal = return
36
37valMeta :: Val -> PureStr
38valMeta _ = cast "Object"
39
40valShow :: Val -> PureStr
41valShow _ = cast "<opaque>"
42
43formatVal :: Val -> Doc
44formatVal (MkInvocant x _) = text (show x)
45
46castVal :: forall a m . (Monad m, Typeable a) => Val -> m a
47castVal (MkInvocant v _)  = fromTypeable v
48
49instance ((:>:) PureNum) Rational where cast = NRational
50instance ((:<:) PureNum) Rational where
51    castBack (NDouble   x) = toRational x
52    castBack (NRational x) = x
53instance ((:>:) PureNum) Double where cast = NDouble
54instance ((:<:) PureNum) Double where
55    castBack (NDouble   x) = x
56    castBack (NRational x) = fromRational x
57
58instance ((:>:) PureInt) Integer where cast = IFinite
59instance ((:<:) 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
65instance ((:>:) PureInt) Int where cast = IFinite . toInteger
66instance ((:<:) 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"
71type PureList = [Val] -- Seq (Either PureSeq PureRange) -- XXX - *very bogus*
72
73newtype PureBit = MkBit Bool
74    deriving (Typeable, Show, Eq, Ord, Data, (:>:) Bool, (:<:) Bool)
75
76type PureStr = ByteString
77
78data PureInt
79    = IFinite      !Integer
80    | IInfinite    !Sign
81    | INotANumber
82    deriving (Typeable, Show, Eq, Ord, Data)
83
84data PureNum
85    = NDouble   !Double              -- change to "!NativeDouble"
86    | NRational !Rational
87    deriving (Typeable, Show, Eq, Ord, Data)
88
89data Sign
90    = SPositive
91    | SNegative
92    deriving (Show, Eq, Ord, Data, Typeable)
93
94-- | L<S02/"Undefined types">
95data 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
102instance Boxable ValUndef
103instance Boxable PureInt
104instance Boxable PureNum
105instance Boxable PureSig
106instance Boxable PureBit
107instance Boxable ValCapt
108
109instance Boxable Int
110{-
111module 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
123import Pugs.Internals
124import Pugs.Class
125import GHC.Exts
126import Data.Generics.Basics hiding (cast)
127import qualified Data.Typeable as Typeable
128import qualified Data.ByteString as Buf
129import qualified Data.Map as Map
130import qualified Data.Set as Set
131import Data.Monoid
132
133import Pugs.AST.SIO
134import Pugs.Val.Base
135--import Pugs.Val.Sig
136--import Pugs.Val.Code
137--import Pugs.Exp
138import {-# SOURCE #-} Pugs.Exp
139import qualified Pugs.Types as Types
140import Pugs.Types (Var(..))
141
142import 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
149This module contains the definition of the five variants for a Perl 6 value.
150However, the actual constructors for each variant are abstract, and this module
151does not provide concrete data type definitions beyond those five.
152
153-}
154
155-- | 'Val' represents what an unconstrained scalar container can hold.
156data 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
164castVal :: 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.
166castVal (VUndef v)  = fromTypeable v
167castVal (VNative v) = fromTypeable v
168castVal (VPure v)   = fromTypeable v
169castVal (VMut v)    = fromTypeable v
170castVal (VExt v)    = fromTypeable v
171
172-- | Value view. Contains methods for inspecting values: getting
173-- their metaclass, ids, stringification and so on.
174class 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
197instance 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"
211itemVal :: Val -> SIO Val
212itemVal v@(VPure x) = f v x asItem
213itemVal v@(VMut x)  = f v x asItem
214itemVal v@(VExt x)  = f v x asItem
215itemVal v           = return v
216
217-- evaluate a Val in List context, a.k.a. flattening, a.k.a. "is slurpy"
218listVal :: Val -> SIO PureList
219listVal v@(VPure x) = f v x asList
220listVal v@(VMut x)  = f v x asList
221listVal v@(VExt x)  = f v x asList
222listVal v           = cast v
223
224f v x g = maybe (cast v) cast (g x)
225
226instance ((:>:) PureList) Val where
227    cast = singleton -- . Left . singleton
228
229instance 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
247instance ((:>:) WHICH) NativeBuf where
248    cast = cast . NBuf
249
250instance ICoercible P ValNative where
251    asNative = return . id
252
253instance 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.
266type WHICH = Maybe ValNative
267
268instance ((:>:) WHICH) ValNative where
269    cast = Just
270
271--------------------------------------------------------------------------------------
272
273-- | L<S02/"Undefined types">
274data 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.
283data 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
292type NativeBit      = Bool
293type NativeInt      = Int
294type NativeUint     = Word
295type NativeBuf      = ByteString
296type NativeNum      = Float
297
298-- Haskell's Complex type does not instantiate Ord and Data.
299newtype NativeComplex = MkNComplex { unComplex :: Complex NativeNum }
300    deriving (Show, Eq, Typeable)
301instance Ord NativeComplex where
302    compare = error "NativeComplex numbers cannot be ordered"
303instance 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.
314type P = Identity
315instance Typeable1 P
316
317class (ICoercible P a, Ord a, Show a) => Pure a where
318    purePretty :: a -> Doc
319    purePretty = text . show
320
321instance (ICoercible P a, Ord a, Show a) => Pure a where {}
322
323liftP :: Monad m => P a -> m a
324liftP = return . runIdentity
325
326instance Pure a => IValue P a where
327    val         = VPure
328    valId       = liftP . asNative
329    valShow     = cast . show
330    valCompare  = compare
331
332instance Mut a => IValue STM a where
333    val         = VMut
334
335instance Ext a => IValue SIO a where
336    val         = VExt
337
338class ICoercible STM a => Mut a where {}
339instance ICoercible STM a => Mut a where {}
340
341class ICoercible SIO a => Ext a where {}
342instance ICoercible SIO a => Ext a where {}
343
344-- type Class = PureStr -- XXX - Wrong
345
346dynEq :: (Typeable a, Typeable b, Eq a) => a -> b -> Bool
347dynEq x y = case Typeable.cast y of
348    Just y' -> x == y'
349    Nothing -> False
350
351dynCompare :: forall a b ma mb. (IValue ma a, IValue mb b) => a -> b -> Ordering
352dynCompare 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-}
378type PureBool       = Bool
379type PureException  = ()            -- XXX *very* bogus
380type PureCode       = ()            -- XXX *very* bogus
381type PureCap        = ()
382type PureSet        = Set Val
383type PureSeq        = Seq Val
384type PureComplex    = ()
385type PureRange      = ()
386type PureJunc       = ()
387type PurePair       = ()
388type PureMap        = ()
389
390{-
391--------------------------------------------------------------------------------------
392-- | L<S02/"Mutable types"> minus IO types
393--   Computations on these types take place in the STM monad.
394data 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.
420data 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
428type ExtFile         = ()
429type ExtSocket       = ()
430type ExtThread       = ()
431type ExtProcess      = ()
432
433--------------------------------------------------------------------------------------
434
435-- | General purpose mapping from identifiers to values.
436type Table = Map.Map ID Val
437
438
439{- Pad -}
440{-|
441A 'Pad' keeps track of the names of all currently-bound symbols, and
442associates them with the things they actually represent.
443
444It is represented as a mapping from names to /lists/ of bound items.
445This is to allow for multi subs, because we will need to keep
446/multiple/ subs associated with one symbol. In other cases, the list
447should just contain a single value. See 'Pugs.AST.genSym' and 'Pugs.AST.genMultiSym' for
448more details.
449
450@TVar@ indicates that the mapped-to items are STM transactional variables.
451
452Pads are stored in the current 'Code', and lexical lookups proceed through
453progressively 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
457newtype Pad = MkPad { padEntries :: Map.Map Var PadEntry }
458    deriving (Show, Eq, Ord, Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-}
459
460newtype EntryStorage = MkStorage { s_cell :: TVar Val }
461    deriving (Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-}
462instance Show EntryStorage where
463    show _ = error "can't show EntryStorage"
464instance Ord EntryStorage where
465    compare _ = error "can't compare EntryStorage"
466instance Eq EntryStorage where
467    (==) = error "can't equate EntryStorage"
468
469data EntryDeclarator
470    = DeclMy
471    | DeclOur
472    | DeclHas
473    | DeclState
474    | DeclConstant
475    deriving (Show, Eq, Ord, Data, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-}
476
477data 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 {-
491data 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
507data 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--------------------------------------------------------------------------------------
532formatVal :: Val -> Doc
533formatVal (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) ++ "}"
538formatVal (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)"
546formatVal (VPure v) = purePretty v
547formatVal 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. *-}
555instance 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
567instance 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
575instance 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-}
Note: See TracBrowser for help on using the browser.