列表&字典解析式

python的一个特色就是提供列表/字典/集合等数据结构的解析式,比如:
[i * i for i in xrange(100) if i % 2 == 0]
表示一个包含0到99的所有偶数的平方的列表


larva也实现了这种语法,不过稍微有些区别,其实要实现一模一样的也可以,不过最后没这么做


首先是没做多重嵌套的for和if,python中没有限制列表解析式的for和if的嵌套,larva限制了只能有一个for,或一个for...if,我不想把这个语法搞太复杂,其实大部分时候都是只有一个for的,多重嵌套用的地方很少


其次是for语句的左值,larva只允许变量名,或变量名组成的解包赋值(可以嵌套解包),且这些变量名所在命名空间是独立在这个解析式里面的,比如python中:
a = [i for i in l]
print i
这是可以的,因为i被认为是在a所在的命名空间,会打印它在l最后迭代的值,但是这在larva中是不允许的,列表解析式的左值被认为是临时变量,不会和解析式本身所在的命名空间冲突,其实另一个原因是编译器和代码转换实现的便利性,如果解析式中的左值不单独一个命名空间,则当编译器搜索一个函数的局部变量时,需要扫描所有表达式,比较麻烦


在代码转换实现上,如果独立一个命名空间,解析式就可以简单地转成一个函数。考虑一个解析式:
[A for B in C if D]
这个解析式的实现是:
1 计算C
2 建立一个空列表l
3 对C的结果做迭代,对每个元素,赋值给B,计算D,若D成立,则计算A,结果增加到l中
4 返回l


如果把这个实现写为函数f,则可以将C的值直接传给f,因为只需要它的值,但是A和D需要实现在f内部,而B则可在编译阶段解析好,实现为函数的局部变量
计算A和D的时候,可能只需要B中的变量,也可能要引用解析式本身所在的环境,这些环境数据分情况讨论:
1 全局变量,只需要把f写在当前模块即可
2 若解析式出现在方法中,可能引用当前对象,比如this和super关键字,跟1一样,这时候只需要将f写在类内部即可
3 局部变量,需要传入,因为目标语言可能不支持嵌套函数


一个例子(larva的方法中对于当前对象的属性引用可以省略this,即下面的“.a”相当于“this.a”):
g = 123
m = []
class A:
    func __init__():
        .a = "hello"
    func f():
        for i in range(10):
            l = [.a + str(g) + j for j, k in m if i]
            ... //deal with l
这个例子中对l赋值这一项会被转换为类似如下java代码:
l = build_list_compr_0001(m, i);
即局部变量i这时候的值会被传入构造列表解析式的函数,函数的实现类似:
LarObj build_list_compr_0001(LarObj obj, LarObj i)
{
    LarObj j, k;
    LarObj l = new LarObjList();
    for (LarObj iter = obj.iterator(); iter.has_next();)
    {
        LarObj[] unpack_0001 = unpack_seq(iter.next(), 2);
        j = unpack_0001[0];
        k = unpack_0001[1]; //解包赋值实现参考前面的日志
        if (i.op_bool())
        {
            l.add(this.a.op_add(str(g)).op_add(j));
        }
    }
    return l;
}

这个函数实现在class A对应的输出代码中,所以能直接访问this和g,如上所述,i是通过参数传入,而j是临时变量,不会影响调用者的命名空间
当然这个例子并非实际的转换结果,比如代码中变量命名等,larva最终的输出代码做了更严格的规范,可以用编译器实际测试一下


字典解析的实现也是类似的,就不赘述了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值