Truth table: Difference between revisions

Line 3,494:
 
{{omit from|GUISS}}
 
== {{header|XBasic}} ==
{{trans|C}}
{{works with|Windows XBasic}}
<lang xbasic>
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
</lang>
{{out}}
<pre>
Accepts single-character variables (except for 'T' and 'F',
which specify explicit true or false values), postfix, with
&|!^ for and, or, not, xor, respectively; optionally
seperated by space. Just enter nothing to quit.
 
Boolean expression: a b ^
 
A B AB^
=========
F F F
F T T
T F T
T T F
 
Boolean expression: a b c ^ |
 
A B C ABC^|
==============
F F F F
F F T T
F T F T
F T T F
T F F T
T F T T
T T F T
T T T T
 
Boolean expression: a b c d ^ ^ ^
 
A B C D ABCD^^^
===================
F F F F F
F F F T T
F F T F T
F F T T F
F T F F T
F T F T F
F T T F F
F T T T T
T F F F T
T F F T F
T F T F F
T F T T T
T T F F F
T T F T T
T T T F T
T T T T F
 
Boolean expression:
</pre>
Anonymous user