BoolExGen:
CEDAR
PROGRAM
IMPORTS BoolEx, IO, SymTab
EXPORTS BoolEx
= BEGIN
inType: NAT = default-2000; -- for elementary type checking
outType: NAT = default-1000; -- for elementary type checking
Context: TYPE = BoolEx.Context;
default: NAT = BoolEx.default;
InOut: TYPE = BoolEx.InOut;
Create:
PUBLIC
PROC[name:
IO.
ROPE]
RETURNS[ctx: Context] = {
RETURN[
NEW[BoolEx.ContextRec ← [
name: name,
expr: NIL,
logic: LIST[NIL],
data: LIST[NIL],
declares: NIL, -- Used during declarations
signals: NIL, -- Used after all declarations
termIndex: 0,
outTermTab: SymTab.Create[],
invTab: SymTab.Create[] ] ] ]};
Declare:
PUBLIC PROC [ctx: Context, name:
IO.
ROPE, io: InOut, size:
NAT ← 1]
RETURNS [ix: NAT] = {
ix ← IF ctx.declares=NIL THEN 0 ELSE ctx.declares.first.index+1;
ctx.declares ← CONS[[name, io, size, ix], ctx.declares];
ix ← ix + (IF io=in THEN inType ELSE outType)};
If:
PUBLIC PROC[ctx: Context, f, v:
NAT, m:
NAT ← default] = {
currentLogic: BoolEx.CurrentLogic ← ctx.logic.first;
IF f = default OR v = default THEN ERROR;
IF f NOT IN [inType..outType) THEN ERROR;
currentLogic ← CONS[[f-inType, v, m], currentLogic];
ctx.logic ← CONS[currentLogic, ctx.logic];
ctx.data ← CONS[ctx.data.first, ctx.data]};
And:
PUBLIC PROC[ctx: Context, f, v:
NAT, m:
NAT ← default] = {
currentLogic: BoolEx.CurrentLogic ← ctx.logic.first;
IF f = default OR v = default THEN ERROR;
IF f NOT IN [inType..outType) THEN ERROR;
currentLogic ← CONS[[f-inType, v, m], currentLogic];
ctx.logic.first ← currentLogic};
AddOut:
PUBLIC PROC[ctx: Context, f, v:
NAT, m:
NAT ← default] = {
currentData: BoolEx.CurrentData ← ctx.data.first;
IF f = default OR v = default THEN ERROR;
IF f NOT IN [outType..default) THEN ERROR;
currentData ← CONS[[f-outType, v, m], currentData];
ctx.data.first ← currentData};
EndIf:
PUBLIC PROC[ctx: Context]= {
GetInv:
PROC[nm:
IO.
ROPE]
RETURNS[inv:
IO.
ROPE] = {
inv ← NARROW[SymTab.Fetch[ctx.invTab, nm].val];
IF inv=
NIL
THEN {
def: LIST OF REF;
inv ← IO.PutFR["NOT%g", IO.rope[nm]];
def ← LIST[NEW[BoolEx.OpIndex ← not], nm];
def ← LIST[NEW[BoolEx.OpIndex ← term], inv, def];
ctx.expr ← CONS[def, ctx.expr];
[]←SymTab.Store[ctx.invTab, nm, inv]} };
def: LIST OF REF ← NIL;
term: LIST OF REF ← NIL;
termNm: IO.ROPE ← IO.PutFR["xT%03g", IO.int[ctx.termIndex]];
IF ctx.termIndex=0
THEN {
ctx.signals ← NEW [BoolEx.SignalSeqRec[ctx.declares.first.index+1]];
FOR decl:
LIST
OF BoolEx.Declaration ← ctx.declares, decl.rest
WHILE decl#
NIL
DO
ctx.signals[decl.first.index] ← decl.first; ENDLOOP};
ctx.termIndex ← ctx.termIndex+1;
FOR logic: BoolEx.CurrentLogic ← ctx.logic.first, logic.rest
WHILE logic#
NIL
DO
name: IO.ROPE ← ctx.signals[logic.first.f].name;
size: NAT ← ctx.signals[logic.first.f].size;
v: NAT ← logic.first.v;
m: NAT ← logic.first.m;
IF ctx.signals[logic.first.f].io#in THEN ERROR;
IF size=1
THEN {
IF (m
MOD 2)=1
THEN
term ← CONS[(IF (v MOD 2)=1 THEN name ELSE GetInv[name]), term]}
ELSE
FOR bit:
NAT
DECREASING
IN [0..size)
DO
bitNm: IO.ROPE ← IO.PutFR["%g%g", IO.rope[name], IO.int[bit]];
bitOne: BOOL ← (v MOD 2)=1;
msk: BOOL ← (m MOD 2)=1;
v ← v/2; m ← m/2;
IF ~msk THEN LOOP;
term ← CONS[(IF bitOne THEN bitNm ELSE GetInv[bitNm]), term] ENDLOOP;
ENDLOOP;
term ← CONS[NEW[BoolEx.OpIndex ← and], term];
def ← LIST[NEW[BoolEx.OpIndex ← term], termNm, term];
ctx.expr ← CONS[def, ctx.expr];
FOR data: BoolEx.CurrentData ← ctx.data.first, data.rest
WHILE data#
NIL
DO
OrToOutput:
PROC[out:
IO.
ROPE] = {
outTerms: LIST OF REF ← NARROW[SymTab.Fetch[ctx.outTermTab, out].val];
outTerms ← CONS[termNm, outTerms];
[]←SymTab.Store[ctx.outTermTab, out, outTerms]};
name: IO.ROPE ← ctx.signals[data.first.f].name;
size: NAT ← ctx.signals[data.first.f].size;
v: NAT ← data.first.v;
IF ctx.signals[data.first.f].io#out THEN ERROR;
IF size=1
THEN {IF (v MOD 2)=1 THEN OrToOutput[name]}
ELSE
FOR bit:
NAT
DECREASING
IN [0..size)
DO
bitNm: IO.ROPE ← IO.PutFR["%g%g", IO.rope[name], IO.int[bit]];
bitOne: BOOL ← (v MOD 2)=1;
v ← v/2;
IF bitOne THEN OrToOutput[bitNm] ENDLOOP;
ENDLOOP;
ctx.logic ← ctx.logic.rest;
ctx.data ← ctx.data.rest};
Finish:
PUBLIC PROC[ctx: Context]
RETURNS[mach:
LIST
OF
REF] = {
OutDefs: SymTab.EachPairAction = {
def: LIST OF REF;
outSum: LIST OF REF ← NARROW[val];
outSum ← CONS[NEW[BoolEx.OpIndex ← or], outSum];
def ← LIST[NEW[BoolEx.OpIndex ← out], key, outSum];
ctx.expr ← CONS[def, ctx.expr]};
[]←SymTab.Pairs[ctx.outTermTab, OutDefs];
ctx.expr ← CONS[NEW[BoolEx.OpIndex ← mach], CONS[ctx.name, ctx.expr]];
IF ctx.logic.rest #NIL THEN ERROR;
IF ctx.data.rest #NIL THEN ERROR;
IF ctx.logic.first #NIL THEN ERROR;
IF ctx.data.first #NIL THEN ERROR;
BoolEx.Sort[ctx.expr];
RETURN[NARROW[ctx.expr]]};