diff --git a/src/sem/Sema.cpp b/src/sem/Sema.cpp index f25fab6..9c9f305 100644 --- a/src/sem/Sema.cpp +++ b/src/sem/Sema.cpp @@ -1,5 +1,58 @@ -// 语义分析主流程: -// - 符号解析与绑定、类型检查、控制流规则检查 -// - 记录/插入必要的隐式转换(或在节点上标注) -// - 输出为“带类型 / 符号 / 常量信息”的 AST +// 极简语义分析:只检查变量是否先声明再使用。 +// 如需扩展,可在此基础上加入: +// - 常量折叠/类型检查 +// - 函数签名/参数数量校验 +// - 控制流相关检查(return 覆盖、break/continue 合法性等) +#include "sem/Sema.h" +#include +#include +#include + +#include "ast/AstNodes.h" +#include "sem/SymbolTable.h" + +namespace { + +class SemaVisitor { + public: + explicit SemaVisitor(SymbolTable& table) : table_(table) {} + + void CheckBlock(const ast::Block& block) { + for (const auto& decl : block.varDecls) { + table_.Add(decl->name); + if (decl->init) CheckExpr(*decl->init); + } + for (const auto& stmt : block.stmts) { + if (auto ret = dynamic_cast(stmt.get())) { + CheckExpr(*ret->value); + + } + } + } + + void CheckExpr(const ast::Expr& expr) { + if (auto var = dynamic_cast(&expr)) { + if (!table_.Contains(var->name)) { + throw std::runtime_error("使用了未定义的变量: " + var->name); + } + } else if (auto bin = dynamic_cast(&expr)) { + CheckExpr(*bin->lhs); + CheckExpr(*bin->rhs); + + } + } + + private: + SymbolTable& table_; +}; + +} // namespace + +std::shared_ptr RunSema(std::shared_ptr ast) { + if (!ast || !ast->func || !ast->func->body) return ast; + SymbolTable table; + SemaVisitor visitor(table); + visitor.CheckBlock(*ast->func->body); + return ast; +} diff --git a/src/sem/Sema.h b/src/sem/Sema.h new file mode 100644 index 0000000..2886337 --- /dev/null +++ b/src/sem/Sema.h @@ -0,0 +1,11 @@ +// 语义检查 +#pragma once + +#include + +namespace ast { +struct CompUnit; +} + +// 返回经过检查的 AST(当前直接返回原 AST)。 +std::shared_ptr RunSema(std::shared_ptr ast); diff --git a/src/sem/SymbolTable.cpp b/src/sem/SymbolTable.cpp index 3d3327e..67ba4d4 100644 --- a/src/sem/SymbolTable.cpp +++ b/src/sem/SymbolTable.cpp @@ -2,3 +2,4 @@ // - 支持嵌套作用域(块/函数/全局) // - 变量/函数/参数/常量的注册、查找与遮蔽规则 +#include "sem/SymbolTable.h" diff --git a/src/sem/SymbolTable.h b/src/sem/SymbolTable.h new file mode 100644 index 0000000..eaf565e --- /dev/null +++ b/src/sem/SymbolTable.h @@ -0,0 +1,16 @@ +// 极简符号表:记录局部变量是否定义。 +#pragma once + +#include +#include + +class SymbolTable { + public: + void Add(const std::string& name) { table_[name] = true; } + bool Contains(const std::string& name) const { + return table_.find(name) != table_.end(); + } + + private: + std::unordered_map table_; +};