public
Description: Haskell implemented JavaScript interpreter
Homepage:
Clone URL: git://github.com/motemen/jusk.git
jusk / JSDate.hs
100644 75 lines (63 sloc) 2.149 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
{-
JSDate.hs
Dateオブジェクト
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/15-9_Date_Objects.html
-}
 
module JSDate where
import Monad
import System.Time
 
import DataTypes
import Internal
 
-- Date.prototype
prototypeObject :: Value
prototypeObject =
    nullObject {
        objPropMap = nativeFuncPropMap [
                ("constructor", constructor, 7),
                ("toString", toStringMethod, 0),
                ("valueOf", valueOf, 1),
                ("getTime", getTime, 1)
            ]
    }
 
-- Date()
function :: NativeCode
function _ [] =
    do time <- liftIO $ getClockTime
       return $ String $ show time
 
-- new Date()
constructor :: NativeCode
constructor _ [] =
    do time <- liftIO $ getClockTime
       return $ nullObject { objClass = "Date", objValue = toValue $ toMillisecs time }
 
-- Date.prototype.toString
toStringMethod :: NativeCode
toStringMethod this _ =
    do this <- readRef this
       klass <- classOf this
       if klass == "Date"
          then liftIO $ liftM (String . calendarTimeToString) (millisecsToCT $ getMillisecs this)
          else throw "TypeError" "Date.prototype.toString called on incompatible"
 
-- Date.prototype.valueOf
valueOf :: NativeCode
valueOf this _ =
    do this <- readRef this
       klass <- classOf this
       if klass == "Date"
          then return $ toValue $ getMillisecs this
          else throw "TypeError" $ "Date.prototype.toString called on incompatible " ++ klass
 
-- Date.prototype.getTime
getTime :: NativeCode
getTime this _ =
    do this <- readRef this
       klass <- classOf this
       if klass == "Date"
          then return $ toValue $ getMillisecs this
          else throw "TypeError" $ "Date.prototype.getTime called on incompatible " ++ klass
 
getMillisecs (Object { objValue = Number (Integer millisecs) }) = millisecs
 
toMillisecs ct =
    let TOD secs picosecs = ct
        in secs * 1000 + picosecs `div` 1000000000
 
millisecsToCT millisecs =
    do let (secs, milli) = millisecs `divMod` 1000
           nanosecs = milli * 1000000000
       toCalendarTime =<< return (TOD secs nanosecs)