Add support for custom modes
Signed-off-by: Danila Fedorin <danila.fedorin@gmail.com>
This commit is contained in:
parent
d1fb4bfdc1
commit
bfc21c2928
|
@ -64,15 +64,20 @@ input[type="text"] {
|
|||
node: document.getElementById('elm'),
|
||||
flags: {
|
||||
inputModes: {
|
||||
"My Mode": { "custom": "mymode" },
|
||||
"Query": "query",
|
||||
"Language Term": "syntax",
|
||||
"My Mode": { "custom": "mymode" },
|
||||
},
|
||||
inputRules: "PromptConverter @ prompt(type(empty, ?term, ?t)) <- input(?term);",
|
||||
query: "type(empty, app(abs(x, number, var(x)), lit(1)), ?tau)",
|
||||
input: "type(empty, app(abs(x, number, var(x)), lit(1)), ?tau)",
|
||||
renderRules: renderRules, rules: rules
|
||||
}
|
||||
});
|
||||
|
||||
app.ports.convertInput.subscribe(({ mode, input }) => {
|
||||
console.log(input);
|
||||
app.ports.receiveConverted.send({ input, query: `type(empty, lit(${input}), ?tau )` });
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
|
111
src/Main.elm
111
src/Main.elm
|
@ -1,4 +1,4 @@
|
|||
module Main exposing (main)
|
||||
port module Main exposing (main)
|
||||
|
||||
import Browser
|
||||
import Html exposing (Html)
|
||||
|
@ -48,37 +48,50 @@ resultModeEq rm1 rm2 =
|
|||
|
||||
type alias Model =
|
||||
{ program : String
|
||||
-- ^ The Bergamot rules to execute a search against
|
||||
, renderProgram: String
|
||||
-- ^ The Bergamot render rules to apply when generating LaTeX
|
||||
, inputProgram : String
|
||||
-- ^ The Bergamot rules to apply to convert a Syntax term into a query
|
||||
, tab : Tab
|
||||
, query : String
|
||||
-- ^ The current tab (editor, redner rule editor, rendered)
|
||||
, input : String
|
||||
-- ^ The string the user has in the input box
|
||||
, desugaredQuery : Maybe String
|
||||
-- ^ The Bergamot query corresponding to input. May be Nothing while waiting for
|
||||
-- Custom mode, which has user JS convert input to a query.
|
||||
, inputModes : List (String, EditMode)
|
||||
-- ^ A List of input modes that can be used with the input box.
|
||||
, inputMode : Int
|
||||
-- ^ The index of the currently selected input mode.
|
||||
, resultMode : ResultMode
|
||||
-- ^ How the result should be displayed (judgement or proof tree)
|
||||
}
|
||||
type alias Flags =
|
||||
{ renderRules : String
|
||||
, inputRules : String
|
||||
, rules : String
|
||||
, query : String
|
||||
, input : String
|
||||
, inputModes : Json.Decode.Value
|
||||
}
|
||||
type Msg
|
||||
= SetProgram String
|
||||
| SetRenderProgram String
|
||||
| SetQuery String
|
||||
| SetInput String
|
||||
| SetTab Tab
|
||||
| SetInputMode Int
|
||||
| SetResultMode ResultMode
|
||||
| SetDesugaredQuery { input: String, query: String }
|
||||
|
||||
decodeInputModes: Json.Decode.Value -> List (String, EditMode)
|
||||
decodeInputModes val =
|
||||
let
|
||||
exactString s1 v =
|
||||
string
|
||||
|> Json.Decode.andThen (\s2 -> if s1 == s2
|
||||
then succeed v
|
||||
else Json.Decode.fail "did not match expected string")
|
||||
|> Json.Decode.andThen (\s2 ->
|
||||
if s1 == s2
|
||||
then succeed v
|
||||
else Json.Decode.fail "did not match expected string")
|
||||
editModeDecoder = oneOf
|
||||
[ exactString "query" Query
|
||||
, exactString "syntax" Syntax
|
||||
|
@ -88,21 +101,39 @@ decodeInputModes val =
|
|||
in
|
||||
case Json.Decode.decodeValue decoder val of
|
||||
Ok l -> l
|
||||
Err _ -> [("Query", Query), ("Language Term", Syntax)]
|
||||
Err _ -> [("Language Term", Syntax), ("Query", Query)]
|
||||
|
||||
-- Convert the user-entered string 'input' using custom query mode 'mode'
|
||||
port convertInput : { mode : String, input : String } -> Cmd msg
|
||||
|
||||
-- Invoked when user code finishes converting 'input' into a Bergamot query
|
||||
port receiveConverted : ({ input : String, query : String } -> msg) -> Sub msg
|
||||
|
||||
convertInputCmd : Int -> List (String, EditMode) -> String -> Cmd Msg
|
||||
convertInputCmd inputMode inputModes input =
|
||||
case getEditMode inputMode inputModes of
|
||||
Ok (Custom modeType) ->
|
||||
convertInput { mode = modeType, input = input }
|
||||
_ -> Cmd.none
|
||||
|
||||
init : Flags -> (Model, Cmd Msg)
|
||||
init fs =
|
||||
( { program = fs.rules
|
||||
, renderProgram = fs.renderRules
|
||||
, inputProgram = fs.inputRules
|
||||
, query = fs.query
|
||||
, tab = Rendered
|
||||
, inputModes = decodeInputModes fs.inputModes
|
||||
, inputMode = 0
|
||||
, resultMode = Conclusion
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
let
|
||||
inputModes = decodeInputModes fs.inputModes
|
||||
inputMode = 0
|
||||
in
|
||||
( { program = fs.rules
|
||||
, renderProgram = fs.renderRules
|
||||
, inputProgram = fs.inputRules
|
||||
, input = fs.input
|
||||
, desugaredQuery = Nothing
|
||||
, tab = Rendered
|
||||
, inputModes = inputModes
|
||||
, inputMode = 0
|
||||
, resultMode = Conclusion
|
||||
}
|
||||
, convertInputCmd inputMode inputModes fs.input
|
||||
)
|
||||
|
||||
viewSection : String -> Html Msg -> Html Msg
|
||||
viewSection name content =
|
||||
|
@ -211,18 +242,18 @@ getEditMode i l =
|
|||
((_, editMode) :: xs) ->
|
||||
if i == 0 then Ok editMode else getEditMode (i - 1) xs
|
||||
|
||||
proofGoal : EditMode -> String -> String -> Result Error (Term Metavariable)
|
||||
proofGoal editMode inputProgs querys =
|
||||
if querys == ""
|
||||
proofGoal : EditMode -> String -> String -> Maybe String -> Result Error (Term Metavariable)
|
||||
proofGoal editMode inputProgs input desugaredQuery =
|
||||
if input == ""
|
||||
then Err Silent
|
||||
else
|
||||
case editMode of
|
||||
Query ->
|
||||
case run topLevelTerm querys of
|
||||
case run topLevelTerm input of
|
||||
Nothing -> Err BadQuery
|
||||
Just query -> Ok query
|
||||
Syntax ->
|
||||
case (run program inputProgs, run topLevelExpr querys) of
|
||||
case (run program inputProgs, run topLevelExpr input) of
|
||||
(Just inputProg, Just e) ->
|
||||
let
|
||||
inputRule = { name = "UserInput", premises = [], conclusion = Call "input" [exprToTerm e] }
|
||||
|
@ -237,7 +268,13 @@ proofGoal editMode inputProgs querys =
|
|||
_ -> Err NoConversionResults
|
||||
(_, Nothing) -> Err BadObjectTerm
|
||||
(Nothing, _) -> Err BadInputProg
|
||||
Custom _ -> Err BadInputProg
|
||||
Custom _ ->
|
||||
case desugaredQuery of
|
||||
Just querys ->
|
||||
case run topLevelTerm querys of
|
||||
Nothing -> Err BadQuery
|
||||
Just query -> Ok query
|
||||
Nothing -> Err Silent
|
||||
|
||||
progAndRenderProg : String -> String -> Result Error (RuleEnv, RuleEnv)
|
||||
progAndRenderProg progs renderProgs =
|
||||
|
@ -270,7 +307,7 @@ view : Model -> Html Msg
|
|||
view m =
|
||||
let
|
||||
mode = getEditMode m.inputMode m.inputModes
|
||||
termOrErr = mode |> Result.andThen (\editMode -> proofGoal editMode m.inputProgram m.query)
|
||||
termOrErr = mode |> Result.andThen (\editMode -> proofGoal editMode m.inputProgram m.input m.desugaredQuery)
|
||||
progsOrErr = progAndRenderProg m.program m.renderProgram
|
||||
proofTreeOrErr = combineTwoResults (viewProofTree m.resultMode) termOrErr progsOrErr
|
||||
in
|
||||
|
@ -278,7 +315,7 @@ view m =
|
|||
[ viewSection "Input" <| Html.div [] <|
|
||||
[ viewInputModeSelector m.inputMode <|
|
||||
List.map (\(a, b) -> (b, a)) m.inputModes
|
||||
, Html.input [ type_ "text", onInput SetQuery, value m.query ] []
|
||||
, Html.input [ type_ "text", onInput SetInput, value m.input ] []
|
||||
] ++
|
||||
viewIfError termOrErr
|
||||
, viewSection "Result" <| Html.div[]
|
||||
|
@ -300,13 +337,27 @@ update msg m =
|
|||
case msg of
|
||||
SetProgram prog -> ({ m | program = prog }, Cmd.none)
|
||||
SetRenderProgram prog -> ({ m | renderProgram = prog }, Cmd.none)
|
||||
SetQuery query -> ({ m | query = query }, Cmd.none)
|
||||
SetInput input ->
|
||||
( { m | input = input }
|
||||
, convertInputCmd m.inputMode m.inputModes input
|
||||
)
|
||||
SetTab tab -> ({ m | tab = tab }, Cmd.none)
|
||||
SetInputMode mode -> ({ m | inputMode = mode }, Cmd.none)
|
||||
SetInputMode mode ->
|
||||
( { m | inputMode = mode }
|
||||
, convertInputCmd mode m.inputModes m.input
|
||||
)
|
||||
SetResultMode mode -> ({ m | resultMode = mode }, Cmd.none)
|
||||
SetDesugaredQuery data ->
|
||||
({ m | desugaredQuery =
|
||||
if m.input == data.input
|
||||
then Just data.query
|
||||
else m.desugaredQuery
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ = Sub.none
|
||||
subscriptions _ = receiveConverted SetDesugaredQuery
|
||||
|
||||
main =
|
||||
Browser.element
|
||||
|
|
Loading…
Reference in New Issue
Block a user