Excel 名称框概述-英雄云拓展知识分享
128
2023-11-07
【摘要】 本书摘自《自己动手写 Python 虚拟机》一书中第7章,第1节,海纳编著。
7.1.2 操作列表
列表对象上定义了很多操作,最典型的就是查找、修改、增加和删除。这一小节 分别来研究一下如何实现这些功能。
1. 取下标
列表的取下标非常类似于 C 语言中的数组,它是通过中括号语法进行索引的, 代码如下:
使用中括号和下标的形式取得列表中的指定元素,这种语法我们第一次遇到。 与以前相同,通过 show_file 工具查看一下这种数组下标的语法会被翻译成怎样的 字节码,如下所示:
第4行,赫然又是一个新的字节码:BINARY_SUBSCR 。 在这个字节码之前,已 经把列表lst 和整数0加载到了栈顶。这个字节码的意义是取出列表 Ist 的 第 0 项 , 并将结果送入栈顶,它是 subscript 的缩写。
实际上,除了列表有取下标操作以外,string 对象也支持取下标操作,未来还会 遇到自定义类型中也可以支持取下标的操作。因此,这就有必要在 HiObject 对象体 系中引入取下标操作了。先来定义 HiObject 中的 subscr 方法,然后再扩展到 HiList 和 HiString 类中去,代码如下:
在 Object 类中,subscr 的真正实现转移到它的 Klass 中去了。在 Klass 中,sub- scr 会是一个虚函数,通过多态机制保证了不同类型的对象可以调用相应的 subscr 方法。例如,list 类型的实现代码如下:
1 //object/klass.hpp
2 class Klass{
3 private:
4
5 public:
6
7 virtual HiObject *subscr (HiObject*x,HiObject*y)(return 0;)
8 };
9
10 //object/hiList.hpp
11 class ListKlass:public Klass{
12 private:
13
14 public:
15
16 virtual HiObject*subscr(HiCbject*x,HiObject*y);
17 };
18
19 //object/hiList.cpp
20 HiObject*ListKlass::subscr(HiObject*x,HiObject*y){
21 assert(x&&x>klass()==(Klass*)this);
22 assert(y &&y>klass()==(Klass*)IntegerKlass::get_instance());
23
24 HiList *lx =(HiList*)x;
25 HiInteger*iy =(HiInteger*)y;
26
27 return lx->inner_list()>get(iy->value());
28
在上述代码的第22行,检查了第二个参数的类型,也就是下标,在 list 中,它必 须是整型。如果不是整型的话,虚拟机就会直接退出。实际上,Python 的行为是会 抛出异常,到目前为止,异常还没有完整地实现,所以先采用“报错退出”这种处理方 式。除此之外其他代码就比较简单了,不多做解释。
最后,还要在Interpreter 中添加 BINARY_SUBSCR 的实现。只需要将栈顶的码清单7.2所示。
void Interpreter::run(CodeObject*codes)(
2 _frame =new FrameObject(codes);
3 while(_frame->has_more_codes())(
4 unsigned char op_code =_frame>get_op_code();
5
6 FunctionObject*fo;
7
8 switch(op_code)
9 · ·
10 case ByteCode::BINARY_SUBSCR:
11 v=POP();
12 W =POP();
13 PUSH(w->subscr(v));
14 break;
15
16
17
18
至此,本小节开始的那个测试就可以正确执行了。
在完成了list 的 subscr 操作之后,为string 添加相应的操作就很简单了。整个 流程的框架已经搭起来了,只需要在StringKlass 中添加 subscr 即可,代码如下:
string 的取下标操作与列表的取下标操作几乎一样,唯一不同的是,subscr 方法 的返回值,在list 中直接从列表中读出就可以了,在 StringKlass 中则必须先创建一 个新的 string 对象。我们使用了带有长度参数的构造方法来创建这个字符串对象。 这个构造方法的具体实现,请读者参考第五章字符串的实现部分。
2. 查 找
在 Python 中,查找列表是否包含了某个对象,通常使用in 关键字使用in 关键字可以判断“hello” 是否在列表中。和以前一样,使用 show_file 工 具查看这个例子的字节码:
注意第4行的字节码:COMPARE_OP 。 这个字节码我们已经很熟悉了,在第四 章已经为这个字节码实现了是否相等和比较大小等操作。我们知道,这个字节码是 带有参数的,它的参数的意义是比较操作符的类型,比如4代表大于,0代表小于,2 代表等于。在这一节,COMPARE_OP 带了一个新的参数:6,括号里的注释也标明 了这个参数代表in。首先,要先把in操作添加到COMPARE
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们 18664393530@aliyun.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~