Skip to content

Commit 30c14a3

Browse files
Add Signature<T> modules for making signature types
1 parent c4fda0f commit 30c14a3

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,15 +444,23 @@ The declared predicate signatures look as follows:
444444
- etc., for `Ternary`, `Quaternary`, and up to `Senary` (six parameter) predicates.
445445

446446
**SignatureTypes.qll** contains various baseline signature types to aid in writing correct
447-
parameterized modules:
447+
parameterized modules, as well as a utility to create a signature type from any existing type.
448448

449449
```ql
450+
// A module that accepts any type that is a subclass of `Expr`:
451+
module MyModule<Qtil::Signature<Expr>::Type ExprType> { ... }>
452+
453+
// A module that accepts any pair of finite types:
450454
module MyModule<Qtil::FiniteType A, Qtil::FiniteType B> { ... }
451455
```
452456

457+
- `Qtil::Signature<T>::Type`: A module that allows you to create a signature type from any existing
458+
type `T`. This is useful for parameterized modules that need to accept a type as a parameter.
453459
- `Qtil::FiniteType`: Any finite type. Supports `newtype`s. No support for primitive types.
454460
- `Qtil::FiniteStringableType`: Any finite class (has a `toString()` member). No support for
455461
`newtype`s or primitive types.
462+
- `Qtil::InfSignature<T>::Type`: Like `Qtil::Signature<T>::Type`, but allows you to create a signature
463+
type from any existing infinite type `T`.
456464
- `Qtil::InfiniteType`: Any finite or infinite type, with `bindingset[this]`. Supports
457465
`newtype`s and primitives.
458466
- `Qtil::InfiniteStringableType`: Any finite or infinite class, with `bindingset[this]`,

src/qtil/parameterization/SignatureTypes.qll

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
/**
2+
* A module to declare any finite type as a signature type, without a separate declaration.
3+
*
4+
* With this module, rather than writing `signature class ExprSig extends Expr;`, you can simply
5+
* declare a module `module MyModule<Signature<Expr>::Type T> { ... }` to declare a parameterized
6+
* module that takes a type that extends `Expr` as a parameter.
7+
*
8+
* To create an infinite signature type, use `InfSignature` instead.
9+
*/
10+
module Signature<FiniteType T> {
11+
signature class Type extends T;
12+
}
13+
14+
/**
15+
* A module to declare any infinite type as a signature type, without a separate declaration.
16+
*
17+
* With this module, rather than writing `signature class MyInt extends int;` with a `bindingset`,
18+
* you can simply declare a module `module MyModule<InfSignature<MyInt>::Type T> { ... }` to declare
19+
* a * parameterized module that takes a type that extends `int` as a parameter.
20+
*
21+
* To create a finite signature type, use `Signature` instead.
22+
*/
23+
module InfSignature<InfiniteType T> {
24+
bindingset[this]
25+
signature class Type extends T;
26+
}
27+
128
/**
229
* A common signature type that can be used to represent any finite type, including `newtype`s.
330
*

0 commit comments

Comments
 (0)