<commit_before>> module Epic.Bytecode where

> import Control.Monad.State
> import List

> import Epic.Language
> import Debug.Trace

> type Local = Int
> type TmpVar = Int
> type StrVar = Int

Register based - most operations do an action, then put the result in a
'TmpVar' which is basically a numbered register. There are infinite registers
at this stage.

> data ByteOp = CALL TmpVar Name [TmpVar]
>             | TAILCALL TmpVar Name [TmpVar]
>             | THUNK TmpVar Int Name [TmpVar]
>             | ADDARGS TmpVar TmpVar [TmpVar]
>             | FOREIGN Type TmpVar String [(TmpVar, Type)]
>             | VAR TmpVar Local
>             | ASSIGN Local TmpVar
>             | TMPASSIGN TmpVar TmpVar
>             | NOASSIGN Local TmpVar -- No-op, but flag not to eval the register
>             | CON TmpVar Tag [TmpVar]
>             | UNIT TmpVar
>             | UNUSED TmpVar
>             | INT TmpVar Int
>             | BIGINT TmpVar Integer
>             | FLOAT TmpVar Float
>             | BIGFLOAT TmpVar Double
>             | STRING TmpVar StrVar
>             | PROJ TmpVar TmpVar Int -- project into a register
>             | PROJVAR Local TmpVar Int -- project into a local variable
>               -- each case branch records which tag it's code for
>             | CASE TmpVar [(Int, Bytecode)] (Maybe Bytecode)
>             | INTCASE TmpVar [(Int, Bytecode)] (Maybe Bytecode)
>             | IF TmpVar Bytecode Bytecode
>             | OP TmpVar Op TmpVar TmpVar
>             | LOCALS Int -- allocate space for locals
>             | TMPS Int -- declare temporary variables
>             | CONSTS [String] -- declare constants
>             | LABEL Int
>             | WHILE Bytecode Bytecode
>             | WHILEACC Bytecode TmpVar Bytecode
>             | BREAKFALSE TmpVar
>             | JFALSE TmpVar Int
>             | JUMP Int
>             | EVAL TmpVar Bool -- Bool is True if update required
>             | EVALINT TmpVar Bool -- Bool is True if update required
>             -- | LET TmpVar Local TmpVar
>             | RETURN TmpVar
>             | DRETURN -- return dummy value
>             | ERROR String -- Fatal error, exit
>             | TRACE String [TmpVar]
>             | COMMENT String -- handy for adding notes to output
>   deriving Show

> type Bytecode = [ByteOp]

> data FunCode = Code [Type] Bytecode
>   deriving Show

> data CompileState = CS { arg_types :: [Type],
>                          num_locals :: Int,
>                          next_tmp :: Int,
>                          string_pool :: [String],
>                          max_tmp :: Int,
>                          next_label :: Int }

> compile :: Context -> Name -> Func -> FunCode
> compile ctxt fname fn@(Bind args locals def flags) = 
>     let cs = (CS (map snd args) (length args) 1 [] 1 0)
>         code = evalState (scompile ctxt fname fn) cs 
>         opt = peephole' evalled code in
>               Code (map snd args) opt
>   where evalled | elem Strict flags = [] --take locals [0..]
>                 | otherwise = []

> data TailCall = Tail | Middle

> scompile :: Context -> Name -> Func -> State CompileState Bytecode
> scompile ctxt fname (Bind args locals def _) = 
>     do -- put (CS args (length args) 1)
>        code <- ecomp (False, True) Tail def 0 (length args)
>        cs <- get
>        return $ (LOCALS (num_locals cs)):
>                 (TRACE (show fname) [0..(length args)-1]):
>                 (TMPS (max_tmp cs)):(CONSTS (string_pool cs)):code ++
>                   [EVAL 0 True, RETURN 0]

>   where

>     new_tmp :: State CompileState Int
>     new_tmp = do cs <- get
>                  let reg' = next_tmp cs
>                  let max = if (reg'+ 1) > max_tmp cs then reg'+1 else max_tmp cs
>                  put (cs { next_tmp = reg'+1, max_tmp = max } )
>                  return reg'

>     set_tmp :: Int -> State CompileState ()
>     set_tmp n = do cs <- get
>                    put (cs { next_tmp = n } )

>     get_tmp :: State CompileState Int
>     get_tmp = do cs <- get
>                  return $ next_tmp cs

>     new_label :: State CompileState Int
>     new_label = do cs <- get
>                    let reg' = next_label cs
>                    put (cs { next_label = reg'+1 } )<commit_msg>Removed a spurious EVAL<commit_after>> module Epic.Bytecode where

> import Control.Monad.State
> import List

> import Epic.Language
> import Debug.Trace

> type Local = Int
> type TmpVar = Int
> type StrVar = Int

Register based - most operations do an action, then put the result in a
'TmpVar' which is basically a numbered register. There are infinite registers
at this stage.

> data ByteOp = CALL TmpVar Name [TmpVar]
>             | TAILCALL TmpVar Name [TmpVar]
>             | THUNK TmpVar Int Name [TmpVar]
>             | ADDARGS TmpVar TmpVar [TmpVar]
>             | FOREIGN Type TmpVar String [(TmpVar, Type)]
>             | VAR TmpVar Local
>             | ASSIGN Local TmpVar
>             | TMPASSIGN TmpVar TmpVar
>             | NOASSIGN Local TmpVar -- No-op, but flag not to eval the register
>             | CON TmpVar Tag [TmpVar]
>             | UNIT TmpVar
>             | UNUSED TmpVar
>             | INT TmpVar Int
>             | BIGINT TmpVar Integer
>             | FLOAT TmpVar Float
>             | BIGFLOAT TmpVar Double
>             | STRING TmpVar StrVar
>             | PROJ TmpVar TmpVar Int -- project into a register
>             | PROJVAR Local TmpVar Int -- project into a local variable
>               -- each case branch records which tag it's code for
>             | CASE TmpVar [(Int, Bytecode)] (Maybe Bytecode)
>             | INTCASE TmpVar [(Int, Bytecode)] (Maybe Bytecode)
>             | IF TmpVar Bytecode Bytecode
>             | OP TmpVar Op TmpVar TmpVar
>             | LOCALS Int -- allocate space for locals
>             | TMPS Int -- declare temporary variables
>             | CONSTS [String] -- declare constants
>             | LABEL Int
>             | WHILE Bytecode Bytecode
>             | WHILEACC Bytecode TmpVar Bytecode
>             | BREAKFALSE TmpVar
>             | JFALSE TmpVar Int
>             | JUMP Int
>             | EVAL TmpVar Bool -- Bool is True if update required
>             | EVALINT TmpVar Bool -- Bool is True if update required
>             -- | LET TmpVar Local TmpVar
>             | RETURN TmpVar
>             | DRETURN -- return dummy value
>             | ERROR String -- Fatal error, exit
>             | TRACE String [TmpVar]
>             | COMMENT String -- handy for adding notes to output
>   deriving Show

> type Bytecode = [ByteOp]

> data FunCode = Code [Type] Bytecode
>   deriving Show

> data CompileState = CS { arg_types :: [Type],
>                          num_locals :: Int,
>                          next_tmp :: Int,
>                          string_pool :: [String],
>                          max_tmp :: Int,
>                          next_label :: Int }

> compile :: Context -> Name -> Func -> FunCode
> compile ctxt fname fn@(Bind args locals def flags) = 
>     let cs = (CS (map snd args) (length args) 1 [] 1 0)
>         code = evalState (scompile ctxt fname fn) cs 
>         opt = peephole' evalled code in
>               Code (map snd args) opt
>   where evalled | elem Strict flags = [] --take locals [0..]
>                 | otherwise = []

> data TailCall = Tail | Middle

> scompile :: Context -> Name -> Func -> State CompileState Bytecode
> scompile ctxt fname (Bind args locals def _) = 
>     do -- put (CS args (length args) 1)
>        code <- ecomp (False, True) Tail def 0 (length args)
>        cs <- get
>        return $ (LOCALS (num_locals cs)):
>                 (TRACE (show fname) [0..(length args)-1]):
>                 (TMPS (max_tmp cs)):(CONSTS (string_pool cs)):code ++
>                   [RETURN 0]

>   where

>     new_tmp :: State CompileState Int
>     new_tmp = do cs <- get
>                  let reg' = next_tmp cs
>                  let max = if (reg'+ 1) > max_tmp cs then reg'+1 else max_tmp cs
>                  put (cs { next_tmp = reg'+1, max_tmp = max } )
>                  return reg'

>     set_tmp :: Int -> State CompileState ()
>     set_tmp n = do cs <- get
>                    put (cs { next_tmp = n } )

>     get_tmp :: State CompileState Int
>     get_tmp = do cs <- get
>                  return $ next_tmp cs

>     new_label :: State CompileState Int
>     new_label = do cs <- get
>                    let reg' = next_label cs
>                    put (cs { next_label = reg'+1 } )
{'fraction_non_alphanumeric': 0.0946213977365535, 'fraction_numerical': 0.003150157507875394, 'mean_word_length': 1.5920774115512548, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 207, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6492076', 'n_tokens_mistral': 2584, 'n_tokens_neox': 2499, 'n_words': 886}