Skip to content

Latest commit

 

History

History
60 lines (40 loc) · 3.65 KB

File metadata and controls

60 lines (40 loc) · 3.65 KB

知识问答:Lua 代码执行全流程解析

本文档将详细拆解在 haifa-python 项目中,一段 Lua 源代码是如何一步步被处理,并最终得到执行结果的。这将把前面几篇文档的知识点串联起来,形成一个完整的链路。

整个过程可以概括为以下几个核心阶段:

Lua 源代码 -> [词法分析] -> Tokens -> [语法分析] -> AST -> [语义分析] -> 带分析信息的 AST -> [编译/代码生成] -> 字节码 -> [虚拟机执行] -> 最终结果

阶段一:词法分析 (Lexical Analysis)

  • 做什么:读取原始的 Lua 代码字符串,将其分解成一个个独立的、有意义的“单词”,即词法单元(Tokens)。例如,local 是一个关键字 Token,my_var 是一个标识符 Token,= 是一个操作符 Token。
  • 谁来做haifa_lua/lexer.py 中的 Lexer 类。
  • 输入:Lua 源代码字符串(例如 local a = 10)。
  • 输出:一个 Token 列表(例如 [TOKEN_LOCAL, TOKEN_IDENTIFIER('a'), TOKEN_ASSIGN, TOKEN_NUMBER(10)])。

阶段二:语法分析 (Syntax Analysis)

  • 做什么:接收词法分析产生的 Token 序列,并根据 Lua 的语法规则,将它们组织成一个结构化的树形表示——抽象语法树(AST)。这个树精确地反映了代码的逻辑结构。
  • 谁来做haifa_lua/parser.py 中的 Parser 类。
  • 输入:Token 列表。
  • 输出:一个由 haifa_lua/ast.py 中定义的节点组成的 AST。例如,local a = 10 会被构造成一个 Assignment 节点。

阶段三:语义分析 (Semantic Analysis)

  • 做什么:在正式编译成字节码之前,对 AST 进行一次深度遍历和分析。这个阶段不改变代码结构,但会收集关键的语义信息,尤其是关于变量作用域和闭包的信息。它会确定:
    • 每个变量是局部的还是全局的。
    • 哪些局部变量被其内部的函数所引用(即被“捕获”),需要作为 upvalue 来处理。
  • 谁来做haifa_lua/analysis.py 中的 analyze 函数。
  • 输入:原始的 AST。
  • 输出:一个“信息映射表”(closure_map),其中包含了每个函数节点的分析结果(FunctionInfo),详细记录了其参数、局部变量、以及需要捕获的 upvalue 等信息。

阶段四:编译 / 代码生成 (Compilation / Code Generation)

  • 做什么:这是将高级结构(AST)转换为低级指令的核心步骤。编译器会遍历 AST,并根据 analysis.py 提供的语义信息,生成一系列为目标虚拟机设计的字节码指令。
  • 谁来做haifa_lua/compiler.py 中的 LuaCompiler 类。
  • 输入:AST 和 closure_map
  • 输出:一个由 compiler/bytecode.py 中定义的 Instruction 对象组成的列表,即字节码序列。例如,a + b 会被编译成类似 ADD r3, r1, r2 的指令。

阶段五:虚拟机执行 (VM Execution)

  • 做什么:这是代码生命周期的最后一站。虚拟机作为字节码的解释器,会逐条读取并执行字节码指令。它内部维护着一个虚拟的寄存器组、调用栈等,模拟一个真实 CPU 的行为。
  • 谁来做compiler/bytecode_vm.py 中的 BytecodeVM 类。
  • 输入:字节码序列。
  • 输出:程序的最终运行结果(例如,print 函数的输出)。

通过这五个阶段,haifa-python 项目实现了一个从源代码到机器(虚拟的)指令的完整翻译和执行流程,完美地诠释了现代编程语言的工作原理。