diff options
Diffstat (limited to 'Sjit/Run.icl')
-rw-r--r-- | Sjit/Run.icl | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/Sjit/Run.icl b/Sjit/Run.icl new file mode 100644 index 0000000..b5858ec --- /dev/null +++ b/Sjit/Run.icl @@ -0,0 +1,63 @@ +implementation module Sjit.Run + +import StdEnv +import StdMaybe + +from Data.Map import :: Map(..), get + +import Sjit.Compile + +interpret :: !CompileState -> Int +interpret cs = exec 0 [] +where + prog = get_program cs + sz = size prog + + exec :: !Int ![Int] -> Int + exec i stack + | i < 0 || i >= sz = abort "out of bounds\n" + | otherwise = case prog.[i] of + PushI n -> exec (i+1) [n:stack] + PushRef r -> exec (i+1) [stack!!r:stack] + Put n -> case stack of + [val:stack] -> exec (i+1) (take (n-1) stack ++ [val:drop n stack]) + Pop n -> exec (i+1) (drop n stack) + Call f -> exec f [i+1:stack] + Ret -> case stack of + [ret:stack] -> exec ret stack + Halt -> case stack of + [r] -> r + _ -> abort (toString (length stack) +++ " values left on stack\n") + + IAddRet -> case stack of + [ret:a:b:stack] -> exec ret [a:a+b:stack] + IMulRet -> case stack of + [ret:a:b:stack] -> exec ret [a:a*b:stack] + ISubRet -> case stack of + [ret:a:b:stack] -> exec ret [a:a-b:stack] + IDivRet -> case stack of + [ret:a:b:stack] -> exec ret [a:a/b:stack] + + get_program :: !CompileState -> Program + get_program cs + # prog = loop 0 cs.blocks (createArray (sum [size b \\ b <|- cs.blocks]) Halt) + # prog & [1] = Call (fromJust (get "main" cs.funs)) + = prog + where + loop :: !Int ![!Program!] !*Program -> .Program + loop i [!b:bs!] prog + # (i,prog) = copy i 0 (size b-1) b prog + = loop i bs prog + where + copy :: !Int !Int !Int !Program !*Program -> *(!Int, !*Program) + copy i _ -1 _ prog = (i, prog) + copy i bi n b prog = copy (i+1) (bi+1) (n-1) b {prog & [i]=b.[bi]} + loop _ [!!] prog = prog + +exec :: !CompileState -> Int +exec {jitst} = exec jitst.code_start +where + exec :: !Int -> Int + exec _ = code { + ccall jit_exec "p:I" + } |