Changeset 7

Show
Ignore:
Timestamp:
02/09/05 06:00:26 (4 years ago)
Author:
autrijus
svk:copy_cache_prev:
1041
Message:

* This be 6.0.2

Files:
1 added
13 modified

Legend:

Unmodified
Added
Removed
  • AUTHORS

    r6 r7  
    44the appropriate patches.  Corrections, additions, deletions welcome: 
    55 
     6Bestian Tang 
    67Brian Ingerson          (INGY) 
    78Damian Conway           (DCONWAY) 
  • MANIFEST

    r6 r7  
    1818SIGNATURE                       Public-key signature (added by MakeMaker) 
    1919src/AST.hs 
     20src/Context.hs 
    2021src/Eval.hs 
    2122src/Help.hs 
     
    2728src/Prim.hs 
    2829src/Shell.hs 
     30t/01basic.t 
  • Makefile.PL

    r5 r7  
    22 
    33use strict; 
     4use FindBin; 
    45use inc::Module::Install; 
     6 
     7chdir $FindBin::Bin; 
    58 
    69name            ('Perl6-Pugs'); 
     
    3336 
    3437 
     38open IN, '< lib/Perl6/Pugs.pm' or die $!; 
    3539open FH, '> config.h' or die $!; 
     40 
     41while (<IN>) { 
     42    /version (\S+) .*\breleased (.*)\./ or next; 
     43    print FH << "."; 
     44 
     45#ifdef VERSION 
     46#undef VERSION 
     47#endif 
     48#define VERSION "$1" 
     49 
     50#ifdef DATE 
     51#undef DATE 
     52#endif 
     53#define DATE "$2" 
     54 
     55. 
     56    last; 
     57} 
     58 
    3659if ($has_readline) { 
    3760    print FH "#define READLINE 1\n"; 
  • lib/Perl6/Pugs.pm

    r6 r7  
    11package Perl6::Pugs; 
    2 $Pugs::VERSION = '6.0.1'; 
     2$Pugs::VERSION = '6.0.2'; 
    33 
    44use strict; 
     
    1010=head1 VERSION 
    1111 
    12 This document describes version 6.0.1 of Pugs, released February 7, 2005. 
     12This document describes version 6.0.2 of Pugs, released February 9, 2005. 
    1313 
    1414=head1 SYNOPSIS 
    1515 
    16     % pugs -e "'Hello, World!'" 
     16    % pugs -e 'sub hi { "Hello, " ~ $_ } ; hi "World!\n"' 
    1717    Hello, World! 
    1818 
     
    5656=over 4 
    5757 
    58 =item * C<@*ARGS>, C<$*PID>, C<$*PROGRAM_NAME>, etc.. 
     58=item * C<@*ARGS>, C<$*PID>, C<$*PROGRAM_NAME>, etc. 
    5959 
    60 =item * C<< <> >> (lazily-evaluated lines of input) 
     60=item * C<< <> >> (lazily-evaluated lines of input). 
    6161 
    6262=item * The toplevel evaluation result is printed under flattened list context with items stringified. 
  • src/AST.hs

    r4 r7  
    1515import Internals 
    1616 
     17import Context 
     18 
    1719type Ident = String 
    1820 
     
    2527    vCast (VPair _ v)   = vCast v 
    2628    vCast v             = doCast v 
     29    castV :: n -> Val 
     30    castV v = error $ "cannot cast into Val" 
    2731    doCast :: Val -> n 
    28     doCast v = error $ "cannot cast: " ++ (show v) 
     32    doCast v = error $ "cannot cast from Val: " ++ (show v) 
     33    fmapVal :: (n -> n) -> Val -> Val 
     34    fmapVal f = castV . f . vCast 
     35 
     36instance Context VSub where 
     37    castV = VSub 
     38    doCast (VSub b) = b 
    2939 
    3040instance Context VBool where 
     41    castV = VBool 
    3142    doCast (VJunc j l) = juncToBool j l 
    3243    doCast (VBool b)   = b 
     
    4758 
    4859instance Context VInt where 
     60    castV = VInt 
    4961    doCast (VInt i)     = i 
    5062    doCast (VStr s) 
     
    5466 
    5567instance Context VRat where 
     68    castV = VRat 
    5669    doCast (VInt i)     = i % 1 
    5770    doCast (VRat r)     = r 
     
    5972 
    6073instance Context VNum where 
     74    castV = VNum 
    6175    doCast VUndef       = 0 
    6276    doCast (VBool b)    = if b then 1 else 0 
     
    7185 
    7286instance Context VComplex where 
     87    castV = VComplex 
    7388    doCast x            = (vCast x :: VNum) :+ 0 
    7489 
    7590instance Context VStr where 
     91    castV = VStr 
    7692    vCast VUndef        = "" 
    7793    vCast (VStr s)      = s 
     
    93109 
    94110instance Context VList where 
     111    castV = VList 
    95112    vCast (VList l)     = l 
    96113    vCast (VPair k v)   = [k, v] 
     
    110127 
    111128instance Context VScalar where 
    112     vCast x             = x 
     129    vCast = id 
     130    castV = id 
    113131 
    114132strRangeInf s = (s:strRangeInf (strInc s)) 
     
    148166instance (Show a, Show b) => Show (FiniteMap a b) where 
    149167    show fm = show (fmToList fm) 
    150  
    151 instance (Ord a, Ord b) => Ord (FiniteMap a b) where 
    152  
    153 instance Ord VComplex where 
    154     {- ... -} 
    155168 
    156169data Val 
     
    167180    | VRef      Val 
    168181    | VPair     Val Val 
    169     | VSub      Exp 
     182    | VSub      VSub 
    170183    | VBlock    Exp 
    171184    | VJunc     JuncType [Val] 
    172185    | VError    VStr Exp 
    173     | VPoly     { polyScalar    :: Val 
    174                 , polyList      :: Val 
    175                 } 
     186    deriving (Show, Eq, Ord) 
     187 
     188data SubType = SubMethod | SubRoutine | SubMulti 
     189    deriving (Show, Eq, Ord) 
     190 
     191data VSub = Sub 
     192    { subType       :: SubType 
     193    , subAssoc      :: String 
     194    , subParams     :: [Cxt] 
     195    , subReturns    :: Cxt 
     196    , subFun        :: Exp 
     197    } 
    176198    deriving (Show, Eq, Ord) 
    177199 
     
    184206    deriving (Show, Eq, Ord) 
    185207 
     208instance Eq ([Val] -> Val) 
     209instance Ord ([Val] -> Val) 
     210instance Ord VComplex where {- ... -} 
     211instance (Ord a, Ord b) => Ord (FiniteMap a b) 
     212 
     213type Var = String 
     214 
    186215data Exp 
    187     = Op1 String Exp 
    188     | Op2 String Exp Exp 
    189     | Op3 String Exp Exp Exp 
    190     | OpCmp String Exp Exp 
     216    = App String [Exp] 
     217    | Syn String [Exp] 
     218    | Prim ([Val] -> Val) 
    191219    | Val Val 
     220    | Var Var SourcePos 
     221    | Parens Exp 
    192222    | NonTerm SourcePos 
    193223    deriving (Show, Eq, Ord) 
     224 
     225isTotalJunc (VJunc JAll _, b)   = not b 
     226isTotalJunc (VJunc JNone _, b)  = not b 
     227isTotalJunc _                   = False 
     228 
     229isPartialJunc (VJunc JOne _, b) = not b 
     230isPartialJunc (VJunc JAny _, b) = not b 
     231isPartialJunc _                 = False 
     232 
  • src/Eval.hs

    r1 r7  
    44    Evaluation and reduction engine. 
    55 
    6     Tree and flower and leaf and grass, 
    7     Let them pass! Let them pass! 
    8     Hill and water under sky, 
    9     Pass them by! Pass them by! 
     6    Home is behind, the world ahead, 
     7    And there are many paths to tread 
     8    Through shadows to the edge of night, 
     9    Until the stars are all alight. 
     10    Then world behind and home ahead, 
     11    We'll wander back to home and bed... 
    1012-} 
    1113 
    1214module Eval where 
     15import Internals 
     16 
    1317import AST 
    1418import Prim 
     19import Context 
    1520 
    16 type Env = () 
    17 emptyEnv = () 
     21data Env = Env { cxt :: Cxt 
     22               , sym :: Symbols 
     23               , cls :: ClassTree 
     24               } deriving (Show) 
     25emptyEnv = Env { cxt = "List" 
     26               , sym = initSyms 
     27               , cls = initTree 
     28               } 
     29 
     30addSym :: Env -> [(String, Val)] -> Env 
     31addSym env [] = env 
     32addSym env ((var, val):vs) = env{ sym = (var, val):(sym $ addSym env vs) } 
    1833 
    1934evaluate :: Env -> Exp -> Val 
    20 evaluate env exp 
    21     | Val v <- reduce env exp   = v 
    22     | otherwise                 = VError "invalid expression" exp 
    23  
    24 -- Lazy evaluation for lists. 
    25 -- Context propagation. 
     35evaluate env@Env{ cxt = cxt, cls = cls } exp 
     36    | Val v <- val  = v 
     37    | otherwise     = VError "Invalid expression" exp 
     38    where 
     39    (env', val) = reduce env exp 
     40    isaContext = isaType cls cxt 
    2641 
    2742-- OK... Now let's implement the hideously clever autothreading algorithm. 
     
    4459    = Nothing 
    4560 
    46 reduce :: Env -> Exp -> Exp 
    47 reduce env (Op1 name exp) 
    48     | VError _ _ <- arg 
    49     = Val $ arg 
    50     | VJunc j l <- arg 
    51     = if name == "?" 
    52         then Val $ VBool (vCast arg) 
    53         else Val $ VJunc j [ reval a | a <- l ] 
     61applyFun :: Env -> Exp -> [Val] -> Val 
     62applyFun env (Prim f) vals = f vals 
     63applyFun env body vals 
     64    | Val val   <- exp          = val 
     65    | otherwise                 = VError "Invalid expression" exp 
     66    where 
     67    (fenv, exp) = reduce (env `addSym` [("$_", head vals),("@_", VList vals)]) body 
     68 
     69chainFun :: Env -> Exp -> Exp -> [Val] -> Val 
     70chainFun env f1 f2 (v1:v2:vs) 
     71    | VBool False <- applyFun env f1 [v1, v2] 
     72    = VBool False 
    5473    | otherwise 
    55     = Val $ op1 name (vCast arg) 
     74    = applyFun env f2 (v2:vs) 
     75 
     76apply :: Env -> VSub -> [Exp] -> ((Env -> Env), Exp) 
     77apply env@Env{ cls = cls } Sub{ subParams = prms, subFun = fun } exps 
     78    = retVal $ juncApply eval args 
    5679    where 
    57     arg = evaluate env exp 
    58     reval = evaluate env . Op1 name . Val 
     80    eval = applyFun env fun 
     81    args = map expToVal (prms `zip` exps) 
     82    expToVal (cxt, exp) = (evaluate env{ cxt = cxt } exp, isaType cls cxt "Bool") 
    5983 
    60 reduce env (OpCmp name exp1 exp2) 
    61     | OpCmp _ _ exp1b <- exp1 
    62     = reduce env $ Op2 "&&" exp1 $ Op2 name exp1b exp2 
     84juncApply f args 
     85    | (before, (VJunc j vs, cxt):after) <- break isTotalJunc args 
     86    = VJunc j [ juncApply f (before ++ ((v, cxt):after)) | v <- vs ] 
     87    | (before, (VJunc j vs, cxt):after) <- break isPartialJunc args 
     88    = VJunc j [ juncApply f (before ++ ((v, cxt):after)) | v <- vs ] 
     89    | (val, _):_ <- [ err | err@(VError _ _, _) <- args ] 
     90    = val 
    6391    | otherwise 
    64     = reduce env $ Op2 name exp1 exp2 
     92    = f $ map fst args  
    6593 
    66 {- XXX - this really wants a rewrite with multi subs -} 
    67 reduce env (Op2 name exp1 exp2) 
    68     | name `elem` words " ! & | ^ && || ^^ // and or xor err " -- XXX contextify 
    69     = Val $ op arg1 arg2 
    70     | VError _ _ <- arg1 = Val $ arg1 
    71     | VError _ _ <- arg2 = Val $ arg2 
    72     -- two junctions, all/none at left 
    73     | Just (j1, l1) <- arg1 `juncTypeIs` [JAll, JNone] 
    74     , Just (j2, l2) <- juncType arg2 
    75     = Val $ VJunc j1 [ VJunc j2 [ reval a1 a2 | a2 <- l2 ] | a1 <- l1 ] 
    76     -- two junctions, all/none at right 
    77     | Just (j1, l1) <- juncType arg1 
    78     , Just (j2, l2) <- arg2 `juncTypeIs` [JAll, JNone] 
    79     = Val $ VJunc j2 [ VJunc j1 [ reval a1 a2 | a1 <- l1 ] | a2 <- l2 ] 
    80     -- two junctions with all low prec. 
    81     | Just (j1, l1) <- juncType arg1 
    82     , Just (j2, l2) <- juncType arg2 
    83     = Val $ VJunc j1 [ VJunc j2 [ reval a1 a2 | a2 <- l2 ] | a1 <- l1 ] 
    84     -- one junctions at left 
    85     | Just (j, l) <- juncType arg1 
    86     = Val $ VJunc j [ reval a arg2 | a <- l ] 
    87     -- one junctions at right 
    88     | Just (j, l) <- juncType arg2 
    89     = Val $ VJunc j [ reval arg1 a | a <- l ] 
     94retVal :: Val -> ((Env -> Env), Exp) 
     95retVal val = (id, Val val) 
     96 
     97reduce :: Env -> Exp -> ((Env -> Env), Exp) 
     98reduce env@Env{ sym = sym } exp@(Var var _) 
     99    | Just val <- lookup var sym 
     100    = retVal val 
    90101    | otherwise 
    91     = Val $ op arg1 arg2 
     102    = retVal $ VError ("Undefined variable " ++ var) exp 
     103 
     104reduce env@Env{ cxt = cxt } exp@(Syn name exps) 
     105    | name `isInfix` ";" 
     106    , [left, right]     <- exps 
     107    , (env', exp)       <- runStatement "Any" (env, Val VUndef) left 
     108    , (env', exp)       <- runStatement cxt   (env', exp)       right 
     109    = (const env', exp) 
     110    | name `isInfix` ":=" 
     111    , [Var var _, exp]  <- exps 
     112    , (fenv, Val val)   <- reduce env exp 
     113    = (combineEnv fenv var val, Val val) 
     114    | name `isInfix` "::=" 
     115    , [Var var _, Val val]  <- exps 
     116    = (combineEnv id var val, Val VUndef) 
    92117    where 
    93     op = op2 name 
    94     arg1 = evaluate env exp1 
    95     arg2 = evaluate env exp2 
    96     reval x y = evaluate env $ Op2 name (Val x) (Val y) 
     118    runStatement :: Cxt -> (Env, Exp) -> Exp -> (Env, Exp) 
     119    runStatement cxt (env, (Val val)) exp 
     120        | VError _ _    <- val 
     121        = (env, Val val) 
     122        | (fenv, exp)   <- reduce env{ cxt = cxt } exp 
     123        = (fenv env, exp) 
     124        | otherwise 
     125        = (env, Val $ VError "Unterminated statement" exp) 
     126    combineEnv f var val env = (f env) `addSym` [(var, val)] 
     127    isInfix name s = name == "&infix:" ++ s 
    97128 
    98 reduce env other = other 
     129reduce env@Env{ cxt = cxt, cls = cls } exp@(App name exps) 
     130    | Just sub <- findSub name 
     131    = applySub sub exps 
     132    | otherwise 
     133    = retVal $ VError ("Undefined subroutine " ++ name ++ (show $ sym env)) exp 
     134    where 
     135    applySub sub exps 
     136        -- list-associativity 
     137        | Sub{ subAssoc = "list" }  <- sub 
     138        , (App name' exps'):rest    <- exps 
     139        , name == name' 
     140        = applySub sub (exps' ++ rest) 
     141        -- fix subParams to agree with number of actual arguments 
     142        | Sub{ subAssoc = "list", subParams = (p:_) }   <- sub 
     143        , trace ("meow " ++ (show exps)) True 
     144        = apply env sub{ subParams = (length exps) `replicate` p } exps 
     145        -- chain-associativity 
     146        | Sub{ subAssoc = "chain", subFun = fun }   <- sub 
     147        , (App name' exps'):rest                    <- exps 
     148        , Just sub'                                 <- findSub name' 
     149        , Sub{ subAssoc = "chain", subFun = fun' }  <- sub' 
     150        = applySub sub{ subFun = Prim $ chainFun env fun' fun } (exps' ++ rest) 
     151        -- fix subParams to agree with number of actual arguments 
     152        | Sub{ subAssoc = "chain", subParams = (p:_) }   <- sub 
     153        = apply env sub{ subParams = (length exps) `replicate` p } exps -- XXX Wrong 
     154        -- apply normally 
     155        | Sub{ subParams = [('*':p)] }              <- sub -- XXX Wrong 
     156        = apply env sub{ subParams = (length exps) `replicate` p } exps 
     157        | otherwise 
     158        = apply env sub exps 
     159    findSub name 
     160        | ((_, sub):_) <- sort (subs name)  = Just sub 
     161        | otherwise                         = Nothing 
     162    subs name = [ ((subT, deltaFromCxt ret : map deltaFromScalar prms), sub) 
     163           | (n, val) <- sym env 
     164           , let sub@(Sub{ subType = subT, subReturns = ret, subParams = prms }) = vCast val 
     165           , n == name 
     166           , arityMatch sub prms exps 
     167           , deltaFromCxt ret /= 0 
     168           ] 
     169    deltaFromCxt        = deltaType cls cxt 
     170    deltaFromScalar x   = deltaType cls x "Scalar" 
     171    arityMatch Sub{ subAssoc = assoc, subParams = prms } x y 
     172        | assoc == "list"           = True 
     173        | Just _ <- find ((== '*') . head) prms 
     174        , assoc == "pre"            = True 
     175        | (length x) == (length y)  = True  -- XXX - slurping star 
     176        | otherwise                 = False 
    99177 
     178reduce env (Parens exp) = reduce env exp 
     179reduce env other = (id, other) 
     180 
  • src/Help.hs

    r1 r7  
    11{-# OPTIONS -cpp #-} 
     2#define VERSION "" 
     3#define DATE "" 
     4#include "config.h" 
    25 
    36{- 
     
    2629 
    2730name       = "Perl6 User's Golfing System" 
    28 versnum    = "6.0.0" 
    29 date       = "04 Feb 2005" 
     31versnum    = VERSION 
     32date       = DATE 
    3033version    = name ++ ", version " ++ versnum ++ ", " ++ date 
    31 copyright  = "Copyright (c) 2005 by Autrijus Tang" 
     34copyright  = "Copyright 2005 by Autrijus Tang" 
    3235disclaimer = 
    3336    "This software is distributed under the terms of the " ++ 
     
    4548    [ ".=====. __  __  ____   ___    _________________________________________" 
    4649    , "||   || ||  || ||  || ||__'   Pugs 6: Based on the Perl 6 Synopses     " 
    47     , "||====' ||__|| ||__||  __||   Copyright (c) 2005 Autrijus Tang         " 
     50    , "||====' ||__|| ||__||  __||   " ++ copyright 
    4851    , "||      `===='  ___|| `==='   World Wide Web: http://autrijus.org/pugs " 
    4952    , "||             `===='         Report bugs to: autrijus@autrijus.org    " 
    5053    , "==" ++ versionFill 27    ++ " =========================================" 
    5154    , "" 
    52     , "Welcome to Pugs -- Perl6 User's Golfing System" 
     55    , "Welcome to Pugs -- " ++ name 
    5356    , "Type :h for help" 
    5457    ] 
  • src/Internals.hs

    r4 r7  
    2020    module Data.List, 
    2121    module Data.Word, 
     22    module Data.Ratio, 
    2223    module Data.Char, 
     24    module Data.Tree, 
    2325    module Data.Maybe, 
    24     module Data.Ratio, 
    2526    module Data.Complex, 
    2627    module Data.FiniteMap, 
     
    3637import Data.Bits 
    3738import Data.Maybe 
     39import Data.List 
    3840import Data.Ratio 
    39 import Data.List 
    4041import Data.Word 
    4142import Data.Char 
     
    4344import Data.Complex 
    4445import Data.FiniteMap 
     46import Data.Tree 
    4547import Debug.Trace 
    4648import Text.ParserCombinators.Parsec 
  • src/Lexer.hs

    r5 r7  
    1919          , P.commentLine    = "#" 
    2020          , P.nestedComments = False 
    21           , P.identStart     = letter <|> oneOf "_:$@%&" 
    22           , P.identLetter    = alphaNum <|> oneOf "_:" 
     21          , P.identStart     = letter <|> char '_' 
     22          , P.identLetter    = alphaNum <|> oneOf "_" 
    2323          , P.reservedNames  = words $ 
    2424                "if then else do while skip" 
     
    4646float      = P.float perl6Lexer 
    4747lexeme     = P.lexeme perl6Lexer 
     48identifier = P.identifier perl6Lexer 
     49braces     = P.braces perl6Lexer 
     50brackets   = P.brackets perl6Lexer 
    4851stringLiteral = choice 
    4952    [ P.stringLiteral  perl6Lexer 
     
    5154    ] 
    5255 
    53 naturalOrFloat  = lexeme (natFloat) <?> "number" 
     56naturalOrRat  = do 
     57        b <- lexeme sign 
     58        n <- lexeme natRat 
     59        return $ if b 
     60            then n 
     61            else case n of 
     62                Left x -> Left $ -x 
     63                Right y -> Right $ -y 
     64    <?> "number" 
    5465    where 
    55     natFloat        = do{ char '0' 
    56                         ; zeroNumFloat 
    57                         } 
    58                       <|> decimalFloat 
     66    natRat = do 
     67            char '0' 
     68            zeroNumRat 
     69        <|> decimalRat 
    5970                       
    60     zeroNumFloat    =  do{ n <- hexadecimal <|> octal <|> binary 
    61                          ; return (Left n) 
    62                          } 
    63                     <|> decimalFloat 
    64                     <|> fractFloat 0 
    65                     <|> return (Left 0)                   
     71    zeroNumRat = do 
     72            n <- hexadecimal <|> octal <|> binary 
     73            return (Left n) 
     74        <|> decimalRat 
     75        <|> fractRat 0 
     76        <|> return (Left 0)                   
    6677                       
    67     decimalFloat    = do{ n <- decimal 
    68                         ; option (Left n)  
    69                                  (try $ fractFloat n) 
    70                         } 
     78    decimalRat = do 
     79        n <- decimal 
     80        option (Left n) (try $ fractRat n) 
    7181 
    72     fractFloat n    = do{ f <- fractExponent n 
    73                         ; return (Right f) 
    74                         } 
    75                          
    76     fractExponent n = do{ fract <- fraction 
    77                         ; expo  <- option 1.0 exponent' 
    78                         ; return ((fromInteger n + fract)*expo) 
    79                         } 
    80                     <|> 
    81                       do{ expo <- exponent' 
    82                         ; return ((fromInteger n)*expo) 
    83                         } 
     82    fractRat n = do 
     83            fract <- try fraction 
     84            expo  <- option (1%1) expo 
     85            return (Right $ ((n % 1) + fract) * expo) -- Right is Rat 
     86        <|> do 
     87            expo <- expo 
     88            if expo < 1 
     89                then return (Left  $ n * numerator expo) 
     90                else return (Right $ (n % 1) * expo) 
    8491 
    85     fraction        = do{ char '.' 
    86                         ; digits <- many digit <?> "fraction" 
    87                         ; return (foldr op 0.0 digits) 
    88                         } 
    89                       <?> "fraction" 
    90                     where 
    91                       op d f    = (f + fromIntegral (digitToInt d))/10.0 
    92                          
    93     exponent'       = do{ oneOf "eE" 
    94                         ; f <- sign 
    95                         ; e <- decimal <?> "exponent" 
    96                         ; return (power (f e)) 
    97                         } 
    98                       <?> "exponent" 
    99                     where 
    100                        power e  | e < 0      = 1.0/power(-e) 
    101                                 | otherwise  = fromInteger (10^e) 
     92    fraction = do 
     93            char '.' 
     94            try $ do { char '.'; unexpected "dotdot" } <|> return () 
     95            digits <- many digit <?> "fraction" 
     96            return (digitsToRat digits) 
     97        <?> "fraction" 
     98        where 
     99        digitsToRat d = digitsNum d % (10 ^ length d) 
     100        digitsNum d = foldl (\x y -> x * 10 + (toInteger $ digitToInt y)) 0 d  
    102101 
     102    expo :: GenParser Char st Rational 
     103    expo = do 
     104            oneOf "eE" 
     105            f <- sign 
     106            e <- decimal <?> "exponent" 
     107            return (power (if f then e else -e)) 
     108        <?> "exponent" 
     109        where 
     110        power e | e < 0      = 1 % (10^e) 
     111                | otherwise  = (10^e) % 1 
    103112 
    104     -- integers and naturals 
    105     int             = do{ f <- lexeme sign 
    106                         ; n <- nat 
    107                         ; return (f n) 
    108                         } 
    109