1+ <template >
2+ <div :class =" $style.playgroundRoot" >
3+ <div :class =" $style.playgroundButtons" >
4+ <button @click =" run" >Run</button >
5+ </div >
6+ <div :class =" $style.playgroundLogs" >
7+ <div v-for =" log in logs" :key =" log" :class =" $style.playgroundLogItem" >{{ log }}</div >
8+ </div >
9+ </div >
10+ </template >
11+
12+ <script setup lang="ts">
13+ import { ref } from ' vue' ;
14+ import type { Interpreter , Parser , utils as aisUtils } from ' @syuilo/aiscript' ;
15+
16+ const props = defineProps <{
17+ code: string ;
18+ }>();
19+
20+ const logs = ref <string []>([]);
21+
22+ let ParserClass: typeof Parser | null = null ;
23+ let InterpreterClass: typeof Interpreter | null = null ;
24+ let utils: typeof aisUtils | null = null ;
25+
26+ let parser: Parser | null = null ;
27+ let interpreter: Interpreter | null = null ;
28+
29+ async function run() {
30+ logs .value = [' [Playground] Loading...' ];
31+ if (! ParserClass || ! InterpreterClass || ! utils ) {
32+ const [
33+ { Parser, Interpreter, utils : importedUtils },
34+ ] = await Promise .all ([
35+ import (' @syuilo/aiscript' ),
36+ new Promise ((resolve ) => setTimeout (resolve , 250 )),
37+ ]);
38+ ParserClass = Parser ;
39+ InterpreterClass = Interpreter ;
40+ utils = importedUtils ;
41+ } else {
42+ await new Promise ((resolve ) => setTimeout (resolve , 250 ));
43+ }
44+ if (! parser ) {
45+ parser = new ParserClass ();
46+ }
47+ if (interpreter ) {
48+ interpreter .abort ();
49+ }
50+ interpreter = new InterpreterClass ({}, {
51+ out : (value ) => {
52+ logs .value .push (value .type === ' num' ? value .value .toString () : value .type === ' str' ? value .value : utils .valToString (value ));
53+ },
54+ });
55+
56+ logs .value = [];
57+
58+ const ast = parser .parse (props .code );
59+ await interpreter .exec (ast );
60+ }
61+ </script >
62+
63+ <style module>
64+ .playgroundRoot {
65+ border-top : 1px solid var (--vp-c-divider );
66+ padding : 12px 24px ;
67+ display : grid ;
68+ grid-template-columns : auto 1fr ;
69+ gap : 12px ;
70+ }
71+
72+ .playgroundButtons button {
73+ background-color : var (--vp-button-brand-bg );
74+ color : var (--vp-button-brand-text );
75+ font-weight : 700 ;
76+ transition : background-color 0.25s ;
77+ padding : 4px 16px ;
78+ border-radius : 8px ;
79+ cursor : pointer ;
80+ }
81+
82+ .playgroundButtons button :hover {
83+ color : var (--vp-button-brand-hover-text );
84+ background-color : var (--vp-button-brand-hover-bg );
85+ }
86+
87+ .playgroundLogs {
88+ background-color : var (--vp-c-bg );
89+ padding : 12px ;
90+ min-height : 120px ;
91+ max-height : 400px ;
92+ overflow-y : auto ;
93+ border-radius : 8px ;
94+ display : flex ;
95+ flex-direction : column ;
96+ gap : 4px ;
97+ }
98+
99+ .playgroundLogItem {
100+ font-family : var (--vp-font-family-mono );
101+ white-space : pre-wrap ;
102+ font-size : 14px ;
103+ }
104+ </style >
0 commit comments