3.2. 整数

凹语言目前支持以下几种整数类型:

  • u8 :无符号8位整数;
  • u16 :无符号16位整数;
  • i32 :有符号32位整数;
  • u32 :无符号32位整数;
  • i64 :有符号64位整数;
  • u64 :无符号64位整数;
  • int :不定宽有符号整数;
  • uint :不定宽无符号整数;
  • bool:布尔型。

其中:

  • intuint 为不定宽整数,它们的宽度是由目标平台决定的。之所以有不定宽整数类型,是因为目标平台的寻址范围可能不同,内建函数 len 等涉及存储范围的操作,需要统一的数据类型以保持代码在不同的目标平台上能正常编译,并充分利用平台寻址范围;
  • bool 型实际内存布局为 u8,合法取值的字面值为 truefalse,对应内存数值为 1 和 0。

当前凹语言的主要目标平台为 wasm32,在该平台下,不定宽整数的位宽为32位,既4字节。

除布尔型外的整数支持以下单目运算:

  • ^ :按位取反
  • - :取算术负值(既用0减去操作数)

例如:

    i: u8 = 9
    println(^i) // 246
    println(-i) // 247

    j: i32 = 9
    println(^i) // -10
    println(-i) // -9

除布尔型外的整数支持以下双目算术运算:

  • +:求和,两个操作数类型必须一致,返回值类型与操作数一致;
  • -:求差,两个操作数类型必须一致,返回值类型与操作数一致;
  • *:求积,两个操作数类型必须一致,返回值类型与操作数一致;
  • /:求商,两个操作数类型必须一致,返回值类型与操作数一致;
  • %:求余,两个操作数类型必须一致,返回值类型与操作数一致。

例如:

    i, j: u8 = 9, 250
    println(i + j) // 3
    println(i - j) // 15
    println(i * j) // 202
    println(j / i) // 27
    println(j % i) // 7

除布尔型的整数支持以下双目位运算:

  • &:按位取与,两个操作数类型必须一致,返回值类型与操作数一致;
  • |:按位取或,两个操作数类型必须一致,返回值类型与操作数一致;
  • ^:按位取异或,两个操作数类型必须一致,返回值类型与操作数一致;
  • &^:按位清空,两个操作数类型必须一致,返回值类型与操作数一致。对 z = x &^ y,设 xnynzn 分别为 xyz 的第n位,则当 yn 为1时 zn 为0,否则 zn 等于 xn。该运算等价于 z = x & (^y)
  • <<:左移,对 z = x << yz 的类型与 x 一致,y 必须为大于0的整数,移位时低位补0;
  • >>:右移,对 z = x >> yz 的类型与 x 一致,y 必须为大于0的整数,移位时高位补0。

例如:

    i, j: u16 = 343, 47831
    println(i & j)  // 87
    println(i | j)  // 48087
    println(i ^ j)  // 48000
    println(i &^ j) // 256
    println(i << 5) // 10976
    println(j >> 5) // 1494

加、减、乘、左移等运算的结果可能超过操作数的表达范围,此时将截取低位部分作为结果。

除布尔型的整数支持以下比较运算(双目):

  • ==:相等。操作数类型必须一致,返回值为 bool 型,符合判断条件返回 true,否则返回 false,下同;
  • !=:不等;
  • >:大于;
  • >=:大等于;
  • <:小于;
  • <=:小等于。

如果参与比较的两个操作数中有一个为常数,则常数应位于比较运算符的右侧。

布尔型支持以下单目运算:

  • !:取反,操作数为 false 返回 true,否则返回 false

实际上除了通过2.4节介绍的常量声明的具名常量外,代码中出现的很多字面值,也是常量,比如:

    i := 13

代码中的 13 就是一个无类型的整数常量。使用无类型整数常量进行变量快捷声明时,变量的类型为不定宽有符号整数(既 int),上述代码等价于:

    i: int
    i = 13

将整数常量赋值给整数变量时,会在编译时执行类型和范围检查,自动匹配至变量类型——向无符号整数赋予负数常量、或常量值超过被赋值变量宽度等行为将被判定为非法。

整数拥有所有的二元运算符,二元运算符的优先级按以下顺序递减(同一行内的优先级相同,从左至右执行):

*      /      %      <<       >>     &       &^
+      -      |      ^
==     !=     <      <=       >      >=
&&
||