LslPlus 0.4.2 → 0.4.3
raw patch · 8 files changed
+84/−86 lines, 8 files
Files
- LslPlus.cabal +1/−1
- src/Language/Lsl/Internal/Compiler.hs +4/−2
- src/Language/Lsl/Internal/Exec.hs +5/−5
- src/Language/Lsl/Internal/Optimize.hs +32/−31
- src/Language/Lsl/Parse.hs +9/−9
- src/Language/Lsl/Render.hs +14/−14
- src/Language/Lsl/Syntax.hs +18/−23
- src/LslPlus.hs +1/−1
LslPlus.cabal view
@@ -1,5 +1,5 @@ Name: LslPlus -version: 0.4.2 +version: 0.4.3 Synopsis: An execution and testing framework for the Linden Scripting Language (LSL) Description: Provides a framework for executing Linden Scripting Language scripts offline,
src/Language/Lsl/Internal/Compiler.hs view
@@ -144,14 +144,16 @@ renderScriptsToFiles :: Bool -> [(String,Validity CompiledLSLScript)] -> [(String,String)] -> IO () renderScriptsToFiles opt compiledScripts pathTable = let scriptsToRender = - [(path,script) | (Just path,Right script) <- map (\ (name,vs) -> (lookup name pathTable,vs)) compiledScripts] + [(name, path, script) | (name, Just path,Right script) <- + map (\ (name,vs) -> (name, lookup name pathTable,vs)) compiledScripts] scriptsToRemove = [path | (Just path,Left _) <- map (\ (name,vs) -> (lookup name pathTable,vs)) compiledScripts] in do clockTime <- getClockTime calTime <- toCalendarTime clockTime let stamp = calendarTimeToString calTime - mapM_ (\ (path,script) -> renderScriptToFile opt stamp path script) scriptsToRender + mapM_ (\ (name,path,script) -> + renderScriptToFile opt (name ++ " " ++ stamp) path script) scriptsToRender mapM_ (removeOutputScript) scriptsToRemove renderScriptToFile opt stamp path script =
src/Language/Lsl/Internal/Exec.hs view
@@ -351,8 +351,8 @@ | EvShiftL | EvShiftR | EvCast LSLType | EvGet (String,Component) | EvSet (String,Component) | EvCons | EvMkVec | EvMkRot | EvPop | EvReturn | EvDiscard | EvBind String LSLType - | EvCond Statement Statement | EvCall String (Maybe SourceContext) [Var] [Ctx Statement] Bool - | EvPredef String | EvLoop Expr [Ctx Expr] Statement | EvMark + | EvCond (Ctx Statement) (Ctx Statement) | EvCall String (Maybe SourceContext) [Var] [Ctx Statement] Bool + | EvPredef String | EvLoop Expr [Ctx Expr] (Ctx Statement) | EvMark deriving (Show,Data,Typeable) queryState q = evalT (\s -> (q s, s)) @@ -757,7 +757,7 @@ EvStatement (If expr stmt1 stmt2) -> pushElements [EvCond stmt1 stmt2,EvExpr $ ctxItem expr] EvStatement (While expr stmt) -> modMark (+1) >> pushElements [EvMark,EvLoop (ctxItem expr) [] stmt,EvExpr $ ctxItem expr] EvStatement (DoWhile stmt expr) -> modMark (+1) >> - pushElements [EvMark,EvLoop (ctxItem expr) [] stmt, EvExpr (ctxItem expr),EvStatement stmt] + pushElements [EvMark,EvLoop (ctxItem expr) [] stmt, EvExpr (ctxItem expr),EvCtxStatement stmt] EvStatement (For mexpr1 mexpr2 mexpr3 stmt) -> do let expr = case mexpr2 of Nothing -> (IntLit 1) @@ -792,11 +792,11 @@ pushElement element -- last, re-evaluate loop pushElement (EvExpr expr) -- next-to-last, re-evaluate expr) pushElements [EvDiscard, EvExpr (ListExpr mexpr)] -- evaluate end-of-loop expressions - pushElement (EvStatement stmt) -- first, evaluate statement) + pushElement (EvCtxStatement stmt) -- first, evaluate statement) continue EvCond stmt1 stmt2 -> do val <- popVal - pushElement (EvStatement (if trueCondition val then stmt1 else stmt2)) + pushElement (EvCtxStatement (if trueCondition val then stmt1 else stmt2)) continue EvExpr (IntLit i) -> pushVal (IVal i) >> continue EvExpr (FloatLit f) -> pushVal (FVal (realToFrac f)) >> continue
src/Language/Lsl/Internal/Optimize.hs view
@@ -116,6 +116,7 @@ nullCtx :: a -> Ctx a nullCtx = Ctx Nothing +nullCtxStmt = nullCtx NullStmt sminsert k v (m:ms) = M.insert k v m : ms @@ -365,28 +366,28 @@ inlineStmts endLabel (While expr stmt:stmts) = do (renames,rewrites) <- getRewriteInfo stmts' <- inlineStmts endLabel stmts - ss <- inlineStmts endLabel [stmt] - return (While (rewriteCtxExpr renames rewrites expr) (Compound (map nullCtx ss)) : stmts') + ss <- inlineStmts endLabel [ctxItem stmt] + return (While (rewriteCtxExpr renames rewrites expr) (nullCtx (Compound (map nullCtx ss))) : stmts') inlineStmts endLabel (DoWhile stmt expr:stmts) = do stmts' <- inlineStmts endLabel stmts - ss <- inlineStmts endLabel [stmt] + ss <- inlineStmts endLabel [ctxItem stmt] (renames,rewrites) <- getRewriteInfo - return (DoWhile (Compound (map nullCtx ss)) (rewriteCtxExpr renames rewrites expr) : stmts') + return (DoWhile (nullCtx (Compound (map nullCtx ss))) (rewriteCtxExpr renames rewrites expr) : stmts') inlineStmts endLabel (For es0 e es1 stmt:stmts) = do (renames,rewrites) <- getRewriteInfo let rewriteExprs = map (rewriteCtxExpr renames rewrites) stmts' <- inlineStmts endLabel stmts - ss <- inlineStmts endLabel [stmt] + ss <- inlineStmts endLabel [ctxItem stmt] let body = case ss of s:[] -> s _ -> Compound (map nullCtx ss) - return (For (rewriteExprs es0) (fmap (rewriteCtxExpr renames rewrites) e) (rewriteExprs es1) body: stmts') + return (For (rewriteExprs es0) (fmap (rewriteCtxExpr renames rewrites) e) (rewriteExprs es1) (nullCtx body): stmts') inlineStmts endLabel (If e s0 s1:stmts) = do (renames,rewrites) <- getRewriteInfo stmts' <- inlineStmts endLabel stmts - s0s <- inlineStmts endLabel [s0] - s1s <- inlineStmts endLabel [s1] - return (If (rewriteCtxExpr renames rewrites e) (newS s0s) (newS s1s) : stmts') + s0s <- inlineStmts endLabel [ctxItem s0] + s1s <- inlineStmts endLabel [ctxItem s1] + return (If (rewriteCtxExpr renames rewrites e) (nullCtx (newS s0s)) (nullCtx (newS s1s)) : stmts') where newS ss = case ss of [s] -> s @@ -455,14 +456,14 @@ refreshOState bgnLoop <- mkName "bgnLoop" (expr',stmts) <- inlineExpr' expr - ss <- performInliningForStmt (nullCtx s) + ss <- performInliningForStmt s return $ case (stmts,ss) of - ([],[s']) -> [nullCtx $ While expr' (ctxItem s')] - ([],_) -> [nullCtx $ While expr' (Compound ss)] + ([],[s']) -> [nullCtx $ While expr' s'] + ([],_) -> [nullCtx $ While expr' $ nullCtx (Compound ss)] _ -> ((nullCtx $ Label bgnLoop) : (stmts ++ case ss of - [] -> [nullCtx $ If expr' (Jump bgnLoop) NullStmt] - _ -> [nullCtx $ If expr' (Compound (ss ++ [nullCtx $ Jump bgnLoop])) NullStmt])) -performInliningForStmt s@(Ctx _ NullStmt) = refreshOState >> return [nullCtx NullStmt] + [] -> [nullCtx $ If expr' (nullCtx (Jump bgnLoop)) (nullCtxStmt)] + _ -> [nullCtx $ If expr' (nullCtx (Compound (ss ++ [nullCtx $ Jump bgnLoop]))) (nullCtxStmt)])) +performInliningForStmt s@(Ctx _ NullStmt) = refreshOState >> return [nullCtxStmt] performInliningForStmt s@(Ctx _ (Decl (Var v t) Nothing)) = do refreshOState v' <- renameToNewInInliner v @@ -486,11 +487,11 @@ performInliningForStmt (Ctx _ (DoWhile s expr)) = do refreshOState bgnLoop <- mkName "bgnLoop" - ss <- performInliningForStmt (nullCtx s) + ss <- performInliningForStmt s (expr',stmts) <- inlineExpr' expr let s' = case ss ++ stmts of - [s''] -> ctxItem s'' - ss' -> Compound ss' + [s''] -> s'' + ss' -> nullCtx $ Compound ss' return [nullCtx $ DoWhile s' expr'] performInliningForStmt (Ctx _ (For ies1 mte ses2 s)) = do refreshOState @@ -501,29 +502,29 @@ Just te -> do (te',tss) <- inlineExpr' te return (Just te',tss) (ses2', sss2s) <- inlineExprs ses2 - ss <- performInliningForStmt (nullCtx s) + ss <- performInliningForStmt s let iss1 = concat iss1s let sss2 = concat sss2s case (iss1,tss,sss2,ss) of - ([],[],[],[s']) -> return [(nullCtx $ For ies1' mte' ses2' (ctxItem s'))] - ([],[],[],_) -> return [(nullCtx $ For ies1' mte' ses2' (Compound ss))] + ([],[],[],[s']) -> return [(nullCtx $ For ies1' mte' ses2' s')] + ([],[],[],_) -> return [(nullCtx $ For ies1' mte' ses2' $ nullCtx (Compound ss))] _ -> return (iss1 ++ (map (nullCtx . Do) ies1') ++ [nullCtx $ Label bgnLoop] ++ rest) where rest = case mte' of Nothing -> ss ++ sss2 ++ (map (nullCtx . Do) ses2') ++ [nullCtx $ Jump bgnLoop] Just te' -> tss ++ - [nullCtx $ If te' (Compound (ss ++ sss2 ++ (map (nullCtx . Do) ses2') ++ [nullCtx $ Jump bgnLoop])) NullStmt] + [nullCtx $ If te' (nullCtx (Compound (ss ++ sss2 ++ (map (nullCtx . Do) ses2') ++ [nullCtx $ Jump bgnLoop]))) (nullCtxStmt)] performInliningForStmt (Ctx _ (If e s0 s1)) = do refreshOState (e',ess) <- inlineExpr' e - s0s <- performInliningForStmt (nullCtx s0) - s1s <- performInliningForStmt (nullCtx s1) + s0s <- performInliningForStmt s0 + s1s <- performInliningForStmt s1 let branch1 = case s0s of [s] -> ctxItem s _ -> Compound s0s let branch2 = case s1s of [s] -> ctxItem s _ -> Compound s1s - return (ess ++ [nullCtx $ If e' branch1 branch2]) + return (ess ++ [nullCtx $ If e' (nullCtx branch1) (nullCtx branch2)]) inlineExprs :: [Ctx Expr] -> OState ([Ctx Expr], [[Ctx Statement]]) inlineExprs exprs = do @@ -644,7 +645,7 @@ (Ctx _ (Jump l)) | l == label -> initial | otherwise -> ss (Ctx c (Compound ss')) -> initial ++ [(Ctx c (Compound (withoutFinalJumpTo label ss')))] - (Ctx c (If expr s0 s1)) -> initial ++ [Ctx c (If expr (rmvj s0) (rmvj s1))] + (Ctx c (If expr s0 s1)) -> initial ++ [Ctx c (If expr (nullCtx (rmvj $ ctxItem s0)) (nullCtx (rmvj $ ctxItem s1)))] (Ctx c s) -> ss where final = last ss initial = init ss @@ -913,7 +914,7 @@ simplifyE (Ge (Ctx _ (IntLit i)) (Ctx _ (IntLit j))) = return (IntLit (bb2int (>=) i j)) simplifyE (Le (Ctx _ (IntLit i)) (Ctx _ (IntLit j))) = return (IntLit (bb2int (<=) i j)) simplifyE (Equal (Ctx _ (IntLit i)) (Ctx _ (IntLit j))) = return (IntLit (bb2int (==) i j)) -simplifyE (NotEqual (Ctx _ (IntLit i)) (Ctx _ (IntLit j))) = return (IntLit (bb2int (==) i j)) +simplifyE (NotEqual (Ctx _ (IntLit i)) (Ctx _ (IntLit j))) = return (IntLit (bb2int (/=) i j)) simplifyE (BAnd (Ctx _ (IntLit i)) (Ctx _ (IntLit j))) = return (IntLit (i .&. j)) simplifyE (BOr (Ctx _ (IntLit i)) (Ctx _ (IntLit j))) = return (IntLit (i .|. j)) simplifyE (Xor (Ctx _ (IntLit i)) (Ctx _ (IntLit j))) = return (IntLit (i `xor` j)) @@ -1024,10 +1025,10 @@ checkVal _ v = valToExpr v -- could simplify for other types, but this should be sufficient for the main use case -simplifyS (If (Ctx _ (IntLit 0)) _ stmt) = return stmt -simplifyS (If (Ctx _ (IntLit _)) stmt _) = return stmt -simplifyS (If (Ctx _ (FloatLit 0)) _ stmt) = return stmt -simplifyS (If (Ctx _ (FloatLit _)) stmt _) = return stmt +simplifyS (If (Ctx _ (IntLit 0)) _ stmt) = return $ ctxItem stmt +simplifyS (If (Ctx _ (IntLit _)) stmt _) = return $ ctxItem stmt +simplifyS (If (Ctx _ (FloatLit 0)) _ stmt) = return $ ctxItem stmt +simplifyS (If (Ctx _ (FloatLit _)) stmt _) = return $ ctxItem stmt simplifyS (Do (Ctx _ (Get _))) = return NullStmt simplifyS s = return s
src/Language/Lsl/Parse.hs view
@@ -27,8 +27,9 @@ import Data.Char(digitToInt) import Data.List(intersperse) import Language.Lsl.Internal.Pragmas(Pragma(..)) -import Language.Lsl.Syntax(Expr(..),Statement(..),Func(..),FuncDec(..),Handler(Handler),State(..),Ctx(..),TextLocation(..),SourceContext(..),LSLType(..), - Component(..),Var(..),LModule(..),LSLScript(..),GlobDef(..),goodHandlers) +import Language.Lsl.Syntax(Expr(..),Statement(..),Func(..),FuncDec(..),Handler(Handler),State(..),Ctx(..), + TextLocation(..),SourceContext(..),LSLType(..), + Component(..),Var(..),LModule(..),LSLScript(..),GlobDef(..),goodHandlers,nullCtx) import Text.ParserCombinators.Parsec hiding (State) import qualified Text.ParserCombinators.ParsecExtras.Token as P import Text.ParserCombinators.ParsecExtras.Language( javaStyle, emptyDef ) @@ -214,8 +215,7 @@ return v natOrFloat = (decimalFraction 0.0 >>= return . Right) - <|> do char '0' - option (Left 0) prefZeroNum + <|> try (char '0' >> option (Left 0) prefZeroNum) <|> decimalOrFloat prefZeroNum = (hex >>= return . Left) @@ -518,12 +518,12 @@ whileStatement = do reserved "while" e <- parens expr - stmt <- statement + stmt <- ctxify statement return $ While e stmt ifElseStatement = do reserved "if" e <- parens expr - stmt1 <- statement - stmt2 <- (option NullStmt (reserved "else" >> statement)) + stmt1 <- ctxify statement + stmt2 <- (option (nullCtx NullStmt) (reserved "else" >> ctxify statement)) return $ If e stmt1 stmt2 stateStatement = do reserved "state" @@ -541,11 +541,11 @@ mexpr3 <- commaSep expr char ')' whiteSpace - stmt <- statement + stmt <- ctxify statement return $ For mexpr1 mexpr2 mexpr3 stmt doWhileStatement = do reserved "do" - stmt <- statement + stmt <- ctxify statement reserved "while" e <- parens expr semi
src/Language/Lsl/Render.hs view
@@ -95,31 +95,31 @@ renderStatement' n (While expr stmt) = renderString "while (" . renderCtxExpr expr . renderChar ')' . case stmt of - NullStmt -> renderString ";\n" - _ -> renderStatement True n stmt + (Ctx _ NullStmt) -> renderString ";\n" + _ -> renderCtxStatement True n stmt renderStatement' n (DoWhile stmt expr) = renderString "do " . (case stmt of - NullStmt -> renderString ";\n" - _ -> renderStatement True n stmt) . doHang False n . renderString "while (" . renderCtxExpr expr . renderString ");\n" + (Ctx _ NullStmt) -> renderString ";\n" + _ -> renderCtxStatement True n stmt) . doHang False n . renderString "while (" . renderCtxExpr expr . renderString ");\n" renderStatement' n (For mexpr1 mexpr2 mexpr3 stmt) = renderString "for (" . renderCtxExprs "" mexpr1 . renderString "; " . renderOptionalExpression mexpr2 . renderString "; " . renderCtxExprs "" mexpr3 . renderString ")" . case stmt of - NullStmt -> renderString ";\n" - _ -> renderStatement True n stmt + (Ctx _ NullStmt) -> renderString ";\n" + _ -> renderCtxStatement True n stmt renderStatement' n (If expr stmt1 stmt2) = renderString "if (" . renderCtxExpr expr . renderChar ')' . (case stmt1 of - NullStmt -> renderString ";\n" - If expr (Compound _) _ -> renderStatement True n stmt1 - If expr _ NullStmt -> case stmt2 of - NullStmt -> renderStatement True n stmt1 - _ -> renderStatement True n (Compound [Ctx Nothing stmt1]) - _ -> renderStatement True n stmt1) . + (Ctx _ NullStmt) -> renderString ";\n" + (Ctx _ (If expr (Ctx _ (Compound _)) _)) -> renderCtxStatement True n stmt1 + (Ctx _ (If expr _ (Ctx _ NullStmt))) -> case stmt2 of + (Ctx _ NullStmt) -> renderCtxStatement True n stmt1 + _ -> renderStatement True n (Compound [stmt1]) + _ -> renderCtxStatement True n stmt1) . case stmt2 of - NullStmt -> blank - _ -> renderIndent n . renderString "else " . (renderStatement True n stmt2) + (Ctx _ NullStmt) -> blank + _ -> renderIndent n . renderString "else " . (renderCtxStatement True n stmt2) renderStatement' n (Decl var val) = renderVar var . case val of
src/Language/Lsl/Syntax.hs view
@@ -179,10 +179,10 @@ -- | An LSL statement. data Statement = Compound [CtxStmt] - | While CtxExpr Statement - | DoWhile Statement CtxExpr - | For ([CtxExpr]) (Maybe CtxExpr) ([CtxExpr]) Statement - | If CtxExpr Statement Statement + | While CtxExpr CtxStmt + | DoWhile CtxStmt CtxExpr + | For ([CtxExpr]) (Maybe CtxExpr) ([CtxExpr]) CtxStmt + | If CtxExpr CtxStmt CtxStmt | Decl Var (Maybe CtxExpr) | NullStmt | Return (Maybe CtxExpr) @@ -707,22 +707,22 @@ get'vsBranchReturns compileStatement (Ctx ctx (While expr statement)) = do t <- compileCtxExpr expr - vsmInBranch $ compileStatement (nullCtx statement) + vsmInBranch $ compileStatement statement get'vsBranchReturns compileStatement (Ctx ctx(DoWhile statement expr)) = do t <- compileCtxExpr expr - vsmInBranch $ compileStatement (nullCtx statement) + vsmInBranch $ compileStatement statement get'vsBranchReturns compileStatement (Ctx ctx (For mexpr1 mexpr2 mexpr3 statement)) = do compileExpressions mexpr1 compileExpressions mexpr3 t <- compileMExpression mexpr2 - vsmInBranch $ compileStatement (nullCtx statement) + vsmInBranch $ compileStatement statement get'vsBranchReturns compileStatement (Ctx ctx (If expr thenStmt elseStmt)) = do t <- compileCtxExpr expr - ret1 <- vsmInBranch $ compileStatement (nullCtx thenStmt) - ret2 <- vsmInBranch $ compileStatement (nullCtx elseStmt) + ret1 <- vsmInBranch $ compileStatement thenStmt + ret2 <- vsmInBranch $ compileStatement elseStmt returns <- get'vsBranchReturns put'vsBranchReturns (returns || (ret1 && ret2)) get'vsBranchReturns @@ -1261,15 +1261,6 @@ f (name,Right (lm,_)) = (name, Right lm) in map f augLib -tstLib = [ - ("alpha", LModule [GI (nullCtx "beta") [] []] []), - ("beta", LModule [GI (nullCtx "gamma") [] []] []), - ("gamma", LModule [GI (nullCtx "alpha") [] []] []), - ("omega", LModule [GI (nullCtx "lambda") [] []] []), - ("lambda", LModule [GI (nullCtx "kappa") [] [], GI (nullCtx "sigma") [] []] []), - ("kappa", LModule [] []), - ("sigma", LModule [] [])] - -- | Transform a script into a module, generating function names for each handler, using the -- pattern <state-name>_state_<handler-name>. -- The script following script: @@ -1309,6 +1300,10 @@ case lookup name renames of Nothing -> Ctx ctx name Just name' -> Ctx ctx name' + +rewriteCtxStatement n bindings (Ctx c s) = + let (n',bindings',s') = rewriteStatement n bindings s in (n',bindings', Ctx c s') + rewriteStatements _ _ [] = [] rewriteStatements n bindings (Ctx c s:ss) = let (n',bindings',s') = rewriteStatement n bindings s in @@ -1316,19 +1311,19 @@ rewriteStatement n bindings (Compound stmts) = (n, bindings, Compound $ rewriteStatements n bindings stmts) rewriteStatement n bindings (While expr stmt) = - let (_,_,stmt') = rewriteStatement n bindings stmt in + let (_,_,stmt') = rewriteCtxStatement n bindings stmt in (n, bindings, While (rewriteCtxExpr bindings expr) stmt') rewriteStatement n bindings (DoWhile stmt expr) = - let (_,_,stmt') = rewriteStatement n bindings stmt in + let (_,_,stmt') = rewriteCtxStatement n bindings stmt in (n, bindings, DoWhile stmt' (rewriteCtxExpr bindings expr)) rewriteStatement n bindings (For mexpr1 mexpr2 mexpr3 stmt) = - let (_,_,stmt') = rewriteStatement n bindings stmt + let (_,_,stmt') = rewriteCtxStatement n bindings stmt rewriteMExpr = rewriteMExpression bindings rewriteEs = rewriteCtxExprs bindings in (n, bindings, For (rewriteEs mexpr1) (rewriteMExpr mexpr2) (rewriteEs mexpr3) stmt') rewriteStatement n bindings (If expr stmt1 stmt2) = - let (_,_,stmt1') = rewriteStatement n bindings stmt1 - (_,_,stmt2') = rewriteStatement n bindings stmt2 in + let (_,_,stmt1') = rewriteCtxStatement n bindings stmt1 + (_,_,stmt2') = rewriteCtxStatement n bindings stmt2 in (n, bindings, If (rewriteCtxExpr bindings expr) stmt1' stmt2') rewriteStatement n bindings (Decl (Var name t) val) = let (n',bindings', newname) =
src/LslPlus.hs view
@@ -13,7 +13,7 @@ import System import System.Exit -version="0.4.2" +version="0.4.3" usage progName = "Usage: " ++ progName ++ " [Version|MetaData|Compiler|ExpressionHandler|SimMetaData|SystemTester|UnitTester|CompilationServer]" main = do progName <- getProgName