Redy基本数据类型--整数
(一)简介
在每种编程语言的基本数据类型里面,整数肯定是少不了。Redy同样,支持整数,不过不像c语言,整数有多种类型。在Redy里面整数只有两种,一种为普通整数,一种为长整数。这一章讲述的是整数,长整数会在后面的章节讲到。
普通整数简称整数,一种与机器相关的数据类型,在32位机长,表示范围为:-231~231-1。在64位机器上,表示范围为:-263~263-1。
(二)整数的数据结构
整数的源代码位于src/rtype/中,有两个文件:bt_int.h , bt_int.c 。
(1)结构体定义
代码3.2.1
/* prefix bt short for base type*/ struct bt_int { struct robject i_base; /*继承robject*/ int i_value; /*值*/ }; typedef struct bt_int BtInt; |
为了后面方便表示,用typedef对结构体重定义为BtInt
(2)成员说明
-
i_base表于继承结构体robject,这种使用方法在上一章有介绍
-
i_value用于保存整数的数值
(3)重载运算符
在前面Robject那一章讲到过,如果某种数据类型支持指定的运算符,那么该数据类型就必须实现struct rexpr_ops 中相对应的成员函数,例如,下面一段代码;
代码3.2.2
a=1 #变量a引用整数类型 c=3 #变量c引用整数类型 d=a+c #d=a->r_expr_ops->ro_add(a,c) e=-a #e=a->r_expr_ops->ro_negative(a) print a #调用 a->r_expr_ops->ro_print(a) |
-
当redy解析器运行到第3条语句(d=a+c)时,判断出这是二元运算符'+',就会在变量a所引用的对象成员r_expr_op中查找成员函数ro_add,如果该成员函数没有实现,则解析器判定整数类型不支持二元运算符'+',然后报错。如果实现了,则调用a->r_expr_ops->ro_add(a,c),并把返回值赋值给变量d。
-
当解析器运行到第4行语句(e=-a),解析器判断出这是一元运算符'-'后,同样在变量a所引用的对象成员r_expr_op中查找成员函数ro_negative,如果没有实现,则报错;如果实现,则调用a->r_expr->ops->ro_negative(a),并把返回值赋值给e。
-
当解析器运行到第5行语句(print a),这是一条输出语句,这时查找的成员函数为ro_print,如果没有实现,则调用系统默认的输出方法。如果实现则调用a->r_expr_ops->ro_print(a)。
综上所述,如果上面那一小段代码想要正确的运行,那么就需要结构体rexpr_ops中三个成员函数:ro_add, ro_negative ,ro_print。
(a)一元运算符
整数总共实现了一元运算符有'+' , '- ' , '~' 。其中:
-
'+'表示正号,返回值为自身。
-
'-'表示负号,返回值为自身的相返数。
-
'~'表示取反,返回值为自身取反后的值
(b)二元运算符
对于整数来说,所有二元运算符都支持,具体如下表:
运算符\类型 | 整数 | 长整数 | 浮点数 | 字符串 | 数组 |
ro_mul(*) | 整数 | 长整数 | 浮点数 |
|
|
ro_div(/) | 整数 | 长整数 | 浮点数 |
|
|
ro_mod(%) | 整数 | 长整数 | 浮点数 |
|
|
ro_plus(+) | 整数 | 长整数 | 浮点数 |
|
|
ro_minus(-) | 整数 | 长整数 | 浮点数 |
|
|
ro_lshift(<<) | 整数 | 长整数 |
|
|
|
ro_rshift(>>) | 整数 | 长整数 |
|
|
|
ro_and(&) | 整数 | 长整数 |
|
|
|
ro_and(|) | 整数 | 长整数 |
|
|
|
ro_and(^) | 整数 | 长整数 |
|
|
|
ro_cmp | 整数 | 整数 |
|
|
|
说明:例如在第一行ro_mul中,表示:整数*整数=整数;整数*浮点数=浮点数;整数*长整数=长整数;但是整数不能和字符串还有数组相乘。
如下面的代码:
代码3.2.3
a=1 b=a*3 #合法,运行后b引用类型为整数 b=a*3L #合法,运行后b引用类型为长整数 b=a*3.01 #合法,运行后b引用类型为浮点数 b=a*"hello" #非法,解析器会报错,整数不支持与字符串相乘 b=a*[3,4] #非法,解析器会报错,整数不支持与数组相乘 |
在实现ro_mul时,代码如下:
代码3.2.4
static Robject* bi_mul(Robject* left,Robject* right) { int type=rt_type(right); /*获取类型*/ if(type==RT_INT) /*right为整数*/ { /*类型转换:Robject转换为BtInt*/ int value=R_TO_I(left)->i_value*R_TO_I(right)->i_value; BtInt* ret=bt_int_create(value); return I_TO_R(ret); } else if(type==RT_FLOAT) /*right为浮点数*/ { ..... /*做整数与浮点数的乘法*/ do_int_mul_float(left,right); ..... } else if(type==RT_LONG) /*right为长整数*/ { .... /*做整数与长整数的乘法*/ do_int_mul_long(left,right); .... } else { ...... /*报错*/ do_error_report(); ..... } ..... }; |
上面代码只是用于大概说明,具体找码可以在bt_int.c中找到
(c)逻辑运算
在结构体rexpr_ops中,ro_bool用于逻辑运算。对于整数如果整数的值不为0,则返回值为true,为0则返回为false。
(d)其它
输出语句ro_print。
(4)结构体rexpr_ops
代码3.2.5
static struct rexpr_ops bt_int_expr_ops= { /* unary operator + - */ .ro_negative=bi_negative, .ro_positive=bi_positive, /* arithmetic * / % */ .ro_mul=bi_mul, .ro_div=bi_div, .ro_mod=bi_mod, /* arithmetic + - */ .ro_plus=bi_plus, .ro_minus=bi_minus, /* bit_operator << >>*/ .ro_lshift=bi_lshift, .ro_rshift=bi_rshift, /* simple compare operator used for * < <= == != >= > */ .ro_cmp=bi_cmp, /* bit_operator & | ^ ~ */ .ro_bit_and=bi_and, .ro_bit_or=bi_or, .ro_bit_xor=bi_xor, .ro_bit_negated=bi_negated, /* logic operator and or not */ .ro_bool=bi_booleaned, /*print */ .ro_print=bi_print, };
|
在上面定义变量bt_int_expr_ops时,使用了gcc的扩展语法,如果某一个成员并未在上面出现,则表示该成员的值为0。
(三)整数的接口
(1)构造函数
代码3.3.1
BtInt* bt_int_create(int value); BtInt* bt_int_from_str(char* str); BtInt* bt_int_malloc(); |
其中:
(1)bt_int_from_str表示从字符串中生成整数的数据结构,字符串表示的数可以为:
-
二进制,要求以'0b'或者是'0B'开头,后接一个或多个字符,但后接字符只能为'0'或'1'。如 '0b010101110' , '0B10101'。
-
八进制,要求以'0'或者'0o'或者'0O'开头,后接一个或多个字符,但后接字符只能为'0'~'7'。如'045712' ,'0o145'。
-
十进制,要求以字符'1'-'9'其中之一开头,后接零个或多个字符,但后接字符只能为'0'~'9',如'478554'。
-
十六进制,要求以字符'0x'或者'0X'开头,后接一个或多个字符,但后接字符只能为'0'~'9'或者为'a'~'f'或者'A'~'F',如'0xaf233322' ,'0xAf2ffabc'。
-
字符串'0',表示数值为0。
-
其它,返回值为NULL
(2)bt_int_creat表示从一个int型生成BtInt。
(3)bt_int_malloc创建一个BtInt,其数值为0,其代码如下:
代码3.3.2
inline BtInt* bt_int_malloc() { BtInt* ret=(BtInt*)malloc(sizeof(*ret)); /*分配内存*/ ret->i_value=0; Robject* base=&ret->i_base; /*设置父类属性*/ base->r_name="Integer"; /*型数类型的名称为"integer"*/ base->r_expr_ops=&bt_int_expr_ops; /*支持的运算符类型*/ base->r_type=RT_INT; /*用于表示该对象为整型*/ base->r_ops=&bt_int_ops; return ret; } |
(2)释放函数
代码3.3.3
void bt_int_free(BtInt*); |
(3)属性设置与获取
代码3.3.4
/*value getter and setter */ static inline int bt_int_get(BtInt* bti) { return bti->i_value; } static inline void bt_int_set(BtInt* bti,int value) { bti->i_value=value; } |