Skip to content

Commit 2917e47

Browse files
authored
Implement TStrCat, TNumToStr type functions, StrAlias typeclass
1 parent 86236bf commit 2917e47

File tree

15 files changed

+182
-17
lines changed

15 files changed

+182
-17
lines changed

doc/BSV_ref_guide/BSV_lang.tex

+4-3
Original file line numberDiff line numberDiff line change
@@ -3972,14 +3972,15 @@ \subsection{Type synonyms}
39723972

39733973
\index{Alias}
39743974
\index{NumAlias}
3975+
\index{StrAlias}
39753976

39763977
The \te{typedef} statement must always be at the top level of a
39773978
package, not within a module. To introduce a local name within a
3978-
module, use \te{Alias} or \te{NumAlias} (see \LibRefGuide). Since
3979+
module, use \te{Alias}, \te{NumAlias} or \te{StrAlias} (see \LibRefGuide). Since
39793980
these introduce new names which are type variables as opposed to
39803981
types, the new names must begin with lower case letters.
3981-
\te{NumAlias} is used to give new names to numeric types, while
3982-
\te{Alias} is used for types which can be the types of variables.
3982+
\te{Alias} is used for types which can be the types of variables,
3983+
while \te{NumAlias} and \te{StrAlias} are used to give new names to numeric and string types.
39833984
Example:
39843985

39853986
\begin{verbatim}

doc/libraries_ref_guide/LibDoc/Prelude.tex

+55-2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ \subsection{Type classes}
4848
\hline
4949
\te{NumAlias} & Types which give a new name to a numeric type.\\
5050
\hline
51+
\te{StrAlias} & Types which give a new name to a string type.\\
52+
\hline
5153
\te{FShow} & Types which can convert a value to a \te{Fmt}
5254
representation for use with \te{\$display} system tasks.\\
5355
\hline
@@ -1457,8 +1459,10 @@ \subsubsection{Alias and NumAlias}
14571459
\label{sec-alias}
14581460
\index{Alias}
14591461
\index{NumAlias}
1460-
\index[typeclass]{NumAlias}
1462+
\index{StrAlias}
14611463
\index[typeclass]{Alias}
1464+
\index[typeclass]{NumAlias}
1465+
\index[typeclass]{StrAlias}
14621466

14631467
\te{Alias} specifies that two types can be used interchangeably,
14641468
providing a way to introduce local names for types within a module.
@@ -1480,6 +1484,15 @@ \subsubsection{Alias and NumAlias}
14801484
endtypeclass
14811485
\end{verbatim}
14821486

1487+
\te{StrAlias} is used to give a new name to a string type.
1488+
1489+
\begin{verbatim}
1490+
typeclass StrAlias#(string type a, string type b)
1491+
dependencies (a determines b,
1492+
b determines a);
1493+
endtypeclass
1494+
\end{verbatim}
1495+
14831496
{\bf Examples}
14841497
\begin{verbatim}
14851498
Alias#(fp, FixedPoint#(i,f));
@@ -4154,7 +4167,7 @@ \subsubsection{Rules}
41544167

41554168

41564169
%================================================================
4157-
\subsection{Operations on Numeric Types}
4170+
\subsection{Operations on Numeric and String Types}
41584171

41594172
\subsubsection{Size Relationship/Provisos}
41604173

@@ -4338,6 +4351,46 @@ \subsubsection{valueOf and SizeOf pseudo-functions}
43384351
Bit#(SizeOf#(any_type)) = pack(structIn);
43394352
\end{libverbatim}
43404353

4354+
% ================================================================
4355+
\subsubsection{String type pseudo-functions}
4356+
\index{stringOf@\texttt{valueOf} (pseudo-function of types)}
4357+
\index{TStrCat@\texttt{TStrCat} (pseudo-function on types)}
4358+
\index{TNumToStr@\texttt{TNumToStr} (pseudo-function on types)}
4359+
\index[function]{Prelude!stringOf}
4360+
\index[function]{Prelude!TStrCat}
4361+
\index[function]{Prelude!TNumToStr}
4362+
4363+
Prelude also provides similar pseudo-functions for string types.
4364+
The pseudo-function \te{stringOf} is used to convert a string type into a \te{String} value.
4365+
The type-level pseudo-function \te{TStrCat} is used to concatenate two string types,
4366+
and \te{TNumToStr} is used to convert a numeric type into a string type.
4367+
4368+
\begin{center}
4369+
\begin{tabular}{|p{1 in}|p{4.6 in}|}
4370+
\hline
4371+
& \\
4372+
\te{stringOf}&Converts a string type into its String value.\\
4373+
\cline{2-2}
4374+
&\begin{libverbatim}
4375+
function String stringOf (t) ;
4376+
\end{libverbatim}
4377+
\\
4378+
\hline
4379+
\end{tabular}
4380+
\end{center}
4381+
4382+
\begin{center}
4383+
\begin{tabular}{|p {1 in}|p{1.5 in}| p{2.0 in}|}
4384+
\hline
4385+
Type Function& Type Relationship& Description\\
4386+
\hline
4387+
\hline
4388+
\te{TStrCat}&\verb'TStrCat#(s1,s2)'&Concatenate $s1$ and $s2$\\
4389+
\hline
4390+
\te{TNumToStr}&\verb'TNumToStr#(n)'&Convert numeric type $n$ to a string type\\
4391+
\hline
4392+
\end{tabular}
4393+
\end{center}
43414394

43424395
% ================================================================
43434396
\subsection{Registers and Wires}

src/Libraries/Base1/Prelude.bs

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ package Prelude(
77
PrimParam(..), PrimPort(..),
88
Bit, Rules, Module, Integer, Real, String, Char, SizeOf, Id__,
99
PrimAction, ActionValue, Action, ActionValue_, ActionWorld, AVStruct,
10-
TAdd, TSub, TMul, TDiv, TLog, TExp, TMax, TMin,
10+
TAdd, TSub, TMul, TDiv, TLog, TExp, TMax, TMin, TStrCat, TNumToStr,
1111
Nat(..),
1212
IsModule(..), addModuleRules, addRules,
1313

@@ -2770,6 +2770,9 @@ primitive type TExp :: # -> #
27702770
primitive type TMax :: # -> # -> #
27712771
primitive type TMin :: # -> # -> #
27722772

2773+
primitive type TStrCat :: $ -> $ -> $
2774+
primitive type TNumToStr :: # -> $
2775+
27732776
------------------
27742777

27752778
--- Bit operations

src/Libraries/Base1/PreludeBSV.bsv

+9-1
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ endfunction: lcm
11131113

11141114
// =========================
11151115

1116-
// Alias and NumAlias
1116+
// Alias, NumAlias and StrAlias
11171117

11181118
typeclass Alias#(type a, type b)
11191119
dependencies (a determines b,
@@ -1131,6 +1131,14 @@ endtypeclass
11311131
instance NumAlias#(a,a);
11321132
endinstance
11331133

1134+
typeclass StrAlias#(string type a, string type b)
1135+
dependencies (a determines b,
1136+
b determines a);
1137+
endtypeclass
1138+
1139+
instance StrAlias#(a,a);
1140+
endinstance
1141+
11341142
// =========================
11351143

11361144
// Saturation Modes

src/comp/CType.hs

+10-2
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,13 @@ import Position
6666
import Id
6767
import IdPrint
6868
import PreIds(idArrow, idPrimPair, idPrimUnit, idBit, idString,
69-
idPrimAction, idAction, idActionValue_, idActionValue
69+
idPrimAction, idAction, idActionValue_, idActionValue,
70+
idTNumToStr
7071
{-, idSizeOf -})
7172
import Util(itos)
7273
import ErrorUtil
7374
import Pragma(IfcPragma)
74-
import NumType
75+
import TypeOps
7576
import PVPrint(PVPrint(..))
7677
import FStringCompat
7778

@@ -507,6 +508,13 @@ normTAp (TCon (TyCon op _ _)) (TCon (TyNum x xpos))
507508
| isJust (res) = cTNum (fromJust res) (getPosition op)
508509
where res = opNumT op [x]
509510

511+
normTAp (TAp (TCon (TyCon op _ _)) (TCon (TyStr x xpos))) (TCon (TyStr y ypos))
512+
| isJust (res) = cTStr (fromJust res) (getPosition op)
513+
where res = opStrT op [x, y]
514+
515+
normTAp (TCon (TyCon op _ _)) (TCon (TyNum x xpos))
516+
| op == idTNumToStr = cTStr (mkNumFString x) (getPosition op)
517+
510518
normTAp f a = TAp f a
511519

512520
getTypeKind :: Type -> Maybe Kind

src/comp/ISyntax.hs

+8-2
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ import Eval
9393
import Id
9494
import Wires(ResetId, ClockDomain, ClockId, noClockId, noResetId, noDefaultClockId, noDefaultResetId, WireProps)
9595
import IdPrint
96-
import PreIds(idSizeOf, idId, idBind, idReturn, idPack, idUnpack, idMonad, idLiftModule, idBit, idFromInteger)
96+
import PreIds(idSizeOf, idId, idBind, idReturn, idPack, idUnpack, idMonad, idLiftModule, idBit, idFromInteger, idTNumToStr)
9797
import Backend
9898
import Prim(PrimOp(..))
99-
import NumType
99+
import TypeOps
100100
import ConTagInfo
101101
import VModInfo(VModInfo, vArgs, vName, VName(..), {- VeriPortProp(..), -}
102102
VArgInfo(..), VFieldInfo(..), isParam, VWireInfo)
@@ -105,6 +105,7 @@ import Pragma(Pragma, PProp, RulePragma, ISchedulePragma,
105105
extractSchedPragmaIds, removeSchedPragmaIds, mapSPIds)
106106
import Position
107107
import Data.Maybe
108+
import FStringCompat(mkNumFString)
108109

109110
import qualified Data.Set as S
110111
import Flags
@@ -425,6 +426,11 @@ normITAp (ITAp (ITCon op _ _) (ITNum x)) (ITNum y) | isJust (res) =
425426
normITAp (ITCon op _ _) (ITNum x) | isJust (res) =
426427
mkNumConT (fromJust res)
427428
where res = opNumT op [x]
429+
normITAp (ITAp (ITCon op _ _) (ITStr x)) (ITStr y) | isJust (res) =
430+
ITStr (fromJust res)
431+
where res = opStrT op [x, y]
432+
normITAp (ITCon op _ _) (ITNum x) | op == idTNumToStr =
433+
ITStr (mkNumFString x)
428434

429435
normITAp f@(ITCon op _ _) a | op == idSizeOf && notVar a =
430436
-- trace ("normITAp: " ++ ppReadable (ITAp f a)) $

src/comp/PreIds.hs

+3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ idTLog = prelude_id_no fsTLog
9191
idTExp = prelude_id_no fsTExp
9292
idTMax = prelude_id_no fsTMax
9393
idTMin = prelude_id_no fsTMin
94+
idTStrCat, idTNumToStr :: Id
95+
idTStrCat = prelude_id_no fsTStrCat
96+
idTNumToStr = prelude_id_no fsTNumToStr
9497
idAction, idPrimAction, idToPrimAction, idFromPrimAction :: Id
9598
idAction = prelude_id_no fsAction
9699
idPrimAction = prelude_id_no fsPrimAction

src/comp/PreStrings.hs

+2
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ fsTLog = mkFString "TLog"
279279
fsTExp = mkFString "TExp"
280280
fsTMax = mkFString "TMax"
281281
fsTMin = mkFString "TMin"
282+
fsTStrCat = mkFString "TStrCat"
283+
fsTNumToStr = mkFString "TNumToStr"
282284
fsStaticAssert = mkFString "staticAssert"
283285
fsDynamicAssert = mkFString "dynamicAssert"
284286
fsContinuousAssert = mkFString "continuousAssert"

src/comp/Pred.hs

+4-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import Position
2020
import Id
2121
import IdPrint
2222
import Type
23-
import NumType
23+
import TypeOps
2424
import PFPrint
2525
import CSyntax(CExpr)
2626
import CType
@@ -261,12 +261,14 @@ expandSyn t0 = exp [] t0 []
261261
truncType k n t = internalError ("expandSyn,truncType\n" ++ ppReadable (k, n, t0, t))
262262

263263
isTFun :: Id -> Bool
264-
isTFun i = i `elem` numOpNames
264+
isTFun i = i `elem` numOpNames ++ strOpNames
265265

266266
apTFun :: Type -> Id -> [Type] -> Type
267267
apTFun _ i [TCon (TyNum x px), TCon (TyNum y py)] | Just n <- opNumT i [x, y] = TCon (TyNum n p')
268268
where p' = bestPosition px py
269269
apTFun _ i [TCon (TyNum x px)] | Just n <- opNumT i [x] = TCon (TyNum n px)
270+
apTFun _ i [TCon (TyStr x px), TCon (TyStr y py)] | Just s <- opStrT i [x, y] = TCon (TyStr s p')
271+
where p' = bestPosition px py
270272
apTFun t _ as = foldl TAp t as
271273

272274
-----------------------------------------------------------------------------

src/comp/NumType.hs src/comp/TypeOps.hs

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
module NumType(opNumT, numOpNames) where
2-
-- common routines for handling numeric types
1+
module TypeOps(opNumT, numOpNames, opStrT, strOpNames) where
2+
-- common routines for handling numeric and string types
33

44
import Id
5-
import PreIds(idTAdd, idTSub, idTMul, idTDiv, idTLog, idTExp, idTMax, idTMin)
5+
import PreIds(idTAdd, idTSub, idTMul, idTDiv, idTLog, idTExp, idTMax, idTMin, idTStrCat, idTNumToStr)
66
import Util(divC, log2)
7+
import FStringCompat(FString, concatFString)
78

89
-- do a numeric type operation on a list of arguments
910
-- note that we have to validate that the result is going to
@@ -20,4 +21,11 @@ opNumT i [x, y] | i == idTMin = Just (min x y)
2021
opNumT _ _ = Nothing
2122

2223
numOpNames :: [Id]
23-
numOpNames = [idTAdd, idTSub, idTMul, idTDiv, idTExp, idTLog, idTMax, idTMin]
24+
numOpNames = [idTAdd, idTSub, idTMul, idTDiv, idTExp, idTLog, idTMax, idTMin, idTNumToStr]
25+
26+
opStrT :: Id -> [FString] -> Maybe FString
27+
opStrT i xs | i == idTStrCat = Just $ concatFString xs
28+
opStrT _ _ = Nothing
29+
30+
strOpNames :: [Id]
31+
strOpNames = [idTStrCat]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package TNumToStr where
2+
3+
data (WrapStr :: $ -> *) s = WrapStr
4+
data (WrapNum :: # -> *) s = WrapNum
5+
6+
printWrapStr :: WrapStr s -> Action
7+
printWrapStr _ = $display (stringOf s)
8+
9+
a :: WrapStr (TNumToStr 42)
10+
a = WrapStr
11+
12+
class FoldNumsStr a s | a -> s where {}
13+
14+
instance (FoldNumsStr a s) => FoldNumsStr (WrapNum i, a) (TStrCat (TNumToStr i) (TStrCat "_" s)) where {}
15+
instance FoldNumsStr (WrapNum i) (TNumToStr i) where {}
16+
instance FoldNumsStr () "" where {}
17+
18+
b :: (FoldNumsStr (WrapNum 1, WrapNum 22, WrapNum 333) s) => WrapStr s
19+
b = WrapStr
20+
21+
c :: (FoldNumsStr () s) => WrapStr s
22+
c = WrapStr
23+
24+
sysTNumToStr :: Module Empty
25+
sysTNumToStr = module
26+
27+
rules
28+
when True ==> do
29+
printWrapStr a
30+
printWrapStr b
31+
printWrapStr c
32+
$finish
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package TStrCat where
2+
3+
data (WrapStr :: $ -> *) s = WrapStr
4+
5+
printWrapStr :: WrapStr s -> Action
6+
printWrapStr _ = $display (stringOf s)
7+
8+
a :: WrapStr (TStrCat "aaa" "bbb")
9+
a = WrapStr
10+
11+
class FlatWrapStr a s | a -> s where {}
12+
13+
instance (FlatWrapStr a s2) => FlatWrapStr (WrapStr s1, a) (TStrCat s1 (TStrCat "_" s2)) where {}
14+
instance FlatWrapStr (WrapStr s) s where {}
15+
instance FlatWrapStr () "" where {}
16+
17+
b :: (FlatWrapStr (WrapStr "aaa", WrapStr "bbb", WrapStr "ccc") s) => WrapStr s
18+
b = WrapStr
19+
20+
c :: (FlatWrapStr () s) => WrapStr s
21+
c = WrapStr
22+
23+
sysTStrCat :: Module Empty
24+
sysTStrCat = module
25+
26+
rules
27+
when True ==> do
28+
printWrapStr a
29+
printWrapStr b
30+
printWrapStr c
31+
$finish

testsuite/bsc.typechecker/string/string.exp

+2
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ test_c_veri StringOf
1515
test_c_veri_bsv StringOfBSV
1616

1717
test_c_veri TypeClassString
18+
test_c_veri TStrCat
19+
test_c_veri TNumToStr
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
42
2+
1_22_333
3+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
aaabbb
2+
aaa_bbb_ccc
3+

0 commit comments

Comments
 (0)