Play

Check-in [4712590b0f]
Login
Overview
Comment:Initial work on cli.js <-> CLI.elm interop. Works fine, just need to implement missing messages.
Timelines: family | ancestors | descendants | both | cli
Files: files | file ages | folders
SHA3-256: 4712590b0fbbe0d464cbed9d4987042ca0cabaea6756d87ff6b580a8fd02ea8c
User & Date: robin.hansen on 2021-03-31 14:45:22
Other Links: branch diff | manifest | tags
Context
2021-04-02
12:37
cli.js <-> CLI.elm interop completed, but there seems to be a bug in the parser that needs to be fix... check-in: 695ec5f34b user: robin.hansen tags: cli
2021-03-31
14:45
Initial work on cli.js <-> CLI.elm interop. Works fine, just need to implement missing messages. check-in: 4712590b0f user: robin.hansen tags: cli
2021-03-30
10:04
Load and initialize Elm code in bin/cli.js check-in: cab10c643e user: robin.hansen tags: cli
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified bin/cli.js from [d27b095ff3] to [a530aa6713].

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17






18

















19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env node

// Setup of Elm ports

const compiler = require(__dirname + "/compiler").Elm.CLI.init({});

// CLI


const subCmd = process.argv[2];
const subCmdFlags = process.argv.slice(3);

switch (subCmd) {
    case "check": checkProject(); break;
    default: printHelp(); break;
}

function checkProject() {






    console.log("TODO: compile project");

















}

function printHelp() {
    console.log(`
Play compiler. Alpha-2.

Possible options are:
* check: compile the project.
* help: print this help message.
    `);
}


|
<
<
<
<
>





|



|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|



1
2
3




4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/env node

const path = require("path");




const fs = require("fs");

const subCmd = process.argv[2];
const subCmdFlags = process.argv.slice(3);

switch (subCmd) {
    case "compile": compileProject(); break;
    default: printHelp(); break;
}

function compileProject() {
    const cwd = process.cwd();
    const compiler = require(__dirname + "/compiler").Elm.CLI.init({
        flags: cwd
    });

    compiler.ports.outgoingPort.subscribe((msg) => {
        console.log(msg);
        switch (msg.type) {
            case 'readFile':
                const filePath = path.join(msg.path, msg.fileName);
                const fileContent = fs.readFileSync(filePath, { encoding: "utf-8" });

                compiler.ports.incomingPort.send({
                    type: "fileContents",
                    path: msg.path,
                    fileName: msg.fileName,
                    content: fileContent
                });
                break;
            default:
                console.error("Unknown message received from Elm compiler: ", msg);
                break;
        }
    });
}

function printHelp() {
    console.log(`
Play compiler. Alpha-2.

Possible options are:
* compile: compile the project.
* help: print this help message.
    `);
}

Modified src/CLI.elm from [1457701d5b] to [6db0dd20b5].

1
2


3
4

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61











62
63
64
65
66
67
68
69
70
71


















































72
73
74

75
76
77
78
79
80

port module CLI exposing (main)



import Platform exposing (Program)
import Play.Codegen as Codegen

import Play.Parser as Parser
import Play.Parser.Problem as ParserProblem
import Play.Qualifier as Qualifier
import Play.Qualifier.Problem as QualifierProblem
import Play.TypeChecker as TypeChecker
import Play.TypeChecker.Problem as TypeCheckerProblem
import Wasm


type alias Model =
    ()


type Msg
    = CompileString String


main : Program () Model Msg
main =
    Platform.worker
        { init = init
        , update = update
        , subscriptions = subscriptions
        }


init : () -> ( Model, Cmd Msg )
init _ =
    ( ()
    , Cmd.none
    )


update : Msg -> Model -> ( Model, Cmd Msg )
update msg _ =
    case msg of
        CompileString sourceCode ->
            case compile sourceCode of
                Ok wasm ->
                    ( ()
                    , compileFinished ( True, wasm )
                    )

                Err errmsg ->
                    ( ()
                    , compileFinished ( False, "Compilation failed:\n\n" ++ errmsg )
                    )


compile : String -> Result String String
compile sourceCode =
    case Parser.run sourceCode of
        Err parserErrors ->
            formatErrors (ParserProblem.toString sourceCode) parserErrors

        Ok ast ->
            Ok "It worked!"













formatErrors : (a -> String) -> List a -> Result String b
formatErrors fn problems =
    problems
        |> List.map fn
        |> String.join "\n\n"
        |> Err




















































subscriptions : Model -> Sub Msg
subscriptions _ =
    compileString CompileString



port compileString : (String -> msg) -> Sub msg


port compileFinished : ( Bool, String ) -> Cmd msg



>
>


>










|



|


|








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<
>


|


<
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143

144
port module CLI exposing (main)

import Json.Decode as Json
import Json.Encode as Encode
import Platform exposing (Program)
import Play.Codegen as Codegen
import Play.PackageLoader as PackageLoader
import Play.Parser as Parser
import Play.Parser.Problem as ParserProblem
import Play.Qualifier as Qualifier
import Play.Qualifier.Problem as QualifierProblem
import Play.TypeChecker as TypeChecker
import Play.TypeChecker.Problem as TypeCheckerProblem
import Wasm


type alias Model =
    PackageLoader.Model


type Msg
    = Incomming Json.Value


main : Program String Model Msg
main =
    Platform.worker
        { init = init
        , update = update
        , subscriptions = subscriptions
        }


init : String -> ( Model, Cmd Msg )
init projectDir =
    let
        initialModel =
            PackageLoader.init projectDir
    in
    ( initialModel
    , sendSideEffectFromModel initialModel
    )


sendSideEffectFromModel : PackageLoader.Model -> Cmd Msg
sendSideEffectFromModel model =
    PackageLoader.getSideEffect model
        |> Maybe.map encodeSideEffectAsJson
        |> Maybe.map outgoingPort
        |> Maybe.withDefault Cmd.none


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Incomming packageLoaderMsgJson ->
            case Json.decodeValue decodePackageLoaderMsg packageLoaderMsgJson of
                Ok packageLoaderMsg ->
                    let
                        updatedModel =
                            PackageLoader.update packageLoaderMsg model
                                |> Debug.log "new model"
                    in
                    ( updatedModel
                    , sendSideEffectFromModel updatedModel
                    )

                Err decodeError ->
                    let
                        _ =
                            Debug.log "error" decodeError
                    in
                    ( model
                    , Cmd.none
                    )


formatErrors : (a -> String) -> List a -> Result String b
formatErrors fn problems =
    problems
        |> List.map fn
        |> String.join "\n\n"
        |> Err



-- Json Encoding/Decoding


encodeSideEffectAsJson : PackageLoader.SideEffect -> Json.Value
encodeSideEffectAsJson sf =
    case sf of
        PackageLoader.ReadFile path fileName ->
            Encode.object
                [ ( "type", Encode.string "readFile" )
                , ( "path", Encode.string path )
                , ( "fileName", Encode.string fileName )
                ]

        PackageLoader.ResolveDirectories path ->
            Encode.object
                [ ( "type", Encode.string "resolveDirectories" )
                , ( "path", Encode.string path )
                ]

        PackageLoader.ResolvePackageModules moduleName path ->
            Encode.object
                [ ( "type", Encode.string "resolvePackageModules" )
                , ( "module", Encode.string moduleName )
                , ( "path", Encode.string path )
                ]


decodePackageLoaderMsg : Json.Decoder PackageLoader.Msg
decodePackageLoaderMsg =
    let
        helper typeStr =
            case typeStr of
                "fileContents" ->
                    Json.map3 PackageLoader.FileContents
                        (Json.field "path" Json.string)
                        (Json.field "fileName" Json.string)
                        (Json.field "content" Json.string)

                _ ->
                    Json.fail <| "Unknown msg type: " ++ typeStr
    in
    Json.field "type" Json.string
        |> Json.andThen helper



-- PORTS


subscriptions : Model -> Sub Msg
subscriptions _ =

    incomingPort Incomming


port incomingPort : (Json.Value -> msg) -> Sub msg



port outgoingPort : Json.Value -> Cmd msg

Modified src/Play/PackageLoader.elm from [fe3c68a4e4] to [0dd56e6b64].

1
2
3
4
5

6
7
8
9
10
11
12
..
77
78
79
80
81
82
83






















84
85
86
87
88
89
90
module Play.PackageLoader exposing
    ( Model(..)
    , Msg(..)
    , Problem(..)
    , SideEffect(..)

    , init
    , update
    )

import Dict exposing (Dict)
import Json.Decode as Json
import List.Extra as List
................................................................................


type SideEffect
    = ReadFile String String
    | ResolveDirectories String
    | ResolvePackageModules String String
























init : String -> Model
init projectDirPath =
    Initializing
        (ReadFile projectDirPath "play.json")







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
module Play.PackageLoader exposing
    ( Model(..)
    , Msg(..)
    , Problem(..)
    , SideEffect(..)
    , getSideEffect
    , init
    , update
    )

import Dict exposing (Dict)
import Json.Decode as Json
import List.Extra as List
................................................................................


type SideEffect
    = ReadFile String String
    | ResolveDirectories String
    | ResolvePackageModules String String


getSideEffect : Model -> Maybe SideEffect
getSideEffect model =
    case model of
        Done _ ->
            Nothing

        Failed _ ->
            Nothing

        Initializing sf ->
            Just sf

        LoadingMetadata _ _ sf ->
            Just sf

        ResolvingModulePaths _ _ sf ->
            Just sf

        Compiling _ _ sf ->
            Just sf


init : String -> Model
init projectDirPath =
    Initializing
        (ReadFile projectDirPath "play.json")


Added stdlib/play.json version [1664c7c068].

























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
{
    "name": "play/standard_library",
    "version": "0.2.0",
    "language-version": "0.2.0",
    "exposed-modules": [
        "basic"
    ],
    "dependencies": {
    },
    "package-paths": [
    ]
}

Added stdlib/src/basic.play version [e3769efe5c].





>
>
1
2
def: one
: 1

Modified tests/Test/PackageLoader.elm from [a50f684204] to [715d534793].

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

resolveSideEffects :
    Dict String String
    -> List PackageLoader.SideEffect
    -> PackageLoader.Model
    -> Result String ( List PackageLoader.SideEffect, Qualifier.ExposedAST )
resolveSideEffects fileSystem seenSfs model =
    case getSideEffect model of
        Nothing ->
            case model of
                PackageLoader.Done ast ->
                    Ok ( seenSfs, ast )

                _ ->
                    Err <| "Expected model be Done, was: " ++ Debug.toString model
................................................................................
        case pathParts of
            [ _, "play.json" ] ->
                True

            _ ->
                False


getSideEffect : PackageLoader.Model -> Maybe PackageLoader.SideEffect
getSideEffect model =
    case model of
        PackageLoader.Done _ ->
            Nothing

        PackageLoader.Failed _ ->
            Nothing

        PackageLoader.Initializing sf ->
            Just sf

        PackageLoader.LoadingMetadata _ _ sf ->
            Just sf

        PackageLoader.ResolvingModulePaths _ _ sf ->
            Just sf

        PackageLoader.Compiling _ _ sf ->
            Just sf


testFiles : Dict String String
testFiles =
    Dict.fromList
        [ ( "/project/play.json"
          , """
            {







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
...
175
176
177
178
179
180
181






















182
183
184
185
186
187
188

resolveSideEffects :
    Dict String String
    -> List PackageLoader.SideEffect
    -> PackageLoader.Model
    -> Result String ( List PackageLoader.SideEffect, Qualifier.ExposedAST )
resolveSideEffects fileSystem seenSfs model =
    case PackageLoader.getSideEffect model of
        Nothing ->
            case model of
                PackageLoader.Done ast ->
                    Ok ( seenSfs, ast )

                _ ->
                    Err <| "Expected model be Done, was: " ++ Debug.toString model
................................................................................
        case pathParts of
            [ _, "play.json" ] ->
                True

            _ ->
                False
























testFiles : Dict String String
testFiles =
    Dict.fromList
        [ ( "/project/play.json"
          , """
            {