import Char import Debug.Trace import System.Environment import Control.Monad.Fix {- Hvm.hs By Kevin Reid, 2008-06-15 This is an implementation of the virtual machine described at <http://www.hacker.org/hvm/>. It was designed to fit into a single IRC line so that its definition could be put into lambdabot <http://www.haskell.org/haskellwiki/Lambdabot>, and its inspiration and creation was documented at <http://swhack.com/logs/2008-06-15>. Haskell source not in HTML: <http://switchb.org/kpreid/2008/Hvm.hs> Non-blog location: <http://switchb.org/kpreid/2008/Hvm.html> Explanation of variables: r = VM execution function of call stack, memory, instruction pointer, and operand stack c = call stack m = memory i = instruction pointer j = instruction pointer plus one o = operand stack a = arithmetic handler h = proceed with instruction pointer and operation stack modification g = proceed with operand stack modification z:x = one value popped from operand stack z:w:e = two values popped from operand stack k:l = one value popped from call stack d, t: slice lists using z as length To make it fit in IRC, discard comments, imports, and "main", replace all line breaks with semicolons as appropriate, and discard the ' ' and _ cases (i.e. the interpreter will not support whitespace or report invalid characters). perl -0777 -pe 's/\A.*(?=^s)//ms; s/\s*main .*//; s/--.*$//mg; s/

*/;/g; s/[;\s]*(where|let)[;\s]*/$1 /g; s/;'\'' '\''->g o;_->error\$show\(p!!i\)//;' -} s p=r[](fix(0:))0[] where r c m i o=--trace (show (m,i,(if length p<=i then '!' else p !! i),(reverse o),c)) $ let a(&)=g$w&z:e j=1+i h=r c m g=h j z:x=o w:e=x k:l=c d=drop(1+z) t=take z in case(p++"!")!!i of 'p'->show z++g x 'P'->chr(mod z 128):g x d|isDigit d->g$ord d-48:o '+'->a(+) '-'->a(-) '*'->a(*) '/'->a div ':'->g$signum(w-z):e 'g'->h(z+j)x '?'->h(i+case w of 0->z;_->1)e 'c'->r(j:c)m z x '$'->r l m k o '<'->g$m!!z:x '>'->r c(t m++w:d m)j e '^'->g$x!!z:x 'v'->g$x!!z:t x++d x 'd'->g x '!'->"" ' '->g o _->error$show(p!!i) main = do [p] <- getArgs; putStrLn $ s p