219 lines
4.9 KiB
Plaintext
219 lines
4.9 KiB
Plaintext
PROGRAM "truthtables"
|
|
VERSION "0.001"
|
|
|
|
$$MaxTop = 80
|
|
|
|
TYPE VARIABLE
|
|
STRING*1 .name
|
|
SBYTE .value
|
|
END TYPE
|
|
|
|
TYPE STACKOFBOOL
|
|
SSHORT .top
|
|
SBYTE .elements[$$MaxTop]
|
|
END TYPE
|
|
|
|
DECLARE FUNCTION Entry()
|
|
INTERNAL FUNCTION IsOperator(c$)
|
|
INTERNAL FUNCTION VariableIndex(c$)
|
|
INTERNAL FUNCTION SetVariables(pos%)
|
|
INTERNAL FUNCTION ProcessExpression()
|
|
INTERNAL FUNCTION EvaluateExpression()
|
|
|
|
' Stack manipulation functions
|
|
INTERNAL FUNCTION IsFull(STACKOFBOOL @s)
|
|
INTERNAL FUNCTION IsEmpty(STACKOFBOOL @s)
|
|
INTERNAL FUNCTION Peek(STACKOFBOOL @s)
|
|
INTERNAL FUNCTION Push(STACKOFBOOL @s, val@)
|
|
INTERNAL FUNCTION Pop(STACKOFBOOL @s)
|
|
INTERNAL FUNCTION MakeEmpty(STACKOFBOOL @s)
|
|
INTERNAL FUNCTION ElementsCount(STACKOFBOOL @s)
|
|
|
|
FUNCTION Entry()
|
|
SHARED VARIABLE variables[]
|
|
SHARED variablesLength%
|
|
SHARED expression$
|
|
|
|
DIM variables[23]
|
|
PRINT "Accepts single-character variables (except for 'T' and 'F',"
|
|
PRINT "which specify explicit true or false values), postfix, with"
|
|
PRINT "&|!^ for and, or, not, xor, respectively; optionally"
|
|
PRINT "seperated by space. Just enter nothing to quit."
|
|
DO
|
|
PRINT
|
|
expression$ = INLINE$("Boolean expression: ")
|
|
ProcessExpression()
|
|
IF LEN(expression$) = 0 THEN
|
|
EXIT DO
|
|
END IF
|
|
variablesLength% = 0
|
|
FOR i% = 0 TO LEN(expression$) - 1
|
|
e$ = CHR$(expression${i%})
|
|
IF (!IsOperator(e$)) && (e$ <> "T") && (e$ <> "F") && (VariableIndex(e$) = -1) THEN
|
|
variables[variablesLength%].name = LEFT$(e$, 1)
|
|
variables[variablesLength%].value = $$FALSE
|
|
INC variablesLength%
|
|
END IF
|
|
NEXT i%
|
|
PRINT
|
|
IF variablesLength% = 0 THEN
|
|
PRINT "No variables were entered."
|
|
ELSE
|
|
FOR i% = 0 TO variablesLength% - 1
|
|
PRINT variables[i%].name; " ";
|
|
NEXT i%
|
|
PRINT expression$
|
|
PRINT CHR$(ASC("="), variablesLength% * 3 + LEN(expression$))
|
|
SetVariables(0)
|
|
END IF
|
|
LOOP
|
|
END FUNCTION
|
|
|
|
' Removes space and converts to upper case
|
|
FUNCTION ProcessExpression()
|
|
SHARED expression$
|
|
'
|
|
exprTmp$ = ""
|
|
FOR i% = 0 TO LEN(expression$) - 1
|
|
IF CHR$(expression${i%}) <> " " THEN
|
|
exprTmp$ = exprTmp$ + UCASE$(CHR$(expression${i%}))
|
|
END IF
|
|
NEXT i%
|
|
expression$ = exprTmp$
|
|
END FUNCTION
|
|
|
|
FUNCTION IsOperator(c$)
|
|
RETURN (c$ = "&") || (c$ = "|") || (c$ = "!") || (c$ = "^")
|
|
END FUNCTION
|
|
|
|
FUNCTION VariableIndex(c$)
|
|
SHARED VARIABLE variables[]
|
|
SHARED variablesLength%
|
|
'
|
|
FOR i% = 0 TO variablesLength% - 1
|
|
IF variables[i%].name = c$ THEN
|
|
RETURN i%
|
|
END IF
|
|
NEXT i%
|
|
RETURN -1
|
|
END FUNCTION
|
|
|
|
FUNCTION SetVariables(pos%)
|
|
SHARED VARIABLE variables[]
|
|
SHARED variablesLength%
|
|
'
|
|
SELECT CASE TRUE
|
|
CASE pos% > variablesLength%:
|
|
PRINT
|
|
PRINT "Argument to SetVariables cannot be greater than the number of variables."
|
|
QUIT(1)
|
|
CASE pos% = variablesLength%:
|
|
FOR i% = 0 TO variablesLength% - 1
|
|
IF variables[i%].value THEN
|
|
PRINT "T ";
|
|
ELSE
|
|
PRINT "F ";
|
|
END IF
|
|
NEXT i%
|
|
IF EvaluateExpression() THEN
|
|
PRINT "T"
|
|
ELSE
|
|
PRINT "F"
|
|
END IF
|
|
CASE ELSE:
|
|
variables[pos%].value = $$FALSE
|
|
SetVariables(pos% + 1)
|
|
variables[pos%].value = $$TRUE
|
|
SetVariables(pos% + 1)
|
|
END SELECT
|
|
END FUNCTION
|
|
|
|
FUNCTION EvaluateExpression()
|
|
SHARED VARIABLE variables[]
|
|
SHARED expression$
|
|
STACKOFBOOL s
|
|
'
|
|
MakeEmpty(@s)
|
|
FOR i% = 0 TO LEN(expression$) - 1
|
|
e$ = CHR$(expression${i%})
|
|
vi% = VariableIndex(e$)
|
|
SELECT CASE TRUE
|
|
CASE e$ = "T":
|
|
Push(@s, $$TRUE)
|
|
CASE e$ = "F":
|
|
Push(@s, $$FALSE)
|
|
CASE vi% >= 0:
|
|
Push(@s, variables[vi%].value)
|
|
CASE ELSE:
|
|
SELECT CASE e$
|
|
CASE "&":
|
|
Push(@s, Pop(@s) & Pop(@s))
|
|
CASE "|":
|
|
Push(@s, Pop(@s) | Pop(@s))
|
|
CASE "!":
|
|
Push(@s, !Pop(@s))
|
|
CASE "^":
|
|
Push(@s, Pop(@s) ^ Pop(@s))
|
|
CASE ELSE:
|
|
PRINT
|
|
PRINT "Non-conformant character "; e$; " in expression.";
|
|
QUIT(1)
|
|
END SELECT
|
|
END SELECT
|
|
NEXT i%
|
|
IF ElementsCount(@s) <> 1 THEN
|
|
PRINT
|
|
PRINT "Stack should contain exactly one element."
|
|
QUIT(1)
|
|
END IF
|
|
RETURN Peek(@s)
|
|
END FUNCTION
|
|
|
|
FUNCTION IsFull(STACKOFBOOL s)
|
|
RETURN s.top = $$MaxTop
|
|
END FUNCTION
|
|
|
|
FUNCTION IsEmpty(STACKOFBOOL s)
|
|
RETURN s.top = -1
|
|
END FUNCTION
|
|
|
|
FUNCTION Peek(STACKOFBOOL s)
|
|
IF !IsEmpty(@s) THEN
|
|
RETURN s.elements[s.top]
|
|
ELSE
|
|
PRINT "Stack is empty."
|
|
QUIT(1)
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION Push(STACKOFBOOL s, val@)
|
|
IF !IsFull(@s) THEN
|
|
INC s.top
|
|
s.elements[s.top] = val@
|
|
ELSE
|
|
PRINT "Stack is full."
|
|
QUIT(1)
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION Pop(STACKOFBOOL s)
|
|
IF !IsEmpty(@s) THEN
|
|
res@ = s.elements[s.top]
|
|
DEC s.top
|
|
RETURN res@
|
|
ELSE
|
|
PRINT
|
|
PRINT "Stack is empty."
|
|
QUIT(1)
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION MakeEmpty(STACKOFBOOL s)
|
|
s.top = -1
|
|
END FUNCTION
|
|
|
|
FUNCTION ElementsCount(STACKOFBOOL s)
|
|
RETURN s.top + 1
|
|
END FUNCTION
|
|
END PROGRAM
|