alu_op:type=scalar. alu_mov:val(alu_op). alu_add:val(alu_op). alu_sub:var(alu_op). alu(op:val(alu_op),x:val(int),y:val(int)):expr(int)=( case op when alu_mov => x when alu_add => x+y when alu_sub => x-y ). result:=alu(case opcode when 0 => alu_mov when 1 => alu_add when 2 => alu_sub, op1, op2)The power of case statements can be increased by using them in conjunction with vector or record constructors. The following example illustrates how an AND function can be described in this way:
AND(x:val(int),y:val(int)):expr(int)=( case [x,y] when [0,0] => 0 when [0,1] => 0 when [1,0] => 0 when [1,1] => 1 ).It can also be useful to put vector and record constructors on the right hand side of the =>, but note that these constructors cannot be used as the left hand side of an assignment.
Here is a further example of case statements, in this case for instruction decoding, that uses a record constructor:
decoded_instr:type=record(alu_op::alu_op_type, mem_op::mem_op_type, prefetch_op::prefetch_op_type). decode(instr:val(opcode)):expr(decoded_instr)=( cast(decoded_instr, case instr when op_add => { alu_add, mem_none, prefetch_next } when op_sub => { alu_sub, mem_none, prefetch_next } when op_load => { alu_add, mem_load, prefetch_next } when op_store => { alu_add, mem_store, prefetch_next } when op_branch => { alu_add, mem_none, prefetch_branch } ) ).