@fraczak/k 6.6.0 → 6.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCS/REPL.md +23 -36
- package/TODO.md +112 -0
- package/backends/arm64/README.md +0 -1
- package/backends/arm64/bin/k-arm64-compile.mjs +0 -8
- package/backends/llvm/README.md +13 -11
- package/backends/llvm/bin/k-llvm-build.mjs +40 -38
- package/backends/llvm/bin/k-llvm-compile.mjs +42 -32
- package/backends/llvm/src/cli.mjs +153 -0
- package/backends/llvm/src/executable.mjs +1 -1
- package/backends/llvm/src/kvm2llvm.mjs +11 -1
- package/backends/llvm/tests/integration.sh +18 -22
- package/backends/wasm/bin/k-wasm-compile.mjs +19 -4
- package/browser/repl-browser.mjs +146 -94
- package/browser/vfs-data.mjs +2 -0
- package/package.json +1 -1
- package/repl-codecs.mjs +26 -5
- package/repl.mjs +214 -148
- package/scripts/build-repl-html.mjs +213 -72
- package/tests/test-repl-html.mjs +84 -6
- package/tests/test-repl.mjs +90 -40
package/browser/repl-browser.mjs
CHANGED
|
@@ -3,19 +3,18 @@ import {
|
|
|
3
3
|
evaluateInput,
|
|
4
4
|
createCompleter,
|
|
5
5
|
promptForState,
|
|
6
|
-
helpText,
|
|
7
6
|
analyzeRawSnippet,
|
|
8
7
|
lineTerminatesSnippet,
|
|
9
8
|
lineHasExplicitContinuation,
|
|
10
9
|
savedLibrary,
|
|
11
|
-
listCodecs,
|
|
12
|
-
loadCodecModule,
|
|
13
10
|
registerCodec,
|
|
14
11
|
unregisterCodec,
|
|
15
12
|
resolveCodec,
|
|
16
13
|
codeHashToPattern,
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
formatDuration,
|
|
15
|
+
resolveInputTypeHash,
|
|
16
|
+
resolveInputPattern,
|
|
17
|
+
valueForPattern
|
|
19
18
|
} from "../repl.mjs";
|
|
20
19
|
import { Value, isProduct, isVariant } from "../Value.mjs";
|
|
21
20
|
import { encodeLibrary } from "../object.mjs";
|
|
@@ -71,6 +70,7 @@ let inputPopupCodec;
|
|
|
71
70
|
let inputPopupText;
|
|
72
71
|
let inputPopupStatus;
|
|
73
72
|
let inputPopupHint;
|
|
73
|
+
let inputPopupCodecHint;
|
|
74
74
|
let inputSamplesList;
|
|
75
75
|
|
|
76
76
|
function escapeHtml(str) {
|
|
@@ -569,19 +569,19 @@ function exportKlib() {
|
|
|
569
569
|
const CODEC_PRESETS = {
|
|
570
570
|
yn: {
|
|
571
571
|
name: "yn",
|
|
572
|
-
type: "
|
|
572
|
+
type: "yes_no",
|
|
573
573
|
universal: false,
|
|
574
|
-
parse: `// Parse 'yes', 'no', 'true', 'false' into $
|
|
574
|
+
parse: `// Parse 'yes', 'no', 'true', 'false' into $yes_no (< {} yes, {} no >)
|
|
575
575
|
const tag = text.trim().toLowerCase();
|
|
576
576
|
if (tag === "yes" || tag === "true" || tag === "1") {
|
|
577
|
-
return Value.variant("
|
|
577
|
+
return Value.variant("yes", Value.product({}));
|
|
578
578
|
}
|
|
579
579
|
if (tag === "no" || tag === "false" || tag === "0") {
|
|
580
|
-
return Value.variant("
|
|
580
|
+
return Value.variant("no", Value.product({}));
|
|
581
581
|
}
|
|
582
582
|
throw new Error("Expected yes/no or true/false");`,
|
|
583
|
-
print: `// Serialize
|
|
584
|
-
return value.tag === "
|
|
583
|
+
print: `// Serialize yes_no value to YES / NO
|
|
584
|
+
return value.tag === "yes" ? "YES" : "NO";`
|
|
585
585
|
},
|
|
586
586
|
hex: {
|
|
587
587
|
name: "hex",
|
|
@@ -652,8 +652,9 @@ return "$" + dollars.toString() + "." + cents;`
|
|
|
652
652
|
parse: `// Parse text string and return a K Value
|
|
653
653
|
// Available: Value.product({ field: val }), Value.variant("tag", val)
|
|
654
654
|
return Value.product({});`,
|
|
655
|
-
print: `// Serialize K Value into string
|
|
656
|
-
|
|
655
|
+
print: `// Serialize K Value into string
|
|
656
|
+
// value is a Value instance: inspect value.fields or value.tag & value.value
|
|
657
|
+
return String(value);`
|
|
657
658
|
}
|
|
658
659
|
};
|
|
659
660
|
|
|
@@ -696,7 +697,7 @@ function renderCodecsModal() {
|
|
|
696
697
|
for (const [alias, hash] of aliases) {
|
|
697
698
|
const opt = document.createElement("option");
|
|
698
699
|
opt.value = alias;
|
|
699
|
-
opt.textContent =
|
|
700
|
+
opt.textContent = `$ ${alias} (${hash.slice(0, 10)}...)`;
|
|
700
701
|
typeGroup.appendChild(opt);
|
|
701
702
|
}
|
|
702
703
|
codecTypeSelect.appendChild(typeGroup);
|
|
@@ -838,9 +839,9 @@ function registerCustomCodecFromForm() {
|
|
|
838
839
|
);
|
|
839
840
|
}
|
|
840
841
|
|
|
841
|
-
let codeHash =
|
|
842
|
-
if (
|
|
843
|
-
|
|
842
|
+
let codeHash = "*";
|
|
843
|
+
if (rawType !== "*") {
|
|
844
|
+
codeHash = resolveInputTypeHash(state, rawType);
|
|
844
845
|
}
|
|
845
846
|
|
|
846
847
|
registerCodec(state, {
|
|
@@ -945,8 +946,8 @@ export function print(value, context) {
|
|
|
945
946
|
|
|
946
947
|
const CODEC_SAMPLES = {
|
|
947
948
|
int: ["0", "10", "42", "-15", "1000000"],
|
|
948
|
-
utf8: ["hello", "hello world", "k repl", "
|
|
949
|
-
json: ['{"
|
|
949
|
+
utf8: ["hello", "hello world", "k repl", "abc"],
|
|
950
|
+
json: ['{"x":12,"n":"Woj"}', '{"name":"Alice"}', 'true', '[1, 2, 3]'],
|
|
950
951
|
ieee: ["0.0", "3.14159", "-2.718", "1e6"],
|
|
951
952
|
yn: ["yes", "no", "true", "false"],
|
|
952
953
|
hex: ["0x2A", "0xFF", "0x1000", "-0x10"],
|
|
@@ -997,6 +998,10 @@ function renderInputSamples(codecName) {
|
|
|
997
998
|
btn.onclick = () => {
|
|
998
999
|
if (inputPopupText) {
|
|
999
1000
|
inputPopupText.value = s;
|
|
1001
|
+
if (codecName === "json" && s === '{"x":12,"n":"Woj"}' && (!inputPopupType?.value || inputPopupType.value === "*")) {
|
|
1002
|
+
inputPopupType.value = "{float64 x, string n}";
|
|
1003
|
+
updateInputPopupCodecs();
|
|
1004
|
+
}
|
|
1000
1005
|
inputPopupText.focus();
|
|
1001
1006
|
updateLiveValidation();
|
|
1002
1007
|
}
|
|
@@ -1007,19 +1012,36 @@ function renderInputSamples(codecName) {
|
|
|
1007
1012
|
|
|
1008
1013
|
function updateInputPopupHint() {
|
|
1009
1014
|
if (!inputPopupHint) return;
|
|
1015
|
+
const rawPattern = inputPopupType ? inputPopupType.value.trim() : "(...)";
|
|
1016
|
+
const codecName = inputPopupCodec?.value || state.pendingInput?.codecName;
|
|
1010
1017
|
if (state.pendingInput) {
|
|
1011
|
-
const
|
|
1012
|
-
|
|
1013
|
-
inputPopupHint.innerHTML = `Enter input value for <b>$${escapeHtml(rawType)}</b> using codec <b>${escapeHtml(codecName || "default")}</b>:`;
|
|
1018
|
+
const displayPattern = rawPattern || state.pendingInput.rawExpr || "(...)";
|
|
1019
|
+
inputPopupHint.innerHTML = `Enter input value for <b>${escapeHtml(displayPattern)}</b> using codec <b>${escapeHtml(codecName || "default")}</b>:`;
|
|
1014
1020
|
} else {
|
|
1015
|
-
inputPopupHint.innerHTML = `Choose target
|
|
1021
|
+
inputPopupHint.innerHTML = `Choose target pattern & deserializer, then enter input string:`;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
if (inputPopupCodecHint) {
|
|
1025
|
+
if (codecName === "json") {
|
|
1026
|
+
inputPopupCodecHint.textContent = "Parameterized codec: deserializes JSON into the specified Target Pattern.";
|
|
1027
|
+
} else {
|
|
1028
|
+
inputPopupCodecHint.textContent = "";
|
|
1029
|
+
}
|
|
1016
1030
|
}
|
|
1017
1031
|
}
|
|
1018
1032
|
|
|
1019
1033
|
function updateInputPopupCodecs() {
|
|
1020
1034
|
if (!inputPopupCodec) return;
|
|
1021
|
-
const
|
|
1022
|
-
|
|
1035
|
+
const rawPattern = inputPopupType ? inputPopupType.value.trim() : "(...)";
|
|
1036
|
+
let codeHash = null;
|
|
1037
|
+
if (rawPattern && rawPattern !== "*" && rawPattern !== "(...)") {
|
|
1038
|
+
try {
|
|
1039
|
+
const resolved = resolveInputPattern(state, rawPattern);
|
|
1040
|
+
codeHash = resolved.codeHash;
|
|
1041
|
+
} catch {
|
|
1042
|
+
codeHash = null;
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1023
1045
|
const prev = inputPopupCodec.value;
|
|
1024
1046
|
|
|
1025
1047
|
inputPopupCodec.innerHTML = "";
|
|
@@ -1027,8 +1049,8 @@ function updateInputPopupCodecs() {
|
|
|
1027
1049
|
const store = state.codecs || {};
|
|
1028
1050
|
|
|
1029
1051
|
const candidates = [
|
|
1030
|
-
...(store[codeHash] || []),
|
|
1031
|
-
...(
|
|
1052
|
+
...(codeHash ? (store[codeHash] || []) : []),
|
|
1053
|
+
...(store["*"] || [])
|
|
1032
1054
|
];
|
|
1033
1055
|
|
|
1034
1056
|
const seen = new Set();
|
|
@@ -1039,11 +1061,26 @@ function updateInputPopupCodecs() {
|
|
|
1039
1061
|
}
|
|
1040
1062
|
}
|
|
1041
1063
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
if (rawType === "bool") matchingCodecs.push("yn");
|
|
1045
|
-
if (rawType === "string") matchingCodecs.push("utf8");
|
|
1064
|
+
const bareName = rawPattern.replace(/^(\?|\$)\s*/, "").trim();
|
|
1065
|
+
if (!seen.has("json")) {
|
|
1046
1066
|
matchingCodecs.push("json");
|
|
1067
|
+
seen.add("json");
|
|
1068
|
+
}
|
|
1069
|
+
if ((bareName === "int" || (codeHash && codeHash === state.typeAliases?.int)) && !seen.has("int")) {
|
|
1070
|
+
matchingCodecs.push("int");
|
|
1071
|
+
seen.add("int");
|
|
1072
|
+
}
|
|
1073
|
+
if ((bareName === "string" || bareName === "utf8" || (codeHash && (codeHash === state.typeAliases?.string || codeHash === state.typeAliases?.utf8))) && !seen.has("utf8")) {
|
|
1074
|
+
matchingCodecs.push("utf8");
|
|
1075
|
+
seen.add("utf8");
|
|
1076
|
+
}
|
|
1077
|
+
if ((bareName === "float64" || bareName === "ieee" || (codeHash && codeHash === state.typeAliases?.float64)) && !seen.has("ieee")) {
|
|
1078
|
+
matchingCodecs.push("ieee");
|
|
1079
|
+
seen.add("ieee");
|
|
1080
|
+
}
|
|
1081
|
+
if ((bareName === "yes_no" || bareName === "bool" || (codeHash && codeHash === state.typeAliases?.yes_no)) && !seen.has("yn")) {
|
|
1082
|
+
matchingCodecs.push("yn");
|
|
1083
|
+
seen.add("yn");
|
|
1047
1084
|
}
|
|
1048
1085
|
|
|
1049
1086
|
for (const name of matchingCodecs) {
|
|
@@ -1064,39 +1101,38 @@ function updateInputPopupCodecs() {
|
|
|
1064
1101
|
updateLiveValidation();
|
|
1065
1102
|
}
|
|
1066
1103
|
|
|
1067
|
-
function populateInputPopupDropdowns(
|
|
1104
|
+
function populateInputPopupDropdowns(preselectedPattern = null, preselectedCodec = null) {
|
|
1068
1105
|
if (!inputPopupType) return;
|
|
1069
1106
|
|
|
1070
|
-
|
|
1071
|
-
if (
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1107
|
+
const datalist = document.getElementById("input-popup-type-list");
|
|
1108
|
+
if (datalist) {
|
|
1109
|
+
datalist.innerHTML = "";
|
|
1110
|
+
const aliases = Object.entries(state.typeAliases || {}).sort(([a], [b]) => a.localeCompare(b));
|
|
1111
|
+
for (const [alias, hash] of aliases) {
|
|
1112
|
+
const opt = document.createElement("option");
|
|
1113
|
+
opt.value = `$ ${alias}`;
|
|
1114
|
+
opt.textContent = `$ ${alias} (${hash.slice(0, 10)}...)`;
|
|
1115
|
+
datalist.appendChild(opt);
|
|
1116
|
+
}
|
|
1117
|
+
const universalOpt = document.createElement("option");
|
|
1118
|
+
universalOpt.value = "(...)";
|
|
1119
|
+
universalOpt.textContent = "(...) (Any document)";
|
|
1120
|
+
datalist.appendChild(universalOpt);
|
|
1077
1121
|
}
|
|
1078
1122
|
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
inputPopupType.appendChild(opt);
|
|
1123
|
+
let prevPattern = preselectedPattern;
|
|
1124
|
+
if (!prevPattern && state.pendingInput) {
|
|
1125
|
+
prevPattern = state.pendingInput.rawExpr;
|
|
1126
|
+
if (!prevPattern && state.pendingInput.codeHash) {
|
|
1127
|
+
const foundAlias = Object.entries(state.typeAliases || {}).find(([, h]) => h === state.pendingInput.codeHash);
|
|
1128
|
+
prevPattern = foundAlias ? `$ ${foundAlias[0]}` : state.pendingInput.codeHash;
|
|
1129
|
+
}
|
|
1087
1130
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
universalOpt.value = "*";
|
|
1091
|
-
universalOpt.textContent = "* (Universal / Any)";
|
|
1092
|
-
inputPopupType.appendChild(universalOpt);
|
|
1093
|
-
|
|
1094
|
-
if (prevType && (aliases.some(([a]) => a === prevType) || prevType === "*")) {
|
|
1095
|
-
inputPopupType.value = prevType;
|
|
1096
|
-
} else if (aliases.length > 0) {
|
|
1097
|
-
inputPopupType.value = aliases[0][0];
|
|
1131
|
+
if (!prevPattern) {
|
|
1132
|
+
prevPattern = inputPopupType.value || "(...)";
|
|
1098
1133
|
}
|
|
1099
1134
|
|
|
1135
|
+
inputPopupType.value = prevPattern;
|
|
1100
1136
|
updateInputPopupCodecs();
|
|
1101
1137
|
|
|
1102
1138
|
const targetCodec = preselectedCodec || state.pendingInput?.codecName;
|
|
@@ -1114,26 +1150,39 @@ function updateLiveValidation() {
|
|
|
1114
1150
|
return;
|
|
1115
1151
|
}
|
|
1116
1152
|
|
|
1117
|
-
const
|
|
1153
|
+
const rawPattern = inputPopupType ? inputPopupType.value.trim() : "(...)";
|
|
1118
1154
|
const codecName = inputPopupCodec?.value;
|
|
1119
|
-
if (!
|
|
1120
|
-
inputPopupStatus.innerHTML = `<span class="line-warning" style="margin:0;padding:2px 6px;">
|
|
1155
|
+
if (!rawPattern && !codecName) {
|
|
1156
|
+
inputPopupStatus.innerHTML = `<span class="line-warning" style="margin:0;padding:2px 6px;">Specify a target pattern or codec first.</span>`;
|
|
1121
1157
|
return;
|
|
1122
1158
|
}
|
|
1123
1159
|
|
|
1124
|
-
|
|
1160
|
+
let pattern = null;
|
|
1161
|
+
let codeHash = null;
|
|
1162
|
+
if (rawPattern && rawPattern !== "*" && rawPattern !== "(...)") {
|
|
1163
|
+
try {
|
|
1164
|
+
const resolved = resolveInputPattern(state, rawPattern);
|
|
1165
|
+
pattern = resolved.pattern;
|
|
1166
|
+
codeHash = resolved.codeHash;
|
|
1167
|
+
} catch (err) {
|
|
1168
|
+
inputPopupStatus.innerHTML = `<span class="line-warning" style="margin:0;padding:2px 6px;">⚠ Pattern Error: ${escapeHtml(err.message || String(err))}</span>`;
|
|
1169
|
+
return;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1125
1173
|
try {
|
|
1126
1174
|
const codec = resolveCodec(state, codeHash, codecName || null, "parse");
|
|
1127
|
-
const
|
|
1175
|
+
const resolvedPattern = pattern || (codeHash && codeHash !== "*" ? codeHashToPattern(codeHash, (h) => state.codes?.[h]) : null);
|
|
1128
1176
|
const parsed = codec.parse(text, {
|
|
1129
1177
|
codeHash,
|
|
1130
|
-
pattern,
|
|
1178
|
+
pattern: resolvedPattern,
|
|
1131
1179
|
state,
|
|
1132
1180
|
Value,
|
|
1133
1181
|
isProduct,
|
|
1134
1182
|
isVariant
|
|
1135
1183
|
});
|
|
1136
|
-
const
|
|
1184
|
+
const validated = valueForPattern(parsed, resolvedPattern, text, codec.name);
|
|
1185
|
+
const repr = validated instanceof Value ? validated.toJSON() : (typeof validated === "object" ? JSON.stringify(validated) : String(validated));
|
|
1137
1186
|
inputPopupStatus.innerHTML = `<span class="line-output" style="margin:0;padding:2px 6px;">✓ Valid: <code>${escapeHtml(String(repr))}</code></span>`;
|
|
1138
1187
|
} catch (err) {
|
|
1139
1188
|
inputPopupStatus.innerHTML = `<span class="line-warning" style="margin:0;padding:2px 6px;">⚠ ${escapeHtml(err.message || String(err))}</span>`;
|
|
@@ -1142,25 +1191,43 @@ function updateLiveValidation() {
|
|
|
1142
1191
|
|
|
1143
1192
|
export async function submitInputPopup() {
|
|
1144
1193
|
const text = inputPopupText?.value ?? "";
|
|
1194
|
+
const rawPattern = inputPopupType ? inputPopupType.value.trim() : "(...)";
|
|
1195
|
+
const codecName = inputPopupCodec?.value;
|
|
1145
1196
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1197
|
+
if (!rawPattern && !codecName) {
|
|
1198
|
+
if (inputPopupStatus) inputPopupStatus.innerHTML = `<span class="line-error">Please specify a target pattern or codec.</span>`;
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
let pattern = null;
|
|
1203
|
+
let codeHash = null;
|
|
1204
|
+
let rawExpr = rawPattern || "(...)";
|
|
1205
|
+
if (rawPattern && rawPattern !== "*" && rawPattern !== "(...)") {
|
|
1155
1206
|
try {
|
|
1156
|
-
const
|
|
1157
|
-
|
|
1207
|
+
const resolved = resolveInputPattern(state, rawPattern);
|
|
1208
|
+
pattern = resolved.pattern;
|
|
1209
|
+
codeHash = resolved.codeHash;
|
|
1210
|
+
rawExpr = rawPattern;
|
|
1158
1211
|
} catch (err) {
|
|
1159
|
-
if (inputPopupStatus) inputPopupStatus.innerHTML = `<span class="line-error"
|
|
1212
|
+
if (inputPopupStatus) inputPopupStatus.innerHTML = `<span class="line-error">Pattern Error: ${escapeHtml(err.message || String(err))}</span>`;
|
|
1160
1213
|
return;
|
|
1161
1214
|
}
|
|
1162
1215
|
}
|
|
1163
1216
|
|
|
1217
|
+
try {
|
|
1218
|
+
const codec = resolveCodec(state, codeHash, codecName || null, "parse");
|
|
1219
|
+
state.pendingInput = {
|
|
1220
|
+
pattern,
|
|
1221
|
+
codeHash,
|
|
1222
|
+
codecName: codec.name,
|
|
1223
|
+
promptName: codec.name,
|
|
1224
|
+
rawExpr: rawExpr || codec.name
|
|
1225
|
+
};
|
|
1226
|
+
} catch (err) {
|
|
1227
|
+
if (inputPopupStatus) inputPopupStatus.innerHTML = `<span class="line-error">${escapeHtml(err.message || String(err))}</span>`;
|
|
1228
|
+
return;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1164
1231
|
closeInputPopup();
|
|
1165
1232
|
await executeCommand(text);
|
|
1166
1233
|
}
|
|
@@ -1190,6 +1257,7 @@ export function initRepl() {
|
|
|
1190
1257
|
inputPopupText = document.getElementById("input-popup-text");
|
|
1191
1258
|
inputPopupStatus = document.getElementById("input-popup-status");
|
|
1192
1259
|
inputPopupHint = document.getElementById("input-popup-hint");
|
|
1260
|
+
inputPopupCodecHint = document.getElementById("input-popup-codec-hint");
|
|
1193
1261
|
inputSamplesList = document.getElementById("input-samples-list");
|
|
1194
1262
|
|
|
1195
1263
|
updatePrompt();
|
|
@@ -1197,16 +1265,7 @@ export function initRepl() {
|
|
|
1197
1265
|
// Welcome message
|
|
1198
1266
|
appendSystemMessage(`
|
|
1199
1267
|
<div class="welcome-banner">
|
|
1200
|
-
<div class="welcome-title"
|
|
1201
|
-
<div class="welcome-desc">First-order partial functions over algebraic data types • WebAssembly execution engine • Custom Serializers & Deserializers (:codecs)</div>
|
|
1202
|
-
<div class="welcome-tips">
|
|
1203
|
-
<span>💡 Try: <a href="javascript:void(0)" class="quick-link" data-code=":load core.k">:load core.k</a></span>
|
|
1204
|
-
<span>• <a href="javascript:void(0)" class="quick-link" data-code=":codec load int">:codec load int</a></span>
|
|
1205
|
-
<span>• <a href="javascript:void(0)" class="quick-link" data-code="10 int">10 int</a></span>
|
|
1206
|
-
<span>• <a href="javascript:void(0)" class="quick-link" data-code="{10 int x, 5 int y} plus">{10 int x, 5 int y} plus</a></span>
|
|
1207
|
-
<span>• <a href="javascript:void(0)" class="quick-link" data-code=":codecs">:codecs</a></span>
|
|
1208
|
-
<span>• <a href="javascript:void(0)" class="quick-link" data-code=":help">:help</a></span>
|
|
1209
|
-
</div>
|
|
1268
|
+
<div class="welcome-title">k interactive repl</div>
|
|
1210
1269
|
</div>
|
|
1211
1270
|
`, false, true);
|
|
1212
1271
|
|
|
@@ -1365,14 +1424,6 @@ export function initRepl() {
|
|
|
1365
1424
|
const clearBtn = document.getElementById("btn-clear");
|
|
1366
1425
|
if (clearBtn) clearBtn.onclick = clearOutput;
|
|
1367
1426
|
|
|
1368
|
-
// Reset button
|
|
1369
|
-
const resetBtn = document.getElementById("btn-reset");
|
|
1370
|
-
if (resetBtn) {
|
|
1371
|
-
resetBtn.onclick = () => {
|
|
1372
|
-
executeCommand(":reset");
|
|
1373
|
-
};
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
1427
|
// Help button
|
|
1377
1428
|
const helpBtn = document.getElementById("btn-help");
|
|
1378
1429
|
if (helpBtn) {
|
|
@@ -1458,6 +1509,7 @@ export function initRepl() {
|
|
|
1458
1509
|
|
|
1459
1510
|
if (inputPopupType) {
|
|
1460
1511
|
inputPopupType.addEventListener("change", updateInputPopupCodecs);
|
|
1512
|
+
inputPopupType.addEventListener("input", updateInputPopupCodecs);
|
|
1461
1513
|
}
|
|
1462
1514
|
|
|
1463
1515
|
if (inputPopupCodec) {
|