aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile2
-rw-r--r--Sjit/Compile.dcl44
-rw-r--r--Sjit/Compile.icl (renamed from sjit.icl)129
-rw-r--r--Sjit/Run.dcl6
-rw-r--r--Sjit/Run.icl63
-rw-r--r--Sjit/Syntax.dcl12
-rw-r--r--Sjit/Syntax.icl1
-rw-r--r--isjit.icl32
9 files changed, 164 insertions, 127 deletions
diff --git a/.gitignore b/.gitignore
index 7310f09..b6a6c3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
*.abc
*.o
-sjit
+isjit
diff --git a/Makefile b/Makefile
index ae85740..ec6b966 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CLM:=clm
CLMFLAGS:=-IL Platform -nr -nt
override CFLAGS:=-Wall -Wextra -Werror -Ofast $(CFLAGS)
-BIN:=sjit
+BIN:=isjit
all: $(BIN)
diff --git a/Sjit/Compile.dcl b/Sjit/Compile.dcl
new file mode 100644
index 0000000..4bc1ed5
--- /dev/null
+++ b/Sjit/Compile.dcl
@@ -0,0 +1,44 @@
+definition module Sjit.Compile
+
+from Data.Map import :: Map
+from Data.Maybe import :: Maybe
+from Sjit.Syntax import :: Function
+
+:: Instr
+ = PushRef !Int
+ | PushI !Int
+ | Put !Int
+ | Pop !Int
+
+ | Call !Int
+ | Ret
+ | Halt
+
+ | IAddRet
+ | IMulRet
+ | ISubRet
+ | IDivRet
+
+:: Program :== {!Instr}
+
+:: CompileState =
+ { vars :: !Map String Int
+ , funs :: !Map String Int
+ , sp :: !Int
+ , pc :: !Int
+ , blocks :: ![!Program!]
+ , jitst :: !JITState
+ }
+
+:: JITState =
+ { n_instr :: !Int
+ , code_start :: !Int
+ , code_len :: !Int
+ , code_ptr :: !Int
+ , mapping :: !Int
+ }
+
+appendProgram :: !Bool !Program !JITState -> JITState
+bootstrap :: (!Program, !CompileState)
+compile :: !Function !CompileState -> CompileState
+compile_all :: !(Maybe CompileState) ![Function] -> CompileState
diff --git a/sjit.icl b/Sjit/Compile.icl
index 6b94745..31b6523 100644
--- a/sjit.icl
+++ b/Sjit/Compile.icl
@@ -1,4 +1,4 @@
-module sjit
+implementation module Sjit.Compile
import StdEnv
import StdGeneric
@@ -7,54 +7,10 @@ import StdOverloadedList
from Data.Func import mapSt, $
from Data.Map import :: Map(..), get, put, newMap, fromList
-import System.CommandLine
-import code from "sjit_c."
-
-:: Expr
- = Int !Int
- | Var !String
- | App !String ![Expr]
-
-:: Function =
- { fun_name :: !String
- , fun_args :: ![String]
- , fun_expr :: !Expr
- }
-
-:: Instr
- = PushRef !Int
- | PushI !Int
- | Put !Int
- | Pop !Int
-
- | Call !Int
- | Ret
- | Halt
-
- | IAddRet
- | IMulRet
- | ISubRet
- | IDivRet
+import Sjit.Syntax
-:: Program :== {!Instr}
-
-:: CompileState =
- { vars :: !Map String Int
- , funs :: !Map String Int
- , sp :: !Int
- , pc :: !Int
- , blocks :: ![!Program!]
- , jitst :: !JITState
- }
-
-:: JITState =
- { n_instr :: !Int
- , code_start :: !Int
- , code_len :: !Int
- , code_ptr :: !Int
- , mapping :: !Int
- }
+import code from "sjit_c."
appendProgram :: !Bool !Program !JITState -> JITState
appendProgram is_main prog jitst
@@ -158,53 +114,6 @@ compile_all mcs funs
Nothing -> snd bootstrap
= foldl (flip compile) cs funs
-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
-
generic gEncodedSize a :: !a -> Int
gEncodedSize{|Int|} _ = 1
gEncodedSize{|{!}|} fx xs = 1 + sum [fx x \\ x <-: xs]
@@ -215,8 +124,6 @@ gEncodedSize{|EITHER|} _ fr (RIGHT r) = fr r
gEncodedSize{|CONS|} fx (CONS x) = fx x + 1
gEncodedSize{|OBJECT|} fx (OBJECT x) = fx x
-derive gEncodedSize Instr
-
generic gEncode a :: !a !Int !*{#Int} -> (!Int, !*{#Int})
gEncode{|Int|} n i arr = (i+1, {arr & [i]=n})
gEncode{|{!}|} fx xs i arr = walk 0 (i+1) {arr & [i]=sz}
@@ -236,38 +143,10 @@ gEncode{|EITHER|} _ fr (RIGHT r) i arr = fr r i arr
gEncode{|CONS of {gcd_index}|} fx (CONS x) i arr = fx x (i+1) {arr & [i]=gcd_index}
gEncode{|OBJECT|} fx (OBJECT x) i arr = fx x i arr
+derive gEncodedSize Instr
derive gEncode Instr
encode :: !a -> *{#Int} | gEncodedSize{|*|}, gEncode{|*|} a
encode x
# (_,arr) = gEncode{|*|} x 0 (createArray (gEncodedSize{|*|} x) -1)
= arr
-
-exec :: !CompileState -> Int
-exec {jitst} = exec jitst.code_start
-where
- exec :: !Int -> Int
- exec _ = code {
- ccall jit_exec "p:I"
- }
-
-import Text.GenPrint
-derive gPrint Instr
-
-Start w
-# (io,w) = stdio w
-# io = Foldl (\io b -> io <<< " " <<< printToString b <<< "\n") (io <<< "Program blocks:\n") comp_state.blocks
-# io = io <<< "Interpreted result: " <<< interpreted_result <<< "\n"
-# io = io <<< "JIT-compiled result: " <<< jit_compiled_result <<< "\n"
-# (_,w) = fclose io w
-= setReturnCode (if (interpreted_result==jit_compiled_result) 0 1) w
-where
- interpreted_result = interpret comp_state
- jit_compiled_result = exec comp_state
-
-comp_state =: compile_all Nothing
- [ {fun_name="id", fun_args=["x"], fun_expr=Var "x"}
- , {fun_name="const", fun_args=["x","y"], fun_expr=Var "x"}
- , {fun_name="seven", fun_args=[], fun_expr=App "const" [Int 7, Int 10]}
- , {fun_name="main", fun_args=[], fun_expr=App "+" [App "seven" [], App "const" [Int 5, Int 10]]}
- ]
diff --git a/Sjit/Run.dcl b/Sjit/Run.dcl
new file mode 100644
index 0000000..aff22fc
--- /dev/null
+++ b/Sjit/Run.dcl
@@ -0,0 +1,6 @@
+definition module Sjit.Run
+
+from Sjit.Compile import :: CompileState
+
+interpret :: !CompileState -> Int
+exec :: !CompileState -> Int
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"
+ }
diff --git a/Sjit/Syntax.dcl b/Sjit/Syntax.dcl
new file mode 100644
index 0000000..a289b5a
--- /dev/null
+++ b/Sjit/Syntax.dcl
@@ -0,0 +1,12 @@
+definition module Sjit.Syntax
+
+:: Expr
+ = Int !Int
+ | Var !String
+ | App !String ![Expr]
+
+:: Function =
+ { fun_name :: !String
+ , fun_args :: ![String]
+ , fun_expr :: !Expr
+ }
diff --git a/Sjit/Syntax.icl b/Sjit/Syntax.icl
new file mode 100644
index 0000000..e512e0c
--- /dev/null
+++ b/Sjit/Syntax.icl
@@ -0,0 +1 @@
+implementation module Sjit.Syntax
diff --git a/isjit.icl b/isjit.icl
new file mode 100644
index 0000000..72d95dd
--- /dev/null
+++ b/isjit.icl
@@ -0,0 +1,32 @@
+module isjit
+
+import StdEnv
+import StdMaybe
+import StdOverloadedList
+
+import System.CommandLine
+
+import Sjit.Compile
+import Sjit.Syntax
+import Sjit.Run
+
+import Text.GenPrint
+derive gPrint Instr
+
+Start w
+# (io,w) = stdio w
+# io = Foldl (\io b -> io <<< " " <<< printToString b <<< "\n") (io <<< "Program blocks:\n") comp_state.blocks
+# io = io <<< "Interpreted result: " <<< interpreted_result <<< "\n"
+# io = io <<< "JIT-compiled result: " <<< jit_compiled_result <<< "\n"
+# (_,w) = fclose io w
+= setReturnCode (if (interpreted_result==jit_compiled_result) 0 1) w
+where
+ interpreted_result = interpret comp_state
+ jit_compiled_result = exec comp_state
+
+comp_state =: compile_all Nothing
+ [ {fun_name="id", fun_args=["x"], fun_expr=Var "x"}
+ , {fun_name="const", fun_args=["x","y"], fun_expr=Var "x"}
+ , {fun_name="seven", fun_args=[], fun_expr=App "const" [Int 7, Int 10]}
+ , {fun_name="main", fun_args=[], fun_expr=App "+" [App "seven" [], App "const" [Int 5, Int 10]]}
+ ]