From a6c2ef97ff8a438f820c7f2c72d11f4b0b9764df Mon Sep 17 00:00:00 2001 From: hallgren Date: Wed, 2 Dec 2015 16:41:18 +0000 Subject: [PATCH] GF shell, cc command: try to compute pre{...} tokens in token sequences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is implemented as a simple post-processing step after partial evaluation to try compute pre{...} tokens in token sequences. Nothing is done to deal with intervening free variants. This was done in response to a query from René T on the gf-dev mailing list. --- src/compiler/GF/Command/SourceCommands.hs | 28 +++++++++++++++++-- .../GF/Compile/Compute/ConcreteNew.hs | 4 +-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/compiler/GF/Command/SourceCommands.hs b/src/compiler/GF/Command/SourceCommands.hs index 7d882e262..0ba60d245 100644 --- a/src/compiler/GF/Command/SourceCommands.hs +++ b/src/compiler/GF/Command/SourceCommands.hs @@ -2,7 +2,7 @@ module GF.Command.SourceCommands(HasGrammar(..),sourceCommands) where import Prelude hiding (putStrLn) import qualified Prelude as P(putStrLn) -import Data.List(nub,isInfixOf) +import Data.List(nub,isInfixOf,isPrefixOf) import qualified Data.ByteString.UTF8 as UTF8(fromString) import qualified Data.Map as Map @@ -10,6 +10,7 @@ import GF.Infra.SIO(MonadSIO(..),restricted) import GF.Infra.Option(modifyFlags,optTrace) --,noOptions import GF.Data.Operations (chunks,err,raise) import GF.Text.Pretty(render) +import GF.Data.Str(sstr) import GF.Grammar hiding (Ident,isPrefixOf) import GF.Grammar.Analyse @@ -259,4 +260,27 @@ checkComputeTerm os sgr t = inferLType sgr [] t let opts = modifyFlags (\fs->fs{optTrace=isOpt "trace" os}) t1 = CN.normalForm (CN.resourceValues opts sgr) (L NoLoc identW) t - checkPredefError t1 + t2 = evalStr t1 + checkPredefError t2 + where + -- ** Try to compute pre{...} tokens in token sequences + evalStr t = + case t of + C t1 t2 -> foldr1 C (evalC [t]) + _ -> composSafeOp evalStr t + + evalC (C t1 t2:ts) = evalC (t1:t2:ts) + evalC (t1@(Alts t tts):ts) = case evalC ts of + K s:ts' -> matchPrefix t tts s:K s:ts' + ts' -> evalStr t1:ts' + evalC (t:ts) = evalStr t:evalC ts + evalC [] = [] + + matchPrefix t0 tts0 s = foldr match1 t tts + where + alts@(Alts t tts) = evalStr (Alts t0 tts0) + + match1 (u,a) r = err (const alts) ok (strsFromTerm a) + where ok as = if any (`isPrefixOf` s) (map sstr as) + then u + else r diff --git a/src/compiler/GF/Compile/Compute/ConcreteNew.hs b/src/compiler/GF/Compile/Compute/ConcreteNew.hs index 744074e9e..e368d9d77 100644 --- a/src/compiler/GF/Compile/Compute/ConcreteNew.hs +++ b/src/compiler/GF/Compile/Compute/ConcreteNew.hs @@ -303,8 +303,8 @@ strsFromValue t = case t of vars <- [[(str2strings v, map sstr c) | (v,c) <- zip vv c0] | vv <- combinations v0] ] - VFV ts -> mapM strsFromValue ts >>= return . concat - VStrs ts -> mapM strsFromValue ts >>= return . concat + VFV ts -> concat # mapM strsFromValue ts + VStrs ts -> concat # mapM strsFromValue ts _ -> fail ("cannot get Str from value " ++ show t)