##对象 借鉴java的思想,这里对象要有继承和多态的特性,而且只能单继承。这里的类包含了构造函数、属性和方法的定义。例子如下:
class Worker{
void work(){
printS("...");println();
}
}
class Coder : Worker{
long age;
Coder(){
printS("create a coder");
this.age = 30;
}
void work(){
printS("fuck code");println();
}
}
class CivilServant : Worker{
void work(){
printS("!@#$%^&");println();
}
}
long main(char[][] args){
Worker worker = new Worker();
worker.work();
worker = new Coder();
worker.work();
worker = new CivilServant();
worker.work();
return 0;
}
这里就用指针来实现对象,对应ir的i8*型,这个指针指向从GC上申请的一段数据。要实现多态的特性,这段数据就要包含类的信息,所以这段数据的开始是一个指向类信息的指针,跟着是父对象的指针,后面才是各属性的值。由于各项数据最长是64位,所以这里用64位来对齐。对象的内存布局如下面的样子:
方法是动态查找的,通过调用一个函数sysObjectMethod,传入对象本身和方法的名字,得到方法的指针。方法其实就是函数,只是编译时会增加了一个参数,用来保存对象本身,方法里的this关键字就是第一个参数。例如obj.abc(arg1,arg2)
会转换成类似method = sysObjectMethod(obj,"abc"); method(obj,arg1,arg2)
的效果。对象的属性也是动态获得的,它和方法类似,通过调用sysObjectField,传入对象本身和属性名,得到属性的指针。
##数组 数组的语法也类似于java,数组的大小只是个属性,跟类型无关。下标访问从0开始,下标会先与数组大小求余再进行访问来防止越界,如array[-1]是最后一个元素,array[length]是第一个元素array[0]。数组创建后大小固定不能动态增加。数组的类型表示是基本类型后加"[]"结尾,下面是使用数组的例子:
long main(char[][] args){
long size = 100;
long[] array = new long[size];
printL(array.length);println(); // 100
array = {1,2,3,4};
array[1] = 99;
printL(array.length);println(); // 4
printL(array[3]);println(); // 4
printL(array[5]);println(); // 99
char[] str = "ABC\u66ef";
printS(str);println();
}
数组不同对象,没用继承和多态,类型的安全直接在编译时保证。数组也是用指针实现,数据在堆上动态分配,没有保留类型的信息,只保留长度和元素宽度的信息。下标访问是sysArrayElement函数的调用,传入数组和下标,返回元素的指针,函数里面用上面的方法保证防止越界访问。内存布局如下:
这里字符串就是一个字符数组,它和其他数组是一样的,只是在语法上提供了便利而已。
##自动垃圾回收 这里集成Boehm GC来管理内存,因为Boehm GC的保守机制最容易集成。对象和数组的内存都要向BoehmGC申请,这样对象和数组都不用手动释放内存。
##完整代码 https://github.com/linlifengx/step3
##例子 ####linkedlist.sp class List { Node head; Node tail;
void print(){
for(Node node = head;node != null; ){
printL(node.v);println();
node = node.next;
}
}
void add(Node node){
if(head == null) {
head = node;
tail = node;
} else {
tail.next = node;
tail = node;
}
}
}
class Node {
long v;
Node next;
Node(long v){
this.v = v;
}
}
long main(char[][] args){
List list = new List();
for(long i = 0; i < 100; i++){
list.add(new Node(i));
}
list.print(); // 0 - 99
}