HJavaScript 0.4 → 0.4.4
raw patch · 3 files changed
+606/−565 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Language.HJavaScript.Syntax: JFst :: Exp (Rec a b) -> Exp a
+ Language.HJavaScript.Syntax: JRec :: Exp a -> Exp b -> Exp (Rec a b)
+ Language.HJavaScript.Syntax: JSnd :: Exp (Rec a b) -> Exp b
+ Language.HJavaScript.Syntax: call :: (Args e t) => Exp (t -> r) -> e -> Exp r
+ Language.HJavaScript.Syntax: class VarsToExps v e | v -> e, e -> v
+ Language.HJavaScript.Syntax: data Rec a b
+ Language.HJavaScript.Syntax: instance [overlap ok] IsNullable (t -> r)
+ Language.HJavaScript.Syntax: instance [overlap ok] VarsToExps () ()
+ Language.HJavaScript.Syntax: instance [overlap ok] VarsToExps (Var t) (Exp t)
+ Language.HJavaScript.Syntax: instance [overlap ok] VarsToExps (Var t1, Var t2) (Exp t1, Exp t2)
+ Language.HJavaScript.Syntax: instance [overlap ok] VarsToExps (Var t1, Var t2, Var t3) (Exp t1, Exp t2, Exp t3)
+ Language.HJavaScript.Syntax: instance [overlap ok] VarsToExps (Var t1, Var t2, Var t3, Var t4) (Exp t1, Exp t2, Exp t3, Exp t4)
+ Language.HJavaScript.Syntax: instance [overlap ok] VarsToExps (Var t1, Var t2, Var t3, Var t4, Var t5) (Exp t1, Exp t2, Exp t3, Exp t4, Exp t5)
+ Language.HJavaScript.Syntax: v2e :: (VarsToExps v e) => v -> e
- Language.HJavaScript.Syntax: JParam :: Int -> Var a
+ Language.HJavaScript.Syntax: JParam :: String -> Var a
- Language.HJavaScript.Syntax: mkFParams :: (FormalParams a t) => (a -> b) -> a
+ Language.HJavaScript.Syntax: mkFParams :: (FormalParams a t) => (a -> b) -> Int -> a
Files
- HJavaScript.cabal +10/−9
- Language/HJavaScript/Syntax.hs +0/−556
- src/Language/HJavaScript/Syntax.hs +596/−0
HJavaScript.cabal view
@@ -1,20 +1,21 @@ Name: HJavaScript-Version: 0.4+Version: 0.4.4 License: BSD3 Author: Joel Bjornson, Niklas Broberg Maintainer: joel.bjornson@gmail.com, nibro@cs.chalmers.se -Synopsis: HJavaScript is an abstract syntax for a typed subset of JavaScript.-Description: HJavaScript defines an abstract syntax and pretty printer for- a subset of JavaScript. as Language.HJavaScript. However, a significant - difference from JavaScript is that HJavaScript is typed, even on the - abstract syntax level using GADTs. The subset of JavaScript that is - supported is those parts that lend themself to typing - (i.e. no prototyping of classes).+Synopsis: HJavaScript is an abstract syntax for a typed subset of JavaScript.+Description: HJavaScript defines an abstract syntax and pretty printer for+ a subset of JavaScript. as Language.HJavaScript. However, a significant + difference from JavaScript is that HJavaScript is typed, even on the + abstract syntax level using GADTs. The subset of JavaScript that is + supported is those parts that lend themself to typing + (i.e. no prototyping of classes). +Hs-Source-Dirs: src Exposed-Modules: Language.HJavaScript.Syntax Build-Depends: base Build-Type: Simple-Category: Language+Category: Language
− Language/HJavaScript/Syntax.hs
@@ -1,556 +0,0 @@-{-# OPTIONS_GHC -fglasgow-exts #-}-{-# OPTIONS_GHC -fallow-overlapping-instances #-} -{-# OPTIONS_GHC -fallow-undecidable-instances #-}------------------------------------------------------------------------------ --- | --- Module : Language.HJavaScript.Syntax --- Copyright : (c) Joel Bjornson 2008 --- License : BSD-style --- Maintainer : Joel Bjornson joel.bjornson@gmail.com--- Niklas Broberg nibro@cs.chalmers.se --- Stability : experimental -------------------------------------------------------------------------------module Language.HJavaScript.Syntax- (- -- * Primitive type classes.- JType,- - -- * Fundamental data types.- Exp(..),- Var(..),- Stmt(..),- Block(..),- - -- * Data types and classes for object representation.- IsClass,- HasConstructor,- IsDeref,- - -- * Misc- AssignOp(..),- BinOp(..),- PlusOpType, - PostPre(..),- Elses(..),- IsNullable,- IsFeature,- JShow(..),- - -- * Types for functions and parameters.- Args,- ParamType,- FormalParams(..),- - -- * Array representation.- Array(..),- - -- * Type synonyms.- JInt, JString, JBool, JFloat, JVoid, JObject, JArray,- - -- * Type classes for expression representation.- IsExp(..), - IsJString(..),- IsJBool(..),- IsJInt(..),- IsJFloat(..),- - -- * Helper functions- val, toBlock, deref, derefVar, - methodCall, voidMethodCall, - methodCallNoArgs, voidMethodCallNoArgs- - ) where- -import Data.Char-import Data.Maybe---- | JavaScript types-class JType t-instance JType String-instance JType Int-instance JType Bool-instance JType ()-instance JType Float-instance IsClass c => JType c-instance (Show t1, JType t1, Show t2, JType t2) => JType (t1 -> t2)------------------------------------------------------------------------ JavaScript variable and expression representation--------------------------------------------------------------------- --- Var represents JavaScript variables. -data Var t where - JVar :: String -> Var a - JParam :: Int -> Var a - JMember :: String -> Var a - JDerefVar :: IsDeref d => d -> String -> Var a - JArrayIndex :: Exp (Array t) -> Exp Int -> Var t - -instance Show (Var t) where - showsPrec p var = case var of - JVar v -> showString v - JParam n -> showString "param" . shows n - JMember s -> showString s - JDerefVar o v -> shows o . sDot . showString v - JArrayIndex a ix -> shows a . showString "[" . - shows ix . showString "]" - ---- Exp represents JavaScript Expressions.-data Exp t where- JInt :: Int -> Exp Int- JFloat :: Float -> Exp Float- JBool :: Bool -> Exp Bool- JString :: String -> Exp String- JConst :: String -> Exp t- JAssign :: Var t -> Exp t -> Exp t- JAssignWith :: Var t -> AssignOp t -> Exp t -> Exp t- JNeg :: Exp t -> Exp t- JNot :: Exp Bool -> Exp Bool- JBinOp :: Exp t -> BinOp t r -> Exp t -> Exp r- JIncrement :: Num t => PostPre -> Var t -> Exp t- JDecrement :: Num t => PostPre -> Var t -> Exp t- JIfOp :: Exp Bool -> Exp t -> Exp t -> Exp t- JCall :: (Args e t) => Exp (t -> r) -> e -> Exp r- JNew :: (Args e t, HasConstructor c e t) => c -> e -> Exp c- JDeref :: IsDeref d => d -> String -> Exp t- JFunction :: FormalParams a t => Maybe String -> a -> Block r -> Exp (t -> r)- JThis :: IsClass c => Exp c- JBlock :: Block () -> Exp ()- JNull :: IsNullable t => Exp t- JCastObject :: (IsClass c1, IsClass c2) => Exp c1 -> Exp c2- JValueOf :: Var t -> Exp t- JIsImpl :: (IsClass c , IsFeature f) => Exp c -> f -> Exp Bool- JShow :: JShow t => Exp t -> Exp String- ------------------------------------------------------------------------ | Show for Exp---------------------------------------------------------------------instance Show (Exp t) where- showsPrec p exp = case exp of- JInt n -> shows n- JFloat f -> shows f- JBool b -> if b then - showString "true" - else - showString "false"- JString s -> sJtr s- JConst c -> showString c- JAssign e1 e2 -> shows e1 . sEq . shows e2- JAssignWith e1 op e2 -> shows e1 . shows op . shows e2- JNeg e -> showString "-" . (showParen True $ shows e)- JNot e -> showString "!" . (showParen True $ shows e)- JBinOp e1 op e2 -> shows e1 . shows op . shows e2- JIncrement pp e -> if (pp == Pre) then - (showString "++" . shows e) - else - (shows e . showString "++")- JDecrement pp e -> if (pp == Pre) then - (showString "--" . shows e) - else - (shows e . showString "--")- JIfOp e1 e2 e3 -> shows e1 . showString "?" . shows e2 . - showString ":" . shows e3- JCall x a2 -> shows x . showsArgs a2- JNew c a -> showString "new" . sSpace . shows c . showsArgs a- JDeref o e -> shows o . sDot . showString e- JFunction n fp b -> showString "function" .- sSpace .- sMaybe n . - showsFParams fp . - sBrack b- JThis -> showString "this"- JBlock b -> shows b- JNull -> showString "null"- JIsImpl ob c -> shows ob . sDot . showsFeature c- JValueOf v -> shows v - JCastObject e -> shows e- JShow e -> shows e-------------------------------------------------------------------------- Type synonyms for Exp.---------------------------------------------------------------------type JInt = Exp Int-type JString = Exp String-type JBool = Exp Bool-type JFloat = Exp Float-type JVoid = Exp ()-type JObject c = Exp c-type JArray t = Exp (Array t)------------------------------------------------------------------------- Additional classes------------------------------------------------------------------------ | Class for representing JavaScript "features", e.g. names of --- objects or functions. Example: window `hasFeature` "alert"-class Show a => IsFeature a where- showsFeature :: a -> ShowS---- A class can be a feature-instance IsClass c => IsFeature c where- showsFeature = shows- ---- | Any string value can be a feature.-instance IsFeature String where- showsFeature = showString----- | Class that represents showable types-class JShow a where- jshow :: a -> JString - -instance JShow Int where- jshow = jshow . JInt - -instance JShow Float where- jshow = jshow . JFloat - -instance JShow Bool where- jshow = jshow . JBool - -instance JShow String where - jshow = JString - -instance JShow a => JShow (Exp a) where - jshow = JShow - --- | Allows values to be compared to JNull. E.g. for checking that--- an object is instantiated or is accessible.-class IsNullable a---- | All JString values along with all objects can be nulll.-instance IsNullable String-instance IsClass c => IsNullable c------------------------------------------------------------------------ JavaScript statements representation----------------------------------------------------------------------- | Post or Pre prefix , i.e. --x or x++-data PostPre = Pst | Pre deriving Eq----- | Assign Operator-data AssignOp t where- PlusAssign :: Num t => AssignOp t- MinusAssign :: Num t => AssignOp t- TimesAssign :: Num t => AssignOp t- DivAssign :: AssignOp Float- ModAssign :: AssignOp Int- AndAssign :: AssignOp Bool- OrAssign :: AssignOp Bool--instance Show (AssignOp t) where- showsPrec p exp = case exp of- PlusAssign -> showString "+="- MinusAssign -> showString "-="- TimesAssign -> showString "*="- DivAssign -> showString "/="- ModAssign -> showString "%="- AndAssign -> showString "&="- OrAssign -> showString "|="- ---- | Class for expression that may be "plussed".--- Examples: 1 + 2, "ha" + "skell".-class PlusOpType a -instance PlusOpType String-instance PlusOpType Int-instance PlusOpType Float---- | Binary Operator-data BinOp t r where- Plus :: PlusOpType t => BinOp t t - Minus :: Num t => BinOp t t- Times :: Num t => BinOp t t- Div :: Num t => BinOp t t- Mod :: BinOp Int Int- And :: BinOp Bool Bool- Or :: BinOp Bool Bool- Equals :: BinOp t Bool- NotEquals :: BinOp t Bool- GThan :: Num t => BinOp t Bool- LThan :: Num t => BinOp t Bool- GEThan :: Num t => BinOp t Bool- LEThan :: Num t => BinOp t Bool- --instance Show (BinOp t r) where- showsPrec p exp = case exp of- Plus -> showString " + "- Minus -> showString " - "- Times -> showString " * "- Div -> showString " / "- Mod -> showString " % "- And -> showString " && "- Or -> showString " || "- Equals -> showString " == "- NotEquals -> showString " != "- GThan -> showString " > "- LThan -> showString " < "- GEThan -> showString " >= "- LEThan -> showString " <= "- - -data Stmt t where- VarDecl :: String -> Stmt ()- VarDeclAssign :: String -> Exp t -> Stmt ()- VarAssign :: String -> Exp t -> Stmt ()- ExpStmt :: Exp t -> Stmt ()- While :: Exp Bool -> Block () -> Stmt ()- DoWhile :: Block () -> Exp Bool -> Stmt ()- For :: Stmt t1 -> Exp Bool -> Exp t2 -> Block () -> Stmt () - Break :: Stmt ()- Continue :: Stmt ()- Return :: Exp t -> Stmt t- If :: Exp Bool -> Block t -> Elses t -> Stmt ()- -data Elses t where- Elseif :: Exp Bool -> Block t -> Elses t -> Elses t- Else :: Block t -> Elses t- NoElse :: Elses () - -instance Show (Stmt t) where- showsPrec p stm = case stm of- VarDecl s -> showString "var" . sSpace . showString s- VarAssign s e -> showString s . showString " = " . shows e- VarDeclAssign s e -> showString "var" . sSpace . showString s . - showString " = " . shows e - ExpStmt e -> shows e- While e b -> showString "while" . showParen True (shows e) . - sBrack b- DoWhile b e -> showString "do" . sBrack b . showString "while" . - showParen True (shows e)- For e1 e2 e3 b -> showString "for" . - showParen True (shows e1 . sc . shows e2 . - sc . shows e3) . sBrack b- Break -> showString "break"- Continue -> showString "continue"- Return e -> showString "return" . showString " " . shows e- If e1 b1 b2 -> showString "if" . showParen True (shows e1) . - sBrack b1 . shows b2--instance Show (Elses t) where- showsPrec p elses = case elses of- Elseif e b els -> showString "else" . sBrack b . shows els- Else b -> showString "else" . sBrack b- NoElse -> id ---sBrack s = showString "{" . shows s . showString "}"-sSpace = showString " "-sEq = showString " = "-sDot = showString "." -sc = showString ";" -sNl = showString "\n"-sJtr s = showString "'" . showString s . showString "'"-sMaybe Nothing = id-sMaybe (Just s) = showString s------------------------------------------------------------------------- JavaScript block representation---------------------------------------------------------------------data Block t where- EmptyBlock :: Block ()- Sequence :: Block () -> Stmt t -> Block t--instance Show (Block t) where- showsPrec p block = case block of- EmptyBlock -> id- Sequence b stm -> shows b . shows stm . sc- ----------------------------------------------------------------------- Parameters and functions------------------------------------------------------------------------ | Class for parameter types to JavaScript functions-class ParamType t---- | Instanses for tuples,triples etc..-instance ParamType ()-instance JType t => ParamType t-instance (JType t1, JType t2 ) => ParamType (t1,t2)-instance (JType t1, JType t2, JType t3 ) => ParamType (t1,t2,t3)-instance (JType t1, JType t2, JType t3, JType t4) => ParamType (t1,t2,t3,t4)-instance (JType t1, JType t2, JType t3, JType t4, JType t5) => ParamType (t1,t2,t3,t4,t5)----- | JFormal params represents parameters passed to a function along with their--- corresponding types.-class (Show a , ParamType t) => FormalParams a t | a -> t where- mkFParams :: forall b. (a -> b) -> a- showsFParams :: a -> ShowS--instance FormalParams () () where- mkFParams _ = ()- showsFParams = shows --instance ParamType t => FormalParams (Var t) t where- mkFParams _ = (JParam 0) - showsFParams = showParen True . shows---instance (ParamType (t1,t2)) => FormalParams (Var t1, Var t2) (t1,t2) where- mkFParams _ = (JParam 0, JParam 1)- showsFParams = shows--instance (ParamType (t1,t2,t3)) => FormalParams (Var t1, Var t2, Var t3) (t1,t2,t3) where- mkFParams _ = (JParam 0, JParam 1, JParam 2)- showsFParams = shows ---instance (ParamType (t1,t2,t3,t4)) => FormalParams (Var t1, Var t2, Var t3, Var t4) (t1,t2,t3,t4) where- mkFParams _ = (JParam 0, JParam 1, JParam 2, JParam 3)- showsFParams = shows --instance (ParamType (t1,t2,t3,t4,t5)) => FormalParams (Var t1, Var t2, Var t3, Var t4, Var t5) (t1,t2,t3,t4,t5) where- mkFParams _ = (JParam 0, JParam 1, JParam 2, JParam 3, JParam 4)- showsFParams = shows ----- | Args represents types that can be passed as arguments to--- JavaScript functions.-class Show e => Args e t | e -> t where- showsArgs :: e -> ShowS--instance Args () () where- showsArgs = shows- -instance Args (Exp t) t where- showsArgs = showParen True . shows--instance Args (Exp t1, Exp t2) (t1,t2) where- showsArgs = shows- -instance Args (Exp t1, Exp t2, Exp t3) (t1,t2,t3) where- showsArgs = shows--instance Args (Exp t1, Exp t2, Exp t3, Exp t4) (t1,t2,t3,t4) where- showsArgs = shows--instance Args (Exp t1, Exp t2, Exp t3, Exp t4, Exp t5) (t1,t2,t3,t4,t5) where- showsArgs = shows--------------------------------------------------------------------------- Object representation----------------------------------------------------------------------- Class for representing 'class' elements in javascript (e.g. Math)-class Show c => IsClass c---- | Class for binding objects with constructors. E.g. o = new Date();-class (IsClass c, Args e t) => HasConstructor c e t---- | Class for derefable data types, used to allow the creation of --- dereferencing objects. Examples: Math.random() or document.write()-class Show r => IsDeref r---- There are two kinds of dereferencing; either from classes or objects.-instance IsClass c => IsDeref c-instance IsClass c => IsDeref (Exp c)------------------------------------------------------------------------ | Class for representing expressions.--- First parameter is the expression, second a TBool for variable or constant.--- Third parameter represents the type.----------------------------------------------------------------------class IsExp e t | e -> t where- toExp :: e -> Exp t--instance IsExp (Exp t) t where- toExp = id--instance IsExp String String where- toExp = JString--instance IsExp Int Int where- toExp = JInt--instance IsExp Float Float where- toExp = JFloat--instance IsExp Bool Bool where- toExp = JBool----- | Class for JString expressions-class IsExp e String => IsJString e where- toJString :: e -> Exp String- toJString = toExp- --- | Class for JInt expressions-class IsExp e Int => IsJInt e where- toJInt :: e -> Exp Int- toJInt = toExp- --- | Class for JFloat expressions-class IsExp e Float => IsJFloat e where- toJFloat :: e -> Exp Float- toJFloat = toExp- ---- | Class for JBool expressions-class IsExp e Bool => IsJBool e where- toJBool :: e -> Exp Bool- toJBool = toExp---instance IsExp e String => IsJString e--instance IsExp e Int => IsJInt e--instance IsExp e Float => IsJFloat e--instance IsExp e Bool => IsJBool e------------------------------------------------------------------------ Array----------------------------------------------------------------------- | Array representation-data Array t = Array deriving Show-instance IsClass (Array t)------------------------------------------------------------------------ Helper functions------------------------------------------------------------------------ Dereferencing-deref str obj = JDeref obj str- -derefVar str obj = JDerefVar obj str ---- Method call returning an expression.-methodCall :: (Args e t1, IsDeref d) => String -> e -> d -> Exp t2-methodCall fun args obj = JCall (JDeref obj fun) args---- Method call for void methods. Returns a Stmt since the return value is--- not of any interest.-voidMethodCall :: (Args e t1, IsDeref a) => String -> e -> a -> Stmt ()-voidMethodCall fun args = ExpStmt . methodCall fun args---- Method call for functions without input parameters. Just adds the extra--- dummy argument ().-methodCallNoArgs ::IsDeref d => String -> d -> Exp t-methodCallNoArgs name = methodCall name ()---- Method call for functions without input parameters returning void.-voidMethodCallNoArgs ::IsDeref d => String -> d -> Stmt ()-voidMethodCallNoArgs name = ExpStmt . methodCall name ()----- | Generates a Block from a Stmt.-toBlock :: Stmt t -> Block t-toBlock stm = Sequence EmptyBlock stm- - --- | Get the value of a variable. -val :: Var t -> Exp t -val = JValueOf
+ src/Language/HJavaScript/Syntax.hs view
@@ -0,0 +1,596 @@+{-# OPTIONS_GHC -fglasgow-exts #-}+{-# OPTIONS_GHC -fallow-overlapping-instances #-} +{-# OPTIONS_GHC -fallow-undecidable-instances #-}+----------------------------------------------------------------------------- +-- | +-- Module : Language.HJavaScript.Syntax +-- Copyright : (c) Joel Bjornson 2008 +-- License : BSD-style +-- Maintainer : Joel Bjornson joel.bjornson@gmail.com+-- Niklas Broberg nibro@cs.chalmers.se +-- Stability : experimental +-----------------------------------------------------------------------------+module Language.HJavaScript.Syntax+ (+ -- * Primitive type classes.+ JType,+ + -- * Fundamental data types.+ Exp(..),+ Rec, + Var(..),+ Stmt(..),+ Block(..),+ + -- * Data types and classes for object representation.+ IsClass,+ HasConstructor,+ IsDeref,+ + -- * Misc+ AssignOp(..),+ BinOp(..),+ PlusOpType, + PostPre(..),+ Elses(..),+ IsNullable,+ IsFeature,+ JShow(..),+ + -- * Types for functions and parameters.+ Args,+ ParamType,+ FormalParams(..),+ VarsToExps(..), + + -- * Array representation.+ Array(..),+ + -- * Type synonyms.+ JInt, JString, JBool, JFloat, JVoid, JObject, JArray,+ + -- * Type classes for expression representation.+ IsExp(..), + IsJString(..),+ IsJBool(..),+ IsJInt(..),+ IsJFloat(..),+ + -- * Helper functions+ val, toBlock, deref, derefVar, + call, methodCall, voidMethodCall, + methodCallNoArgs, voidMethodCallNoArgs+ + ) where+ +import Data.Char+import Data.Maybe++-- | JavaScript types+class JType t+instance JType String+instance JType Int+instance JType Bool+instance JType ()+instance JType Float+instance IsClass c => JType c+instance (Show t1, JType t1, Show t2, JType t2) => JType (t1 -> t2)++-------------------------------------------------------------------+-- JavaScript variable and expression representation+-------------------------------------------------------------------+ +-- Var represents JavaScript variables. +data Var t where + JVar :: String -> Var a + JParam :: String -> Var a + JMember :: String -> Var a + JDerefVar :: IsDeref d => d -> String -> Var a + JArrayIndex :: Exp (Array t) -> Exp Int -> Var t + +instance Show (Var t) where + showsPrec p var = case var of + JVar v -> showString v + JParam name -> showString name + JMember s -> showString s + JDerefVar o v -> shows o . sDot . showString v + JArrayIndex a ix -> shows a . showString "[" . + shows ix . showString "]" + + +-- We model records simply as tuples, for lack of a better record mechanism +data Rec a b ++-- Exp represents JavaScript Expressions.+data Exp t where+ JInt :: Int -> Exp Int+ JFloat :: Float -> Exp Float+ JBool :: Bool -> Exp Bool+ JString :: String -> Exp String+ JRec :: Exp a -> Exp b -> Exp (Rec a b) + JFst :: Exp (Rec a b) -> Exp a + JSnd :: Exp (Rec a b) -> Exp b + JConst :: String -> Exp t+ JAssign :: Var t -> Exp t -> Exp t+ JAssignWith :: Var t -> AssignOp t -> Exp t -> Exp t+ JNeg :: Exp t -> Exp t+ JNot :: Exp Bool -> Exp Bool+ JBinOp :: Exp t -> BinOp t r -> Exp t -> Exp r+ JIncrement :: Num t => PostPre -> Var t -> Exp t+ JDecrement :: Num t => PostPre -> Var t -> Exp t+ JIfOp :: Exp Bool -> Exp t -> Exp t -> Exp t+ JCall :: (Args e t) => Exp (t -> r) -> e -> Exp r+ JNew :: (Args e t, HasConstructor c e t) => c -> e -> Exp c+ JDeref :: IsDeref d => d -> String -> Exp t+ JFunction :: FormalParams a t => Maybe String -> a -> Block r -> Exp (t -> r)+ JThis :: IsClass c => Exp c+ JBlock :: Block () -> Exp ()+ JNull :: IsNullable t => Exp t+ JCastObject :: (IsClass c1, IsClass c2) => Exp c1 -> Exp c2+ JValueOf :: Var t -> Exp t+ JIsImpl :: (IsClass c , IsFeature f) => Exp c -> f -> Exp Bool+ JShow :: JShow t => Exp t -> Exp String+ ++-------------------------------------------------------------------+-- | Show for Exp+-------------------------------------------------------------------+instance Show (Exp t) where+ showsPrec p exp = case exp of+ JInt n -> shows n+ JFloat f -> shows f+ JBool b -> if b then + showString "true" + else + showString "false"+ JString s -> sJtr s+ JRec e1 e2 -> showString "{fst:" . shows e1 . showString "," . + showString "snd:" . shows e2 . showString "}" + JFst e -> shows e . showString ".fst" + JSnd e -> shows e . showString ".snd" + JConst c -> showString c+ JAssign e1 e2 -> shows e1 . sEq . shows e2+ JAssignWith e1 op e2 -> shows e1 . shows op . shows e2+ JNeg e -> showString "-" . (showParen True $ shows e)+ JNot e -> showString "!" . (showParen True $ shows e)+ JBinOp e1 op e2 -> shows e1 . shows op . shows e2+ JIncrement pp e -> if (pp == Pre) then + (showString "++" . shows e) + else + (shows e . showString "++")+ JDecrement pp e -> if (pp == Pre) then + (showString "--" . shows e) + else + (shows e . showString "--")+ JIfOp e1 e2 e3 -> shows e1 . showString "?" . shows e2 . + showString ":" . shows e3+ JCall x a2 -> shows x . showsArgs a2+ JNew c a -> showString "new" . sSpace . shows c . showsArgs a+ JDeref o e -> shows o . sDot . showString e+ JFunction n fp b -> showString "function" .+ sSpace .+ sMaybe n . + showsFParams fp . + sBrack b+ JThis -> showString "this"+ JBlock b -> shows b+ JNull -> showString "null"+ JIsImpl ob c -> shows ob . sDot . showsFeature c+ JValueOf v -> shows v + JCastObject e -> shows e+ JShow e -> shows e++++-------------------------------------------------------------------+-- Type synonyms for Exp.+-------------------------------------------------------------------+type JInt = Exp Int+type JString = Exp String+type JBool = Exp Bool+type JFloat = Exp Float+type JVoid = Exp ()+type JObject c = Exp c+type JArray t = Exp (Array t)+++-------------------------------------------------------------------+-- Additional classes+-------------------------------------------------------------------++-- | Class for representing JavaScript "features", e.g. names of +-- objects or functions. Example: window `hasFeature` "alert"+class Show a => IsFeature a where+ showsFeature :: a -> ShowS++-- A class can be a feature+instance IsClass c => IsFeature c where+ showsFeature = shows+ ++-- | Any string value can be a feature.+instance IsFeature String where+ showsFeature = showString+++-- | Class that represents showable types+class JShow a where+ jshow :: a -> JString + +instance JShow Int where+ jshow = jshow . JInt + +instance JShow Float where+ jshow = jshow . JFloat + +instance JShow Bool where+ jshow = jshow . JBool + +instance JShow String where + jshow = JString + +instance JShow a => JShow (Exp a) where + jshow = JShow + +-- | Allows values to be compared to JNull. E.g. for checking that+-- an object is instantiated or is accessible.+class IsNullable a++-- | All JString values along with all objects and all functions can be null.+instance IsNullable String+instance IsClass c => IsNullable c+instance IsNullable (t -> r) ++-------------------------------------------------------------------+-- JavaScript statements representation+-------------------------------------------------------------------+-- | Post or Pre prefix , i.e. --x or x+++data PostPre = Pst | Pre deriving Eq+++-- | Assign Operator+data AssignOp t where+ PlusAssign :: Num t => AssignOp t+ MinusAssign :: Num t => AssignOp t+ TimesAssign :: Num t => AssignOp t+ DivAssign :: AssignOp Float+ ModAssign :: AssignOp Int+ AndAssign :: AssignOp Bool+ OrAssign :: AssignOp Bool++instance Show (AssignOp t) where+ showsPrec p exp = case exp of+ PlusAssign -> showString "+="+ MinusAssign -> showString "-="+ TimesAssign -> showString "*="+ DivAssign -> showString "/="+ ModAssign -> showString "%="+ AndAssign -> showString "&="+ OrAssign -> showString "|="+ ++-- | Class for expression that may be "plussed".+-- Examples: 1 + 2, "ha" + "skell".+class PlusOpType a +instance PlusOpType String+instance PlusOpType Int+instance PlusOpType Float++-- | Binary Operator+data BinOp t r where+ Plus :: PlusOpType t => BinOp t t + Minus :: Num t => BinOp t t+ Times :: Num t => BinOp t t+ Div :: Num t => BinOp t t+ Mod :: BinOp Int Int+ And :: BinOp Bool Bool+ Or :: BinOp Bool Bool+ Equals :: BinOp t Bool+ NotEquals :: BinOp t Bool+ GThan :: Num t => BinOp t Bool+ LThan :: Num t => BinOp t Bool+ GEThan :: Num t => BinOp t Bool+ LEThan :: Num t => BinOp t Bool+ ++instance Show (BinOp t r) where+ showsPrec p exp = case exp of+ Plus -> showString " + "+ Minus -> showString " - "+ Times -> showString " * "+ Div -> showString " / "+ Mod -> showString " % "+ And -> showString " && "+ Or -> showString " || "+ Equals -> showString " == "+ NotEquals -> showString " != "+ GThan -> showString " > "+ LThan -> showString " < "+ GEThan -> showString " >= "+ LEThan -> showString " <= "+ + +data Stmt t where+ VarDecl :: String -> Stmt ()+ VarDeclAssign :: String -> Exp t -> Stmt ()+ VarAssign :: String -> Exp t -> Stmt ()+ ExpStmt :: Exp t -> Stmt ()+ While :: Exp Bool -> Block () -> Stmt ()+ DoWhile :: Block () -> Exp Bool -> Stmt ()+ For :: Stmt t1 -> Exp Bool -> Exp t2 -> Block () -> Stmt () + Break :: Stmt ()+ Continue :: Stmt ()+ Return :: Exp t -> Stmt t+ If :: Exp Bool -> Block t -> Elses t -> Stmt ()+ +data Elses t where+ Elseif :: Exp Bool -> Block t -> Elses t -> Elses t+ Else :: Block t -> Elses t+ NoElse :: Elses () + +instance Show (Stmt t) where+ showsPrec p stm = case stm of+ VarDecl s -> showString "var" . sSpace . showString s+ VarAssign s e -> showString s . showString " = " . shows e+ VarDeclAssign s e -> showString "var" . sSpace . showString s . + showString " = " . shows e + ExpStmt e -> shows e+ While e b -> showString "while" . showParen True (shows e) . + sBrack b+ DoWhile b e -> showString "do" . sBrack b . showString "while" . + showParen True (shows e)+ For e1 e2 e3 b -> showString "for" . + showParen True (shows e1 . sc . shows e2 . + sc . shows e3) . sBrack b+ Break -> showString "break"+ Continue -> showString "continue"+ Return e -> showString "return" . showString " " . shows e+ If e1 b1 b2 -> showString "if" . showParen True (shows e1) . + sBrack b1 . shows b2++instance Show (Elses t) where+ showsPrec p elses = case elses of+ Elseif e b els -> showString "else" . sBrack b . shows els+ Else b -> showString "else" . sBrack b+ NoElse -> id +++sBrack s = showString "{" . shows s . showString "}"+sSpace = showString " "+sEq = showString " = "+sDot = showString "." +sc = showString ";" +sNl = showString "\n"+sJtr s = showString "'" . showString s . showString "'"+sMaybe Nothing = id+sMaybe (Just s) = showString s+++-------------------------------------------------------------------+-- JavaScript block representation+-------------------------------------------------------------------+data Block t where+ EmptyBlock :: Block ()+ Sequence :: Block () -> Stmt t -> Block t++instance Show (Block t) where+ showsPrec p block = case block of+ EmptyBlock -> id+ Sequence b stm -> shows b . shows stm . sc+ +-------------------------------------------------------------------+-- Parameters and functions+-------------------------------------------------------------------++-- | Class for parameter types to JavaScript functions+class ParamType t++-- | Instanses for tuples,triples etc..+instance ParamType ()+instance JType t => ParamType t+instance (JType t1, JType t2 ) => ParamType (t1,t2)+instance (JType t1, JType t2, JType t3 ) => ParamType (t1,t2,t3)+instance (JType t1, JType t2, JType t3, JType t4) => ParamType (t1,t2,t3,t4)+instance (JType t1, JType t2, JType t3, JType t4, JType t5) => ParamType (t1,t2,t3,t4,t5)+++-- | JFormal params represents parameters passed to a function along with their+-- corresponding types.+class (Show a , ParamType t) => FormalParams a t | a -> t where+ mkFParams :: forall b. (a -> b) -> Int -> a+ showsFParams :: a -> ShowS++instance FormalParams () () where+ mkFParams _ _ = ()+ showsFParams = shows ++instance ParamType t => FormalParams (Var t) t where+ mkFParams _ n = (JParam $ "param" ++ show n ++ "_0") + showsFParams = showParen True . shows+++instance (ParamType (t1,t2)) => FormalParams (Var t1, Var t2) (t1,t2) where+ mkFParams _ n = (JParam $ "param" ++ show n ++ "_0", JParam $ "param" ++ show n ++ "_1")+ showsFParams = shows++instance (ParamType (t1,t2,t3)) => FormalParams (Var t1, Var t2, Var t3) (t1,t2,t3) where+ mkFParams _ n = (JParam $ "param" ++ show n ++ "_0", JParam $ "param" ++ show n ++ "_1", JParam $ "param" ++ show n ++ "_2")+ showsFParams = shows +++instance (ParamType (t1,t2,t3,t4)) => FormalParams (Var t1, Var t2, Var t3, Var t4) (t1,t2,t3,t4) where+ mkFParams _ n = (JParam $ "param" ++ show n ++ "_0", JParam $ "param" ++ show n ++ "_1", + JParam $ "param" ++ show n ++ "_2", JParam $ "param" ++ show n ++ "_3")+ showsFParams = shows ++instance (ParamType (t1,t2,t3,t4,t5)) => FormalParams (Var t1, Var t2, Var t3, Var t4, Var t5) (t1,t2,t3,t4,t5) where+ mkFParams _ n = (JParam $ "param" ++ show n ++ "_0", JParam $ "param" ++ show n ++ "_1", + JParam $ "param" ++ show n ++ "_2", JParam $ "param" ++ show n ++ "_3", + JParam $ "param" ++ show n ++ "_4")+ showsFParams = shows +++-- | Args represents types that can be passed as arguments to+-- JavaScript functions.+class Show e => Args e t | e -> t where+ showsArgs :: e -> ShowS+ +instance Args () () where+ showsArgs = shows+ +instance Args (Exp t) t where+ showsArgs = showParen True . shows++instance Args (Exp t1, Exp t2) (t1,t2) where+ showsArgs = shows+ +instance Args (Exp t1, Exp t2, Exp t3) (t1,t2,t3) where+ showsArgs = shows++instance Args (Exp t1, Exp t2, Exp t3, Exp t4) (t1,t2,t3,t4) where+ showsArgs = shows++instance Args (Exp t1, Exp t2, Exp t3, Exp t4, Exp t5) (t1,t2,t3,t4,t5) where+ showsArgs = shows++ +class VarsToExps v e | v -> e, e -> v where + v2e :: v -> e + +instance VarsToExps () () where + v2e = id + +instance VarsToExps (Var t) (Exp t) where + v2e = val + +instance VarsToExps (Var t1, Var t2) (Exp t1, Exp t2) where + v2e (v1,v2) = (val v1,val v2) ++instance VarsToExps (Var t1, Var t2, Var t3) (Exp t1, Exp t2, Exp t3) where + v2e (v1,v2,v3) = (val v1,val v2,val v3) ++instance VarsToExps (Var t1, Var t2, Var t3, Var t4) (Exp t1, Exp t2, Exp t3, Exp t4) where + v2e (v1,v2,v3,v4) = (val v1,val v2,val v3,val v4) + +instance VarsToExps (Var t1, Var t2, Var t3, Var t4, Var t5) (Exp t1, Exp t2, Exp t3, Exp t4, Exp t5) where + v2e (v1,v2,v3,v4,v5) = (val v1,val v2,val v3,val v4,val v5) + +--------------------------------------------------------------------+-- Object representation+-------------------------------------------------------------------+-- Class for representing 'class' elements in javascript (e.g. Math)+class Show c => IsClass c++-- | Class for binding objects with constructors. E.g. o = new Date();+class (IsClass c, Args e t) => HasConstructor c e t++-- | Class for derefable data types, used to allow the creation of +-- dereferencing objects. Examples: Math.random() or document.write()+class Show r => IsDeref r++-- There are two kinds of dereferencing; either from classes or objects.+instance IsClass c => IsDeref c+instance IsClass c => IsDeref (Exp c)++-------------------------------------------------------------------+-- | Class for representing expressions.+-- First parameter is the expression, second a TBool for variable or constant.+-- Third parameter represents the type.+-------------------------------------------------------------------++class IsExp e t | e -> t where+ toExp :: e -> Exp t++instance IsExp (Exp t) t where+ toExp = id++instance IsExp String String where+ toExp = JString++instance IsExp Int Int where+ toExp = JInt++instance IsExp Float Float where+ toExp = JFloat++instance IsExp Bool Bool where+ toExp = JBool+++-- | Class for JString expressions+class IsExp e String => IsJString e where+ toJString :: e -> Exp String+ toJString = toExp+ +-- | Class for JInt expressions+class IsExp e Int => IsJInt e where+ toJInt :: e -> Exp Int+ toJInt = toExp+ +-- | Class for JFloat expressions+class IsExp e Float => IsJFloat e where+ toJFloat :: e -> Exp Float+ toJFloat = toExp+ ++-- | Class for JBool expressions+class IsExp e Bool => IsJBool e where+ toJBool :: e -> Exp Bool+ toJBool = toExp+++instance IsExp e String => IsJString e++instance IsExp e Int => IsJInt e++instance IsExp e Float => IsJFloat e++instance IsExp e Bool => IsJBool e++-------------------------------------------------------------------+-- Array+-------------------------------------------------------------------+-- | Array representation+data Array t = Array deriving Show+instance IsClass (Array t)++-------------------------------------------------------------------+-- Helper functions+-------------------------------------------------------------------++-- Dereferencing+deref str obj = JDeref obj str+ +derefVar str obj = JDerefVar obj str ++-- Calling a function+call :: (Args e t) => Exp (t -> r) -> e -> Exp r+call = JCall++-- Method call returning an expression.+methodCall :: (Args e t1, IsDeref d) => String -> e -> d -> Exp t2+methodCall fun args obj = JCall (JDeref obj fun) args++-- Method call for void methods. Returns a Stmt since the return value is+-- not of any interest.+voidMethodCall :: (Args e t1, IsDeref a) => String -> e -> a -> Stmt ()+voidMethodCall fun args = ExpStmt . methodCall fun args++-- Method call for functions without input parameters. Just adds the extra+-- dummy argument ().+methodCallNoArgs ::IsDeref d => String -> d -> Exp t+methodCallNoArgs name = methodCall name ()++-- Method call for functions without input parameters returning void.+voidMethodCallNoArgs ::IsDeref d => String -> d -> Stmt ()+voidMethodCallNoArgs name = ExpStmt . methodCall name ()+++-- | Generates a Block from a Stmt.+toBlock :: Stmt t -> Block t+toBlock stm = Sequence EmptyBlock stm+ + +-- | Get the value of a variable. +val :: Var t -> Exp t +val = JValueOf