aboutsummaryrefslogtreecommitdiff
path: root/Sjit/Run.icl
diff options
context:
space:
mode:
Diffstat (limited to 'Sjit/Run.icl')
-rw-r--r--Sjit/Run.icl63
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"
+ }