Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| language:types2 [2024/07/18 16:28] – [Macros and Functions] rajit | language:types2 [2025/09/19 10:22] (current) – [Functions] rajit | ||
|---|---|---|---|
| Line 160: | Line 160: | ||
| adder and five-bit adder. | adder and five-bit adder. | ||
| + | ==== Default parameters ==== | ||
| - | ===== Direction flags and user-defined | + | When defining complex user-defined types with many parameters, it can be useful to have |
| + | default parameter values. ACT has syntax to support default parameter values for trailing | ||
| + | parameters in a template definition. | ||
| + | |||
| + | <code act> | ||
| + | template <pint N; pbool active_high | ||
| + | defproc driver(bool? | ||
| + | { | ||
| + | bool sig; | ||
| + | prs { | ||
| + | inp => sig- | ||
| + | } | ||
| + | [active_high -> prs { sig => outp- } | ||
| + | [] else -> sig = outp; | ||
| + | ] | ||
| + | } | ||
| + | </ | ||
| + | (Note: this is not a real signal driver, but the idea here is the you have a parameterized | ||
| + | driver that can drive a fanout of '' | ||
| + | '' | ||
| + | <code act> | ||
| + | driver< | ||
| + | </ | ||
| + | will have four production rules: | ||
| + | <code act> | ||
| + | x.inp -> sig- | ||
| + | ~x.inp -> sig+ | ||
| + | sig -> x.outp- | ||
| + | ~sig -> x.outp+ | ||
| + | </ | ||
| + | However, this behavior can be changed by using: | ||
| + | <code act> | ||
| + | driver< | ||
| + | </ | ||
| + | In this case, '' | ||
| + | |||
| + | Note that ACT is very strict about type-checking; | ||
| + | |||
| + | ==== Grouping parameters ==== | ||
| + | |||
| + | Parameters can be combined into [[language: | ||
| + | |||
| + | ===== Direction flags | ||
| Line 205: | Line 248: | ||
| is detailed in the section on connections. | is detailed in the section on connections. | ||
| - | ===== Macros and Functions ===== | + | ===== Macros and Functions |
| User-defined types support additional methods (beyond the special ones for channels and data types). | User-defined types support additional methods (beyond the special ones for channels and data types). | ||
| Line 213: | Line 256: | ||
| ==== Macros ==== | ==== Macros ==== | ||
| + | |||
| + | A macro is, as the name sounds, a CHP fragment. This fragment is used to substitute for the macro in the places where it is used. Macros can be defined for any user-defined type (except for parameter structures). | ||
| + | |||
| + | <code act> | ||
| + | defproc stack (chan(int)? in; chan(int)!out ) | ||
| + | { | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | In ordinary circumstances, | ||
| + | |||
| + | <code act> | ||
| + | ... | ||
| + | stack s; | ||
| + | int x; | ||
| + | ... | ||
| + | chp { | ||
| + | ... | ||
| + | | ||
| + | ... | ||
| + | | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | As an alternative, | ||
| + | |||
| + | <code act> | ||
| + | defproc stack (chan(int)? in; chan(int)!out ) | ||
| + | { | ||
| + | ... | ||
| + | methods { | ||
| + | macro push(int val) { | ||
| + | in!val | ||
| + | } | ||
| + | macro pop(int res) { | ||
| + | out?res | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | The same stack use case can be written as: | ||
| + | <code act> | ||
| + | ... | ||
| + | stack s; | ||
| + | int x; | ||
| + | ... | ||
| + | chp { | ||
| + | ... | ||
| + | | ||
| + | ... | ||
| + | | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| ==== Functions ==== | ==== Functions ==== | ||
| + | In addition to macros, [[language: | ||
| + | |||
| + | <code act> | ||
| + | deftype signed_int (bool s; int< | ||
| + | { | ||
| + | methods { | ||
| + | function negative() : bool | ||
| + | { | ||
| + | chp { | ||
| + | self := s | ||
| + | } | ||
| + | } | ||
| + | function mag() : int< | ||
| + | { | ||
| + | chp { | ||
| + | self := v | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | With this definition, a user can use method calls to access the fields of the structure as follows: | ||
| + | |||
| + | <code act> | ||
| + | | ||
| + | ... | ||
| + | chp { | ||
| + | ... | ||
| + | [ s.negative() -> log (" | ||
| + | [] else -> log (" | ||
| + | ] | ||
| + | } | ||
| + | ... | ||
| + | </ | ||
| + | |||
| + | Note that functions cannot have any side-effects; | ||
| + | any of the members of the pure structure. Macros can be used to change those. | ||
| + | |||
| + | ==== Operator overloading ==== | ||
| + | |||
| + | Functions within pure structures are also used to support operator overloading. In particular, the following function methods are interpreted to be the definition of operator overloading for arithmetic operators: | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | An example of a fixed-point arithmetic datatype is provided in the [[https:// | ||
| + | In the linked example, '' | ||