Skip to content

Instantly share code, notes, and snippets.

@pi8027
Last active January 2, 2016 07:49
Show Gist options
  • Save pi8027/8272265 to your computer and use it in GitHub Desktop.
Save pi8027/8272265 to your computer and use it in GitHub Desktop.
/switch { % key cases otherwise <switch> any
2 index null eq {
exch pop exch pop
} {
1 index 3 index known {
pop exch get
} {
exch pop exch pop
} ifelse
} ifelse
} def
/ifopt { % ?any proc proc <ifopt> -
3 2 roll dup null eq { pop exch pop exec } { exch pop exch exec } ifelse
} def
/readc { dup read not { null } if } def
/digit { % file ?char <digit> file ?char ?digit
48 1 index le 1 index 57 le and { 48 sub exch readc 3 2 roll } { null } ifelse
} def
/skipspaces { % file ?char <skipspaces> file ?char
{ % file ?char self
exch { % file self char
dup 10 eq 1 index 32 eq or {
pop [ 3 2 roll readc 4 3 roll dup /exec cvx ] cvx exec
} { exch pop } ifelse
} { % file self
pop null
} ifopt
} dup exec
} def
/gexpr { % child opdict file ?char <gexpr> file ?char ?result
3 index exec {
{ % child opdict file ?char expr self
4 2 roll skipspaces % child opdict expr self file ?char
dup 5 index null switch % child opdict expr self file ?char ?op
{
exch pop exch readc % child opdict expr self op file ?char
6 index exec { % child opdict expr self op file ?char expr
[ 7 6 roll {} /forall cvx 5 4 roll {} /forall cvx 10 9 roll ] cvx
[ exch exec cvx ] 4 3 roll dup exec
} { 7 5 roll pop pop pop pop pop null } ifopt
} { % child opdict expr self file ?char
3 2 roll pop 5 3 roll pop pop 3 2 roll
} ifopt
} dup exec
} { % child opdict file ?char
4 2 roll pop pop null
} ifopt
} def
/expr {
{ { factor } << 42 /mul 47 /div >> 4 2 roll gexpr } % 42 = '*', 47 = '/'
<< 43 /add 45 /sub >> % 43 = '+', 45 = '-'
4 2 roll gexpr
} def
/factor { % file ?char <factor> file ?char ?result
skipspaces {
dup 40 eq {
pop readc expr 3 1 roll skipspaces % ?result file ?char
dup 41 eq { pop readc 3 2 roll } { 3 2 roll pop null } ifelse
} { % file ?char
digit { % file ?char acc
{ % file ?char acc self
4 2 roll digit { % acc self file ?char digit
5 4 roll 10 mul add % self file ?char acc
4 3 roll dup exec
} {
4 2 roll pop [ exch ]
} ifopt
} dup exec
} { null } ifopt
} ifelse
} { null null } ifopt
} def
(%stdin) (r) file
readc expr cvx { dup == exec = } { (error) = } ifopt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment