Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| language:expressions [2023/09/06 10:05] – [External circuit functions] rajit | language:expressions [2025/04/21 17:39] (current) – [Structure references] rajit | ||
|---|---|---|---|
| Line 9: | Line 9: | ||
| * The query expression '' | * The query expression '' | ||
| * Logical shift operators are ''<<'' | * Logical shift operators are ''<<'' | ||
| - | * Bit operations: For a variable '' | + | * Bit operations: For a variable '' |
| * Concatenation: | * Concatenation: | ||
| Line 19: | Line 19: | ||
| * '' | * '' | ||
| + | Syntactic replication is also supported for the operators ''&'', | ||
| + | <code act> | ||
| + | (+ i : 3 : p[i] + 2*i) | ||
| + | </ | ||
| + | and is equivalent to | ||
| + | <code act> | ||
| + | p[0] + 2*0 + p[1] + 2*1 + p[2] + 2*2 | ||
| + | </ | ||
| ===== Parameters and constant expressions ===== | ===== Parameters and constant expressions ===== | ||
| Line 40: | Line 48: | ||
| ===== Expressions in CHP ===== | ===== Expressions in CHP ===== | ||
| - | The same expression syntax is also used in the '' | + | The same expression syntax is also used in the '' |
| + | |||
| + | ==== Bit-width rules ==== | ||
| + | |||
| + | The rules that are used to determine the bit-width of an expression involving circuit variables | ||
| * Each variable has the bit-width specified by its type. | * Each variable has the bit-width specified by its type. | ||
| - | * A constant uses the minimum number of bits needed to represent it. Note that a negative constant is assumed to be a two's complement value, an its bit-width is determined in the same way. | + | * A constant uses the minimum number of bits needed to represent it. Note that a negative constant is assumed to be a two's complement value, an its bit-width is determined in the same way. If you are unsure about what is going to happen and want to control the bit-width of a constant, '' |
| * For unary operators, the bit-width of the result is the same as the bit-width of the argument | * For unary operators, the bit-width of the result is the same as the bit-width of the argument | ||
| * For binary operators and ternary operators where the result is an integer, let //left// be the bit-width of the left-hand side of the operator, and //right// be the bit-width of the right hand side. There are six categories of result bit-widths: | * For binary operators and ternary operators where the result is an integer, let //left// be the bit-width of the left-hand side of the operator, and //right// be the bit-width of the right hand side. There are six categories of result bit-widths: | ||
| Line 64: | Line 76: | ||
| - //left// + 2^//right// - 1 | - //left// + 2^//right// - 1 | ||
| * left shift ''<<'' | * left shift ''<<'' | ||
| - | * For concatenation, | + | * For concatenation, |
| + | * For bitfield extraction, the bitwidth is determined by the number of bits extracted. | ||
| + | ==== Idiosyncrasies ==== | ||
| + | |||
| + | While these bit-width rules are nice because you never lose bits, they can have some unexpected consequences. One of the not-so-nice effects of these rules is that, technically, | ||
| + | |||
| + | <code act> | ||
| + | int< | ||
| + | int< | ||
| + | int< | ||
| + | ... | ||
| + | chp { | ||
| + | ... | ||
| + | x := (a + b) + c; | ||
| + | y := a + (b + c); | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Applying the bit-width rules, the expression '' | ||
| + | |||
| + | Another strange example is: | ||
| + | |||
| + | <code act> | ||
| + | ... | ||
| + | chp { | ||
| + | ... | ||
| + | x := x - 1; | ||
| + | y := y + (-1); | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Now the right hand side of the first assignment takes '' | ||
| + | |||
| + | ==== Conversion from/to integer to/from pure structures ==== | ||
| + | |||
| + | A [[language: | ||
| + | <code act> | ||
| + | mystructname s; | ||
| + | int< | ||
| + | ... | ||
| + | chp { | ||
| + | ... | ||
| + | x := int(s); | ||
| + | s := mystructname(x) | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| + | In this example, '' | ||
| + | The expression " | ||
| + | |||
| + | When a structure has multiple fields, ACT packs them into an integer in left-to-right field order. So, for example, the structure | ||
| + | |||
| + | <code act> | ||
| + | deftype mystruct (int< | ||
| + | </ | ||
| + | |||
| + | would have the '' | ||
| ===== Functions ===== | ===== Functions ===== | ||
| Line 115: | Line 185: | ||
| } | } | ||
| } | } | ||
| + | </ | ||
| + | |||
| + | ===== Structure references ===== | ||
| + | |||
| + | Functions can return [[language: | ||
| + | |||
| + | <code act> | ||
| + | deftype mystruct (int a, b) | ||
| + | { | ||
| + | | ||
| + | function getsum() : int | ||
| + | { | ||
| + | chp { | ||
| + | self := a + b | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | { | ||
| + | chp { | ||
| + | self.a := a + 1; | ||
| + | self.b := b + 1 | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | We can have expressions of the following form: | ||
| + | |||
| + | <code act> | ||
| + | mystruct s; | ||
| + | int a; | ||
| + | ... | ||
| + | chp { | ||
| + | ... | ||
| + | a := s.addone().getsum(); | ||
| + | ... | ||
| + | } | ||
| </ | </ | ||
| Line 208: | Line 316: | ||
| An example of file I/O implemented with external functions can be found in the '' | An example of file I/O implemented with external functions can be found in the '' | ||
| + | |||
| + | ===== Operator Precedence ===== | ||
| + | |||
| + | The operators have the following precedence, from the highest to lowest: | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - ''<<'', | ||
| + | - ''&'' | ||
| + | - '' | ||
| + | - '' | ||
| + | - ''?'' | ||