Play

Check-in [0075328824]
Login
Overview
Comment:Added cli command for executing a function. Missing elm-side implementation.
Timelines: family | ancestors | descendants | both | cli
Files: files | file ages | folders
SHA3-256: 0075328824aa830b4a5d1fa54f6769fa72c99dfd8b8864f91500c205a3ccb125
User & Date: robin.hansen on 2021-04-06 08:02:26
Other Links: branch diff | manifest | tags
Context
2021-04-06
08:17
Function marked as entry point is now actually exported from wasm module. Command works! check-in: 271a8a283a user: robin.hansen tags: cli
08:02
Added cli command for executing a function. Missing elm-side implementation. check-in: 0075328824 user: robin.hansen tags: cli
2021-04-03
07:56
Remove debug statement. check-in: 874da70254 user: robin.hansen tags: cli
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified bin/cli.js from [6acf0f0708] to [6bc7e134f7].

1
2
3
4

5
6
7
8
9
10

11
12
13









14
15
16
17



18
19
20
21
22
23
24
..
48
49
50
51
52
53
54

55



56
57
58
59
60
61
62
..
86
87
88
89
90
91
92

93
94
95





























#!/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) => {
        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: "resolvedDirectories",
                    parentDir: msg.path,
                    paths: subFolders
                });
                break;
            case "compilationDone":

                console.log("Compiled successfully");



                break;
            case "compilationFailure":
                console.error(msg.error);
                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.
    `);
}

































>






>



>
>
>
>
>
>
>
>
>
|


|
>
>
>







 







>
|
>
>
>







 







>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
...
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
#!/usr/bin/env node

const path = require("path");
const fs = require("fs");
const wabtInit = require("wabt");

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

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

function runProject() {
    if (subCmdFlags.length !== 1) {
        console.error("run command requires exactly one argument: the function to run.");
        return;
    }

    compileProject(subCmdFlags[0]);
}

function compileProject(entryPoint) {
    const cwd = process.cwd();
    const compiler = require(__dirname + "/compiler").Elm.CLI.init({
        flags: {
            projectDir: cwd,
            entryPoint: typeof entryPoint === "undefined" ? null : entryPoint
        }
    });

    compiler.ports.outgoingPort.subscribe((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: "resolvedDirectories",
                    parentDir: msg.path,
                    paths: subFolders
                });
                break;
            case "compilationDone":
                if (typeof entryPoint === "undefined") {
                    console.log("Compiled successfully");
                } else {
                    executeWat(msg.wast, entryPoint);
                }
                break;
            case "compilationFailure":
                console.error(msg.error);
                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.
* run <function_name>: compile the project, and execute the given function.
* help: print this help message.
    `);
}

async function executeWat(wat, entryPointName) {
    const wabt = await wabtInit();
    const wasmModule = wabt.parseWat('tmp', wat).toBinary({}).buffer;

    const memory = new WebAssembly.Memory({
        initial: 10
    });

    const imports = {
        host: {
            memory: memory
        }
    };

    const program = await WebAssembly.instantiate(wasmModule, imports);
    const entryPoint = program.instance.exports[entryPointName];
    if (typeof entryPoint === 'undefined') {
        console.error("Could not find a function named '" + entryPointName + "'");
        return;
    }

    entryPoint();

    const memView = new Int32Array(memory.buffer);
    // First three i32 elements are stack and heap information
    const returnValue = memView[3].toString(); 
    console.log(returnValue);
}

Modified src/CLI.elm from [65ae4b6f00] to [1ec8dd7844].

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
..
83
84
85
86
87
88
89
90
91
92
93
94
95



96
97
98
99
100
101
102
import Play.Codegen as Codegen
import Play.Data.PackagePath as PackagePath
import Play.PackageLoader as PackageLoader
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
................................................................................

                        _ ->
                            ( 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







>
>
>
>
>
>









|








|
|



>
>
>







 







<
<
<
<

<
>
>
>







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
..
92
93
94
95
96
97
98




99

100
101
102
103
104
105
106
107
108
109
import Play.Codegen as Codegen
import Play.Data.PackagePath as PackagePath
import Play.PackageLoader as PackageLoader
import Play.TypeChecker as TypeChecker
import Play.TypeChecker.Problem as TypeCheckerProblem
import Wasm


type alias Flags =
    { projectDir : String
    , entryPoint : Maybe String
    }


type alias Model =
    PackageLoader.Model


type Msg
    = Incomming Json.Value


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


init : Flags -> ( Model, Cmd Msg )
init { projectDir, entryPoint } =
    let
        initialModel =
            PackageLoader.init projectDir

        _ =
            Debug.log "entry" entryPoint
    in
    ( initialModel
    , sendSideEffectFromModel initialModel
    )


sendSideEffectFromModel : PackageLoader.Model -> Cmd Msg
................................................................................

                        _ ->
                            ( updatedModel
                            , sendSideEffectFromModel updatedModel
                            )

                Err decodeError ->




                    ( model

                    , outgoingPort <|
                        encodeCompilationFailure <|
                            Json.errorToString decodeError
                    )


formatErrors : (a -> String) -> List a -> Result String b
formatErrors fn problems =
    problems
        |> List.map fn