📄 eqnentry.pas
字号:
unit Eqnentry;
interface
uses WinTypes, WinProcs, Classes, Graphics, Forms, Controls, Buttons,
StdCtrls, ExtCtrls, Dialogs, SysUtils, LogicEV, Help1;
type
TEqnDlg = class(TForm)
OKBtn: TBitBtn;
CancelBtn: TBitBtn;
HelpBtn: TBitBtn;
Bevel1: TBevel;
InputEqn: TEdit;
procedure OKBtnClick(Sender: TObject);
procedure CancelBtnClick(Sender: TObject);
procedure InputEqnChange(Sender: TObject);
procedure HelpBtnClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
LastEqn:string;
EqnDlg: TEqnDlg;
procedure DrawTruths(var TTbl:TruthType);
implementation
var
thisTruth:TruthType;
{$R *.DFM}
{ RmvBlanks- Removes all spaces from a string. }
procedure RmvBlanks(var Equation:string);
var dest:integer;
i:integer;
begin
dest := 1;
for i := 1 to length(Equation) do
if (Equation[i] <> ' ') then begin
Equation[dest] := Equation[i];
dest := dest + 1;
end;
end;
{ DrawTruths- This procedure takes a truth table as a parameter and }
{ draws that truth table on the CREATE page. Zero variable functions }
{ produce a blank truth table, one-variable functions produce a 1x2 }
{ truth table, two-variable functions produce a 2x2 table, three- }
{ variable functions produce a 2x4 table, and four-variable functions }
{ produce a 4x4 table. }
procedure DrawTruths(var TTbl:TruthType);
var
i,j,
a,b,c,d,
Clk :integer;
{ ToDigit converts the integer value at the given spot in the truth }
{ table to a '0' or '1' character and returns this character. }
function ToDigit(clk,d,c,b,a:integer):char;
begin
result := chr(ord('0') + TTbl.tt[clk,d,c,b,a]);
end;
begin {DrawTruth}
{Initialize all the truth table labels to spaces. We will fill }
{in the necessary ones later. }
with LogicEval do begin
ba00.Caption := '';
ba01.Caption := '';
ba10.Caption := '';
ba11.Caption := '';
dc00.Caption := '';
dc01.Caption := '';
dc10.Caption := '';
dc11.Caption := '';
dc200.Caption := '';
dc201.Caption := '';
dc210.Caption := '';
dc211.Caption := '';
end;
{ Clear all the labels in the truth table. For functions with }
{ less than four variables, the unused squares need to be blank.}
{ We will fill in the non-blank ones later. }
for clk := 0 to 1 do
for a:= 0 to 1 do
for b := 0 to 1 do
for c := 0 to 1 do
for d := 0 to 1 do
begin
tt[clk,d,c,b,a].Caption := '';
end;
{ Okay, fill in the truth tables and attach appropriate labels }
{ down here. Since functions of different numbers of variables }
{ each produce completely different truth tables, the following }
{ case statement divides up the work depending on the number }
{ of variables in the function. }
case TTbl.NumVars of
{ Handle functions of a single variable here. Produce a 1x2 }
{ truth table. }
1: begin
for Clk := 0 to 1 do
for a := 0 to 1 do
tt[Clk,0,0,0,a].Caption := ToDigit(Clk,0,0,0,a);
with LogicEval do begin
ba00.Caption := ' ' + TTbl.theVars[0] + '''';
ba01.Caption := ' ' + TTbl.theVars[0];
end;
end;
{ Handle functions of two variables here, producing a 2x2 }
{ truth table. Note that this code swaps the B and C variables }
{ in the actual truth table to get a 2x2 format rather than a }
{ 1x4 format. }
2: begin
for clk := 0 to 1 do
for a:= 0 to 1 do
for b:= 0 to 1 do
tt[clk,0,b,0,a].Caption := ToDigit(clk,0,0,b,a);
with LogicEval do begin
ba00.Caption := ' ' + TTbl.theVars[0] + '''';
ba01.Caption := ' ' + TTbl.theVars[0];
dc00.Caption := ' ' + TTbl.theVars[1] + '''';
dc01.Caption := ' ' + TTbl.theVars[1];
dc200.Caption := ' ' + TTbl.theVars[1] + '''';
dc201.Caption := ' ' + TTbl.theVars[1];
end;
end;
{ Process three-variable functions down here. This code pro- }
{ duces a 2x4 truth table. }
3: begin
for clk := 0 to 1 do
for c := 0 to 1 do
for b := 0 to 1 do
for a := 0 to 1 do
begin
tt[clk,0,c,b,a].Caption := ToDigit(clk,0,c,b,a);
end;
with LogicEval do begin
ba00.Caption := TTbl.theVars[1] + '''' +
TTbl.theVars[0] + '''';
ba01.Caption := TTbl.theVars[1] + '''' +
TTbl.theVars[0];
ba10.Caption := TTbl.theVars[1] +
TTbl.theVars[0] + '''';
ba11.Caption := TTbl.theVars[1] +
TTbl.theVars[0];
dc00.Caption := ' ' + TTbl.theVars[2] + '''';
dc01.Caption := ' ' + TTbl.theVars[2];
dc200.Caption := ' ' + TTbl.theVars[2] + '''';
dc201.Caption := ' ' + TTbl.theVars[2];
end;
end;
{ Produce a 4x4 truth table for functions of four variables. }
4: begin
for clk := 0 to 1 do
for d := 0 to 1 do
for c := 0 to 1 do
for b := 0 to 1 do
for a := 0 to 1 do
begin
tt[clk,d,c,b,a].Caption :=
ToDigit(clk,d,c,b,a);
end;
with LogicEval do begin
ba00.Caption := TTbl.theVars[1] + '''' +
TTbl.theVars[0] + '''';
ba01.Caption := TTbl.theVars[1] + '''' +
TTbl.theVars[0];
ba10.Caption := TTbl.theVars[1] +
TTbl.theVars[0] + '''';
ba11.Caption := TTbl.theVars[1] +
TTbl.theVars[0];
dc00.Caption := TTbl.theVars[3] + '''' +
TTbl.theVars[2] + '''';
dc01.Caption := TTbl.theVars[3] + '''' +
TTbl.theVars[2];
dc10.Caption := TTbl.theVars[3] +
TTbl.theVars[2] + '''';
dc11.Caption := TTbl.theVars[3] +
TTbl.theVars[2];
dc200.Caption := TTbl.theVars[3] + '''' +
TTbl.theVars[2] + '''';
dc201.Caption := TTbl.theVars[3] + '''' +
TTbl.theVars[2];
dc210.Caption := TTbl.theVars[3] +
TTbl.theVars[2] + '''';
dc211.Caption := TTbl.theVars[3] +
TTbl.theVars[2];
end;
end;
end;
end;
{ ParseEqn- This function checks to see if an equation input by the }
{ user is syntactically correct. If not, this function }
{ returns false. If so, this function constructs the }
{ truth table for the equation by evaluating the function }
{ for all possible values of the clock, a, b, c, and d. }
function ParseEqn:boolean;
var
a,b,c,d,
clk,
i :integer;
CurChar :integer;
Equation :string;
TruthVars : set of char;
{ Parse- Parses the "Equation" string and evaluates it. }
{ Returns true if expression is legal, returns }
{ false if the equation is syntactically incorrect. }
{ }
{ Grammar: }
{ S -> X + S | X }
{ X -> YX | Y }
{ Y -> Y' | Z }
{ Z -> a .. z | # | ( S ) }
function S:boolean;
function X:boolean;
var dummy:boolean;
function Y:boolean;
function Z:boolean;
begin
case (Equation[CurChar]) of
{ The following case handles parenthesized }
{ expressions. }
'(': begin
inc(CurChar); { Skip the parenthesis. }
Result := S; { Check internal expr. }
{ Be sure the expression ends with a }
{ closing parenthesis. }
if (Equation[CurChar] <> ')') then
Result := false
else inc(CurChar);
end;
{ If this term is a variable name, we need }
{ check a couple of things. First of all, }
{ equations cannot have more than four dif- }
{ ferent variables. The TruthVars set con- }
{ tains the variables found in the equation }
{ up to this point. If the current vari- }
{ able is not in this set, add it to the }
{ set and bump the variable counter by one. }
{ If the variable is already in the set, }
{ then we've already counted it towards our }
{ maximum of four variables. }
{ We return true if we haven't exceeded our }
{ four variable maximum. }
'A'..'Z': begin
if (not (Equation[CurChar] in TruthVars)) then
begin
thisTruth.theVars[thisTruth.NumVars]:=
Equation[CurChar];
TruthVars := TruthVars +
[Equation[CurChar]];
Result := thisTruth.NumVars < 4;
if Result then inc(thisTruth.NumVars);
end
else Result := true;
inc(CurChar);
end;
{ The clock value ("#") and the zero and }
{ one constants do not need any special }
{ handling. Just skip over them and return }
{ true as the function result. }
'#','0','1': begin
Result := true;
Inc(CurChar);
end;
{ If not one of the above symbols, we've }
{ got an illegal symbol in the equation. }
{ Return an error if this occurs. }
else Result := false;
end;
end;
{ Y handles all sub-expressions of the form <var>'. }
begin {Y}
{ Note: This particular operation is left recursive }
{ and would require considerable grammar transform- }
{ ation to repair. However, a simple trick is to }
{ note that the result would have tail recursion }
{ which we can solve iteratively rather than recur- }
{ sively. Hence the while loop in the following }
{ code. }
Result := Z;
while (Result) and (Equation[CurChar] = '''') do
inc(CurChar);
end;
{ X handles all subexpressions containing concatenated values }
{ (i.e., logical AND operations). }
begin {X}
Result := Y;
if Result and
(Equation[CurChar] in ['A'..'Z','0','1','#','(']) then
result := X;
end;
{ S handles all general expressions and, in particular, those tak- }
{ ing the form <var> + <var>. }
begin {S}
Result := X;
if Result and (Equation[CurChar] = '+') then
begin
inc(CurChar);
Result := S;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -