在arcmap中添加脚本语言——python 用Rust写脚本语言(一):一切存在皆对象
目录
代码仓库:whoiscc/shattuck。在我写「欢迎围观」之前都不会有什么观赏价值,纯粹是为了证明我并不是在纸上谈兵。
这些年来看过、跟着做过的「3分钟发明一门编程语言!」的教程数不胜数。它们中的绝大多数都有一个共同点:从前往后。最开始几乎一定是一段展示最终效果的代码块;接下来是词法分析、语法分析,然后对语法树进行eval,全文终。你自然可以嘲笑我看的教程太不入流,但我还是想为这些「不入流」的教程再添上这么一篇。这篇教程(更准确的说,日记)的目的不只是向读者展示编写一个脚本语言的解释器需要哪些部件,而且还希望将更多的精力投入到设计语言特性的方面。甚至可以说,代码并不是这个项目的主体在arcmap中添加脚本语言——python,而仅仅是验证思路的工具。
综上,我决定以如下的方式开展这个项目:
如果最后没有完成,那么也一定要弄清楚困难在哪里,算是可以加深对Python语言设计的理解的一种方式。
整个项目计划用Rust完成。这也是这个项目隐藏在表面之下的真实目的:学习和巩固Rust。如果这个目的提前达到了那么本项目即刻宣告烂尾(。如果Rust真的可以作为C/C++的无缝替换者的话,作为脚本语言的运行时应该属于它可以优雅完成的任务,这个项目算是一个粗浅的验证。
作为废话的最后一部分,shattuck的名字来自于我目前所住的公寓面向的大街:
还有最后的两周了。再见,Berkeley。
在Python关于其内部实现的文档中,写在最开头的话包括了「一切存在都是对象」这一句。这里的「对象」和面向对象编程的对象没有什么关系,仅仅是脚本语言用来管理内存和功能的最小单位。在Shattuck中,用户可以通过代码以及native拓展创建的一切也都是对象。这个对象不可以是struct,因为它可能包含任何东西,代表整型的对象需要包含i64,代表文件的对象需要包含文件描述符,等等。因此在Rust中它是一个trait。
这个trait具有哪些方法呢?思来想去,我觉得最重要的,还是「属性」:
pub trait Object: Debug {
fn get_property(&self, key: &String) -> Option<Addr>;
fn set_property(&mut self, key: &String, new_prop: Addr);
}
比如说一个实现了Objecttrait的整型对象struct辅助论坛,Shattuck无法直接看到和接触到它包含有i64的字段,但是可以通过访问它的属性,比如string,来得到这个整数的格式化字符串。当然对于这个字符串对象我们还是不能接触到它内部包含的String 类型的Rust字段,但是也许可以通过某个属性把它打印在屏幕上。目前我们暂时要求实现Object的类型一定要实现Debug,就是因为在目前欠缺基础设施的情况下想要获取一个对象的内部信息实在太困难了,所以通过显示出来的方式对付一下。
那么方法呢?我要怎么调用一个对象上绑定的方法呢?
方法本身可以作为对象的一个属性存在,这样做的好处就是我们可以随意的将一个对象的方法绑定在任意的名字上。那么接下来,如何允许方法被调用呢?我在下一篇文章之前会解决好这个问题。
获取和设置属性并没有直接返回和传入类似于Box类型的值,而是通过一个叫做Addr的类型。这在接下来讲Memorystruct的时候会进行说明。尝试获取一个不存在的属性会返回None。在我看来这是这个方法唯一失败的原因(并且设置属性的方法永远都不应该失败),因此并不需要引入Result类型的返回值以及对应的Error类型,这太复杂了。