关于“静态类型检查”,想必使用C 或Java 的各位应该非常熟悉了。在此过程中将检查表达式的类型,发现类型不正确的操作时就会报错。例如结构体之间无法用+ 进行加法运算,指针和数值之间无法用* 进行乘法运算,将数组传递给参数类型为int 型的函数会出现莫名其妙的结果。在编译过程中检查是否符合这样的限制的处理就是静态类型检查。

在静态类型检查过程中也会实施隐式类型转换。

    /*入口
*
*/
public void check(AST ast) throws SemanticException {
/*
* 第1 个foreach 语句对全局变量的定义进行遍历,
*/
for (DefinedVariable var : ast.definedVariables()) {
checkVariable(var);
}
/*
* 第2 个foreach 语句对函数定义进行遍历,并实施类型检查。
*/
for (DefinedFunction f : ast.definedFunctions()) {
currentFunction = f;
checkReturnType(f);
checkParamTypes(f);
check(f.body());
}
if (errorHandler.errorOccured()) {
throw new SemanticException("compile failed.");
}
}
    /*
* checkVariable 方法在检查变量的类型是否为非void 的同
时,还对变量的初始化表达式进行遍历。
*/
private void checkVariable(DefinedVariable var) {
if (isInvalidVariableType(var.type())) {
error(var.location(), "invalid variable type");
return;
}
if (var.hasInitializer()) {
if (isInvalidLHSType(var.type())) {
error(var.location(), "invalid LHS type: " + var.type());
return;
}
check(var.initializer());
var.setInitializer(implicitCast(var.type(), var.initializer()));
}
}
    /*
* checkReturnType 方法检查函数返回值的类型是否为非结
构体、联合体或数组。这里再重复一下,Ocelot中函数不能返回结构体或联合体。
*/
private void checkReturnType(DefinedFunction f) {
if (isInvalidReturnType(f.returnType())) {
error(f.location(), "returns invalid type: " + f.returnType());
}
}
    /*
* checkParamTypes 方法检查函数形参的类型是否为非结构体、联合体或void。因为Ocelot
中函数参数的类型不能是结构体或联合体。
*/
private void checkParamTypes(DefinedFunction f) {
for (Parameter param : f.parameters()) {
if (isInvalidParameterType(param.type())) {
error(param.location(),
"invalid parameter type: " + param.type());
}
}
}
    /*
* check 是遍历参数节点的方法。各节点类会重写该函数,通过调用check(f.
body()) 对函数体进行遍历。
*/
private void check(StmtNode node) {
visitStmt(node);
}

最新文章

  1. 【干货分享】流程DEMO-出差申请单
  2. activity跳转到新的activity后清除之前的activity
  3. java自带BASE64工具进行图片和字符串转换
  4. 解决方案: scp/ssh 的登陆提示很慢 (Linux)
  5. winform错误提示 :窗口类名无效(Window class name is not valid)
  6. Scala语法笔记
  7. log4j.properties配置文件
  8. QQWry.dat 数据写入
  9. struts启动报错Javassist library is missing
  10. Fetcher类的工作流程
  11. mfc窗口,父窗口parentwindow,所有者窗口ownerwindow 区别
  12. VirtualBox 复制vdi文件和修改vdi的uuid
  13. 项目实战6—Mysql实现企业级日志管理、备份与恢复实战
  14. Swift中关于任意类型的数组
  15. css3之border-radius理解
  16. [linux-脚本]shebang(shabang #!)
  17. PL/SQL Developper导入导出数据库的方法及说明
  18. Pandas 基础(6) - 用 replace() 函数处理不合理数据
  19. ES6之导入模块时的内存共享
  20. QT TCP网络编程

热门文章

  1. 理解CSS外边距margin
  2. .NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法
  3. ABP教程-打造一个《电话簿项目》-目录-MPA版本-基于ABP1.13版本
  4. ASP.NET MVC5+EF6+EasyUI 后台管理系统(76)-微信公众平台开发-网页授权
  5. Linux学习之文件操作
  6. BPM配置故事之案例10-获取外部数据
  7. 怎样在Dos里切换盘符
  8. 2DToolkit官方文档中文版打地鼠教程(一):初始设置
  9. ASP.NET Core MVC 配置全局路由前缀
  10. mono for android学习过程系列教程(1)