函数和全局变量

函数

function_param -> 'const'? IDENT ':' ty
function_param_list -> function_param (',' function_param)*
function -> 'fn' IDENT '(' function_param_list? ')' '->' ty block_stmt
//               ^~~~      ^~~~~~~~~~~~~~~~~~~~          ^~ ^~~~~~~~~~
//               |              |                        |  |
//               function_name  param_list     return_type  function_body

与 miniplc0 不同,c0 中存在函数。

c0 中一个函数的定义由 函数名参数列表返回类型函数体 组成。

函数有以下语义约束:

  • 函数的名称 function_name 不能重复,也不能和全局变量重复。
  • 函数的参数声明 param_list 与 含有初始化表达式的变量声明 有相同的语义约束。
  • 函数体、函数的参数声明 在同一个作用域(函数作用域)中,是全局作用域的子作用域。

另外再提醒一下,返回值类型 return_type 即使为 void 也不能省略。

函数体的组成单位是语句,见 语句页面

全局变量

全局变量的声明与局部变量相同,都是使用 声明语句 进行声明。全局变量的定义方式和约束与局部变量相同。全局变量所在作用域是全局,因此有可能被函数内定义的局部变量覆盖。

程序结构

program -> decl_stmt* function*

一个 c0 的程序中可以存在多个 变量声明,后接多个 函数声明

语义约束:

  • 一个合法的 c0 程序必须存在一个名为 main 的函数作为程序入口,否则应视为编译错误;
  • 一个函数或变量只能在它的定义中及之后的位置被引用,换句话说就是不存在先使用后定义的情况。

注:扩展 c0 中允许变量声明和函数声明混搭,但仍要遵循以上规定。