From 73c16504d22dd14d61249b6765553f908876c250 Mon Sep 17 00:00:00 2001 From: krangelov Date: Fri, 10 Dec 2021 10:30:25 +0100 Subject: [PATCH] added bracketedLinearizeAll --- src/runtime/c/pgf/graphviz.cxx | 4 +++ src/runtime/c/pgf/graphviz.h | 9 ++--- src/runtime/c/pgf/linearizer.cxx | 4 +++ src/runtime/c/pgf/linearizer.h | 11 +++--- src/runtime/c/pgf/pgf.cxx | 21 +++++++++++ src/runtime/c/pgf/pgf.h | 57 +++++++++++++++++------------ src/runtime/haskell/PGF2.hsc | 62 +++++++++++++++++++++++++++++++- src/runtime/haskell/PGF2/FFI.hsc | 2 ++ 8 files changed, 138 insertions(+), 32 deletions(-) diff --git a/src/runtime/c/pgf/graphviz.cxx b/src/runtime/c/pgf/graphviz.cxx index 3b31be5f4..fc7e69a4c 100644 --- a/src/runtime/c/pgf/graphviz.cxx +++ b/src/runtime/c/pgf/graphviz.cxx @@ -91,6 +91,10 @@ void PgfLinearizationGraphvizOutput::symbol_bind() { } +void PgfLinearizationGraphvizOutput::flush() +{ +} + void PgfLinearizationGraphvizOutput::generate_graphviz_level(PgfPrinter *printer, PgfGraphvizOptions* opts, ParseLevel *level) { printer->puts("\n subgraph {\n rank=same;\n"); diff --git a/src/runtime/c/pgf/graphviz.h b/src/runtime/c/pgf/graphviz.h index 1158e2163..9d4430d24 100644 --- a/src/runtime/c/pgf/graphviz.h +++ b/src/runtime/c/pgf/graphviz.h @@ -37,10 +37,11 @@ public: PgfText *generate_graphviz(PgfGraphvizOptions* opts); virtual void symbol_token(PgfText *tok); - virtual void begin_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun); - virtual void end_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun); - virtual void symbol_ne(); - virtual void symbol_bind(); + virtual void begin_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun); + virtual void end_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun); + virtual void symbol_ne(); + virtual void symbol_bind(); + virtual void flush(); }; class PGF_INTERNAL_DECL PgfAbstractGraphvizOutput : public PgfUnmarshaller { diff --git a/src/runtime/c/pgf/linearizer.cxx b/src/runtime/c/pgf/linearizer.cxx index 1ae4de8d4..c4c87669e 100644 --- a/src/runtime/c/pgf/linearizer.cxx +++ b/src/runtime/c/pgf/linearizer.cxx @@ -763,3 +763,7 @@ void PgfLinearizationOutput::symbol_bind() { bind = true; } + +void PgfLinearizationOutput::flush() +{ +} diff --git a/src/runtime/c/pgf/linearizer.h b/src/runtime/c/pgf/linearizer.h index 166d0cec8..b08f7e4ae 100644 --- a/src/runtime/c/pgf/linearizer.h +++ b/src/runtime/c/pgf/linearizer.h @@ -11,11 +11,12 @@ public: PgfText *get_text(); - virtual void symbol_token(PgfText *tok); - virtual void begin_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun); - virtual void end_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun); - virtual void symbol_ne(); - virtual void symbol_bind(); + virtual void symbol_token(PgfText *tok); + virtual void begin_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun); + virtual void end_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun); + virtual void symbol_ne(); + virtual void symbol_bind(); + virtual void flush(); }; class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller { diff --git a/src/runtime/c/pgf/pgf.cxx b/src/runtime/c/pgf/pgf.cxx index 91b98520b..5462ebebb 100644 --- a/src/runtime/c/pgf/pgf.cxx +++ b/src/runtime/c/pgf/pgf.cxx @@ -2140,6 +2140,27 @@ void pgf_bracketed_linearize(PgfDB *db, PgfConcrRevision revision, } PGF_API_END } +PGF_API_DECL +void pgf_bracketed_linearize_all(PgfDB *db, PgfConcrRevision revision, + PgfExpr expr, PgfPrintContext *ctxt, + PgfMarshaller *m, + PgfLinearizationOutputIface *out, + PgfExn* err) +{ + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + + ref concr = PgfDB::revision2concr(revision); + PgfLinearizer linearizer(ctxt, concr, m); + m->match_expr(&linearizer, expr); + linearizer.reverse_and_label(true); + while (linearizer.resolve()) { + linearizer.linearize(out, 0); + out->flush(); + } + } PGF_API_END +} + PGF_API PgfText *pgf_get_printname(PgfDB *db, PgfConcrRevision revision, PgfText *fun, PgfExn* err) diff --git a/src/runtime/c/pgf/pgf.h b/src/runtime/c/pgf/pgf.h index e06045b4e..770c38dc4 100644 --- a/src/runtime/c/pgf/pgf.h +++ b/src/runtime/c/pgf/pgf.h @@ -585,40 +585,46 @@ int pgf_has_linearization(PgfDB *db, PgfConcrRevision revision, #ifdef __cplusplus struct PgfLinearizationOutputIface { - /// Output tokens - virtual void symbol_token(PgfText *tok)=0; + /// Output tokens + virtual void symbol_token(PgfText *tok)=0; - /// Begin phrase - virtual void begin_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun)=0; + /// Begin phrase + virtual void begin_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun)=0; - /// End phrase - virtual void end_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun)=0; + /// End phrase + virtual void end_phrase(PgfText *cat, int fid, PgfText *ann, PgfText *fun)=0; - /// handling nonExist - virtual void symbol_ne()=0; + /// handling nonExist + virtual void symbol_ne()=0; - /// token binding - virtual void symbol_bind()=0; + /// token binding + virtual void symbol_bind()=0; + + /// called when the current linearization is finished + virtual void flush()=0; }; #else typedef struct PgfLinearizationOutputIface PgfLinearizationOutputIface; typedef struct PgfLinearizationOutputIfaceVtbl PgfLinearizationOutputIfaceVtbl; struct PgfLinearizationOutputIfaceVtbl { - /// Output tokens - void (*symbol_token)(PgfLinearizationOutputIface *this, PgfText *tok); + /// Output tokens + void (*symbol_token)(PgfLinearizationOutputIface *this, PgfText *tok); - /// Begin phrase - void (*begin_phrase)(PgfLinearizationOutputIface *this, PgfText *cat, int fid, PgfText *ann, PgfText *fun); + /// Begin phrase + void (*begin_phrase)(PgfLinearizationOutputIface *this, PgfText *cat, int fid, PgfText *ann, PgfText *fun); - /// End phrase - void (*end_phrase)(PgfLinearizationOutputIface *this, PgfText *cat, int fid, PgfText *ann, PgfText *fun); + /// End phrase + void (*end_phrase)(PgfLinearizationOutputIface *this, PgfText *cat, int fid, PgfText *ann, PgfText *fun); - /// handling nonExist - void (*symbol_ne)(PgfLinearizationOutputIface *this); + /// handling nonExist + void (*symbol_ne)(PgfLinearizationOutputIface *this); - /// token binding - void (*symbol_bind)(PgfLinearizationOutputIface *this); + /// token binding + void (*symbol_bind)(PgfLinearizationOutputIface *this); + + /// called when the current linearization is finished + void (*flush)(PgfLinearizationOutputIface *this); }; struct PgfLinearizationOutputIface { @@ -632,12 +638,12 @@ PgfText *pgf_linearize(PgfDB *db, PgfConcrRevision revision, PgfMarshaller *m, PgfExn* err); -PGF_API +PGF_API_DECL PgfText **pgf_tabular_linearize(PgfDB *db, PgfConcrRevision revision, PgfExpr expr, PgfPrintContext *ctxt, PgfMarshaller *m, PgfExn* err); -PGF_API +PGF_API_DECL PgfText **pgf_tabular_linearize_all(PgfDB *db, PgfConcrRevision revision, PgfExpr expr, PgfPrintContext *ctxt, PgfMarshaller *m, PgfExn* err); @@ -649,6 +655,13 @@ void pgf_bracketed_linearize(PgfDB *db, PgfConcrRevision revision, PgfLinearizationOutputIface *out, PgfExn* err); +PGF_API_DECL +void pgf_bracketed_linearize_all(PgfDB *db, PgfConcrRevision revision, + PgfExpr expr, PgfPrintContext *ctxt, + PgfMarshaller *m, + PgfLinearizationOutputIface *out, + PgfExn* err); + PGF_API_DECL PgfText *pgf_get_printname(PgfDB *db, PgfConcrRevision revision, PgfText *fun, PgfExn* err); diff --git a/src/runtime/haskell/PGF2.hsc b/src/runtime/haskell/PGF2.hsc index 2b2fa0c14..c07637291 100644 --- a/src/runtime/haskell/PGF2.hsc +++ b/src/runtime/haskell/PGF2.hsc @@ -736,11 +736,13 @@ bracketedLinearize c e = unsafePerformIO $ do bracket (wrapSymbol2 (end_phrase ref)) freeHaskellFunPtr $ \c_end_phrase -> bracket (wrapSymbol0 (symbol_bind ref)) freeHaskellFunPtr $ \c_symbol_bind -> bracket (wrapSymbol0 (symbol_ne ref)) freeHaskellFunPtr $ \c_symbol_ne -> do + bracket (wrapSymbol0 (flush ref)) freeHaskellFunPtr $ \c_flush -> do (#poke PgfLinearizationOutputIfaceVtbl, symbol_token) vtbl c_symbol_token (#poke PgfLinearizationOutputIfaceVtbl, begin_phrase) vtbl c_begin_phrase (#poke PgfLinearizationOutputIfaceVtbl, end_phrase) vtbl c_end_phrase (#poke PgfLinearizationOutputIfaceVtbl, symbol_bind) vtbl c_symbol_bind (#poke PgfLinearizationOutputIfaceVtbl, symbol_ne) vtbl c_symbol_ne + (#poke PgfLinearizationOutputIfaceVtbl, flush) vtbl c_flush (#poke PgfLinearizationOutputIface, vtbl) c_out vtbl withPgfExn "bracketedLinearize" (pgf_bracketed_linearize (c_db c) c_revision c_e nullPtr m c_out)) (ne,_,bs) <- readIORef ref @@ -775,8 +777,66 @@ bracketedLinearize c e = unsafePerformIO $ do (ne,stack,bs) <- readIORef ref writeIORef ref (True,[],[]) + flush _ _ = return () + bracketedLinearizeAll :: Concr -> Expr -> [[BracketedString]] -bracketedLinearizeAll = error "TODO: bracketedLinearizeAll" +bracketedLinearizeAll c e = unsafePerformIO $ do + ref <- newIORef (False,[],[],[]) + (withForeignPtr (c_revision c) $ \c_revision -> + bracket (newStablePtr e) freeStablePtr $ \c_e -> + withForeignPtr marshaller $ \m -> + allocaBytes (#size PgfLinearizationOutputIface) $ \c_out -> + allocaBytes (#size PgfLinearizationOutputIfaceVtbl) $ \vtbl -> + bracket (wrapSymbol1 (symbol_token ref)) freeHaskellFunPtr $ \c_symbol_token -> + bracket (wrapSymbol2 (begin_phrase ref)) freeHaskellFunPtr $ \c_begin_phrase -> + bracket (wrapSymbol2 (end_phrase ref)) freeHaskellFunPtr $ \c_end_phrase -> + bracket (wrapSymbol0 (symbol_bind ref)) freeHaskellFunPtr $ \c_symbol_bind -> + bracket (wrapSymbol0 (symbol_ne ref)) freeHaskellFunPtr $ \c_symbol_ne -> do + bracket (wrapSymbol0 (flush ref)) freeHaskellFunPtr $ \c_flush -> do + (#poke PgfLinearizationOutputIfaceVtbl, symbol_token) vtbl c_symbol_token + (#poke PgfLinearizationOutputIfaceVtbl, begin_phrase) vtbl c_begin_phrase + (#poke PgfLinearizationOutputIfaceVtbl, end_phrase) vtbl c_end_phrase + (#poke PgfLinearizationOutputIfaceVtbl, symbol_bind) vtbl c_symbol_bind + (#poke PgfLinearizationOutputIfaceVtbl, symbol_ne) vtbl c_symbol_ne + (#poke PgfLinearizationOutputIfaceVtbl, flush) vtbl c_flush + (#poke PgfLinearizationOutputIface, vtbl) c_out vtbl + withPgfExn "bracketedLinearizeAll" (pgf_bracketed_linearize_all (c_db c) c_revision c_e nullPtr m c_out)) + (_,_,_,all) <- readIORef ref + return all + where + symbol_token ref _ c_text = do + (ne,stack,bs,all) <- readIORef ref + token <- peekText c_text + writeIORef ref (ne,stack,Leaf token : bs,all) + + begin_phrase ref _ c_cat c_fid c_ann c_fun = do + (ne,stack,bs,all) <- readIORef ref + writeIORef ref (ne,bs:stack,[],all) + + end_phrase ref _ c_cat c_fid c_ann c_fun = do + (ne,bs':stack,bs,all) <- readIORef ref + if null bs + then writeIORef ref (ne,stack,bs',all) + else do cat <- peekText c_cat + let fid = fromIntegral c_fid + ann <- peekText c_ann + fun <- peekText c_fun + writeIORef ref (ne,stack,Bracket cat fid ann fun (reverse bs) : bs',all) + + symbol_bind ref _ = do + (ne,stack,bs,all) <- readIORef ref + writeIORef ref (ne,stack,BIND : bs,all) + + symbol_ne ref _ = do + (ne,stack,bs,all) <- readIORef ref + writeIORef ref (True,[],[],all) + + flush ref _ = do + (ne,_,bs,all) <- readIORef ref + if ne + then writeIORef ref (False,[],[],all) + else writeIORef ref (False,[],[],reverse bs:all) + generateAll :: PGF -> Type -> [(Expr,Float)] generateAll p ty = error "TODO: generateAll" diff --git a/src/runtime/haskell/PGF2/FFI.hsc b/src/runtime/haskell/PGF2/FFI.hsc index 370e22811..b39e84e15 100644 --- a/src/runtime/haskell/PGF2/FFI.hsc +++ b/src/runtime/haskell/PGF2/FFI.hsc @@ -217,6 +217,8 @@ foreign import ccall pgf_tabular_linearize_all :: Ptr PgfDB -> Ptr Concr -> Stab foreign import ccall pgf_bracketed_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr PgfLinearizationOutputIface -> Ptr PgfExn -> IO () +foreign import ccall pgf_bracketed_linearize_all :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr PgfLinearizationOutputIface -> Ptr PgfExn -> IO () + foreign import ccall "wrapper" wrapSymbol0 :: Wrapper (Ptr PgfLinearizationOutputIface -> IO ()) foreign import ccall "wrapper" wrapSymbol1 :: Wrapper (Ptr PgfLinearizationOutputIface -> Ptr PgfText -> IO ())