自底向上的轨迹
(每道题开头都有同一段:上一站的 parser(多记了位置)、show(),和错误类 SemError——错误写成一行「原因@行:列」。) trace 按「先孩子后自己」的顺序记下每个表达式节点的类型
推不出来怎么办
let x = y ;,而 y 从没声明过。此时 x 的类型【0】。
推断的顺序
推 ( rate * 3 ) >= 30 的类型时,先算出来的是【0】。
没写类型,类型从哪来
这门语言的 let total = rate * 3 ; 没有写 total 是什么类型,符号表里却登记了 num。这个类型是【0】。
补全:排好序的报告
(每道题开头都有同一段:上一站的 parser(多记了位置)、show(),和错误类 SemError——错误写成一行「原因@行:列」。) 补全 report(errors):按 (行, 列) 排序,
补全:错了记下来继续
(每道题开头都有同一段:上一站的 parser(多记了位置)、show(),和错误类 SemError——错误写成一行「原因@行:列」。) 补全 check_all:对顶层每句 try 一次 chec
补全:登记时查重
(每道题开头都有同一段:上一站的 parser(多记了位置)、show(),和错误类 SemError——错误写成一行「原因@行:列」。) 补全 Scope.declare:当前层已有同名就抛「重复声
补全:用到没登记的名字
(每道题开头都有同一段:上一站的 parser(多记了位置)、show(),和错误类 SemError——错误写成一行「原因@行:列」。) 补全 type_of 的 var 分支:查表拿不到就抛「未定
一次报全部
(每道题开头都有同一段:上一站的 parser(多记了位置)、show(),和错误类 SemError——错误写成一行「原因@行:列」。) 五句话里四处错。check_all 逐句检查、记下错误、继续
两种错各在什么时候查
「未定义」和「重复声明」这两种错误,检查的时机分别是【0】。