home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 19
/
CD_ASCQ_19_010295.iso
/
vrac
/
tsetd2.zip
/
EXPR.S
< prev
next >
Wrap
Text File
|
1994-12-14
|
10KB
|
316 lines
/*************************************************************************
Expr Calculates the value of a specified mathematical expression.
Author: SemWare
Date: Mar 23, 1994
Overview:
This macro operates as a simple calculator, and handles decimal
or hexadecimal numbers. For decimal numbers, only whole numbers
are accepted.
Keys: (none)
Usage notes:
This macro does not have any key assignments. To use, simply
select it from the Potpourri menu.
The following operations are available:
> SHR (bitwise shift right)
< SHL (bitwise shift left)
~ COMP (2's complement)
% MOD (modulo division)
& AND (bitwise AND)
| OR (bitwise OR)
^ XOR (bitwise eXclusive-OR)
+ Addition
- Subtraction
* Multiplication
/ Division
Precedence is as in SAL, but can be forced by using parenthesis.
Hex number may be entered using C format, or ending with an 'h'
or '$'. Regardless, the first character _must_ be numeric.
Copyright 1992-1994 SemWare Corporation. All Rights Reserved Worldwide.
Use, modification, and distribution of this SAL macro is encouraged by
SemWare provided that this statement, including the above copyright
notice, is not removed; and provided that no fee or other remuneration
is received for distribution. You may add your own copyright notice
to cover new matter you add to the macro, but SemWare Corporation will
neither support nor assume legal responsibility for any material added
or any changes made to the macro.
*************************************************************************/
HelpDef ExprHelp
"The following operators are available within an Expresson:"
""
"Operator Meaning Precedence"
""
" () Sub-expression 1"
""
" ~ Bitwise 2's Complement 2"
""
" * Multiplication 3"
" / Division 3"
" % Modulo Division 3"
" ^ Bitwise eXclusive-OR 3"
" > Bitwise Shift Right 3"
" < Bitwise Shift Left 3"
" & Bitwise AND 3"
""
" + Addition 4"
" - Subtraction 4"
" | Bitwise OR 4"
""
"Hex number may be entered by beginning with '0x' or"
"ending with an 'h' or '$'. Regardless, the first"
"character _must_ be numeric."
""
end
/*
Work variables
*/
string InputLine[80]
integer Col // current column in InputLine
string Token[15] // currently parsed token from InputLine
integer symbol // numeric "code" representing what token is
string Ch[1] // next Char from InputLine
integer hex // is current symbol hex? used only by GetToken/isHex
forward integer proc SimpleExpression()
proc GetNextChar()
Ch = Upper(SubStr(inputline, col, 1))
col = col + 1
end
integer proc isNumeric()
return (Ch >= '0' and Ch <= '9')
end
integer proc isHexChar()
if Ch >= 'A' and Ch <= 'F'
hex = TRUE
return (TRUE)
endif
return (FALSE)
end
/*
These are "magic" values that GetToken will store in the global variable
symbol, to indicate what is the next item coming.
*/
constant
symNumber = 0,
symAddition = 1,
symSubtraction = 2,
symMultiplication = 3,
symDivision = 4,
symLeftParen = 5,
symRightParen = 6,
symAND = 7,
symOR = 8,
symXOR = 9,
symCOMP = 10,
symMOD = 11,
symSHR = 12,
symSHL = 13,
symEndOfString = -1,
symError = -2
// GetToken _must_ set hex to FALSE on startup and exit.
proc GetToken()
while ch == " " // Skip over any leading blanks
GetNextChar()
endwhile
token = Ch
case token
when ">" symbol = symSHR
when "<" symbol = symSHL
when "~" symbol = symCOMP
when "%" symbol = symMOD
when "&" symbol = symAND
when "|" symbol = symOR
when "^" symbol = symXOR
when "+" symbol = symAddition
when "-" symbol = symSubtraction
when "*" symbol = symMultiplication
when "/" symbol = symDivision
when "(" symbol = symLeftParen
when ")" symbol = symRightParen
when "" symbol = symEndOfString
otherwise // if token is numeric, collect rest of digits
hex = FALSE
if not isNumeric() and not isHexChar()
symbol = symError
else
symbol = symNumber // Tag this as an integer value
GetNextChar()
if (Ch == "X") // Allow c-style hex strings
hex = TRUE
GetNextChar()
endif
while isNumeric() or isHexChar()
token = token + ch
GetNextChar()
endwhile
if Ch == 'H' or Ch == '$' // Allow assembly/Turbo Pascal hex strings
hex = TRUE
GetNextChar()
endif
if hex
token = token + 'H'
endif
endif
hex = FALSE
return ()
endcase
GetNextChar()
end
//
// Set up globals so SimpleExpression starts off on the right foot
//
proc SyntaxError()
Warn("Expression syntax error")
Halt
end
proc ParenError()
Warn("Missing right parenthesis")
Halt
end
integer proc Factor()
integer result, base = 10
case symbol
when symNumber // found a number
if token[Length(token)] == 'H'
token = substr(token, 1, Length(token) - 1)
base = 16
endif
result = Val(token, base) // get its value
GetToken() // and skip to next
when symLeftParen // found a left paren
GetToken() // skip over "("
result = SimpleExpression()
if symbol <> symRightParen // make sure the right paren exists
ParenError()
endif
GetToken() // skip over ")"
when symCOMP
GetToken()
result = ~Factor()
otherwise
SyntaxError() // not number or paren--error
endcase
return (result)
end
integer proc Term()
integer result, sym
result = Factor()
while (symbol == symMultiplication) or // "*" sign, or
(symbol == symDivision) or // "/" sign...
(symbol == symMOD) or // "%" sign...
(symbol == symXOR) or // "^" sign...
(symbol == symSHR) or // ">" sign...
(symbol == symSHL) or // "<" sign...
(symbol == symAND) // "&" sign...
sym = symbol
GetToken() // skip over math op
case sym
when symMultiplication
result = result * Factor() // multiplication
when symDivision
result = result / Factor() // division
when symAND
result = result & Factor()
when symXOR
result = result ^ Factor()
when symMOD
result = result mod Factor()
when symSHR
result = result shr Factor()
when symSHL
result = result shl Factor()
endcase
endwhile
if symbol == symError
SyntaxError()
endif
return (result)
end
integer proc SimpleExpression()
integer result, sym
result = Term()
while (symbol == symNumber ) or // another integer coming, or
(symbol == symOR ) or // "|" sign, or
(symbol == symAddition ) or // "+" sign, or
(symbol == symSubtraction) // "-" sign....
sym = symbol
if sym == symNumber // if another integer came immediately
sym = symAddition // then default to adding
else
GetToken() // else skip over the math op
endif
case sym
when symAddition
result = result + Term()
when symSubtraction
result = result - Term()
when symOR
result = result | Term()
endcase
endwhile
if symbol == symError
SyntaxError()
endif
return (result)
end
keydef ExprHelpKey
<F1> QuickHelp(ExprHelp)
end
proc PromptStartup()
Enable(ExprHelpKey)
UnHook(PromptStartup)
end
proc Main()
integer result
loop
Hook(_PROMPT_STARTUP_, PromptStartup)
if Ask("Enter Expression: (<F1> for help)", InputLine) and Length(InputLine)
// Prime the pump...
Col = 1
Token = ''
GetNextChar()
GetToken()
result = SimpleExpression()
Message("The result is: ", result, " (", str(result, 16), "h)")
else
break
endif
endloop
end