diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs
index 5845ec2..0617f98 100644
--- a/backends/GenerateC.hs
+++ b/backends/GenerateC.hs
@@ -37,6 +37,7 @@ import EvalLiterals
import Metadata
import Pass
import Errors
+import ShowCode
import TLP
import Types
import Utils
@@ -117,6 +118,7 @@ data GenOps = GenOps {
genLiteral :: GenOps -> A.LiteralRepr -> CGen (),
genLiteralRepr :: GenOps -> A.LiteralRepr -> CGen (),
genMissing :: GenOps -> String -> CGen (),
+ genMissingC :: GenOps -> CGen String -> CGen (),
genMonadic :: GenOps -> Meta -> A.MonadicOp -> A.Expression -> CGen (),
genOutput :: GenOps -> A.Variable -> [A.OutputItem] -> CGen (),
genOutputCase :: GenOps -> A.Variable -> A.Name -> [A.OutputItem] -> CGen (),
@@ -204,6 +206,7 @@ cgenOps = GenOps {
genLiteral = cgenLiteral,
genLiteralRepr = cgenLiteralRepr,
genMissing = cgenMissing,
+ genMissingC = (\ops x -> x >>= cgenMissing ops),
genMonadic = cgenMonadic,
genOutput = cgenOutput,
genOutputCase = cgenOutputCase,
@@ -376,7 +379,7 @@ cgenType _ (A.Chan _ _ t) = tell ["Channel *"]
cgenType ops t
= case call getScalarType ops t of
Just s -> tell [s]
- Nothing -> call genMissing ops $ "genType " ++ show t
+ Nothing -> call genMissingC ops $ formatCode "genType %" t
-- | Generate the number of bytes in a type that must have a fixed size.
cgenBytesIn :: GenOps -> A.Type -> Maybe A.Variable -> CGen ()
@@ -423,7 +426,7 @@ cgenBytesIn' _ (A.Chan {}) _
cgenBytesIn' ops t _
= case call getScalarType ops t of
Just s -> tell ["sizeof (", s, ")"] >> return Nothing
- Nothing -> die $ "genBytesIn' " ++ show t
+ Nothing -> dieC $ formatCode "genBytesIn' %" t
--}}}
--{{{ declarations
@@ -817,7 +820,7 @@ cgenTypeSymbol :: GenOps -> String -> A.Type -> CGen ()
cgenTypeSymbol ops s t
= case call getScalarType ops t of
Just ct -> tell ["occam_", s, "_", ct]
- Nothing -> call genMissing ops $ "genTypeSymbol " ++ show t
+ Nothing -> call genMissingC ops $ formatCode "genTypeSymbol %" t
cgenIntrinsicFunction :: GenOps -> Meta -> String -> [A.Expression] -> CGen ()
cgenIntrinsicFunction ops m s es
@@ -1503,7 +1506,7 @@ cgenAssign ops m [v] el
tell [" = "]
call genExpression ops e
tell [";\n"]
- Nothing -> call genMissing ops $ "assignment of type " ++ show t
+ Nothing -> call genMissingC ops $ formatCode "assignment of type %" t
--}}}
--{{{ input
cgenInput :: GenOps -> A.Variable -> A.InputMode -> CGen ()
diff --git a/backends/GenerateCPPCSP.hs b/backends/GenerateCPPCSP.hs
index d9d7d34..d719e0e 100644
--- a/backends/GenerateCPPCSP.hs
+++ b/backends/GenerateCPPCSP.hs
@@ -87,6 +87,7 @@ import EvalLiterals
import Metadata
import Pass
import Errors
+import ShowCode
import TLP
import Types
import Utils
@@ -1079,7 +1080,7 @@ cppgenType _ (A.Any)
cppgenType ops t
= case call getScalarType ops t of
Just s -> tell [s]
- Nothing -> call genMissing ops $ "genType " ++ show t
+ Nothing -> call genMissingC ops $ formatCode "genType %" t
-- | Helper function for prefixing an underscore to a name.
diff --git a/common/AST.hs b/common/AST.hs
index 372fc4f..80641c1 100644
--- a/common/AST.hs
+++ b/common/AST.hs
@@ -127,34 +127,7 @@ data Type =
| Any
| Timer
| Port Type
- deriving (Eq, Typeable, Data)
-
-instance Show Type where
- show Bool = "BOOL"
- show Byte = "BYTE"
- show UInt16 = "UINT16"
- show UInt32 = "UINT32"
- show UInt64 = "UINT64"
- show Int = "INT"
- show Int8 = "INT8"
- show Int16 = "INT16"
- show Int32 = "INT32"
- show Int64 = "INT64"
- show Real32 = "REAL32"
- show Real64 = "REAL64"
- show (Array ds t)
- = concat [case d of
- Dimension n -> "[" ++ show n ++ "]"
- UnknownDimension -> "[]"
- | d <- ds] ++ show t
- show (UserDataType n) = nameName n ++ "{data type}"
- show (Record n) = nameName n ++ "{record}"
- show (UserProtocol n) = nameName n ++ "{protocol}"
- show (Chan _ _ t) = "CHAN OF " ++ show t
- show (Counted ct et) = show ct ++ "::" ++ show et
- show Any = "ANY"
- show Timer = "TIMER"
- show (Port t) = "PORT OF " ++ show t
+ deriving (Show, Eq, Typeable, Data)
-- | An array dimension.
-- Depending on the context, an array type may have empty dimensions, which is
diff --git a/common/CompState.hs b/common/CompState.hs
index 0572d72..a3cc8ee 100644
--- a/common/CompState.hs
+++ b/common/CompState.hs
@@ -24,6 +24,7 @@ import Data.Map (Map)
import qualified Data.Map as Map
import Data.Set (Set)
import qualified Data.Set as Set
+import Control.Monad.Error
import Control.Monad.State
import qualified AST as A
@@ -77,7 +78,7 @@ data CompState = CompState {
csAdditionalArgs :: Map String [A.Actual],
csParProcs :: Set A.Name
}
- deriving (Show, Data, Typeable)
+ deriving (Data, Typeable)
instance Show (A.Structured -> A.Structured) where
show p = "(function on Structured)"
@@ -247,3 +248,12 @@ makeNonceVariable :: CSM m => String -> Meta -> A.Type -> A.NameType -> A.Abbrev
makeNonceVariable s m t nt am
= defineNonce m s (A.Declaration m t) nt am
--}}}
+
+diePC :: (CSM m, Die m) => Meta -> m String -> m a
+diePC m str = str >>= (dieP m)
+
+dieC :: (CSM m, Die m) => m String -> m a
+dieC str = str >>= die
+
+throwErrorC :: (CSM m,MonadError String m) => m String -> m a
+throwErrorC str = str >>= throwError
diff --git a/common/EvalConstants.hs b/common/EvalConstants.hs
index 1095180..21035b7 100644
--- a/common/EvalConstants.hs
+++ b/common/EvalConstants.hs
@@ -37,6 +37,7 @@ import Errors
import EvalLiterals
import Metadata
import Pass
+import ShowCode
import Types
-- | Simplify an expression by constant folding, and also return whether it's a
@@ -167,7 +168,7 @@ evalExpression (A.BytesInType _ t)
= do b <- underlyingType t >>= bytesInType
case b of
BIJust n -> return $ OccInt (fromIntegral $ n)
- _ -> throwError $ "BYTESIN non-constant-size type " ++ show t ++ " used"
+ _ -> throwErrorC $ formatCode "BYTESIN non-constant-size type % used" t
evalExpression e = throwError "bad expression"
evalMonadicOp :: (forall t. (Num t, Integral t, Bits t) => t -> t) -> OccValue -> EvalM OccValue
diff --git a/common/ShowCode.hs b/common/ShowCode.hs
new file mode 100644
index 0000000..efbc183
--- /dev/null
+++ b/common/ShowCode.hs
@@ -0,0 +1,173 @@
+{-# OPTIONS_GHC -fallow-incoherent-instances #-}
+{-
+Tock: a compiler for parallel languages
+Copyright (C) 2007 University of Kent
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation, either version 2 of the License, or (at your
+option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see .
+-}
+
+-- | A module with type-classes and functions for displaying code, dependent on the context.
+-- Primarily, this means showing code as occam in error messages for the occam frontend, and Rain code for the Rain frontend.
+module ShowCode where
+
+import Control.Monad.State
+import Text.Regex
+import qualified AST as A
+import CompState
+
+-- | A type-class that indicates that the data (AST item) is displayable as occam code.
+class ShowOccam a where
+ showOccam :: a -> String
+
+-- | A type-class that indicates that the data (AST item) is displayable as Rain code.
+class ShowRain a where
+ showRain :: a -> String
+
+-- | Shows the given code (AST item) as either occam or Rain code, depending on which frontend was selected
+showCode :: (CSM m, ShowOccam a, ShowRain a) => a -> m String
+showCode o
+ = do st <- get
+ return $ case csFrontend st of
+ FrontendOccam -> showOccam o
+ FrontendRain -> showRain o
+
+-- | Some type hackery to allow formatCode to take a variable number of functions.
+class CSM m => ShowCodeFormat a m | a -> m where
+ chain :: [String] -> [m String] -> a
+
+instance CSM m => ShowCodeFormat (m String) m where
+ chain xs ys = (liftM concat) (sequence $ interleave (map return xs) (ys))
+ where
+ --Given [a,b,c] [1,2], produces [a,1,b,2,c] etc
+ interleave :: [a] -> [a] -> [a]
+ interleave xs [] = xs
+ interleave [] ys = ys
+ interleave (x:xs) (y:ys) = (x:y: (interleave xs ys))
+
+
+instance (ShowOccam a, ShowRain a, ShowCodeFormat r m, CSM m) => ShowCodeFormat (a -> r) m where
+ chain a x = (\y -> chain a (x ++ [showCode y]))
+
+
+-- | Formats the given code as either occam or Rain code, depending on the frontend (using showCode).
+-- Use like this:
+-- dieC $ formatCode "Types do not match: % and %" ta tb
+formatCode :: (CSM m,ShowCodeFormat r m) => String -> r
+formatCode fmt = chain (splitRegex (mkRegex "%") fmt) []
+
+
+--Type-class instances follow for ShowOccam and ShowRain:
+
+instance ShowOccam A.Type where
+ showOccam A.Bool = "BOOL"
+ showOccam A.Byte = "BYTE"
+ showOccam A.UInt16 = "UINT16"
+ showOccam A.UInt32 = "UINT32"
+ showOccam A.UInt64 = "UINT64"
+ showOccam A.Int = "INT"
+ showOccam A.Int8 = "INT8"
+ showOccam A.Int16 = "INT16"
+ showOccam A.Int32 = "INT32"
+ showOccam A.Int64 = "INT64"
+ showOccam A.Real32 = "REAL32"
+ showOccam A.Real64 = "REAL64"
+ showOccam (A.Array ds t)
+ = concat [case d of
+ A.Dimension n -> "[" ++ show n ++ "]"
+ A.UnknownDimension -> "[]"
+ | d <- ds] ++ showOccam t
+ showOccam (A.UserDataType n) = A.nameName n ++ "{data type}"
+ showOccam (A.Record n) = A.nameName n ++ "{record}"
+ showOccam (A.UserProtocol n) = A.nameName n ++ "{protocol}"
+ showOccam (A.Chan _ _ t) = "CHAN OF " ++ showOccam t
+ showOccam (A.Counted ct et) = showOccam ct ++ "::" ++ showOccam et
+ showOccam A.Any = "ANY"
+ showOccam A.Timer = "TIMER"
+ showOccam (A.Port t) = "PORT OF " ++ showOccam t
+
+
+instance ShowRain A.Type where
+ showRain A.Bool = "bool"
+ showRain A.Byte = "uint8"
+ showRain A.UInt16 = "uint16"
+ showRain A.UInt32 = "uint32"
+ showRain A.UInt64 = "uint64"
+ showRain A.Int8 = "sint8"
+ showRain A.Int16 = "sint16"
+ showRain A.Int32 = "sint32"
+ showRain A.Int64 = "int"
+ showRain A.Int = "int"
+ showRain (A.Chan dir attr t)
+ = case dir of
+ A.DirUnknown -> "channel " ++ ao (A.caWritingShared attr) ++ "2" ++ ao (A.caReadingShared attr) ++ " " ++ showRain t
+ A.DirInput -> (if A.caReadingShared attr then "shared" else "") ++ " ?" ++ showRain t
+ A.DirOutput -> (if A.caWritingShared attr then "shared" else "") ++ " !" ++ showRain t
+ where
+ ao :: Bool -> String
+ ao b = if b then "any" else "one"
+ showRain x = ""
+
+instance ShowOccam A.DyadicOp where
+ showOccam A.Add = "+"
+ showOccam A.Subtr = "-"
+ showOccam A.Mul = "*"
+ showOccam A.Div = "/"
+ showOccam A.Rem = "REM"
+ showOccam A.Plus = "PLUS"
+ showOccam A.Minus = "MINUS"
+ showOccam A.Times = "TIMES"
+ showOccam A.BitAnd = "/\\"
+ showOccam A.BitOr = "\\/"
+ showOccam A.BitXor = "><"
+ showOccam A.LeftShift = "<<"
+ showOccam A.RightShift = ">>"
+ showOccam A.And = "AND"
+ showOccam A.Or = "OR"
+ showOccam A.Eq = "="
+ showOccam A.NotEq = "<>"
+ showOccam A.Less = "<"
+ showOccam A.More = ">"
+ showOccam A.LessEq = "<="
+ showOccam A.MoreEq = ">="
+ showOccam A.After = "AFTER"
+
+
+instance ShowRain A.DyadicOp where
+ showRain A.Div = "/"
+ showRain A.Rem = "%"
+ showRain A.Plus = "+"
+ showRain A.Minus = "-"
+ showRain A.Times = "*"
+ showRain A.And = "and"
+ showRain A.Or = "or"
+ showRain A.Eq = "=="
+ showRain A.NotEq = "<>"
+ showRain A.Less = "<"
+ showRain A.More = ">"
+ showRain A.LessEq = "<="
+ showRain A.MoreEq = ">="
+ showRain x = ""
+
+instance ShowOccam A.Variable where
+ showOccam (A.Variable _ n) = show n
+ showOccam (A.SubscriptedVariable _ s v) = showOccam v ++ "[" ++ show s ++ "]"
+ showOccam (A.DirectedVariable _ A.DirUnknown v) = showOccam v
+ showOccam (A.DirectedVariable _ A.DirInput v) = showOccam v ++ "?"
+ showOccam (A.DirectedVariable _ A.DirOutput v) = showOccam v ++ "!"
+
+instance ShowRain A.Variable where
+ showRain (A.Variable _ n) = show n
+ showRain (A.DirectedVariable _ A.DirInput v) = "?" ++ showRain v
+ showRain (A.DirectedVariable _ A.DirOutput v) = "!" ++ showRain v
+ showRain x = ""
diff --git a/common/TestUtil.hs b/common/TestUtil.hs
index e044ba7..1a146ab 100644
--- a/common/TestUtil.hs
+++ b/common/TestUtil.hs
@@ -49,6 +49,7 @@ import Control.Monad.State
import Control.Monad.Error
import Pass
import CompState
+import PrettyShow
import Utils
import qualified Data.Map as Map
@@ -332,7 +333,7 @@ testPassShouldFail testName actualPass startStateTrans =
do ret <- runPass actualPass (execState startStateTrans emptyState)
case ret of
(_,Left err) -> return ()
- _ -> assertFailure $ testName ++ " pass succeeded when expected to fail, data: " ++ (show ret)
+ _ -> assertFailure $ testName ++ " pass succeeded when expected to fail, data: " ++ (pshow ret)
-- | Asserts that a particular variable is defined in the given 'CompState'.
assertVarDef ::
diff --git a/common/Types.hs b/common/Types.hs
index 1763d8b..bc37c9c 100644
--- a/common/Types.hs
+++ b/common/Types.hs
@@ -48,6 +48,7 @@ import Errors
import EvalLiterals
import Intrinsics
import Metadata
+import ShowCode
import Utils
-- | Gets the 'A.SpecType' for a given 'A.Name' from the recorded types in the 'CompState'. Dies with an error if the name is unknown.
@@ -124,7 +125,7 @@ plainSubscriptType m sub (A.Array (d:ds) t)
ok = case ds of
[] -> t
_ -> A.Array ds t
-plainSubscriptType m _ t = dieP m $ "subscript of non-array type " ++ show t
+plainSubscriptType m _ t = diePC m $ formatCode "subscript of non-array type: %" t
-- | Apply a subscript to a type, and return what the type is after it's been
-- subscripted.
@@ -145,7 +146,7 @@ subscriptType (A.SubscriptFor m count) t
= sliceType m (makeConstant emptyMeta 0) count t
subscriptType (A.SubscriptField m tag) t = typeOfRecordField m t tag
subscriptType (A.Subscript m sub) t = plainSubscriptType m sub t
-subscriptType _ t = die $ "unsubscriptable type: " ++ show t
+subscriptType sub t = diePC (findMeta sub) $ formatCode "Unsubscriptable type: %" t
-- | The inverse of 'subscriptType': given a type that we know is the result of
-- a subscript, return what the type being subscripted is.
@@ -165,10 +166,10 @@ unsubscriptType (A.Subscript _ sub) t
-- subscriptType with constant 0 as a subscript, but without the checking.
-- This is used for the couple of cases where we know it's safe and don't want
-- the usage check.
-trivialSubscriptType :: (Die m) => A.Type -> m A.Type
+trivialSubscriptType :: (CSM m, Die m) => A.Type -> m A.Type
trivialSubscriptType (A.Array [d] t) = return t
trivialSubscriptType (A.Array (d:ds) t) = return $ A.Array ds t
-trivialSubscriptType t = die $ "not plain array type: " ++ show t
+trivialSubscriptType t = dieC $ formatCode "not plain array type: %" t
-- | Gets the 'A.Type' of a 'A.Variable' by looking at the types recorded in the 'CompState'.
typeOfVariable :: (CSM m, Die m) => A.Variable -> m A.Type
diff --git a/frontends/ParseOccam.hs b/frontends/ParseOccam.hs
index 6f45d9d..3f51884 100644
--- a/frontends/ParseOccam.hs
+++ b/frontends/ParseOccam.hs
@@ -38,6 +38,7 @@ import Intrinsics
import LexOccam
import Metadata
import Pass
+import ShowCode
import Types
import Utils
@@ -294,7 +295,7 @@ maybeSliced inner subscripter typer
t <- typer v >>= underlyingType
case t of
(A.Array _ _) -> return ()
- _ -> fail $ "slice of non-array type " ++ show t
+ _ -> fail $ "slice of non-array type " ++ showOccam t
e <- intExpr
sub <- case ff1 of
@@ -392,7 +393,7 @@ matchType et rt
else bad
_ -> if rt == et then return () else bad
where
- bad = fail $ "type mismatch (got " ++ show rt ++ "; expected " ++ show et ++ ")"
+ bad = fail $ "type mismatch (got " ++ showOccam rt ++ "; expected " ++ showOccam et ++ ")"
-- | Check that two lists of types match (for example, for parallel assignment).
matchTypes :: [A.Type] -> [A.Type] -> OccParser ()
@@ -672,7 +673,7 @@ makeLiteral x@(A.Literal m t lr) wantT
typesOK <- isValidLiteralType m t wantT
when (not typesOK) $
- dieP m $ "default type of literal (" ++ show t ++ ") cannot be coerced to desired type (" ++ show wantT ++ ")"
+ dieP m $ "default type of literal (" ++ showOccam t ++ ") cannot be coerced to desired type (" ++ showOccam wantT ++ ")"
case (underT, lr) of
-- An array literal.
@@ -1936,7 +1937,7 @@ actual (A.Formal am t n)
A.Timer -> var timer
A.Port _ -> var (portOfType t)
_ -> var (variableOfType t)
- > "actual of type " ++ show t ++ " for " ++ show n
+ > "actual of type " ++ showOccam t ++ " for " ++ show n
where
var inner = liftM (A.ActualVariable am t) inner
--}}}
diff --git a/frontends/RainTypes.hs b/frontends/RainTypes.hs
index 4be2f02..d90f3b2 100644
--- a/frontends/RainTypes.hs
+++ b/frontends/RainTypes.hs
@@ -27,6 +27,7 @@ import Types
import Control.Monad.State
import CompState
import Metadata
+import ShowCode
-- | A pass that records inferred types. Currently the only place where types are inferred is in seqeach\/pareach loops.
@@ -148,8 +149,7 @@ coerceType :: String -> A.Type -> A.Type -> A.Expression -> PassM A.Expression
coerceType customMsg to from item
= if isImplicitConversionRain from to
then return $ A.Conversion (findMeta item) A.DefaultConversion to item
- else dieP (findMeta item) $ "Could not perform implicit cast from supplied type: " ++ (show from) ++
- " to expected type: " ++ (show to) ++ customMsg
+ else diePC (findMeta item) $ (liftM concat) $ sequence [formatCode "Could not perform implicit cast from supplied type: % to expected type: %" from to, return customMsg]
-- | Checks the types in expressions
@@ -161,14 +161,14 @@ checkExpressionTypes = everywhereASTM checkExpression
= do tlhs <- typeOfExpression lhs
trhs <- typeOfExpression rhs
if (tlhs == trhs)
- then (if validOp op tlhs then return e else dieP m $ "Operator: \"" ++ show op ++ "\" is not valid on type: \"" ++ show tlhs)
+ then (if validOp op tlhs then return e else diePC m $ formatCode "Operator: \"%\" is not valid on type: \"%\"" op tlhs)
else if (isIntegerType tlhs && isIntegerType trhs)
then case (leastGeneralSharedTypeRain [tlhs,trhs]) of
- Nothing -> dieP m $ "Cannot find a suitable type to convert expression to, types are: " ++ show tlhs ++ " and " ++ show trhs
- Just t -> if validOp op t then return $ A.Dyadic m op (convert t tlhs lhs) (convert t trhs rhs) else dieP m $
- "Operator: \"" ++ show op ++ "\" is not valid on type: \"" ++ show tlhs
+ Nothing -> diePC m $ formatCode "Cannot find a suitable type to convert expression to, types are: % and %" tlhs trhs
+ Just t -> if validOp op t then return $ A.Dyadic m op (convert t tlhs lhs) (convert t trhs rhs) else diePC m $
+ formatCode "Operator: \"%\" is not valid on type: \"%\"" op tlhs
else --The operators are not equal, and are not integers. Therefore this must be an error:
- dieP m $ "Mis-matched types; no operator applies to types: " ++ show tlhs ++ " and " ++ show trhs
+ diePC m $ formatCode "Mis-matched types; no operator applies to types: % and %" tlhs trhs
checkExpression e@(A.Monadic m op rhs)
= do trhs <- typeOfExpression rhs
if (op == A.MonadicMinus)
@@ -176,13 +176,13 @@ checkExpressionTypes = everywhereASTM checkExpression
A.Byte -> return $ A.Monadic m op $ convert A.Int16 trhs rhs
A.UInt16 -> return $ A.Monadic m op $ convert A.Int32 trhs rhs
A.UInt32 -> return $ A.Monadic m op $ convert A.Int64 trhs rhs
- A.UInt64 -> dieP m $ "Cannot apply unary minus to type: " ++ show trhs ++ " because there is no type large enough to safely contain the result"
- _ -> if (isIntegerType trhs) then return e else dieP m $ "Trying to apply unary minus to non-integer type: " ++ show trhs
+ A.UInt64 -> diePC m $ formatCode "Cannot apply unary minus to type: % because there is no type large enough to safely contain the result" trhs
+ _ -> if (isIntegerType trhs) then return e else diePC m $ formatCode "Trying to apply unary minus to non-integer type: %" trhs
else if (op == A.MonadicNot)
then
case trhs of
A.Bool -> return e
- _ -> dieP m $ "Cannot apply unary not to non-boolean type: " ++ show trhs
+ _ -> diePC m $ formatCode "Cannot apply unary not to non-boolean type: %" trhs
else dieP m $ "Invalid Rain operator: \"" ++ show op ++ "\""
checkExpression e@(A.Conversion m cm dest rhs)
= do src <- typeOfExpression rhs
@@ -190,7 +190,7 @@ checkExpressionTypes = everywhereASTM checkExpression
then return e
else if isImplicitConversionRain src dest
then return e
- else dieP m $ "Invalid cast from: " ++ show dest ++ " to: " ++ show src
+ else diePC m $ formatCode "Invalid cast from: % to: %" dest src
checkExpression e = return e
convert :: A.Type -> A.Type -> A.Expression -> A.Expression
@@ -266,8 +266,8 @@ checkCommTypes = everywhereASTM checkInputOutput
else
if (innerType == destType)
then return p
- else dieP m $ "Mis-matching types; channel: " ++ show chanVar ++ " has inner-type: " ++ show innerType ++
- " but destination variable: " ++ show destVar ++ " has type: " ++ show destType
+ else diePC m $ formatCode "Mis-matching types; channel: \"%\" has inner-type: % but destination variable: \"%\" has type: %"
+ chanVar innerType destVar destType
_ -> dieP m $ "Tried to input from a variable that is not of type channel: " ++ show chanVar
checkInputOutput p@(A.Output m chanVar [A.OutExpression m' srcExp])
= do chanType <- typeOfVariable chanVar