summaryrefslogtreecommitdiff
path: root/godel/js/main.js
blob: bd36ef924a6afce767fa9933f501ad6f48ca9b51 (plain)
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
const MESSAGES = {
  COMPILE: "COMPILE",
  COMPILE_RESULT: "COMPILE_RESULT",
  EVAL: "EVAL",
  EVAL_STATUS: "EVAL_RESULT",
};

// -- the "real" code --

const state = new Observable();

const prepareSource = (text) => text.replaceAll(/\/\/.*/g, "").trim();

const main = () => {
  let program;

  state.subscribe((msg) => {
    if (msg.type == MESSAGES.COMPILE) {
      const { value } = msg;
      const source = prepareSource(value);
      try {
        const ast = parser.parse(source);
        const program = compile(ast);

        state.notify({
          type: MESSAGES.COMPILE_RESULT,
          value: program,
        });
      } catch (e) {
        state.notify({
          type: MESSAGES.COMPILE_RESULT,
          error: e.toString(),
        });
      }
    }
    if (msg.type == MESSAGES.EVAL) {
      const source = compiledEditorEl.getValue();
      try {
        const result = eval(source);
        state.notify({
          type: MESSAGES.EVAL_RESULT,
          value: result,
        });
      } catch (e) {
        state.notify({
          type: MESSAGES.EVAL_RESULT,
          error: e.toString(),
        });
      }
    }
  });
};
main();

// -- a bit of some hacky ui code --

const instructionsEl = document.getElementById("instructions");
const instructionsEditorEl = CodeMirror.fromTextArea(instructionsEl, {
  lineNumbers: true,
});

const compileButton = document.getElementById("compile");
const evalButton = document.getElementById("eval");
const evalStatusEl = document.getElementById("eval_status");
const compileStatusEl = document.getElementById("compile_status");
const compiledEl = document.getElementById("compiled");
const compiledEditorEl = CodeMirror.fromTextArea(compiledEl, {
  lineNumbers: true,
});
state.subscribe((msg) => {
  if (msg.type == MESSAGES.COMPILE_RESULT) {
    evalStatusEl.classList.remove("error");
    evalStatusEl.classList.remove("success");
    evalStatusEl.innerHTML = "";

    if (typeof msg.value !== "undefined") {
      compiledEditorEl.setValue(msg.value);

      compileStatusEl.classList.add("success");
      compileStatusEl.classList.remove("error");
      compileStatusEl.innerHTML = `Successful compile at ${new Date().toLocaleString()}!`;
    } else if (msg.error) {
      compiledEditorEl.setValue("");

      compileStatusEl.classList.remove("success");
      compileStatusEl.classList.add("error");
      compileStatusEl.innerHTML = msg.error;
    }
  }
});
state.subscribe((msg) => {
  if (msg.type == MESSAGES.EVAL_RESULT) {
    if (typeof msg.value !== "undefined") {
      evalStatusEl.classList.add("success");
      evalStatusEl.classList.remove("error");
      evalStatusEl.innerHTML = `Result: ${msg.value}`;
    } else if (msg.error) {
      evalStatusEl.classList.remove("success");
      evalStatusEl.classList.add("error");
      evalStatusEl.innerHTML = msg.error;
    }
  }
});

const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get("instructions")) {
  editorEl.setValue(atob(urlParams.get("instructions")));
}

compileButton.addEventListener("click", () => {
  state.notify({
    type: MESSAGES.COMPILE,
    value: instructionsEditorEl.getValue(),
  });
});

evalButton.addEventListener("click", () => {
  state.notify({
    type: MESSAGES.EVAL,
  });
});