This commit is contained in:
crumbtoo
2024-04-25 14:28:57 -06:00
parent 6f5c7ee284
commit 5876afec40
8 changed files with 518 additions and 43 deletions

View File

@@ -1 +0,0 @@
53855

View File

@@ -9,14 +9,61 @@
"version": "0.0.1",
"dependencies": {
"ace-builds": "^1.32.7",
"react": "16.13.0",
"react-ace": "^10.1.0",
"react-dom": "16.13.0"
"react": "^18.3.0",
"react-ace": "11.0.1",
"react-dom": "18.3.0",
"react-resplit": "^1.3.1"
},
"devDependencies": {
"shadow-cljs": "2.28.3"
}
},
"node_modules/@babel/runtime": {
"version": "7.24.4",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz",
"integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@radix-ui/react-compose-refs": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
"integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-slot": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
"integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/ace-builds": {
"version": "1.33.1",
"resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.33.1.tgz",
@@ -900,28 +947,26 @@
}
},
"node_modules/react": {
"version": "16.13.0",
"resolved": "https://registry.npmjs.org/react/-/react-16.13.0.tgz",
"integrity": "sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ==",
"version": "18.3.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.0.tgz",
"integrity": "sha512-RPutkJftSAldDibyrjuku7q11d3oy6wKOyPe5K1HA/HwwrXcEqBdHsLypkC2FFYjP7bPUa6gbzSBhw4sY2JcDg==",
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2"
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-ace": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/react-ace/-/react-ace-10.1.0.tgz",
"integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==",
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/react-ace/-/react-ace-11.0.1.tgz",
"integrity": "sha512-ulk2851Fx2j59AAahZHTe7rmQ5bITW1xytskAt11F8dv3rPLtdwBXCyT2qSbRnJvOq8UpuAhWO4/JhKGqQBEDA==",
"dependencies": {
"ace-builds": "^1.4.14",
"ace-builds": "^1.32.8",
"diff-match-patch": "^1.0.5",
"lodash.get": "^4.4.2",
"lodash.isequal": "^4.5.0",
"prop-types": "^15.7.2"
"prop-types": "^15.8.1"
},
"peerDependencies": {
"react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
@@ -929,17 +974,15 @@
}
},
"node_modules/react-dom": {
"version": "16.13.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.0.tgz",
"integrity": "sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg==",
"version": "18.3.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.0.tgz",
"integrity": "sha512-zaKdLBftQJnvb7FtDIpZtsAIb2MZU087RM8bRDZU8LVCCFYjPTsDZJNFUWPcVz3HFSN1n/caxi0ca4B/aaVQGQ==",
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.19.0"
"scheduler": "^0.23.1"
},
"peerDependencies": {
"react": "^16.0.0"
"react": "^18.3.0"
}
},
"node_modules/react-is": {
@@ -947,6 +990,18 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-resplit": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/react-resplit/-/react-resplit-1.3.1.tgz",
"integrity": "sha512-i1sYitKd3spooCOpDw5IH7STsE6g8jC/UgEWrSGjTG+GISr5PmLpGkWws2ean7ESTS5bXfScCHCs8QusivwZrw==",
"dependencies": {
"@radix-ui/react-slot": "^1.0.2"
},
"peerDependencies": {
"react": ">=16",
"react-dom": ">=16"
}
},
"node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
@@ -986,6 +1041,11 @@
"node": ">= 0.8.0"
}
},
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"node_modules/ripemd160": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
@@ -1017,12 +1077,11 @@
]
},
"node_modules/scheduler": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz",
"integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==",
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.1.tgz",
"integrity": "sha512-5GKS5JGfiah1O38Vfa9srZE4s3wdHbwjlCrvIookrg2FO9aIwKLOJXuJQFlEfNcVSOXuaL2hzDeY20uVXcUtrw==",
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
"loose-envify": "^1.1.0"
}
},
"node_modules/set-function-length": {

View File

@@ -1 +1 @@
{"name":"gmvis","version":"0.0.1","private":true,"devDependencies":{"shadow-cljs":"2.28.3"},"dependencies":{"ace-builds":"^1.32.7","react":"16.13.0","react-ace":"^10.1.0","react-dom":"16.13.0"}}
{"name":"gmvis","version":"0.0.1","private":true,"devDependencies":{"shadow-cljs":"2.28.3"},"dependencies":{"ace-builds":"^1.32.7","react":"^18.3.0","react-ace":"11.0.1","react-dom":"18.3.0","react-resplit":"^1.3.1"}}

View File

@@ -0,0 +1,32 @@
@import "solarized-light.css";
html, body, #mount
{ height: 100%
; width: 100%
}
body
{ max-width: 90%
; margin: 0 auto
; padding: 0
}
.split-root
{ height: 100%
}
.split-splitter
{ width: 100%
; height: 100%
; background: #ccc
}
.split-pane
{ margin: 0
; padding: 0
}
.pane-content
{ margin: 0.5em
}

View File

@@ -0,0 +1,304 @@
@import url(http://fonts.googleapis.com/css?family=Inconsolata);
@import url(http://fonts.googleapis.com/css?family=PT+Sans);
@import url(http://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700);
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section,
summary {
display: block;
}
audio,
canvas,
video {
display: inline-block;
}
audio:not([controls]) {
display: none;
height: 0;
}
[hidden] {
display: none;
}
html {
font-family: sans-serif;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
body {
margin: 0;
}
a:focus {
outline: thin dotted;
}
a:active,
a:hover {
outline: 0;
}
h1 {
font-size: 2em;
}
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong {
font-weight: bold;
}
dfn {
font-style: italic;
}
mark {
background: #ff0;
color: #000;
}
code,
kbd,
pre,
samp {
font-family: monospace, serif;
font-size: 1em;
}
pre {
white-space: pre-wrap;
word-wrap: break-word;
}
q {
quotes: "\201C" "\201D" "\2018" "\2019";
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
img {
border: 0;
width: 100%;
}
svg:not(:root) {
overflow: hidden;
}
figure {
margin: 0;
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
legend {
border: 0;
padding: 0;
}
button,
input,
select,
textarea {
font-family: inherit;
font-size: 100%;
margin: 0;
}
button,
input {
line-height: normal;
}
button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button;
cursor: pointer;
}
button[disabled],
input[disabled] {
cursor: default;
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0;
}
input[type="search"] {
-webkit-appearance: textfield;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
textarea {
overflow: auto;
vertical-align: top;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
html {
font-family: 'PT Sans', sans-serif;
}
pre,
code {
font-family: 'Inconsolata', sans-serif;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'PT Sans Narrow', sans-serif;
font-weight: 700;
}
html {
background-color: #eee8d5;
color: #657b83;
margin: 1em;
}
body {
background-color: #fdf6e3;
margin: 0 auto;
max-width: 23cm;
border: 1pt solid #93a1a1;
padding: 1em;
}
code {
background-color: #eee8d5;
padding: 2px;
}
a {
color: #b58900;
}
a:visited {
color: #cb4b16;
}
a:hover {
color: #cb4b16;
}
h1 {
color: #d33682;
}
h2,
h3,
h4,
h5,
h6 {
color: #859900;
}
pre {
background-color: #fdf6e3;
color: #657b83;
border: 1pt solid #93a1a1;
padding: 1em;
box-shadow: 5pt 5pt 8pt #eee8d5;
}
pre code {
background-color: #fdf6e3;
}
h1 {
font-size: 2.8em;
}
h2 {
font-size: 2.4em;
}
h3 {
font-size: 1.8em;
}
h4 {
font-size: 1.4em;
}
h5 {
font-size: 1.3em;
}
h6 {
font-size: 1.15em;
}
.tag {
background-color: #eee8d5;
color: #d33682;
padding: 0 0.2em;
}
.todo,
.next,
.done {
color: #fdf6e3;
background-color: #dc322f;
padding: 0 0.2em;
}
.tag {
-webkit-border-radius: 0.35em;
-moz-border-radius: 0.35em;
border-radius: 0.35em;
}
.TODO {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #2aa198;
}
.NEXT {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #268bd2;
}
.ACTIVE {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #268bd2;
}
.DONE {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #859900;
}
.WAITING {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #cb4b16;
}
.HOLD {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #d33682;
}
.NOTE {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #d33682;
}
.CANCELLED {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #859900;
}

View File

@@ -11,6 +11,8 @@
</style>
</head>
<body>
<div id="mount">
</div>
<script src="/js/main.js"></script>
</body>
</html>

View File

@@ -1,31 +1,28 @@
(ns main
(:require
["react-ace$default" :as AceEditor]
["ace-builds/src-noconflict/mode-haskell"]
["ace-builds/src-noconflict/theme-solarized_light"]
["ace-builds/src-noconflict/keybinding-vim"]
[ui :as ui]
[wscljs.client :as ws]
[wscljs.format :as fmt]
[clojure.string :as str]
[cljs.core.match :refer-macros [match]]))
[cljs.core.match :refer-macros [match]]
[reagent.dom :as rdom]))
(defn display-errors [es]
(doseq [{{e :contents} :diagnostic} es]
(let [fmte (map #(str " • " % "\n") e)]
(js/console.warn (apply str "message from rlpc:\n" fmte)))))
;------------------------------------------------------------------------------;
(def *rlp-socket nil)
;------------------------------------------------------------------------------;
(defn on-message [e]
(let [r (js->clj (js/JSON.parse (.-data e)) :keywordize-keys true)]
(match r
{:tag "Evaluated" :contents c}
(prn c)
(reset! ui/current-evaluation c)
:else
(js/console.warn "unrecognised response from rlp"))))
(def +rlp-socket+ nil)
(defn send [msg]
(ws/send +rlp-socket+ msg fmt/json))
(ws/send *rlp-socket msg fmt/json))
(defn on-open []
(println "socket opened")
@@ -39,7 +36,7 @@
"main = fac 3;"])}))
(defn init-rlp-socket []
(set! +rlp-socket+ (ws/create "ws://127.0.0.1:9002"
(set! *rlp-socket (ws/create "ws://127.0.0.1:9002"
{:on-message on-message
:on-open on-open
:on-close #(println "socket closed")
@@ -47,12 +44,14 @@
;; this is called before any code is reloaded
(defn ^:dev/before-load stop []
(ws/close +rlp-socket+)
(ws/close *rlp-socket)
(js/console.log "stop"))
;; start is called by init and after code reloading finishes
(defn ^:dev/after-load start []
(js/console.log "start")
(rdom/render [ui/Main]
(js/document.getElementById "mount"))
(init-rlp-socket))
;; init is called ONCE when the page loads

View File

@@ -0,0 +1,80 @@
(ns ui
(:require
[wscljs.client :as ws]
[wscljs.format :as fmt]
[clojure.string :as str]
[cljs.core.match :refer-macros [match]]
["react-ace$default" :as AceEditor]
["react-resplit" :refer (Resplit)]
["ace-builds/src-noconflict/mode-haskell"]
["ace-builds/src-noconflict/theme-solarized_light"]
["ace-builds/src-noconflict/keybinding-vim"]
[reagent.core :as r]
[reagent.dom :as rdom]))
;------------------------------------------------------------------------------;
(def current-evaluation (r/atom []))
(def current-index (r/atom 0))
(def +split-width+ "4px")
;------------------------------------------------------------------------------;
(defn Root [props & children]
[:> Resplit.Root (assoc props :class "split-root")
[:<> children]])
(defn Pane [props & children]
[:> Resplit.Pane (assoc props :class "split-pane")
[:<> children]])
(defn Splitter [props & children]
[:> Resplit.Splitter (assoc props :class "split-splitter")
[:<> children]])
;------------------------------------------------------------------------------;
(defn Stack []
[:div {:class "pane-content"}
[:h1 "Stack"]])
(defn Dump []
[:div {:class "pane-content"}
[:h1 "Dump"]])
(defn Heap []
[:div {:class "pane-content"}
[:h1 "Heap"]])
(defn Code []
[:div {:class "pane-content"}
[:h1 "Code"]])
;------------------------------------------------------------------------------;
(defn GM [{st :st}]
[Root {:direction "horizontal"}
[Pane {:order 0 :initialSize "0.333fr"}
[Heap]]
[Splitter {:order 1 :size +split-width+}]
[Pane {:order 2 :initialSize "0.333fr"}
[Root {:direction "vertical"}
[Pane {:order 0 :initialSize "0.8fr"}
[Stack]]
[Splitter {:order 1 :size +split-width+}]
[Pane {:order 2 :initialSize "0.2fr"}
[Code]]]]
[Splitter {:order 3 :size +split-width+}]
[Pane {:order 5 :initialSize "0.333fr"}
[Dump]]])
(defn Main []
(prn @current-evaluation)
(prn @current-index)
(if-let [st (nth @current-evaluation
@current-index
nil)]
[GM {:st st}]
[:h1 "no evaluation"]))