diff --git a/LobsterLang/src/AstOptimizer.hs b/LobsterLang/src/AstOptimizer.hs index c6b482c..f36dc4d 100644 --- a/LobsterLang/src/AstOptimizer.hs +++ b/LobsterLang/src/AstOptimizer.hs @@ -41,66 +41,23 @@ data AstOptimised -- whether the optimization take place insinde a function and returns the -- list of `Either` `AstError` or `AstOptimised` optimizeAst :: [ScopeMb] -> [Ast] -> Bool -> [Either AstError AstOptimised] -optimizeAst stack ((Value v) : xs) inFunc = - Right (Result (Value v)) : optimizeAst stack xs inFunc -optimizeAst stack ((Boolean b) : xs) inFunc = - Right (Result (Boolean b)) : optimizeAst stack xs inFunc -optimizeAst stack ((String str) : xs) inFunc = - Right (Result (String str)) : optimizeAst stack xs inFunc -optimizeAst stack ((List asts) : xs) inFunc = - case sequence (optimizeAst stack asts inFunc) of - Left err -> Left err : optimizeAst stack xs inFunc +optimizeAst stack ((Value v) : xs) inF = + Right (Result (Value v)) : optimizeAst stack xs inF +optimizeAst stack ((Boolean b) : xs) inF = + Right (Result (Boolean b)) : optimizeAst stack xs inF +optimizeAst stack ((String str) : xs) inF = + Right (Result (String str)) : optimizeAst stack xs inF +optimizeAst stack ((List asts) : xs) inF = + case sequence (optimizeAst stack asts inF) of + Left err -> Left err : optimizeAst stack xs inF Right opAst -> Right (Result (List (map fromOptimised opAst))) - : optimizeAst stack xs inFunc -optimizeAst stack ((Define n ast) : xs) inFunc = - case optimizeAst stack [ast] inFunc of - [Left err] -> Left err : optimizeAst stack xs inFunc - [Right (Result opAst)] -> case evalAst stack (Define n opAst) of - (Right _, stack') -> - Right (Result (Define n opAst)) - : optimizeAst stack' xs inFunc - (Left ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs'), _) - | inFunc -> - Right (Result (Define n opAst)) - : optimizeAst stack xs inFunc - | otherwise -> - Left - ( Error - ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs') - (Define n opAst) - ) - : optimizeAst stack xs inFunc - (Left err, _) -> - Left (Error err (Define n opAst)) - : optimizeAst stack xs inFunc - [Right (Warning mes opAst)] -> case evalAst stack (Define n opAst) of - (Right _, stack') -> - Right (Warning mes (Define n opAst)) - : optimizeAst stack' xs inFunc - ( Left ('R' : 'e' : 'c' : 'u' : 'r' : 's' : 'i' : 'o' : 'n' : _), - stack' - ) -> - Right (Warning "Possible infinite recursion" (Define n opAst)) - : optimizeAst stack' xs inFunc - (Left ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs'), _) - | inFunc -> - Right (Result (Define n opAst)) - : optimizeAst stack xs inFunc - | otherwise -> - Left - ( Error - ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs') - (Define n opAst) - ) - : optimizeAst stack xs inFunc - (Left err, _) -> - Left (Error err (Define n opAst)) - : optimizeAst stack xs inFunc - _ -> shouldntHappen stack (Define n ast : xs) inFunc -optimizeAst stack ((Symbol s Nothing) : xs) inFunc - | inFunc = - Right (Result (Symbol s Nothing)) : optimizeAst stack xs inFunc + : optimizeAst stack xs inF +optimizeAst stack ((Define n ast) : xs) inF = + checkOptiAfterDef stack (optimizeAst stack [ast] inF) n ast xs inF +optimizeAst stack ((Symbol s Nothing) : xs) inF + | inF = + Right (Result (Symbol s Nothing)) : optimizeAst stack xs inF | otherwise = case getVarInScope stack s of Nothing -> Left @@ -111,118 +68,121 @@ optimizeAst stack ((Symbol s Nothing) : xs) inFunc ) (Symbol s Nothing) ) - : optimizeAst stack xs inFunc - Just _ -> Right (Result (Symbol s Nothing)) : optimizeAst stack xs inFunc -optimizeAst stack ((Symbol s (Just asts)) : xs) inFunc + : optimizeAst stack xs inF + Just _ -> Right (Result (Symbol s Nothing)) : optimizeAst stack xs inF +optimizeAst stack ((Symbol s (Just asts)) : xs) inF | foldr ((&&) . isUnoptimizable) True asts = - checkEvalReturnSame stack (Symbol s (Just asts) : xs) inFunc - | otherwise = case sequence (optimizeAst stack asts inFunc) of - Left err -> Left err : optimizeAst stack xs inFunc + checkEvalReturnSame stack (Symbol s (Just asts) : xs) + (evalAst stack (Symbol s (Just asts))) inF + | otherwise = case sequence (optimizeAst stack asts inF) of + Left err -> Left err : optimizeAst stack xs inF Right opAst -> optimizeAst stack (Symbol s (Just (map fromOptimised opAst)) : xs) - inFunc -optimizeAst stack ((Call op asts) : xs) inFunc + inF +optimizeAst stack ((Call op asts) : xs) inF | foldr ((&&) . isUnoptimizable) True asts && foldr ((&&) . isValue) True asts = - checkEval stack (Call op asts : xs) inFunc + checkEval stack (Call op asts : xs) (evalAst stack (Call op asts)) inF | foldr ((&&) . isUnoptimizable) True asts = - checkEvalReturnSame stack (Call op asts : xs) inFunc - | otherwise = case sequence (optimizeAst stack asts inFunc) of - Left err -> Left err : optimizeAst stack xs inFunc + checkEvalReturnSame stack (Call op asts : xs) + (evalAst stack (Call op asts)) inF + | otherwise = case sequence (optimizeAst stack asts inF) of + Left err -> Left err : optimizeAst stack xs inF Right asts' -> optimizeAst stack (Call op (map fromOptimised asts') : xs) - inFunc -optimizeAst stack ((Cond condAst trueAst mFalseAst) : xs) inFunc - | not (isUnoptimizable condAst) = case optimizeAst stack [condAst] inFunc of - [Left err] -> Left err : optimizeAst stack xs inFunc + inF +optimizeAst stack ((Cond condAst trueAst mFalseAst) : xs) inF + | not (isUnoptimizable condAst) = case optimizeAst stack [condAst] inF of + [Left err] -> Left err : optimizeAst stack xs inF [Right (Result condAst')] -> - optimizeAst stack (Cond condAst' trueAst mFalseAst : xs) inFunc + optimizeAst stack (Cond condAst' trueAst mFalseAst : xs) inF [Right (Warning _ condAst')] -> - optimizeAst stack (Cond condAst' trueAst mFalseAst : xs) inFunc - _ -> shouldntHappen stack (Cond condAst trueAst mFalseAst : xs) inFunc - | not (isUnoptimizable trueAst) = case optimizeAst stack [trueAst] inFunc of - [Left err] -> Left err : optimizeAst stack xs inFunc + optimizeAst stack (Cond condAst' trueAst mFalseAst : xs) inF + _ -> shouldntHappen stack (Cond condAst trueAst mFalseAst : xs) inF + | not (isUnoptimizable trueAst) = case optimizeAst stack [trueAst] inF of + [Left err] -> Left err : optimizeAst stack xs inF [Right (Result trueAst')] -> - optimizeAst stack (Cond condAst trueAst' mFalseAst : xs) inFunc + optimizeAst stack (Cond condAst trueAst' mFalseAst : xs) inF [Right (Warning _ trueAst')] -> - optimizeAst stack (Cond condAst trueAst' mFalseAst : xs) inFunc - _ -> shouldntHappen stack (Cond condAst trueAst mFalseAst : xs) inFunc + optimizeAst stack (Cond condAst trueAst' mFalseAst : xs) inF + _ -> shouldntHappen stack (Cond condAst trueAst mFalseAst : xs) inF | isJust mFalseAst && not (isUnoptimizable (fromJust mFalseAst)) = - case optimizeAst stack [fromJust mFalseAst] inFunc of - [Left err] -> Left err : optimizeAst stack xs inFunc + case optimizeAst stack [fromJust mFalseAst] inF of + [Left err] -> Left err : optimizeAst stack xs inF [Right (Result falseAst')] -> - optimizeAst stack (Cond condAst trueAst (Just falseAst') : xs) inFunc + optimizeAst stack (Cond condAst trueAst (Just falseAst') : xs) inF [Right (Warning _ falseAst')] -> - optimizeAst stack (Cond condAst trueAst (Just falseAst') : xs) inFunc - _ -> shouldntHappen stack (Cond condAst trueAst mFalseAst : xs) inFunc + optimizeAst stack (Cond condAst trueAst (Just falseAst') : xs) inF + _ -> shouldntHappen stack (Cond condAst trueAst mFalseAst : xs) inF | otherwise = case condAst of Boolean True -> Right (Warning "Condition is always true" trueAst) - : optimizeAst stack xs inFunc + : optimizeAst stack xs inF Boolean False -> Right ( Warning "Condition is always false" (fromMaybe (Cond condAst trueAst mFalseAst) mFalseAst) ) - : optimizeAst stack xs inFunc + : optimizeAst stack xs inF _ -> Right (Result (Cond condAst trueAst mFalseAst)) - : optimizeAst stack xs inFunc -optimizeAst stack (FunctionValue params ast Nothing : xs) inFunc = + : optimizeAst stack xs inF +optimizeAst stack (FunctionValue params ast Nothing : xs) inF = case optimizeAst stack [ast] True of - [Left err] -> Left err : optimizeAst stack xs inFunc + [Left err] -> Left err : optimizeAst stack xs inF [Right (Result ast')] -> Right (Result (FunctionValue params ast' Nothing)) - : optimizeAst stack xs inFunc + : optimizeAst stack xs inF [Right (Warning mes ast')] -> Right (Warning mes (FunctionValue params ast' Nothing)) - : optimizeAst stack xs inFunc - _ -> shouldntHappen stack (FunctionValue params ast Nothing : xs) inFunc -optimizeAst stack (FunctionValue params ast (Just asts) : xs) inFunc + : optimizeAst stack xs inF + _ -> shouldntHappen stack (FunctionValue params ast Nothing : xs) inF +optimizeAst stack (FunctionValue params ast (Just asts) : xs) inF | not (isUnoptimizable ast) = case optimizeAst stack [ast] True of - [Left err] -> Left err : optimizeAst stack xs inFunc + [Left err] -> Left err : optimizeAst stack xs inF [Right (Result ast')] -> - optimizeAst stack (FunctionValue params ast' (Just asts) : xs) inFunc + optimizeAst stack (FunctionValue params ast' (Just asts) : xs) inF [Right (Warning _ ast')] -> - optimizeAst stack (FunctionValue params ast' (Just asts) : xs) inFunc + optimizeAst stack (FunctionValue params ast' (Just asts) : xs) inF _ -> shouldntHappen stack (FunctionValue params ast (Just asts) : xs) - inFunc + inF | not (foldr ((&&) . isUnoptimizable) True asts) = - case sequence (optimizeAst stack asts inFunc) of - Left err -> Left err : optimizeAst stack xs inFunc + case sequence (optimizeAst stack asts inF) of + Left err -> Left err : optimizeAst stack xs inF Right asts' -> optimizeAst stack (FunctionValue params ast (Just (map fromOptimised asts')) : xs) - inFunc + inF | length params > length asts = case evalAst stack (FunctionValue params ast (Just asts)) of (Left err, _) -> Left (Error err (FunctionValue params ast (Just asts))) - : optimizeAst stack xs inFunc + : optimizeAst stack xs inF (Right (Just ast'), stack') -> Right (Result ast') - : optimizeAst stack' xs inFunc + : optimizeAst stack' xs inF (Right Nothing, _) -> shouldntHappen stack (FunctionValue params ast (Just asts) : xs) - inFunc + inF | otherwise = checkEvalReturnSame stack (FunctionValue params ast (Just asts) : xs) - inFunc + (evalAst stack (FunctionValue params ast (Just asts))) + inF optimizeAst _ [] _ = [] -- | Check whether an `Ast` is optimizable @@ -268,24 +228,29 @@ fromOptimised (Result ast) = ast -- | Handle cases where the optimization depends on -- the result of a evaluation of the `Ast` and it have to return evaluated -- result -checkEval :: [ScopeMb] -> [Ast] -> Bool -> [Either AstError AstOptimised] -checkEval stack (ast : xs) inFunc = - case evalAst stack ast of - (Left ('R' : 'e' : 'c' : 'u' : 'r' : 's' : 'i' : 'o' : 'n' : _), _) -> - Right (Warning "Possible infinite recursion" ast) - : optimizeAst stack xs inFunc - (Left ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs'), _) - | inFunc -> Right (Result ast) : optimizeAst stack xs inFunc - | otherwise -> - Left - (Error ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs') ast) - : optimizeAst stack xs inFunc - (Left err, _) -> Left (Error err ast) : optimizeAst stack xs inFunc - (Right (Just ast'), stack') -> - Right (Result ast') - : optimizeAst stack' xs inFunc - _ -> shouldntHappen stack (ast : xs) inFunc -checkEval _ _ _ = +checkEval :: + [ScopeMb] -> + [Ast] -> + (Either String (Maybe Ast), [ScopeMb]) -> + Bool -> + [Either AstError AstOptimised] +checkEval stack (ast : xs) + (Left ('R' : 'e' : 'c' : 'u' : 'r' : 's' : 'i' : 'o' : 'n' : _), _) inF = + Right (Warning "Possible infinite recursion" ast) : + optimizeAst stack xs inF +checkEval stack (ast : xs) + (Left ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs'), _) inF + | inF = Right (Result ast) : optimizeAst stack xs inF + | otherwise = Left + (Error ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs') ast) + : optimizeAst stack xs inF +checkEval stack (ast : xs) (Left err, _) inF = + Left (Error err ast) : optimizeAst stack xs inF +checkEval _ (_ : xs) (Right (Just ast'), stack') inF = + Right (Result ast') : optimizeAst stack' xs inF +checkEval stack (ast : xs) _ inF = + shouldntHappen stack (ast : xs) inF +checkEval _ _ _ _ = [ Right ( Warning "This situation really shouldn't happen" @@ -299,27 +264,83 @@ checkEval _ _ _ = checkEvalReturnSame :: [ScopeMb] -> [Ast] -> + (Either String (Maybe Ast), [ScopeMb]) -> Bool -> [Either AstError AstOptimised] -checkEvalReturnSame stack (ast : xs) inFunc = case evalAst stack ast of - (Left ('R' : 'e' : 'c' : 'u' : 'r' : 's' : 'i' : 'o' : 'n' : _), _) -> - Right (Warning "Possible infinite recursion" ast) - : optimizeAst stack xs inFunc - (Left ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs'), _) - | inFunc -> Right (Result ast) : optimizeAst stack xs inFunc - | otherwise -> - Left - (Error ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs') ast) - : optimizeAst stack xs inFunc - (Left err, _) -> Left (Error err ast) : optimizeAst stack xs inFunc - (Right (Just _), stack') -> Right (Result ast) : optimizeAst stack' xs inFunc - _ -> shouldntHappen stack (ast : xs) inFunc -checkEvalReturnSame _ _ _ = +checkEvalReturnSame stack (ast : xs) + (Left ('R' : 'e' : 'c' : 'u' : 'r' : 's' : 'i' : 'o' : 'n' : _), _) inF = + Right (Warning "Possible infinite recursion" ast) + : optimizeAst stack xs inF +checkEvalReturnSame stack (ast : xs) + (Left ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs'), _) inF + | inF = Right (Result ast) : optimizeAst stack xs inF + | otherwise = Left + (Error ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs') ast) + : optimizeAst stack xs inF +checkEvalReturnSame stack (ast : xs) (Left err, _) inF = + Left (Error err ast) : optimizeAst stack xs inF +checkEvalReturnSame _ (ast : xs) (Right (Just _), stack') inF = + Right (Result ast) : optimizeAst stack' xs inF +checkEvalReturnSame stack (ast : xs) _ inF = + shouldntHappen stack (ast : xs) inF +checkEvalReturnSame _ _ _ _ = [Right (Warning "This situation really shouldn't happen" (String "bruh"))] shouldntHappen :: [ScopeMb] -> [Ast] -> Bool -> [Either AstError AstOptimised] -shouldntHappen stack (ast : xs) inFunc = +shouldntHappen stack (ast : xs) inF = Right (Warning "This situation shouldn't happen" ast) - : optimizeAst stack xs inFunc + : optimizeAst stack xs inF shouldntHappen _ _ _ = [Right (Warning "This situation really shouldn't happen" (String "bruh"))] + +checkOptiAfterDef :: + [ScopeMb] -> + [Either AstError AstOptimised] -> + String -> + Ast -> + [Ast] -> + Bool -> + [Either AstError AstOptimised] +checkOptiAfterDef stack [Left err] _ _ xs inF = + Left err : optimizeAst stack xs inF +checkOptiAfterDef stack [Right (Result opAst)] n _ xs inF = + case evalAst stack (Define n opAst) of + (Right _, stack') -> Right (Result (Define n opAst)) : + optimizeAst stack' xs inF + (Left ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs'), _) + | inF -> Right (Result (Define n opAst)) : optimizeAst stack xs inF + | otherwise -> + Left (Error ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs') + (Define n opAst)) : optimizeAst stack xs inF + (Left e, _) -> Left (Error e (Define n opAst)) : optimizeAst stack xs inF +checkOptiAfterDef stack [Right (Warning mes opAst)] n _ xs inF = + checkEvalAfterWarningDef stack (evalAst stack (Define n opAst)) + n opAst xs inF mes +checkOptiAfterDef stack _ n ast xs inF = + shouldntHappen stack (Define n ast : xs) inF + +checkEvalAfterWarningDef :: + [ScopeMb] -> + (Either String (Maybe Ast), [ScopeMb]) -> + String -> + Ast -> + [Ast] -> + Bool -> + String -> + [Either AstError AstOptimised] +checkEvalAfterWarningDef _ (Right _, stack') n opAst xs inF mes = + Right (Warning mes (Define n opAst)) : optimizeAst stack' xs inF +checkEvalAfterWarningDef _ + (Left ('R' : 'e' : 'c' : 'u' : 'r' : 's' : 'i' : 'o' : 'n' : _), stack') + n opAst xs inF _ = + Right (Warning "Possible infinite recursion" (Define n opAst)) + : optimizeAst stack' xs inF +checkEvalAfterWarningDef stack + (Left ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs'), _) + n opAst xs inF _ + | inF = Right (Result (Define n opAst)) : optimizeAst stack xs inF + | otherwise = + Left (Error ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs') + (Define n opAst)) : optimizeAst stack xs inF +checkEvalAfterWarningDef stack (Left err, _) n opAst xs inF _ = + Left (Error err (Define n opAst)) : optimizeAst stack xs inF diff --git a/LobsterLang/src/CompiletoVm.hs b/LobsterLang/src/CompiletoVm.hs index a745753..444082e 100644 --- a/LobsterLang/src/CompiletoVm.hs +++ b/LobsterLang/src/CompiletoVm.hs @@ -143,7 +143,7 @@ getArg nbInstruction byteString inst = case (decodeOrFail byteString :: Either ( Left _ -> ([], remainingfile) Right (remfile, _, val) -> getArg (nbInstruction - 1) remfile (inst ++ [Vm.PushArg (fromIntegral (val :: Int32) :: Int)]) Compiler.PutArg -> getArg (nbInstruction - 1) remainingfile (inst ++ [Vm.PutArg]) - Compiler.Fnv _ _ _ _ _ _ -> getArg (nbInstruction - 1) (snd (getFnv (-1) remainingfile [])) (inst ++ (fst (getFnv (-1) remainingfile []))) + Compiler.Fnv {} -> getArg (nbInstruction - 1) (snd (getFnv (-1) remainingfile [])) (inst ++ (fst (getFnv (-1) remainingfile []))) _ -> (inst, byteString) getInstructionFunc :: Int -> BIN.ByteString -> [Vm.Instruction] -> ([Vm.Instruction], BIN.ByteString) @@ -153,7 +153,7 @@ getInstructionFunc nbInstruction byteString inst = case (decodeOrFail byteString Right (remainingfile, _, opcode) -> case toEnum (fromIntegral opcode) of PushI _ -> case (decodeOrFail remainingfile :: Either (BIN.ByteString, ByteOffset, String) (BIN.ByteString, ByteOffset, Int32)) of Left _ -> ([], byteString) - Right (remfile, _, val) -> getInstructionFunc (nbInstruction - 1) remfile (inst ++ [(Vm.Push (IntVal (fromIntegral (val :: Int32) :: Int)))]) + Right (remfile, _, val) -> getInstructionFunc (nbInstruction - 1) remfile (inst ++ [Vm.Push (IntVal (fromIntegral (val :: Int32) :: Int))]) PushB _ -> case (decodeOrFail remainingfile :: Either (BIN.ByteString, ByteOffset, String) (BIN.ByteString, ByteOffset, Word8)) of Left _ -> (inst, byteString) Right (remfile, _, 1) -> getInstructionFunc (nbInstruction - 1) remfile (inst ++ [Vm.Push (BoolVal True)])