BoolEx.mesa
Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved.
Barth, July 17, 1987 5:42:41 pm PDT
Don Curry July 21, 1987 9:13:40 am PDT
Last Edited by: Don Curry December 12, 1987 11:09:13 am PST
Boolean Expressions. See also Bollix: To throw into disorder.
DIRECTORY Basics, IO, SymTab;
BoolEx: CEDAR DEFINITIONS = BEGIN
Expression
MachineDefinition -- A named collection of VariableDefinitions
A Machine Definition is a list where the list operator is "MACH", the first argument is a rope, and the remaining arguments are VariableDefinitions.
VariableDefinition -- An output or intermediate variable definition
A Variable Definition is a 3 element list where the list operator is "VAR" or "OUT", the first argument is a rope, and the remaining argument is a SimpleExpression.
SimpleExpression
A SimpleExpression is a rope or LIST OF REF. If it is a rope then the rope is the name of a variable or primary input. If it is a LIST OF REF then the first member of the list is a REF OpNm[not..nor] and the rest of the list consists of subSimpleExpressions.
Expression:  TYPE = REF ANY;
OpIndex:   TYPE = {mach, out, var, not, and, nand, or, nor, func};
OpNm:   PROC[op: OpIndex] RETURNS[nm: IO.ROPE];
NmOp:   PROC[nm: IO.ROPE] RETURNS[op: OpIndex];
Basic Operations
WriteExprFile:  PROC[expr: Expression, indentedLevs: INT ← 2];
ReadExprFile:  PROC[name: IO.ROPE]  RETURNS[expr: Expression];
Compare:   PROC[i0, i1: Expression] RETURNS[comp: Basics.Comparison];
Sort:     PROC[expr: Expression];
Copy:    PROC[expr: Expression]  RETURNS[new: Expression];
Operations on simple expressions (not, and, nand, or, nor)
OpExpr:    PROC[op: OpIndex, e1, e2: Expression] RETURNS[Expression];
Equal:    PROC[expr1, expr2: REF] RETURNS[equal: BOOLTRUE];
Eval:     PROC[expr:   REF, varTab: SymTab.Ref] RETURNS[BOOL];
All variables must be registered in varTab as "TRUE" or "FALSE"
Scanning and enumeration
ExpressionStats: PROC [expr: Expression] RETURNS [exprStatRope: IO.ROPE];
ScanExpression: PROC
[expr: Expression, eachInput: EachInputProc ← NIL, eachOutput: EachOutputProc ← NIL]
RETURNS[machName: IO.ROPENIL];
EachInputProc: TYPE = PROC [name: IO.ROPE];
EachOutputProc: TYPE = PROC [name: IO.ROPE, expr: Expression];
GetExpressionTables: PUBLIC PROC[mach: Expression]
RETURNS[machName: IO.ROPE, inTab, outTab: SymTab.Ref];
Builds Symbol tables.
Table values are expressions.
val=key for leaf inputs in inTab.
ReplaceID: PROC[old, new: IO.ROPE, symTab: SymTab.Ref];
Expression Generation Procedures
These are useful for writing Expression Generators.
You create a context: ctx ← Create[]
Declare ins and outs: id: NAT ← ctx.Declare[name, in/out, size]
Specify the function: ctx.If[id, val]; ctx.AddOut[id, val]; ctx.EndIf[]; ...
And finish:    expr ← ctx.Finish[]
Create: PROC[name: IO.ROPE] RETURNS[ctx: Context];
Declare: PROC[ctx: Context, name: IO.ROPE, io: InOut, size: NAT ← 1] RETURNS[ix: NAT];
If:   PROC[ctx: Context, f, v: NAT, m: NAT ← default];
And:  PROC[ctx: Context, f, v: NAT, m: NAT ← default];
AddOut: PROC[ctx: Context, f, v: NAT, m: NAT ← default];
EndIf: PROC[ctx: Context];
Finish: PROC[ctx: Context] RETURNS[mach: LIST OF REF];
Expression Generation Types (PRIVATE)
Context:  TYPE = REF ContextRec;
ContextRec: TYPE = RECORD[
name:   IO.ROPE,
expr:   LIST OF REF,
logic:   LIST OF CurrentLogic,
data:   LIST OF CurrentData,
declares:  LIST OF Declaration, -- Used during declarations
signals:  Signals,     -- Used after all declarations
termIndex: NAT,
outTermTab: SymTab.Ref,
invTab:  SymTab.Ref];
CurrentLogic: TYPE = LIST OF FieldValMask ← NIL;
CurrentData:  TYPE = LIST OF FieldValMask ← NIL;
FieldValMask: TYPE = RECORD[f,v,m: NAT ← default];
Signals:   TYPE = REF SignalSeqRec;
SignalSeqRec: TYPE = RECORD [SEQUENCE size: NAT OF Declaration];
Declaration:  TYPE = RECORD [name: IO.ROPE, io: InOut, size: NAT, index: NAT];
InOut:   TYPE = {in, out};
default:   NAT = LAST[NAT];
END.