SNOBOL4
Number of characters: 232
a = pos(0) | '('
n = span('0123456789.')
j = '!+;!-;!*;!/; output = e'
d j '!' len(1) . y = " e a . q n . l '" y "' n . r = q (l " y " r) :s(p)" :s(d)
k = code(j)
e = input
s e ' ' = :s(s)
p e ('(' n . i ')') = i :s(p)f
end
This is a semi-cheat. It uses code() (a variant of eval) to de-compress itself, but not to evaluate the input expression.
De-obfuscated version, without code:
prefix = pos(0) | '('
num = span('0123456789.')
expr = input
spaces expr ' ' = '' :s(spaces)
paren expr ('(' num . x ')') = x :s(paren)
add expr (prefix . pfx) (num . l) '+' (num . r) = pfx (l + r) :s(paren)
sub expr (prefix . pfx) (num . l) '-' (num . r) = pfx (l - r) :s(paren)
mul expr (prefix . pfx) (num . l) '*' (num . r) = pfx (l * r) :s(paren)
div expr (prefix . pfx) (num . l) '/' (num . r) = pfx (l / r) :s(paren)
output = expr
end
Strategy:
- First, remove all spaces (
spaces)
- Whenever possible, remove parentheses surrounding a number (
paren)
- Otherwise, find a simple expression involving two numbers, prefixed by
'(' or at the start of the string
- If none of the above rules apply, the expression is fully evaluated. Now if the input was well formed we should be left with a number.
Example:
1 + (2 * 3) + 4
1+(2*3)+4 [spaces]
1+(6)+4 [mul]
1+6+4 [paren]
7+4 [add]
11 [add]