feat(docs): update computer fundamentals content and demos
- Refactor frontend framework demo descriptions for clarity - Remove interactive features from triad and field map demos - Add new computer organization and DSL documentation links - Split type systems and compilers into separate pages - Enhance power-on-to-web article with relay race analogy - Add new interactive demos for type systems and compilation - Improve visual presentation of boot process and hardware flow - Introduce new Vibe Coding flow demo component
This commit is contained in:
+192
@@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<div class="ast-visualizer-demo">
|
||||
<h4>🌳 AST 可视化:看见代码的"骨架"</h4>
|
||||
<p class="desc">选择一个表达式,观察它的抽象语法树结构</p>
|
||||
|
||||
<div class="expr-selector">
|
||||
<button
|
||||
v-for="(ex, i) in expressions"
|
||||
:key="i"
|
||||
:class="['expr-btn', { active: selected === i }]"
|
||||
@click="selected = i"
|
||||
>
|
||||
<code>{{ ex.code }}</code>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="ast-container">
|
||||
<div class="tree-view">
|
||||
<div class="tree-title">语法树</div>
|
||||
<div class="tree-nodes">
|
||||
<ASTNode
|
||||
:node="expressions[selected].tree"
|
||||
:depth="0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="explain-view">
|
||||
<div class="explain-title">解析说明</div>
|
||||
<div class="explain-list">
|
||||
<div v-for="(step, j) in expressions[selected].explains" :key="j" class="explain-item">
|
||||
<span class="explain-num">{{ j + 1 }}</span>
|
||||
<span>{{ step }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-tip">
|
||||
💡 试试 <a href="https://astexplorer.net/" target="_blank">AST Explorer</a> — 在线查看任意代码的 AST
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, h, defineComponent } from 'vue'
|
||||
|
||||
const selected = ref(0)
|
||||
|
||||
const ASTNode = defineComponent({
|
||||
name: 'ASTNode',
|
||||
props: { node: Object, depth: Number },
|
||||
setup(props) {
|
||||
return () => {
|
||||
const n = props.node
|
||||
const children = []
|
||||
|
||||
children.push(
|
||||
h('div', { class: 'node-box', style: { marginLeft: props.depth * 24 + 'px' } }, [
|
||||
h('span', { class: 'node-type' }, n.type),
|
||||
n.value ? h('span', { class: 'node-value' }, n.value) : null
|
||||
])
|
||||
)
|
||||
|
||||
if (n.children) {
|
||||
for (const child of n.children) {
|
||||
children.push(h(ASTNode, { node: child, depth: props.depth + 1 }))
|
||||
}
|
||||
}
|
||||
|
||||
return h('div', { class: 'node-wrapper' }, children)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const expressions = [
|
||||
{
|
||||
code: '1 + 2 * 3',
|
||||
tree: {
|
||||
type: 'BinaryExpression', value: '+',
|
||||
children: [
|
||||
{ type: 'NumericLiteral', value: '1' },
|
||||
{
|
||||
type: 'BinaryExpression', value: '*',
|
||||
children: [
|
||||
{ type: 'NumericLiteral', value: '2' },
|
||||
{ type: 'NumericLiteral', value: '3' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
explains: [
|
||||
'* 优先级高于 +,所以 2 * 3 先结合',
|
||||
'2 * 3 形成一个 BinaryExpression 子树',
|
||||
'1 和这个子树作为 + 的左右操作数',
|
||||
'最终 + 是根节点,体现了运算顺序'
|
||||
]
|
||||
},
|
||||
{
|
||||
code: 'let x = 10',
|
||||
tree: {
|
||||
type: 'VariableDeclaration', value: 'let',
|
||||
children: [
|
||||
{
|
||||
type: 'VariableDeclarator', value: '',
|
||||
children: [
|
||||
{ type: 'Identifier', value: 'x' },
|
||||
{ type: 'NumericLiteral', value: '10' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
explains: [
|
||||
'let 声明创建 VariableDeclaration 节点',
|
||||
'内部包含一个 VariableDeclarator(声明器)',
|
||||
'声明器左侧是标识符 x,右侧是初始值 10',
|
||||
'树结构清晰表达了"把 10 赋给 x"的语义'
|
||||
]
|
||||
},
|
||||
{
|
||||
code: 'add(a, b)',
|
||||
tree: {
|
||||
type: 'CallExpression', value: '',
|
||||
children: [
|
||||
{ type: 'Identifier', value: 'add' },
|
||||
{
|
||||
type: 'Arguments', value: '',
|
||||
children: [
|
||||
{ type: 'Identifier', value: 'a' },
|
||||
{ type: 'Identifier', value: 'b' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
explains: [
|
||||
'函数调用创建 CallExpression 节点',
|
||||
'被调用的函数名 add 是 Identifier',
|
||||
'参数列表 (a, b) 形成 Arguments 节点',
|
||||
'每个参数都是独立的 Identifier 子节点'
|
||||
]
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ast-visualizer-demo {
|
||||
padding: 20px; border: 1px solid var(--vp-c-divider);
|
||||
border-radius: 12px; margin: 16px 0; background: var(--vp-c-bg-soft);
|
||||
}
|
||||
h4 { margin: 0 0 4px; }
|
||||
.desc { color: var(--vp-c-text-2); font-size: 14px; margin: 0 0 16px; }
|
||||
.expr-selector { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
|
||||
.expr-btn {
|
||||
padding: 6px 14px; border-radius: 6px; border: 1px solid var(--vp-c-divider);
|
||||
background: var(--vp-c-bg); cursor: pointer; font-size: 13px; transition: all 0.2s;
|
||||
}
|
||||
.expr-btn.active { background: var(--vp-c-brand-1); color: #fff; border-color: var(--vp-c-brand-1); }
|
||||
.expr-btn code { font-size: 13px; }
|
||||
.ast-container { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
|
||||
.tree-view, .explain-view {
|
||||
border: 1px solid var(--vp-c-divider); border-radius: 8px;
|
||||
background: var(--vp-c-bg); overflow: hidden;
|
||||
}
|
||||
.tree-title, .explain-title {
|
||||
padding: 8px 12px; font-weight: 600; font-size: 13px;
|
||||
background: var(--vp-c-bg-soft); border-bottom: 1px solid var(--vp-c-divider);
|
||||
}
|
||||
.tree-nodes { padding: 12px; }
|
||||
:deep(.node-box) {
|
||||
display: flex; align-items: center; gap: 6px; padding: 3px 0;
|
||||
}
|
||||
:deep(.node-type) {
|
||||
padding: 2px 8px; background: #dbeafe; color: #1e40af;
|
||||
border-radius: 4px; font-size: 12px; font-weight: 500;
|
||||
}
|
||||
:deep(.node-value) {
|
||||
padding: 2px 6px; background: #fef3c7; color: #92400e;
|
||||
border-radius: 4px; font-size: 12px; font-family: 'Fira Code', monospace;
|
||||
}
|
||||
.explain-list { padding: 10px 12px; }
|
||||
.explain-item { display: flex; align-items: flex-start; gap: 8px; padding: 4px 0; font-size: 13px; }
|
||||
.explain-num {
|
||||
width: 20px; height: 20px; border-radius: 50%; background: var(--vp-c-brand-1);
|
||||
color: #fff; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 11px; font-weight: 600; flex-shrink: 0;
|
||||
}
|
||||
.tool-tip {
|
||||
padding: 8px 12px; font-size: 12px; color: var(--vp-c-text-2);
|
||||
border-top: 1px solid var(--vp-c-divider); background: var(--vp-c-bg-soft);
|
||||
}
|
||||
.tool-tip a { color: var(--vp-c-brand-1); }
|
||||
@media (max-width: 640px) { .ast-container { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
Reference in New Issue
Block a user