用LLVM来开发自己的编译器(三)

##对象 借鉴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
}
展开阅读全文

© 著作权归作者所有

举报
(0)

相关推荐

  • Java 基础知识

    Java 基础知识

  • Java日常开发的21个坑,你踩过几个?

    前言 最近看了极客时间的<Java业务开发常见错误100例>,再结合平时踩的一些代码坑,写写总结,希望对大家有帮助,感谢阅读~ 1. 六类典型空指针问题 包装类型的空指针问题 级联调用的空 ...

  • 科技·Kotlin从入门到精通,基本数据类型

    Kotlin的基本数值类型包括Byte.Short.Int.Long.Float.Double等.不同于Java的是,字符不属于数值类型,是一个独立的数据类型.类型位宽度Double64Float32 ...

  • Web 开发必须掌握的三个技术:Token、Cookie、Session

    WEB前端开发社区 1周前 在Web应用中,HTTP请求是无状态的.即:用户第一次发起请求,与服务器建立连接并登录成功后,为了避免每次打开一个页面都需要登录一下,就出现了cookie,Session. ...

  • 座椅舒适性开发流程系列(三)

    本平台声明 1.文中材料仅供学习交流,不得用于任何商业目的. 2.文中部分数据和文字引自媒体.公开文献及作者在线投稿等方式,版权属原作者.如有涉及内容.版权等问题.请尽快联系我们,我们会及时处理.

  • 汽车零件尺寸工程同步开发技术系列(三)

    汽车零件尺寸工程同步开发技术系列(三)

  • 区块链研究实验室 | 使用Solidity开发智能合约(三)

    原创 链三丰 区块链研究实验室 昨天 前两篇文章里,着重介绍了一下,如何设置Solidity开发环境,编写智能合约的第一行代码:以及Solidity中的变量及其类型,传送门如下: 区块链研究实验室 | ...

  • 薛永武:大学生自我开发的艺术(三)

    开启人才教育的新视野 点击题目下方蓝字关注 薛说人才 九.激发自己的成才需要 大学生要自我开发,还必须有成才的需要,也就是自我实现的需要. 马斯洛曾把人的需要分为五个层次,即生理需要.安全需要.爱的需 ...

  • 速画微课开发与制作(三)

    好人教育 脚本编写之前,要首先考虑布局. 布局指全局布局,场景布局.布局的原则是遵守知识点之间的逻辑关系和层次结构. 组成画面的元素是素材对象,包括文字和图片,如果是中文字,还要把文字制作成图片,因为 ...

  • 冷门景点黄龙山游记,一脚踏三省,无需门票待开发,要去的赶紧了

    黄龙山是湖北.湖南.江西三省交界的地方,以三省的交界点为中心,站在界碑处,可体验一脚踏三省的感觉,这里原始自然风貌保存良好,古朴素雅,风情浓郁.我一共去过黄龙山三次,每一次去都能看到不同的风景,也一直 ...

  • “物联网开发实战”学习笔记-(三)根据光线调节亮度

    让智能电灯可以基于环境的明暗来自动地打开和关闭.可以分为两个阶段,第一阶段是打造传感器设备来感知光照的强弱,判断出环境的明暗状态,第二阶段是创建一个场景联动,根据传感器的数值来控制智能电灯的状态. 1 ...

  • 旅游开发创新策划的神功三式

    现代社会无论想成何事业,必言创新,这天下的武功,早已唯创新不破,旅游产品的策划规划更是如此. 那些处于相对劣势的旅游资源,常常难以突破强势旅游资源的影响覆盖,如何找到适合自己发展的路径,创新产品十分重 ...