diff --git a/.vitepress/pages/Playground.vue b/.vitepress/pages/Playground.vue
index cdb886b..012f52b 100644
--- a/.vitepress/pages/Playground.vue
+++ b/.vitepress/pages/Playground.vue
@@ -9,16 +9,16 @@
-
+
+
Syntax Error
+
See Output tab for details
+
+
+
+
+
+
Syntax Error
+
See Output tab for details
+
+
+
No metadata
@@ -85,9 +102,10 @@ const fizzbuzz = `for (let i, 100) {
\t\telse i
}`;
-const resultTab = ref<'output' | 'ast'>('output');
+const resultTab = ref<'output' | 'ast' | 'metadata'>('output');
//#region Editor
+const editorLoading = ref(true);
const inputEl = useTemplateRef('inputEl');
const code = ref(fizzbuzz);
const editorHtml = ref('');
@@ -159,23 +177,35 @@ const logs = ref<{
}[]>([]);
const logEl = useTemplateRef('logEl');
+const isSyntaxError = ref(false);
+
const ast = ref(null);
const astHtml = ref('');
+const metadata = ref(null);
+const metadataHtml = ref('');
+
function parse() {
+ isSyntaxError.value = false;
+
if (parser != null) {
try {
const _ast = parser.parse(code.value);
logs.value = [];
ast.value = _ast;
+
+ const meta = Interpreter.collectMetadata(_ast);
+ metadata.value = meta?.get(null) ?? null;
} catch (err) {
if (err instanceof errors.AiScriptError) {
logs.value = [{
text: `[SyntaxError] ${err.name}: ${err.message}`,
type: 'error',
}];
+ isSyntaxError.value = true;
}
ast.value = null;
+ metadata.value = null;
}
} else {
ast.value = null;
@@ -299,6 +329,8 @@ const updateHash = useThrottle((d: HashData) => {
//#endregion
onMounted(async () => {
+ const loadStartedAt = Date.now();
+
await init();
initAiScriptEnv();
@@ -324,7 +356,12 @@ onMounted(async () => {
}, { immediate: true });
watch(ast, async (newAst) => {
- if (highlighter && newAst != null) {
+ if (highlighter) {
+ if (newAst == null) {
+ astHtml.value = '';
+ return;
+ }
+
astHtml.value = highlighter.codeToHtml(JSON.stringify(newAst, null, 2), {
lang: 'json',
themes: {
@@ -334,7 +371,31 @@ onMounted(async () => {
defaultColor: false,
});
}
- });
+ }, { immediate: true });
+
+ watch(metadata, async (newMetadata) => {
+ if (highlighter) {
+ if (newMetadata == null) {
+ metadataHtml.value = '';
+ return;
+ }
+
+ metadataHtml.value = highlighter.codeToHtml(JSON.stringify(newMetadata, null, 2), {
+ lang: 'json',
+ themes: {
+ light: 'github-light',
+ dark: 'github-dark',
+ },
+ defaultColor: false,
+ });
+ }
+ }, { immediate: true });
+
+ const loadEndedAt = Date.now();
+
+ setTimeout(() => {
+ editorLoading.value = false;
+ }, Math.max(0, 500 - (loadEndedAt - loadStartedAt)));
});
onUnmounted(() => {
@@ -388,6 +449,19 @@ onUnmounted(() => {
overflow: scroll;
}
+.playgroundEditorLoading {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(255, 255, 255, 0.5);
+ z-index: 1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
.playgroundEditorScroller {
position: relative;
padding: 24px 36px;