packages feed

KiCS-debugger-0.1.0: biosphere/src/Curry/Debugger/DebugInfo.lhs

> {-# LANGUAGE DeriveDataTypeable #-}
> {-# LANGUAGE FlexibleInstances #-}
> {-# LANGUAGE UndecidableInstances #-}

% DebugInfo.lhs
% Andreas Baldeau
% April 13, 2009

Overview
========

> module Curry.Debugger.DebugInfo (
>     DI (..),
>     StaticInfo (..),
>     DynamicInfo (..),
>     ModID,
>     DefID,
>     Term (..),
>     GenTerm (..)
> ) where

> import Data.Generics
> import Curry.Debugger.Logic

The representation of debug information
=======================================

`DI`
----

Our debug information consist of two different kinds of information. The first
ones are static information i.e. information about the executed code.

> data DI = DebugInfo {
>               staticInfo :: StaticInfo,
>               dynamicInfo :: DynamicInfo
>           }
>  deriving Show

`StaticInfo`
------------

`SrcID` holds a reference to the position in code where the function / data
type / etc. of intrest is defined.

> data StaticInfo  = SrcID {
>                        modID :: ModID,
>                        defID :: DefID
>                    }
>                  | SrcDescr String -- ???
>  deriving (Show,Eq,Data,Typeable)

> type ModID = String -- for the moment its the file name
>            --Integer 
> type DefID = Integer

`DynamicInfo`
-------------

The second kind of information are dynamic ones. They hold concrete values as
arguments to a function call, local variables, etc.

> data DynamicInfo = DynamicInfo {
>                        context :: [(StaticInfo, Term)],
>                        currentValues :: [Term]
>                    }
>  deriving Show

`Term`
------

> data Term = Term String StaticInfo [Term]
>           | TermChar Char
>           | TermInt Integer -- deprecated
>           | TermFloat Float
>           | TermExt StaticInfo ExternalValue
>           | TermUnderscore StaticInfo
>           | TermOr StaticInfo OrRef [Term]
>           | TermFail StaticInfo
>  deriving (Show,Eq,Data,Typeable)

> type ExternalValue = String

The class `GenTerm`
===================

The static information is generated during the transformation of the modules
whereas dynamic information has to be generated at runtime. To be able to get
a represantion e.g. of the value returned by a function one can call `genTerm`
as there is an instance of `GenTerm` generated for every data type.

> class Data a => GenTerm a where
>   genTerm :: a -> Term

	`underscore` returns a representation of a not evaluated expression.

	>   underscore :: a


	The class `GenStaticInfo`
	=========================

	Provides a function to return the static information of a term for given constructor.

	> class GenStaticInfo a where
	>   genStaticInfo :: a -> StaticInfo


	The class `DebugType`
	=====================

	Class that has (is going to / GenTerm deprecated) to be available for all transformed types and provides functions for
	- generating terms for given constructors
	- returning a representation failed calculations
	- creating non-deterministic branches for the type
	- returning a representation of not evaluated terms

	> class DebugType a where
	>   generateTerm :: a -> Term
	>   genfailed :: a
	>   makeOr :: OrRef -> [a] -> a
	>   genunderscore :: a

	`DebugType` instance for `Data` and `GenStaticInfo` types
	---------------------------------------------------------

	Generic instance for all types providing an instance of `Data`.

	> instance (Data a,GenStaticInfo a) => DebugType a where

	>   generateTerm x = let si   = genStaticInfo x
	>                        cons = toConstr x in
	>     case constrIndex cons of

	  Special terms for special constructors:

	>       1 -> TermFail si 
	>       2 -> TermOr si (orRef x) (map generateTerm (branches x))
	>       3 -> TermUnderscore si

	  Regular term for a regular constructor:

	>       _ -> Term (showConstr cons) si [] -- (map generateTerm (args x))

	  The failed representation is the 1st constructor of a transformed type:

	>   genfailed = let res = fromConstr $ indexConstr (dataTypeOf res) 1 in res

	  The or branch representation is the 2nd constructor of a transformed type:

	>   makeOr ref xs = 
	>     let orWithUndefined  = fromConstr $ indexConstr (dataTypeOf (head xs)) 2
	>         orWithArgs = gmapT (castArgs ref xs) orWithUndefined
	>       in orWithArgs

	  The representation for not evaluated calculations is the 3rd constructor of a transformed type:

	>   genunderscore = let res = fromConstr $ indexConstr (dataTypeOf res) 3 in res