read the doc and format skeleton code
This commit is contained in:
parent
040115e812
commit
b2142969f8
28
CS143体验报告.md
28
CS143体验报告.md
@ -234,3 +234,31 @@ PA 2-5 正式写编译器。PA2 写词法分析器,首先读一遍 README 和
|
|||||||
- 返回 Object 的情况:objectid 未定义、new 未定义类、函数调用中无法确定被调用函数的情况(类未定义、函数未定义、函数参数个数不对)、loop 返回值。
|
- 返回 Object 的情况:objectid 未定义、new 未定义类、函数调用中无法确定被调用函数的情况(类未定义、函数未定义、函数参数个数不对)、loop 返回值。
|
||||||
|
|
||||||
剩下的基本上能从手册的12章中比较清晰的看出来。
|
剩下的基本上能从手册的12章中比较清晰的看出来。
|
||||||
|
|
||||||
|
|
||||||
|
### PA5
|
||||||
|
|
||||||
|
#### 读文档
|
||||||
|
|
||||||
|
最后一个 PA,那必然是要把剩下来的文档全部读完。需要预先看一遍带是 `cool-tour.pdf` 的第7章 Runtime System 和 PA5 handout,至于 `cool-manual.pdf` 的第13章语义部分倒是可以一边实现一边看。
|
||||||
|
|
||||||
|
先看 handout:
|
||||||
|
- 代码量巨大无比,竟然是 PA4 的2倍(悲
|
||||||
|
- 文件简述:`cgen.{cc|hh}` 大部分需要写的代码,和 PA4 类似的结构,从 AST 的根节点开始进行 `cgen`;`cool-tree.h` 和 PA4 类似;`cgen_supp.cc` 定义辅助函数;`emit.h` 里面有一些 MIPS 汇编和符号宏定义;剩下的都是老熟人了。
|
||||||
|
- 主要任务:
|
||||||
|
- 生成全局常量(prototype objects)
|
||||||
|
- 生成全局表,`class_nameTab` `class_objTab` 还有方法调用表
|
||||||
|
- 生成每个类的初始化代码
|
||||||
|
- 生成方法定义
|
||||||
|
推荐的实现方法还是分两部分,先生成对象布局,然后第二遍在生成每个表达式的代码。
|
||||||
|
- 提醒注意:这次没有必要去“逆向”参考编译器了,因为它实现了一些高级功能比如寄存器分配优化,这个 PA5 并不要求这个。
|
||||||
|
- 运行时错误处理:manual 规定了6种运行时错误,生成的代码需要检测三种:(static) dispatch on void, case on void, missing branch;除零可以交给模拟器;剩下两种由 Runtime 处理。
|
||||||
|
- GC:有一个3个命令行开关控制垃圾回收系统相关的功能。默认情况下不打开 `-g` 开关,此时不启用 GC,也就是说这是一个选做功能;`-t` 迫使 GC 系统在每次分配对象的时候进行回收;`-T` 的功能交给实现,可能会用来实现一些其他的运行时检查。实现 GC 功能的时候,需要认真阅读 Runtime 手册相关内容。这里可以去看看 CS143 课程网站上的那个单独的 `cool-runtime.pdf`,似乎写的更加详细一些。
|
||||||
|
- 测试工具:和 PA4 类似,提供了一个 `-c` 选项来设置全局变量 `cgen_debug`。同时提供了一个第三方实现的 `Coolaid` 工具对生成的 MIPS 汇编进行一些检查,说不定会有帮助。最后关于 `Spim` 的 warning 可能会有用。
|
||||||
|
|
||||||
|
然后看看 Runtime System:
|
||||||
|
- 首先是对象布局:GC Tag 设为-1;Object Size 也得填上;dispatch pointer 因为不会被 runtime 用到,所以需要自己设计 dispatch 表;对于属性,`Int` 只有一个32位整数、`Bool` 也是如此、`String` 有一个32位的长度+后面全部是 ASCII 字节(最后需要 word 对齐),然后还有空指针 void。
|
||||||
|
- 然后是一个叫原型对象(Prototype Object)的东西:COOL 里面新建对象的方法是使用 `Object.copy()`,因此我们需要生成这些供其复制的东西,也就是 prototype object。生成的时候需要正确设置前面的头部,对于属性,三个基本类型有自己的规定,其余类型的属性随意设置。
|
||||||
|
- 栈和寄存器约定:方法调用参数放在栈上、从左到右依次压栈,`a0` 寄存器里面放 `self` 对象指针。指定了一组 Scratch registers 供 runtime routine 存放临时数据,因此需要调用者保存;还有堆指针和堆界限两个寄存器,完全由 runtime 控制。其他的都可以用。
|
||||||
|
- Label:生成的代码需要和 runtime 一起变成最后执行的机器码,因此有一些 label 是指定的,就类似于接口一样的东西。有些 label 是 runtime 提供给我们使用的,也有一些需要我们生成供 runtime 使用。有一句话 `There is no need for code that initializes an object of class Bool if the generated code contains definitions of both Bool objects in the static data area.` 没看懂
|
||||||
|
- 执行初始化:需要生成一些代码来调用 main 方法。首先通过 Main prototype 生成一个 Main 类的对象并用 `Main_init` 初始化,该初始化方法依次执行 Main 的基类的初始化最后初始化 Main;然后调用 `Main.main`,在 `a0` 里面放上 `Main` 的指针并设置 `ra`;执行结束后,`Main.main` 返回,这里打印出提示信息并终止执行。
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "cgen.h"
|
#include "cgen.h"
|
||||||
#include "cgen_gc.h"
|
#include "cgen_gc.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
extern void emit_string_constant(ostream &str, char *s);
|
extern void emit_string_constant(ostream &str, char *s);
|
||||||
extern int cgen_debug;
|
extern int cgen_debug;
|
||||||
@ -43,38 +44,13 @@ extern int cgen_debug;
|
|||||||
// as fixed names used by the runtime system.
|
// as fixed names used by the runtime system.
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
Symbol
|
Symbol arg, arg2, Bool, concat, cool_abort, copy, Int, in_int, in_string, IO,
|
||||||
arg,
|
length, Main, main_meth, No_class, No_type, Object, out_int, out_string,
|
||||||
arg2,
|
prim_slot, self, SELF_TYPE, Str, str_field, substr, type_name, val;
|
||||||
Bool,
|
|
||||||
concat,
|
|
||||||
cool_abort,
|
|
||||||
copy,
|
|
||||||
Int,
|
|
||||||
in_int,
|
|
||||||
in_string,
|
|
||||||
IO,
|
|
||||||
length,
|
|
||||||
Main,
|
|
||||||
main_meth,
|
|
||||||
No_class,
|
|
||||||
No_type,
|
|
||||||
Object,
|
|
||||||
out_int,
|
|
||||||
out_string,
|
|
||||||
prim_slot,
|
|
||||||
self,
|
|
||||||
SELF_TYPE,
|
|
||||||
Str,
|
|
||||||
str_field,
|
|
||||||
substr,
|
|
||||||
type_name,
|
|
||||||
val;
|
|
||||||
//
|
//
|
||||||
// Initializing the predefined symbols.
|
// Initializing the predefined symbols.
|
||||||
//
|
//
|
||||||
static void initialize_constants(void)
|
static void initialize_constants(void) {
|
||||||
{
|
|
||||||
arg = idtable.add_string("arg");
|
arg = idtable.add_string("arg");
|
||||||
arg2 = idtable.add_string("arg2");
|
arg2 = idtable.add_string("arg2");
|
||||||
Bool = idtable.add_string("Bool");
|
Bool = idtable.add_string("Bool");
|
||||||
@ -105,11 +81,9 @@ static void initialize_constants(void)
|
|||||||
val = idtable.add_string("_val");
|
val = idtable.add_string("_val");
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *gc_init_names[] =
|
static char *gc_init_names[] = {"_NoGC_Init", "_GenGC_Init", "_ScnGC_Init"};
|
||||||
{ "_NoGC_Init", "_GenGC_Init", "_ScnGC_Init" };
|
static char *gc_collect_names[] = {"_NoGC_Collect", "_GenGC_Collect",
|
||||||
static char *gc_collect_names[] =
|
"_ScnGC_Collect"};
|
||||||
{ "_NoGC_Collect", "_GenGC_Collect", "_ScnGC_Collect" };
|
|
||||||
|
|
||||||
|
|
||||||
// BoolConst is a class that implements code generation for operations
|
// BoolConst is a class that implements code generation for operations
|
||||||
// on the two booleans, which are given global names here.
|
// on the two booleans, which are given global names here.
|
||||||
@ -129,8 +103,7 @@ BoolConst truebool(TRUE);
|
|||||||
//
|
//
|
||||||
//*********************************************************
|
//*********************************************************
|
||||||
|
|
||||||
void program_class::cgen(ostream &os)
|
void program_class::cgen(ostream &os) {
|
||||||
{
|
|
||||||
// spim wants comments to start with '#'
|
// spim wants comments to start with '#'
|
||||||
os << "# start of generated code\n";
|
os << "# start of generated code\n";
|
||||||
|
|
||||||
@ -140,7 +113,6 @@ void program_class::cgen(ostream &os)
|
|||||||
os << "\n# end of generated code\n";
|
os << "\n# end of generated code\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// emit_* procedures
|
// emit_* procedures
|
||||||
@ -155,159 +127,160 @@ void program_class::cgen(ostream &os)
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void emit_load(char *dest_reg, int offset, char *source_reg, ostream& s)
|
static void emit_load(char *dest_reg, int offset, char *source_reg,
|
||||||
{
|
ostream &s) {
|
||||||
s << LW << dest_reg << " " << offset * WORD_SIZE << "(" << source_reg << ")"
|
s << LW << dest_reg << " " << offset * WORD_SIZE << "(" << source_reg << ")"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_store(char *source_reg, int offset, char *dest_reg, ostream& s)
|
static void emit_store(char *source_reg, int offset, char *dest_reg,
|
||||||
{
|
ostream &s) {
|
||||||
s << SW << source_reg << " " << offset * WORD_SIZE << "(" << dest_reg << ")"
|
s << SW << source_reg << " " << offset * WORD_SIZE << "(" << dest_reg << ")"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_load_imm(char *dest_reg, int val, ostream& s)
|
static void emit_load_imm(char *dest_reg, int val, ostream &s) {
|
||||||
{ s << LI << dest_reg << " " << val << endl; }
|
s << LI << dest_reg << " " << val << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_load_address(char *dest_reg, char *address, ostream& s)
|
static void emit_load_address(char *dest_reg, char *address, ostream &s) {
|
||||||
{ s << LA << dest_reg << " " << address << endl; }
|
s << LA << dest_reg << " " << address << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_partial_load_address(char *dest_reg, ostream& s)
|
static void emit_partial_load_address(char *dest_reg, ostream &s) {
|
||||||
{ s << LA << dest_reg << " "; }
|
s << LA << dest_reg << " ";
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_load_bool(char *dest, const BoolConst& b, ostream& s)
|
static void emit_load_bool(char *dest, const BoolConst &b, ostream &s) {
|
||||||
{
|
|
||||||
emit_partial_load_address(dest, s);
|
emit_partial_load_address(dest, s);
|
||||||
b.code_ref(s);
|
b.code_ref(s);
|
||||||
s << endl;
|
s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_load_string(char *dest, StringEntry *str, ostream& s)
|
static void emit_load_string(char *dest, StringEntry *str, ostream &s) {
|
||||||
{
|
|
||||||
emit_partial_load_address(dest, s);
|
emit_partial_load_address(dest, s);
|
||||||
str->code_ref(s);
|
str->code_ref(s);
|
||||||
s << endl;
|
s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_load_int(char *dest, IntEntry *i, ostream& s)
|
static void emit_load_int(char *dest, IntEntry *i, ostream &s) {
|
||||||
{
|
|
||||||
emit_partial_load_address(dest, s);
|
emit_partial_load_address(dest, s);
|
||||||
i->code_ref(s);
|
i->code_ref(s);
|
||||||
s << endl;
|
s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_move(char *dest_reg, char *source_reg, ostream& s)
|
static void emit_move(char *dest_reg, char *source_reg, ostream &s) {
|
||||||
{ s << MOVE << dest_reg << " " << source_reg << endl; }
|
s << MOVE << dest_reg << " " << source_reg << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_neg(char *dest, char *src1, ostream& s)
|
static void emit_neg(char *dest, char *src1, ostream &s) {
|
||||||
{ s << NEG << dest << " " << src1 << endl; }
|
s << NEG << dest << " " << src1 << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_add(char *dest, char *src1, char *src2, ostream& s)
|
static void emit_add(char *dest, char *src1, char *src2, ostream &s) {
|
||||||
{ s << ADD << dest << " " << src1 << " " << src2 << endl; }
|
s << ADD << dest << " " << src1 << " " << src2 << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_addu(char *dest, char *src1, char *src2, ostream& s)
|
static void emit_addu(char *dest, char *src1, char *src2, ostream &s) {
|
||||||
{ s << ADDU << dest << " " << src1 << " " << src2 << endl; }
|
s << ADDU << dest << " " << src1 << " " << src2 << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_addiu(char *dest, char *src1, int imm, ostream& s)
|
static void emit_addiu(char *dest, char *src1, int imm, ostream &s) {
|
||||||
{ s << ADDIU << dest << " " << src1 << " " << imm << endl; }
|
s << ADDIU << dest << " " << src1 << " " << imm << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_div(char *dest, char *src1, char *src2, ostream& s)
|
static void emit_div(char *dest, char *src1, char *src2, ostream &s) {
|
||||||
{ s << DIV << dest << " " << src1 << " " << src2 << endl; }
|
s << DIV << dest << " " << src1 << " " << src2 << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_mul(char *dest, char *src1, char *src2, ostream& s)
|
static void emit_mul(char *dest, char *src1, char *src2, ostream &s) {
|
||||||
{ s << MUL << dest << " " << src1 << " " << src2 << endl; }
|
s << MUL << dest << " " << src1 << " " << src2 << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_sub(char *dest, char *src1, char *src2, ostream& s)
|
static void emit_sub(char *dest, char *src1, char *src2, ostream &s) {
|
||||||
{ s << SUB << dest << " " << src1 << " " << src2 << endl; }
|
s << SUB << dest << " " << src1 << " " << src2 << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_sll(char *dest, char *src1, int num, ostream& s)
|
static void emit_sll(char *dest, char *src1, int num, ostream &s) {
|
||||||
{ s << SLL << dest << " " << src1 << " " << num << endl; }
|
s << SLL << dest << " " << src1 << " " << num << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_jalr(char *dest, ostream& s)
|
static void emit_jalr(char *dest, ostream &s) {
|
||||||
{ s << JALR << "\t" << dest << endl; }
|
s << JALR << "\t" << dest << endl;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_jal(char *address,ostream &s)
|
static void emit_jal(char *address, ostream &s) { s << JAL << address << endl; }
|
||||||
{ s << JAL << address << endl; }
|
|
||||||
|
|
||||||
static void emit_return(ostream& s)
|
static void emit_return(ostream &s) { s << RET << endl; }
|
||||||
{ s << RET << endl; }
|
|
||||||
|
|
||||||
static void emit_gc_assign(ostream& s)
|
static void emit_gc_assign(ostream &s) { s << JAL << "_GenGC_Assign" << endl; }
|
||||||
{ s << JAL << "_GenGC_Assign" << endl; }
|
|
||||||
|
|
||||||
static void emit_disptable_ref(Symbol sym, ostream& s)
|
static void emit_disptable_ref(Symbol sym, ostream &s) {
|
||||||
{ s << sym << DISPTAB_SUFFIX; }
|
s << sym << DISPTAB_SUFFIX;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_init_ref(Symbol sym, ostream& s)
|
static void emit_init_ref(Symbol sym, ostream &s) {
|
||||||
{ s << sym << CLASSINIT_SUFFIX; }
|
s << sym << CLASSINIT_SUFFIX;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_label_ref(int l, ostream &s)
|
static void emit_label_ref(int l, ostream &s) { s << "label" << l; }
|
||||||
{ s << "label" << l; }
|
|
||||||
|
|
||||||
static void emit_protobj_ref(Symbol sym, ostream& s)
|
static void emit_protobj_ref(Symbol sym, ostream &s) {
|
||||||
{ s << sym << PROTOBJ_SUFFIX; }
|
s << sym << PROTOBJ_SUFFIX;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_method_ref(Symbol classname, Symbol methodname, ostream& s)
|
static void emit_method_ref(Symbol classname, Symbol methodname, ostream &s) {
|
||||||
{ s << classname << METHOD_SEP << methodname; }
|
s << classname << METHOD_SEP << methodname;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_label_def(int l, ostream &s)
|
static void emit_label_def(int l, ostream &s) {
|
||||||
{
|
|
||||||
emit_label_ref(l, s);
|
emit_label_ref(l, s);
|
||||||
s << ":" << endl;
|
s << ":" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_beqz(char *source, int label, ostream &s)
|
static void emit_beqz(char *source, int label, ostream &s) {
|
||||||
{
|
|
||||||
s << BEQZ << source << " ";
|
s << BEQZ << source << " ";
|
||||||
emit_label_ref(label, s);
|
emit_label_ref(label, s);
|
||||||
s << endl;
|
s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_beq(char *src1, char *src2, int label, ostream &s)
|
static void emit_beq(char *src1, char *src2, int label, ostream &s) {
|
||||||
{
|
|
||||||
s << BEQ << src1 << " " << src2 << " ";
|
s << BEQ << src1 << " " << src2 << " ";
|
||||||
emit_label_ref(label, s);
|
emit_label_ref(label, s);
|
||||||
s << endl;
|
s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_bne(char *src1, char *src2, int label, ostream &s)
|
static void emit_bne(char *src1, char *src2, int label, ostream &s) {
|
||||||
{
|
|
||||||
s << BNE << src1 << " " << src2 << " ";
|
s << BNE << src1 << " " << src2 << " ";
|
||||||
emit_label_ref(label, s);
|
emit_label_ref(label, s);
|
||||||
s << endl;
|
s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_bleq(char *src1, char *src2, int label, ostream &s)
|
static void emit_bleq(char *src1, char *src2, int label, ostream &s) {
|
||||||
{
|
|
||||||
s << BLEQ << src1 << " " << src2 << " ";
|
s << BLEQ << src1 << " " << src2 << " ";
|
||||||
emit_label_ref(label, s);
|
emit_label_ref(label, s);
|
||||||
s << endl;
|
s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_blt(char *src1, char *src2, int label, ostream &s)
|
static void emit_blt(char *src1, char *src2, int label, ostream &s) {
|
||||||
{
|
|
||||||
s << BLT << src1 << " " << src2 << " ";
|
s << BLT << src1 << " " << src2 << " ";
|
||||||
emit_label_ref(label, s);
|
emit_label_ref(label, s);
|
||||||
s << endl;
|
s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_blti(char *src1, int imm, int label, ostream &s)
|
static void emit_blti(char *src1, int imm, int label, ostream &s) {
|
||||||
{
|
|
||||||
s << BLT << src1 << " " << imm << " ";
|
s << BLT << src1 << " " << imm << " ";
|
||||||
emit_label_ref(label, s);
|
emit_label_ref(label, s);
|
||||||
s << endl;
|
s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_bgti(char *src1, int imm, int label, ostream &s)
|
static void emit_bgti(char *src1, int imm, int label, ostream &s) {
|
||||||
{
|
|
||||||
s << BGT << src1 << " " << imm << " ";
|
s << BGT << src1 << " " << imm << " ";
|
||||||
emit_label_ref(label, s);
|
emit_label_ref(label, s);
|
||||||
s << endl;
|
s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_branch(int l, ostream& s)
|
static void emit_branch(int l, ostream &s) {
|
||||||
{
|
|
||||||
s << BRANCH;
|
s << BRANCH;
|
||||||
emit_label_ref(l, s);
|
emit_label_ref(l, s);
|
||||||
s << endl;
|
s << endl;
|
||||||
@ -316,8 +289,7 @@ static void emit_branch(int l, ostream& s)
|
|||||||
//
|
//
|
||||||
// Push a register on the stack. The stack grows towards smaller addresses.
|
// Push a register on the stack. The stack grows towards smaller addresses.
|
||||||
//
|
//
|
||||||
static void emit_push(char *reg, ostream& str)
|
static void emit_push(char *reg, ostream &str) {
|
||||||
{
|
|
||||||
emit_store(reg, 0, SP, str);
|
emit_store(reg, 0, SP, str);
|
||||||
emit_addiu(SP, SP, -4, str);
|
emit_addiu(SP, SP, -4, str);
|
||||||
}
|
}
|
||||||
@ -327,19 +299,19 @@ static void emit_push(char *reg, ostream& str)
|
|||||||
// Emits code to fetch the integer value of the Integer object pointed
|
// Emits code to fetch the integer value of the Integer object pointed
|
||||||
// to by register source into the register dest
|
// to by register source into the register dest
|
||||||
//
|
//
|
||||||
static void emit_fetch_int(char *dest, char *source, ostream& s)
|
static void emit_fetch_int(char *dest, char *source, ostream &s) {
|
||||||
{ emit_load(dest, DEFAULT_OBJFIELDS, source, s); }
|
emit_load(dest, DEFAULT_OBJFIELDS, source, s);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Emits code to store the integer value contained in register source
|
// Emits code to store the integer value contained in register source
|
||||||
// into the Integer object pointed to by dest.
|
// into the Integer object pointed to by dest.
|
||||||
//
|
//
|
||||||
static void emit_store_int(char *source, char *dest, ostream& s)
|
static void emit_store_int(char *source, char *dest, ostream &s) {
|
||||||
{ emit_store(source, DEFAULT_OBJFIELDS, dest, s); }
|
emit_store(source, DEFAULT_OBJFIELDS, dest, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emit_test_collector(ostream &s) {
|
||||||
static void emit_test_collector(ostream &s)
|
|
||||||
{
|
|
||||||
emit_push(ACC, s);
|
emit_push(ACC, s);
|
||||||
emit_move(ACC, SP, s); // stack end
|
emit_move(ACC, SP, s); // stack end
|
||||||
emit_move(A1, ZERO, s); // allocate nothing
|
emit_move(A1, ZERO, s); // allocate nothing
|
||||||
@ -348,13 +320,12 @@ static void emit_test_collector(ostream &s)
|
|||||||
emit_load(ACC, 0, SP, s);
|
emit_load(ACC, 0, SP, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_gc_check(char *source, ostream &s)
|
static void emit_gc_check(char *source, ostream &s) {
|
||||||
{
|
if (source != (char *)A1)
|
||||||
if (source != (char*)A1) emit_move(A1, source, s);
|
emit_move(A1, source, s);
|
||||||
s << JAL << "_gc_check" << endl;
|
s << JAL << "_gc_check" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// coding strings, ints, and booleans
|
// coding strings, ints, and booleans
|
||||||
@ -379,33 +350,32 @@ static void emit_gc_check(char *source, ostream &s)
|
|||||||
//
|
//
|
||||||
// Strings
|
// Strings
|
||||||
//
|
//
|
||||||
void StringEntry::code_ref(ostream& s)
|
void StringEntry::code_ref(ostream &s) { s << STRCONST_PREFIX << index; }
|
||||||
{
|
|
||||||
s << STRCONST_PREFIX << index;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Emit code for a constant String.
|
// Emit code for a constant String.
|
||||||
// You should fill in the code naming the dispatch table.
|
// You should fill in the code naming the dispatch table.
|
||||||
//
|
//
|
||||||
|
|
||||||
void StringEntry::code_def(ostream& s, int stringclasstag)
|
void StringEntry::code_def(ostream &s, int stringclasstag) {
|
||||||
{
|
|
||||||
IntEntryP lensym = inttable.add_int(len);
|
IntEntryP lensym = inttable.add_int(len);
|
||||||
|
|
||||||
// Add -1 eye catcher
|
// Add -1 eye catcher
|
||||||
s << WORD << "-1" << endl;
|
s << WORD << "-1" << endl;
|
||||||
|
|
||||||
code_ref(s); s << LABEL // label
|
code_ref(s);
|
||||||
|
s << LABEL // label
|
||||||
<< WORD << stringclasstag << endl // tag
|
<< WORD << stringclasstag << endl // tag
|
||||||
<< WORD << (DEFAULT_OBJFIELDS + STRING_SLOTS + (len+4)/4) << endl // size
|
<< WORD << (DEFAULT_OBJFIELDS + STRING_SLOTS + (len + 4) / 4)
|
||||||
|
<< endl // size
|
||||||
<< WORD;
|
<< WORD;
|
||||||
|
|
||||||
|
|
||||||
/***** Add dispatch information for class String ******/
|
/***** Add dispatch information for class String ******/
|
||||||
|
|
||||||
s << endl; // dispatch table
|
s << endl; // dispatch table
|
||||||
s << WORD; lensym->code_ref(s); s << endl; // string length
|
s << WORD;
|
||||||
|
lensym->code_ref(s);
|
||||||
|
s << endl; // string length
|
||||||
emit_string_constant(s, str); // ascii string
|
emit_string_constant(s, str); // ascii string
|
||||||
s << ALIGN; // align to word
|
s << ALIGN; // align to word
|
||||||
}
|
}
|
||||||
@ -415,8 +385,7 @@ void StringEntry::code_def(ostream& s, int stringclasstag)
|
|||||||
// Generate a string object definition for every string constant in the
|
// Generate a string object definition for every string constant in the
|
||||||
// stringtable.
|
// stringtable.
|
||||||
//
|
//
|
||||||
void StrTable::code_string_table(ostream& s, int stringclasstag)
|
void StrTable::code_string_table(ostream &s, int stringclasstag) {
|
||||||
{
|
|
||||||
for (List<StringEntry> *l = tbl; l; l = l->tl())
|
for (List<StringEntry> *l = tbl; l; l = l->tl())
|
||||||
l->hd()->code_def(s, stringclasstag);
|
l->hd()->code_def(s, stringclasstag);
|
||||||
}
|
}
|
||||||
@ -424,22 +393,19 @@ void StrTable::code_string_table(ostream& s, int stringclasstag)
|
|||||||
//
|
//
|
||||||
// Ints
|
// Ints
|
||||||
//
|
//
|
||||||
void IntEntry::code_ref(ostream &s)
|
void IntEntry::code_ref(ostream &s) { s << INTCONST_PREFIX << index; }
|
||||||
{
|
|
||||||
s << INTCONST_PREFIX << index;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Emit code for a constant Integer.
|
// Emit code for a constant Integer.
|
||||||
// You should fill in the code naming the dispatch table.
|
// You should fill in the code naming the dispatch table.
|
||||||
//
|
//
|
||||||
|
|
||||||
void IntEntry::code_def(ostream &s, int intclasstag)
|
void IntEntry::code_def(ostream &s, int intclasstag) {
|
||||||
{
|
|
||||||
// Add -1 eye catcher
|
// Add -1 eye catcher
|
||||||
s << WORD << "-1" << endl;
|
s << WORD << "-1" << endl;
|
||||||
|
|
||||||
code_ref(s); s << LABEL // label
|
code_ref(s);
|
||||||
|
s << LABEL // label
|
||||||
<< WORD << intclasstag << endl // class tag
|
<< WORD << intclasstag << endl // class tag
|
||||||
<< WORD << (DEFAULT_OBJFIELDS + INT_SLOTS) << endl // object size
|
<< WORD << (DEFAULT_OBJFIELDS + INT_SLOTS) << endl // object size
|
||||||
<< WORD;
|
<< WORD;
|
||||||
@ -450,40 +416,34 @@ void IntEntry::code_def(ostream &s, int intclasstag)
|
|||||||
s << WORD << str << endl; // integer value
|
s << WORD << str << endl; // integer value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// IntTable::code_string_table
|
// IntTable::code_string_table
|
||||||
// Generate an Int object definition for every Int constant in the
|
// Generate an Int object definition for every Int constant in the
|
||||||
// inttable.
|
// inttable.
|
||||||
//
|
//
|
||||||
void IntTable::code_string_table(ostream &s, int intclasstag)
|
void IntTable::code_string_table(ostream &s, int intclasstag) {
|
||||||
{
|
|
||||||
for (List<IntEntry> *l = tbl; l; l = l->tl())
|
for (List<IntEntry> *l = tbl; l; l = l->tl())
|
||||||
l->hd()->code_def(s, intclasstag);
|
l->hd()->code_def(s, intclasstag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bools
|
// Bools
|
||||||
//
|
//
|
||||||
BoolConst::BoolConst(int i) : val(i) { assert(i == 0 || i == 1); }
|
BoolConst::BoolConst(int i) : val(i) { assert(i == 0 || i == 1); }
|
||||||
|
|
||||||
void BoolConst::code_ref(ostream& s) const
|
void BoolConst::code_ref(ostream &s) const { s << BOOLCONST_PREFIX << val; }
|
||||||
{
|
|
||||||
s << BOOLCONST_PREFIX << val;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Emit code for a constant Bool.
|
// Emit code for a constant Bool.
|
||||||
// You should fill in the code naming the dispatch table.
|
// You should fill in the code naming the dispatch table.
|
||||||
//
|
//
|
||||||
|
|
||||||
void BoolConst::code_def(ostream& s, int boolclasstag)
|
void BoolConst::code_def(ostream &s, int boolclasstag) {
|
||||||
{
|
|
||||||
// Add -1 eye catcher
|
// Add -1 eye catcher
|
||||||
s << WORD << "-1" << endl;
|
s << WORD << "-1" << endl;
|
||||||
|
|
||||||
code_ref(s); s << LABEL // label
|
code_ref(s);
|
||||||
|
s << LABEL // label
|
||||||
<< WORD << boolclasstag << endl // class tag
|
<< WORD << boolclasstag << endl // class tag
|
||||||
<< WORD << (DEFAULT_OBJFIELDS + BOOL_SLOTS) << endl // object size
|
<< WORD << (DEFAULT_OBJFIELDS + BOOL_SLOTS) << endl // object size
|
||||||
<< WORD;
|
<< WORD;
|
||||||
@ -507,8 +467,7 @@ void BoolConst::code_def(ostream& s, int boolclasstag)
|
|||||||
//
|
//
|
||||||
//***************************************************
|
//***************************************************
|
||||||
|
|
||||||
void CgenClassTable::code_global_data()
|
void CgenClassTable::code_global_data() {
|
||||||
{
|
|
||||||
Symbol main = idtable.lookup_string(MAINNAME);
|
Symbol main = idtable.lookup_string(MAINNAME);
|
||||||
Symbol string = idtable.lookup_string(STRINGNAME);
|
Symbol string = idtable.lookup_string(STRINGNAME);
|
||||||
Symbol integer = idtable.lookup_string(INTNAME);
|
Symbol integer = idtable.lookup_string(INTNAME);
|
||||||
@ -519,11 +478,21 @@ void CgenClassTable::code_global_data()
|
|||||||
// The following global names must be defined first.
|
// The following global names must be defined first.
|
||||||
//
|
//
|
||||||
str << GLOBAL << CLASSNAMETAB << endl;
|
str << GLOBAL << CLASSNAMETAB << endl;
|
||||||
str << GLOBAL; emit_protobj_ref(main,str); str << endl;
|
str << GLOBAL;
|
||||||
str << GLOBAL; emit_protobj_ref(integer,str); str << endl;
|
emit_protobj_ref(main, str);
|
||||||
str << GLOBAL; emit_protobj_ref(string,str); str << endl;
|
str << endl;
|
||||||
str << GLOBAL; falsebool.code_ref(str); str << endl;
|
str << GLOBAL;
|
||||||
str << GLOBAL; truebool.code_ref(str); str << endl;
|
emit_protobj_ref(integer, str);
|
||||||
|
str << endl;
|
||||||
|
str << GLOBAL;
|
||||||
|
emit_protobj_ref(string, str);
|
||||||
|
str << endl;
|
||||||
|
str << GLOBAL;
|
||||||
|
falsebool.code_ref(str);
|
||||||
|
str << endl;
|
||||||
|
str << GLOBAL;
|
||||||
|
truebool.code_ref(str);
|
||||||
|
str << endl;
|
||||||
str << GLOBAL << INTTAG << endl;
|
str << GLOBAL << INTTAG << endl;
|
||||||
str << GLOBAL << BOOLTAG << endl;
|
str << GLOBAL << BOOLTAG << endl;
|
||||||
str << GLOBAL << STRINGTAG << endl;
|
str << GLOBAL << STRINGTAG << endl;
|
||||||
@ -532,15 +501,11 @@ void CgenClassTable::code_global_data()
|
|||||||
// We also need to know the tag of the Int, String, and Bool classes
|
// We also need to know the tag of the Int, String, and Bool classes
|
||||||
// during code generation.
|
// during code generation.
|
||||||
//
|
//
|
||||||
str << INTTAG << LABEL
|
str << INTTAG << LABEL << WORD << intclasstag << endl;
|
||||||
<< WORD << intclasstag << endl;
|
str << BOOLTAG << LABEL << WORD << boolclasstag << endl;
|
||||||
str << BOOLTAG << LABEL
|
str << STRINGTAG << LABEL << WORD << stringclasstag << endl;
|
||||||
<< WORD << boolclasstag << endl;
|
|
||||||
str << STRINGTAG << LABEL
|
|
||||||
<< WORD << stringclasstag << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//***************************************************
|
//***************************************************
|
||||||
//
|
//
|
||||||
// Emit code to start the .text segment and to
|
// Emit code to start the .text segment and to
|
||||||
@ -548,11 +513,9 @@ void CgenClassTable::code_global_data()
|
|||||||
//
|
//
|
||||||
//***************************************************
|
//***************************************************
|
||||||
|
|
||||||
void CgenClassTable::code_global_text()
|
void CgenClassTable::code_global_text() {
|
||||||
{
|
|
||||||
str << GLOBAL << HEAP_START << endl
|
str << GLOBAL << HEAP_START << endl
|
||||||
<< HEAP_START << LABEL
|
<< HEAP_START << LABEL << WORD << 0 << endl
|
||||||
<< WORD << 0 << endl
|
|
||||||
<< "\t.text" << endl
|
<< "\t.text" << endl
|
||||||
<< GLOBAL;
|
<< GLOBAL;
|
||||||
emit_init_ref(idtable.add_string("Main"), str);
|
emit_init_ref(idtable.add_string("Main"), str);
|
||||||
@ -567,14 +530,12 @@ void CgenClassTable::code_global_text()
|
|||||||
str << endl;
|
str << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CgenClassTable::code_bools(int boolclasstag)
|
void CgenClassTable::code_bools(int boolclasstag) {
|
||||||
{
|
|
||||||
falsebool.code_def(str, boolclasstag);
|
falsebool.code_def(str, boolclasstag);
|
||||||
truebool.code_def(str, boolclasstag);
|
truebool.code_def(str, boolclasstag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CgenClassTable::code_select_gc()
|
void CgenClassTable::code_select_gc() {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// Generate GC choice constants (pointers to GC functions)
|
// Generate GC choice constants (pointers to GC functions)
|
||||||
//
|
//
|
||||||
@ -589,7 +550,6 @@ void CgenClassTable::code_select_gc()
|
|||||||
str << WORD << (cgen_Memmgr_Test == GC_TEST) << endl;
|
str << WORD << (cgen_Memmgr_Test == GC_TEST) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//********************************************************
|
//********************************************************
|
||||||
//
|
//
|
||||||
// Emit code to reserve space for and initialize all of
|
// Emit code to reserve space for and initialize all of
|
||||||
@ -603,8 +563,7 @@ void CgenClassTable::code_select_gc()
|
|||||||
//
|
//
|
||||||
//********************************************************
|
//********************************************************
|
||||||
|
|
||||||
void CgenClassTable::code_constants()
|
void CgenClassTable::code_constants() {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// Add constants that are required by the code generator.
|
// Add constants that are required by the code generator.
|
||||||
//
|
//
|
||||||
@ -616,25 +575,25 @@ void CgenClassTable::code_constants()
|
|||||||
code_bools(boolclasstag);
|
code_bools(boolclasstag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CgenClassTable::CgenClassTable(Classes classes, ostream &s)
|
||||||
CgenClassTable::CgenClassTable(Classes classes, ostream& s) : nds(NULL) , str(s)
|
: nds(NULL), str(s) {
|
||||||
{
|
stringclasstag = 1 /* Change to your String class tag here */;
|
||||||
stringclasstag = 0 /* Change to your String class tag here */;
|
intclasstag = 2 /* Change to your Int class tag here */;
|
||||||
intclasstag = 0 /* Change to your Int class tag here */;
|
boolclasstag = 3 /* Change to your Bool class tag here */;
|
||||||
boolclasstag = 0 /* Change to your Bool class tag here */;
|
|
||||||
|
|
||||||
enterscope();
|
enterscope();
|
||||||
if (cgen_debug) cout << "Building CgenClassTable" << endl;
|
if (cgen_debug)
|
||||||
|
cout << "Building CgenClassTable" << endl;
|
||||||
install_basic_classes();
|
install_basic_classes();
|
||||||
install_classes(classes);
|
install_classes(classes);
|
||||||
build_inheritance_tree();
|
build_inheritance_tree();
|
||||||
|
if (cgen_debug)
|
||||||
|
dump_inheritance_tree();
|
||||||
code();
|
code();
|
||||||
exitscope();
|
exitscope();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CgenClassTable::install_basic_classes()
|
void CgenClassTable::install_basic_classes() {
|
||||||
{
|
|
||||||
|
|
||||||
// The tree package uses these globals to annotate the classes built below.
|
// The tree package uses these globals to annotate the classes built below.
|
||||||
// curr_lineno = 0;
|
// curr_lineno = 0;
|
||||||
@ -661,21 +620,22 @@ void CgenClassTable::install_basic_classes()
|
|||||||
//
|
//
|
||||||
// The Object class has no parent class. Its methods are
|
// The Object class has no parent class. Its methods are
|
||||||
// cool_abort() : Object aborts the program
|
// cool_abort() : Object aborts the program
|
||||||
// type_name() : Str returns a string representation of class name
|
// type_name() : Str returns a string representation of class
|
||||||
// copy() : SELF_TYPE returns a copy of the object
|
// name copy() : SELF_TYPE returns a copy of the object
|
||||||
//
|
//
|
||||||
// There is no need for method bodies in the basic classes---these
|
// There is no need for method bodies in the basic classes---these
|
||||||
// are already built in to the runtime system.
|
// are already built in to the runtime system.
|
||||||
//
|
//
|
||||||
install_class(
|
install_class(new CgenNode(
|
||||||
new CgenNode(
|
class_(
|
||||||
class_(Object,
|
Object, No_class,
|
||||||
No_class,
|
|
||||||
append_Features(
|
append_Features(
|
||||||
append_Features(
|
append_Features(single_Features(method(cool_abort, nil_Formals(),
|
||||||
single_Features(method(cool_abort, nil_Formals(), Object, no_expr())),
|
Object, no_expr())),
|
||||||
single_Features(method(type_name, nil_Formals(), Str, no_expr()))),
|
single_Features(method(type_name, nil_Formals(),
|
||||||
single_Features(method(copy, nil_Formals(), SELF_TYPE, no_expr()))),
|
Str, no_expr()))),
|
||||||
|
single_Features(
|
||||||
|
method(copy, nil_Formals(), SELF_TYPE, no_expr()))),
|
||||||
filename),
|
filename),
|
||||||
Basic, this));
|
Basic, this));
|
||||||
|
|
||||||
@ -686,18 +646,20 @@ void CgenClassTable::install_basic_classes()
|
|||||||
// in_string() : Str reads a string from the input
|
// in_string() : Str reads a string from the input
|
||||||
// in_int() : Int " an int " " "
|
// in_int() : Int " an int " " "
|
||||||
//
|
//
|
||||||
install_class(
|
install_class(new CgenNode(
|
||||||
new CgenNode(
|
class_(
|
||||||
class_(IO,
|
IO, Object,
|
||||||
Object,
|
|
||||||
append_Features(
|
append_Features(
|
||||||
append_Features(
|
append_Features(
|
||||||
append_Features(
|
append_Features(
|
||||||
single_Features(method(out_string, single_Formals(formal(arg, Str)),
|
single_Features(method(out_string,
|
||||||
|
single_Formals(formal(arg, Str)),
|
||||||
SELF_TYPE, no_expr())),
|
SELF_TYPE, no_expr())),
|
||||||
single_Features(method(out_int, single_Formals(formal(arg, Int)),
|
single_Features(method(out_int,
|
||||||
|
single_Formals(formal(arg, Int)),
|
||||||
SELF_TYPE, no_expr()))),
|
SELF_TYPE, no_expr()))),
|
||||||
single_Features(method(in_string, nil_Formals(), Str, no_expr()))),
|
single_Features(
|
||||||
|
method(in_string, nil_Formals(), Str, no_expr()))),
|
||||||
single_Features(method(in_int, nil_Formals(), Int, no_expr()))),
|
single_Features(method(in_int, nil_Formals(), Int, no_expr()))),
|
||||||
filename),
|
filename),
|
||||||
Basic, this));
|
Basic, this));
|
||||||
@ -706,20 +668,17 @@ void CgenClassTable::install_basic_classes()
|
|||||||
// The Int class has no methods and only a single attribute, the
|
// The Int class has no methods and only a single attribute, the
|
||||||
// "val" for the integer.
|
// "val" for the integer.
|
||||||
//
|
//
|
||||||
install_class(
|
install_class(new CgenNode(
|
||||||
new CgenNode(
|
class_(Int, Object, single_Features(attr(val, prim_slot, no_expr())),
|
||||||
class_(Int,
|
|
||||||
Object,
|
|
||||||
single_Features(attr(val, prim_slot, no_expr())),
|
|
||||||
filename),
|
filename),
|
||||||
Basic, this));
|
Basic, this));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bool also has only the "val" slot.
|
// Bool also has only the "val" slot.
|
||||||
//
|
//
|
||||||
install_class(
|
install_class(new CgenNode(
|
||||||
new CgenNode(
|
class_(Bool, Object, single_Features(attr(val, prim_slot, no_expr())),
|
||||||
class_(Bool, Object, single_Features(attr(val, prim_slot, no_expr())),filename),
|
filename),
|
||||||
Basic, this));
|
Basic, this));
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -730,29 +689,27 @@ void CgenClassTable::install_basic_classes()
|
|||||||
// concat(arg: Str) : Str string concatenation
|
// concat(arg: Str) : Str string concatenation
|
||||||
// substr(arg: Int, arg2: Int): Str substring
|
// substr(arg: Int, arg2: Int): Str substring
|
||||||
//
|
//
|
||||||
install_class(
|
install_class(new CgenNode(
|
||||||
new CgenNode(
|
class_(Str, Object,
|
||||||
class_(Str,
|
|
||||||
Object,
|
|
||||||
append_Features(
|
append_Features(
|
||||||
append_Features(
|
append_Features(
|
||||||
append_Features(
|
append_Features(
|
||||||
append_Features(
|
append_Features(
|
||||||
single_Features(attr(val, Int, no_expr())),
|
single_Features(attr(val, Int, no_expr())),
|
||||||
single_Features(attr(str_field, prim_slot, no_expr()))),
|
single_Features(
|
||||||
single_Features(method(length, nil_Formals(), Int, no_expr()))),
|
attr(str_field, prim_slot, no_expr()))),
|
||||||
|
single_Features(
|
||||||
|
method(length, nil_Formals(), Int, no_expr()))),
|
||||||
single_Features(method(concat,
|
single_Features(method(concat,
|
||||||
single_Formals(formal(arg, Str)),
|
single_Formals(formal(arg, Str)),
|
||||||
Str,
|
Str, no_expr()))),
|
||||||
no_expr()))),
|
single_Features(
|
||||||
single_Features(method(substr,
|
method(substr,
|
||||||
append_Formals(single_Formals(formal(arg, Int)),
|
append_Formals(single_Formals(formal(arg, Int)),
|
||||||
single_Formals(formal(arg2, Int))),
|
single_Formals(formal(arg2, Int))),
|
||||||
Str,
|
Str, no_expr()))),
|
||||||
no_expr()))),
|
|
||||||
filename),
|
filename),
|
||||||
Basic, this));
|
Basic, this));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CgenClassTable::install_class
|
// CgenClassTable::install_class
|
||||||
@ -760,12 +717,10 @@ void CgenClassTable::install_basic_classes()
|
|||||||
//
|
//
|
||||||
// install_classes enters a list of classes in the symbol table.
|
// install_classes enters a list of classes in the symbol table.
|
||||||
//
|
//
|
||||||
void CgenClassTable::install_class(CgenNodeP nd)
|
void CgenClassTable::install_class(CgenNodeP nd) {
|
||||||
{
|
|
||||||
Symbol name = nd->get_name();
|
Symbol name = nd->get_name();
|
||||||
|
|
||||||
if (probe(name))
|
if (probe(name)) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -775,8 +730,7 @@ void CgenClassTable::install_class(CgenNodeP nd)
|
|||||||
addid(name, nd);
|
addid(name, nd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CgenClassTable::install_classes(Classes cs)
|
void CgenClassTable::install_classes(Classes cs) {
|
||||||
{
|
|
||||||
for (int i = cs->first(); cs->more(i); i = cs->next(i))
|
for (int i = cs->first(); cs->more(i); i = cs->next(i))
|
||||||
install_class(new CgenNode(cs->nth(i), NotBasic, this));
|
install_class(new CgenNode(cs->nth(i), NotBasic, this));
|
||||||
}
|
}
|
||||||
@ -784,8 +738,7 @@ void CgenClassTable::install_classes(Classes cs)
|
|||||||
//
|
//
|
||||||
// CgenClassTable::build_inheritance_tree
|
// CgenClassTable::build_inheritance_tree
|
||||||
//
|
//
|
||||||
void CgenClassTable::build_inheritance_tree()
|
void CgenClassTable::build_inheritance_tree() {
|
||||||
{
|
|
||||||
for (List<CgenNode> *l = nds; l; l = l->tl())
|
for (List<CgenNode> *l = nds; l; l = l->tl())
|
||||||
set_relations(l->hd());
|
set_relations(l->hd());
|
||||||
}
|
}
|
||||||
@ -796,36 +749,46 @@ void CgenClassTable::build_inheritance_tree()
|
|||||||
// Takes a CgenNode and locates its, and its parent's, inheritance nodes
|
// Takes a CgenNode and locates its, and its parent's, inheritance nodes
|
||||||
// via the class table. Parent and child pointers are added as appropriate.
|
// via the class table. Parent and child pointers are added as appropriate.
|
||||||
//
|
//
|
||||||
void CgenClassTable::set_relations(CgenNodeP nd)
|
void CgenClassTable::set_relations(CgenNodeP nd) {
|
||||||
{
|
|
||||||
CgenNode *parent_node = probe(nd->get_parent());
|
CgenNode *parent_node = probe(nd->get_parent());
|
||||||
nd->set_parentnd(parent_node);
|
nd->set_parentnd(parent_node);
|
||||||
parent_node->add_child(nd);
|
parent_node->add_child(nd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CgenNode::add_child(CgenNodeP n)
|
void CgenNode::add_child(CgenNodeP n) {
|
||||||
{
|
|
||||||
children = new List<CgenNode>(n, children);
|
children = new List<CgenNode>(n, children);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CgenNode::set_parentnd(CgenNodeP p)
|
void CgenNode::set_parentnd(CgenNodeP p) {
|
||||||
{
|
|
||||||
assert(parentnd == NULL);
|
assert(parentnd == NULL);
|
||||||
assert(p != NULL);
|
assert(p != NULL);
|
||||||
parentnd = p;
|
parentnd = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CgenClassTable::dump_inheritance_tree() {
|
||||||
|
CgenNode *object_node = nullptr;
|
||||||
|
|
||||||
|
for (auto l = nds; l; l = l->tl()) {
|
||||||
|
auto cur_node = l->hd();
|
||||||
|
if (cur_node->name == Object) {
|
||||||
|
object_node = cur_node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object_node->traverse_dump(0);
|
||||||
|
}
|
||||||
|
|
||||||
void CgenClassTable::code()
|
void CgenClassTable::code() {
|
||||||
{
|
if (cgen_debug)
|
||||||
if (cgen_debug) cout << "coding global data" << endl;
|
cout << "coding global data" << endl;
|
||||||
code_global_data();
|
code_global_data();
|
||||||
|
|
||||||
if (cgen_debug) cout << "choosing gc" << endl;
|
if (cgen_debug)
|
||||||
|
cout << "choosing gc" << endl;
|
||||||
code_select_gc();
|
code_select_gc();
|
||||||
|
|
||||||
if (cgen_debug) cout << "coding constants" << endl;
|
if (cgen_debug)
|
||||||
|
cout << "coding constants" << endl;
|
||||||
code_constants();
|
code_constants();
|
||||||
|
|
||||||
// Add your code to emit
|
// Add your code to emit
|
||||||
@ -834,22 +797,17 @@ void CgenClassTable::code()
|
|||||||
// - dispatch tables
|
// - dispatch tables
|
||||||
//
|
//
|
||||||
|
|
||||||
if (cgen_debug) cout << "coding global text" << endl;
|
if (cgen_debug)
|
||||||
|
cout << "coding global text" << endl;
|
||||||
code_global_text();
|
code_global_text();
|
||||||
|
|
||||||
// Add your code to emit
|
// Add your code to emit
|
||||||
// - object initializer
|
// - object initializer
|
||||||
// - the class methods
|
// - the class methods
|
||||||
// - etc...
|
// - etc...
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CgenNodeP CgenClassTable::root()
|
|
||||||
{
|
|
||||||
return probe(Object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CgenNodeP CgenClassTable::root() { return probe(Object); }
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -857,16 +815,12 @@ CgenNodeP CgenClassTable::root()
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
CgenNode::CgenNode(Class_ nd, Basicness bstatus, CgenClassTableP ct) :
|
CgenNode::CgenNode(Class_ nd, Basicness bstatus, CgenClassTableP ct)
|
||||||
class__class((const class__class &) *nd),
|
: class__class((const class__class &)*nd), parentnd(NULL), children(NULL),
|
||||||
parentnd(NULL),
|
basic_status(bstatus) {
|
||||||
children(NULL),
|
|
||||||
basic_status(bstatus)
|
|
||||||
{
|
|
||||||
stringtable.add_string(name->get_string()); // Add class name to string table
|
stringtable.add_string(name->get_string()); // Add class name to string table
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//******************************************************************
|
//******************************************************************
|
||||||
//
|
//
|
||||||
// Fill in the following methods to produce code for the
|
// Fill in the following methods to produce code for the
|
||||||
@ -877,85 +831,59 @@ CgenNode::CgenNode(Class_ nd, Basicness bstatus, CgenClassTableP ct) :
|
|||||||
//
|
//
|
||||||
//*****************************************************************
|
//*****************************************************************
|
||||||
|
|
||||||
void assign_class::code(ostream &s) {
|
void assign_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void static_dispatch_class::code(ostream &s) {
|
void static_dispatch_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void dispatch_class::code(ostream &s) {
|
void dispatch_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void cond_class::code(ostream &s) {
|
void cond_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void loop_class::code(ostream &s) {
|
void loop_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void typcase_class::code(ostream &s) {
|
void typcase_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void block_class::code(ostream &s) {
|
void block_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void let_class::code(ostream &s) {
|
void let_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void plus_class::code(ostream &s) {
|
void plus_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void sub_class::code(ostream &s) {
|
void sub_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void mul_class::code(ostream &s) {
|
void mul_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void divide_class::code(ostream &s) {
|
void divide_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void neg_class::code(ostream &s) {
|
void neg_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void lt_class::code(ostream &s) {
|
void lt_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void eq_class::code(ostream &s) {
|
void eq_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void leq_class::code(ostream &s) {
|
void leq_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void comp_class::code(ostream &s) {
|
void comp_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void int_const_class::code(ostream& s)
|
void int_const_class::code(ostream &s) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// Need to be sure we have an IntEntry *, not an arbitrary Symbol
|
// Need to be sure we have an IntEntry *, not an arbitrary Symbol
|
||||||
//
|
//
|
||||||
emit_load_int(ACC, inttable.lookup_string(token->get_string()), s);
|
emit_load_int(ACC, inttable.lookup_string(token->get_string()), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void string_const_class::code(ostream& s)
|
void string_const_class::code(ostream &s) {
|
||||||
{
|
|
||||||
emit_load_string(ACC, stringtable.lookup_string(token->get_string()), s);
|
emit_load_string(ACC, stringtable.lookup_string(token->get_string()), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bool_const_class::code(ostream& s)
|
void bool_const_class::code(ostream &s) {
|
||||||
{
|
|
||||||
emit_load_bool(ACC, BoolConst(val), s);
|
emit_load_bool(ACC, BoolConst(val), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void new__class::code(ostream &s) {
|
void new__class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void isvoid_class::code(ostream &s) {
|
void isvoid_class::code(ostream &s) {}
|
||||||
}
|
|
||||||
|
|
||||||
void no_expr_class::code(ostream &s) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void object_class::code(ostream &s) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void no_expr_class::code(ostream &s) {}
|
||||||
|
|
||||||
|
void object_class::code(ostream &s) {}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "emit.h"
|
|
||||||
#include "cool-tree.h"
|
#include "cool-tree.h"
|
||||||
|
#include "emit.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
enum Basicness { Basic, NotBasic };
|
enum Basicness { Basic, NotBasic };
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
@ -22,7 +23,6 @@ private:
|
|||||||
int intclasstag;
|
int intclasstag;
|
||||||
int boolclasstag;
|
int boolclasstag;
|
||||||
|
|
||||||
|
|
||||||
// The following methods emit code for
|
// The following methods emit code for
|
||||||
// constants and global declarations.
|
// constants and global declarations.
|
||||||
|
|
||||||
@ -42,13 +42,15 @@ private:
|
|||||||
void install_classes(Classes cs);
|
void install_classes(Classes cs);
|
||||||
void build_inheritance_tree();
|
void build_inheritance_tree();
|
||||||
void set_relations(CgenNodeP nd);
|
void set_relations(CgenNodeP nd);
|
||||||
|
//* New Methods
|
||||||
|
void dump_inheritance_tree();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CgenClassTable(Classes, ostream &str);
|
CgenClassTable(Classes, ostream &str);
|
||||||
void code();
|
void code();
|
||||||
CgenNodeP root();
|
CgenNodeP root();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CgenNode : public class__class {
|
class CgenNode : public class__class {
|
||||||
private:
|
private:
|
||||||
CgenNodeP parentnd; // Parent of class
|
CgenNodeP parentnd; // Parent of class
|
||||||
@ -57,24 +59,29 @@ private:
|
|||||||
// `NotBasic' otherwise
|
// `NotBasic' otherwise
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CgenNode(Class_ c,
|
CgenNode(Class_ c, Basicness bstatus, CgenClassTableP class_table);
|
||||||
Basicness bstatus,
|
|
||||||
CgenClassTableP class_table);
|
|
||||||
|
|
||||||
void add_child(CgenNodeP child);
|
void add_child(CgenNodeP child);
|
||||||
List<CgenNode> *get_children() { return children; }
|
List<CgenNode> *get_children() { return children; }
|
||||||
void set_parentnd(CgenNodeP p);
|
void set_parentnd(CgenNodeP p);
|
||||||
CgenNodeP get_parentnd() { return parentnd; }
|
CgenNodeP get_parentnd() { return parentnd; }
|
||||||
int basic() { return (basic_status == Basic); }
|
int basic() { return (basic_status == Basic); }
|
||||||
|
void traverse_dump(int pad) {
|
||||||
|
for (int i = 0; i < pad; ++i)
|
||||||
|
std::cerr << " ";
|
||||||
|
std::cerr << this->name << "\n";
|
||||||
|
for (auto l = children; l; l = l->tl()) {
|
||||||
|
l->hd()->traverse_dump(pad + 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BoolConst
|
class BoolConst {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BoolConst(int);
|
BoolConst(int);
|
||||||
void code_def(ostream &, int boolclasstag);
|
void code_def(ostream &, int boolclasstag);
|
||||||
void code_ref(ostream &) const;
|
void code_ref(ostream &) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,30 +1,25 @@
|
|||||||
|
#include "stringtab.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "stringtab.h"
|
|
||||||
|
|
||||||
static int ascii = 0;
|
static int ascii = 0;
|
||||||
|
|
||||||
void ascii_mode(ostream& str)
|
void ascii_mode(ostream &str) {
|
||||||
{
|
if (!ascii) {
|
||||||
if (!ascii)
|
|
||||||
{
|
|
||||||
str << "\t.ascii\t\"";
|
str << "\t.ascii\t\"";
|
||||||
ascii = 1;
|
ascii = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void byte_mode(ostream& str)
|
void byte_mode(ostream &str) {
|
||||||
{
|
if (ascii) {
|
||||||
if (ascii)
|
|
||||||
{
|
|
||||||
str << "\"\n";
|
str << "\"\n";
|
||||||
ascii = 0;
|
ascii = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit_string_constant(ostream& str, char* s)
|
void emit_string_constant(ostream &str, char *s) {
|
||||||
{
|
|
||||||
ascii = 0;
|
ascii = 0;
|
||||||
|
|
||||||
while (*s) {
|
while (*s) {
|
||||||
@ -46,13 +41,10 @@ void emit_string_constant(ostream& str, char* s)
|
|||||||
str << "\\\"";
|
str << "\\\"";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (*s >= ' ' && ((unsigned char) *s) < 128)
|
if (*s >= ' ' && ((unsigned char)*s) < 128) {
|
||||||
{
|
|
||||||
ascii_mode(str);
|
ascii_mode(str);
|
||||||
str << *s;
|
str << *s;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
byte_mode(str);
|
byte_mode(str);
|
||||||
str << "\t.byte\t" << (int)((unsigned char)*s) << endl;
|
str << "\t.byte\t" << (int)((unsigned char)*s) << endl;
|
||||||
}
|
}
|
||||||
@ -63,5 +55,3 @@ void emit_string_constant(ostream& str, char* s)
|
|||||||
byte_mode(str);
|
byte_mode(str);
|
||||||
str << "\t.byte\t0\t" << endl;
|
str << "\t.byte\t0\t" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -8,10 +8,8 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
#include "tree.h"
|
|
||||||
#include "cool-tree.handcode.h"
|
#include "cool-tree.handcode.h"
|
||||||
|
#include "tree.h"
|
||||||
|
|
||||||
// define the class for phylum
|
// define the class for phylum
|
||||||
// define simple phylum - Program
|
// define simple phylum - Program
|
||||||
@ -27,7 +25,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define simple phylum - Class_
|
// define simple phylum - Class_
|
||||||
typedef class Class__class *Class_;
|
typedef class Class__class *Class_;
|
||||||
|
|
||||||
@ -41,7 +38,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define simple phylum - Feature
|
// define simple phylum - Feature
|
||||||
typedef class Feature_class *Feature;
|
typedef class Feature_class *Feature;
|
||||||
|
|
||||||
@ -55,7 +51,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define simple phylum - Formal
|
// define simple phylum - Formal
|
||||||
typedef class Formal_class *Formal;
|
typedef class Formal_class *Formal;
|
||||||
|
|
||||||
@ -69,7 +64,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define simple phylum - Expression
|
// define simple phylum - Expression
|
||||||
typedef class Expression_class *Expression;
|
typedef class Expression_class *Expression;
|
||||||
|
|
||||||
@ -83,7 +77,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define simple phylum - Case
|
// define simple phylum - Case
|
||||||
typedef class Case_class *Case;
|
typedef class Case_class *Case;
|
||||||
|
|
||||||
@ -97,42 +90,35 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define the class for phylum - LIST
|
// define the class for phylum - LIST
|
||||||
// define list phlyum - Classes
|
// define list phlyum - Classes
|
||||||
typedef list_node<Class_> Classes_class;
|
typedef list_node<Class_> Classes_class;
|
||||||
typedef Classes_class *Classes;
|
typedef Classes_class *Classes;
|
||||||
|
|
||||||
|
|
||||||
// define list phlyum - Features
|
// define list phlyum - Features
|
||||||
typedef list_node<Feature> Features_class;
|
typedef list_node<Feature> Features_class;
|
||||||
typedef Features_class *Features;
|
typedef Features_class *Features;
|
||||||
|
|
||||||
|
|
||||||
// define list phlyum - Formals
|
// define list phlyum - Formals
|
||||||
typedef list_node<Formal> Formals_class;
|
typedef list_node<Formal> Formals_class;
|
||||||
typedef Formals_class *Formals;
|
typedef Formals_class *Formals;
|
||||||
|
|
||||||
|
|
||||||
// define list phlyum - Expressions
|
// define list phlyum - Expressions
|
||||||
typedef list_node<Expression> Expressions_class;
|
typedef list_node<Expression> Expressions_class;
|
||||||
typedef Expressions_class *Expressions;
|
typedef Expressions_class *Expressions;
|
||||||
|
|
||||||
|
|
||||||
// define list phlyum - Cases
|
// define list phlyum - Cases
|
||||||
typedef list_node<Case> Cases_class;
|
typedef list_node<Case> Cases_class;
|
||||||
typedef Cases_class *Cases;
|
typedef Cases_class *Cases;
|
||||||
|
|
||||||
|
|
||||||
// define the class for constructors
|
// define the class for constructors
|
||||||
// define constructor - program
|
// define constructor - program
|
||||||
class program_class : public Program_class {
|
class program_class : public Program_class {
|
||||||
public:
|
public:
|
||||||
Classes classes;
|
Classes classes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
program_class(Classes a1) {
|
program_class(Classes a1) { classes = a1; }
|
||||||
classes = a1;
|
|
||||||
}
|
|
||||||
Program copy_Program();
|
Program copy_Program();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -144,7 +130,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - class_
|
// define constructor - class_
|
||||||
class class__class : public Class__class {
|
class class__class : public Class__class {
|
||||||
public:
|
public:
|
||||||
@ -152,6 +137,7 @@ public:
|
|||||||
Symbol parent;
|
Symbol parent;
|
||||||
Features features;
|
Features features;
|
||||||
Symbol filename;
|
Symbol filename;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class__class(Symbol a1, Symbol a2, Features a3, Symbol a4) {
|
class__class(Symbol a1, Symbol a2, Features a3, Symbol a4) {
|
||||||
name = a1;
|
name = a1;
|
||||||
@ -170,7 +156,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - method
|
// define constructor - method
|
||||||
class method_class : public Feature_class {
|
class method_class : public Feature_class {
|
||||||
public:
|
public:
|
||||||
@ -178,6 +163,7 @@ public:
|
|||||||
Formals formals;
|
Formals formals;
|
||||||
Symbol return_type;
|
Symbol return_type;
|
||||||
Expression expr;
|
Expression expr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
method_class(Symbol a1, Formals a2, Symbol a3, Expression a4) {
|
method_class(Symbol a1, Formals a2, Symbol a3, Expression a4) {
|
||||||
name = a1;
|
name = a1;
|
||||||
@ -196,13 +182,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - attr
|
// define constructor - attr
|
||||||
class attr_class : public Feature_class {
|
class attr_class : public Feature_class {
|
||||||
public:
|
public:
|
||||||
Symbol name;
|
Symbol name;
|
||||||
Symbol type_decl;
|
Symbol type_decl;
|
||||||
Expression init;
|
Expression init;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
attr_class(Symbol a1, Symbol a2, Expression a3) {
|
attr_class(Symbol a1, Symbol a2, Expression a3) {
|
||||||
name = a1;
|
name = a1;
|
||||||
@ -220,12 +206,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - formal
|
// define constructor - formal
|
||||||
class formal_class : public Formal_class {
|
class formal_class : public Formal_class {
|
||||||
public:
|
public:
|
||||||
Symbol name;
|
Symbol name;
|
||||||
Symbol type_decl;
|
Symbol type_decl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
formal_class(Symbol a1, Symbol a2) {
|
formal_class(Symbol a1, Symbol a2) {
|
||||||
name = a1;
|
name = a1;
|
||||||
@ -242,13 +228,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - branch
|
// define constructor - branch
|
||||||
class branch_class : public Case_class {
|
class branch_class : public Case_class {
|
||||||
public:
|
public:
|
||||||
Symbol name;
|
Symbol name;
|
||||||
Symbol type_decl;
|
Symbol type_decl;
|
||||||
Expression expr;
|
Expression expr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
branch_class(Symbol a1, Symbol a2, Expression a3) {
|
branch_class(Symbol a1, Symbol a2, Expression a3) {
|
||||||
name = a1;
|
name = a1;
|
||||||
@ -266,12 +252,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - assign
|
// define constructor - assign
|
||||||
class assign_class : public Expression_class {
|
class assign_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Symbol name;
|
Symbol name;
|
||||||
Expression expr;
|
Expression expr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
assign_class(Symbol a1, Expression a2) {
|
assign_class(Symbol a1, Expression a2) {
|
||||||
name = a1;
|
name = a1;
|
||||||
@ -288,7 +274,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - static_dispatch
|
// define constructor - static_dispatch
|
||||||
class static_dispatch_class : public Expression_class {
|
class static_dispatch_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
@ -296,6 +281,7 @@ public:
|
|||||||
Symbol type_name;
|
Symbol type_name;
|
||||||
Symbol name;
|
Symbol name;
|
||||||
Expressions actual;
|
Expressions actual;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static_dispatch_class(Expression a1, Symbol a2, Symbol a3, Expressions a4) {
|
static_dispatch_class(Expression a1, Symbol a2, Symbol a3, Expressions a4) {
|
||||||
expr = a1;
|
expr = a1;
|
||||||
@ -314,13 +300,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - dispatch
|
// define constructor - dispatch
|
||||||
class dispatch_class : public Expression_class {
|
class dispatch_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression expr;
|
Expression expr;
|
||||||
Symbol name;
|
Symbol name;
|
||||||
Expressions actual;
|
Expressions actual;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dispatch_class(Expression a1, Symbol a2, Expressions a3) {
|
dispatch_class(Expression a1, Symbol a2, Expressions a3) {
|
||||||
expr = a1;
|
expr = a1;
|
||||||
@ -338,13 +324,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - cond
|
// define constructor - cond
|
||||||
class cond_class : public Expression_class {
|
class cond_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression pred;
|
Expression pred;
|
||||||
Expression then_exp;
|
Expression then_exp;
|
||||||
Expression else_exp;
|
Expression else_exp;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cond_class(Expression a1, Expression a2, Expression a3) {
|
cond_class(Expression a1, Expression a2, Expression a3) {
|
||||||
pred = a1;
|
pred = a1;
|
||||||
@ -362,12 +348,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - loop
|
// define constructor - loop
|
||||||
class loop_class : public Expression_class {
|
class loop_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression pred;
|
Expression pred;
|
||||||
Expression body;
|
Expression body;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
loop_class(Expression a1, Expression a2) {
|
loop_class(Expression a1, Expression a2) {
|
||||||
pred = a1;
|
pred = a1;
|
||||||
@ -384,12 +370,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - typcase
|
// define constructor - typcase
|
||||||
class typcase_class : public Expression_class {
|
class typcase_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression expr;
|
Expression expr;
|
||||||
Cases cases;
|
Cases cases;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typcase_class(Expression a1, Cases a2) {
|
typcase_class(Expression a1, Cases a2) {
|
||||||
expr = a1;
|
expr = a1;
|
||||||
@ -406,15 +392,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - block
|
// define constructor - block
|
||||||
class block_class : public Expression_class {
|
class block_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expressions body;
|
Expressions body;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
block_class(Expressions a1) {
|
block_class(Expressions a1) { body = a1; }
|
||||||
body = a1;
|
|
||||||
}
|
|
||||||
Expression copy_Expression();
|
Expression copy_Expression();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -426,7 +410,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - let
|
// define constructor - let
|
||||||
class let_class : public Expression_class {
|
class let_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
@ -434,6 +417,7 @@ public:
|
|||||||
Symbol type_decl;
|
Symbol type_decl;
|
||||||
Expression init;
|
Expression init;
|
||||||
Expression body;
|
Expression body;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
let_class(Symbol a1, Symbol a2, Expression a3, Expression a4) {
|
let_class(Symbol a1, Symbol a2, Expression a3, Expression a4) {
|
||||||
identifier = a1;
|
identifier = a1;
|
||||||
@ -452,12 +436,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - plus
|
// define constructor - plus
|
||||||
class plus_class : public Expression_class {
|
class plus_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression e1;
|
Expression e1;
|
||||||
Expression e2;
|
Expression e2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
plus_class(Expression a1, Expression a2) {
|
plus_class(Expression a1, Expression a2) {
|
||||||
e1 = a1;
|
e1 = a1;
|
||||||
@ -474,12 +458,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - sub
|
// define constructor - sub
|
||||||
class sub_class : public Expression_class {
|
class sub_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression e1;
|
Expression e1;
|
||||||
Expression e2;
|
Expression e2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sub_class(Expression a1, Expression a2) {
|
sub_class(Expression a1, Expression a2) {
|
||||||
e1 = a1;
|
e1 = a1;
|
||||||
@ -496,12 +480,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - mul
|
// define constructor - mul
|
||||||
class mul_class : public Expression_class {
|
class mul_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression e1;
|
Expression e1;
|
||||||
Expression e2;
|
Expression e2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
mul_class(Expression a1, Expression a2) {
|
mul_class(Expression a1, Expression a2) {
|
||||||
e1 = a1;
|
e1 = a1;
|
||||||
@ -518,12 +502,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - divide
|
// define constructor - divide
|
||||||
class divide_class : public Expression_class {
|
class divide_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression e1;
|
Expression e1;
|
||||||
Expression e2;
|
Expression e2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
divide_class(Expression a1, Expression a2) {
|
divide_class(Expression a1, Expression a2) {
|
||||||
e1 = a1;
|
e1 = a1;
|
||||||
@ -540,15 +524,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - neg
|
// define constructor - neg
|
||||||
class neg_class : public Expression_class {
|
class neg_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression e1;
|
Expression e1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
neg_class(Expression a1) {
|
neg_class(Expression a1) { e1 = a1; }
|
||||||
e1 = a1;
|
|
||||||
}
|
|
||||||
Expression copy_Expression();
|
Expression copy_Expression();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -560,12 +542,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - lt
|
// define constructor - lt
|
||||||
class lt_class : public Expression_class {
|
class lt_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression e1;
|
Expression e1;
|
||||||
Expression e2;
|
Expression e2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
lt_class(Expression a1, Expression a2) {
|
lt_class(Expression a1, Expression a2) {
|
||||||
e1 = a1;
|
e1 = a1;
|
||||||
@ -582,12 +564,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - eq
|
// define constructor - eq
|
||||||
class eq_class : public Expression_class {
|
class eq_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression e1;
|
Expression e1;
|
||||||
Expression e2;
|
Expression e2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
eq_class(Expression a1, Expression a2) {
|
eq_class(Expression a1, Expression a2) {
|
||||||
e1 = a1;
|
e1 = a1;
|
||||||
@ -604,12 +586,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - leq
|
// define constructor - leq
|
||||||
class leq_class : public Expression_class {
|
class leq_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression e1;
|
Expression e1;
|
||||||
Expression e2;
|
Expression e2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
leq_class(Expression a1, Expression a2) {
|
leq_class(Expression a1, Expression a2) {
|
||||||
e1 = a1;
|
e1 = a1;
|
||||||
@ -626,15 +608,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - comp
|
// define constructor - comp
|
||||||
class comp_class : public Expression_class {
|
class comp_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression e1;
|
Expression e1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
comp_class(Expression a1) {
|
comp_class(Expression a1) { e1 = a1; }
|
||||||
e1 = a1;
|
|
||||||
}
|
|
||||||
Expression copy_Expression();
|
Expression copy_Expression();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -646,15 +626,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - int_const
|
// define constructor - int_const
|
||||||
class int_const_class : public Expression_class {
|
class int_const_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Symbol token;
|
Symbol token;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int_const_class(Symbol a1) {
|
int_const_class(Symbol a1) { token = a1; }
|
||||||
token = a1;
|
|
||||||
}
|
|
||||||
Expression copy_Expression();
|
Expression copy_Expression();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -666,15 +644,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - bool_const
|
// define constructor - bool_const
|
||||||
class bool_const_class : public Expression_class {
|
class bool_const_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Boolean val;
|
Boolean val;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool_const_class(Boolean a1) {
|
bool_const_class(Boolean a1) { val = a1; }
|
||||||
val = a1;
|
|
||||||
}
|
|
||||||
Expression copy_Expression();
|
Expression copy_Expression();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -686,15 +662,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - string_const
|
// define constructor - string_const
|
||||||
class string_const_class : public Expression_class {
|
class string_const_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Symbol token;
|
Symbol token;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
string_const_class(Symbol a1) {
|
string_const_class(Symbol a1) { token = a1; }
|
||||||
token = a1;
|
|
||||||
}
|
|
||||||
Expression copy_Expression();
|
Expression copy_Expression();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -706,15 +680,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - new_
|
// define constructor - new_
|
||||||
class new__class : public Expression_class {
|
class new__class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Symbol type_name;
|
Symbol type_name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
new__class(Symbol a1) {
|
new__class(Symbol a1) { type_name = a1; }
|
||||||
type_name = a1;
|
|
||||||
}
|
|
||||||
Expression copy_Expression();
|
Expression copy_Expression();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -726,15 +698,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - isvoid
|
// define constructor - isvoid
|
||||||
class isvoid_class : public Expression_class {
|
class isvoid_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Expression e1;
|
Expression e1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
isvoid_class(Expression a1) {
|
isvoid_class(Expression a1) { e1 = a1; }
|
||||||
e1 = a1;
|
|
||||||
}
|
|
||||||
Expression copy_Expression();
|
Expression copy_Expression();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -746,13 +716,11 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - no_expr
|
// define constructor - no_expr
|
||||||
class no_expr_class : public Expression_class {
|
class no_expr_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
public:
|
public:
|
||||||
no_expr_class() {
|
no_expr_class() {}
|
||||||
}
|
|
||||||
Expression copy_Expression();
|
Expression copy_Expression();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -764,15 +732,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define constructor - object
|
// define constructor - object
|
||||||
class object_class : public Expression_class {
|
class object_class : public Expression_class {
|
||||||
public:
|
public:
|
||||||
Symbol name;
|
Symbol name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
object_class(Symbol a1) {
|
object_class(Symbol a1) { name = a1; }
|
||||||
name = a1;
|
|
||||||
}
|
|
||||||
Expression copy_Expression();
|
Expression copy_Expression();
|
||||||
void dump(ostream &stream, int n);
|
void dump(ostream &stream, int n);
|
||||||
|
|
||||||
@ -784,7 +750,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// define the prototypes of the interface
|
// define the prototypes of the interface
|
||||||
Classes nil_Classes();
|
Classes nil_Classes();
|
||||||
Classes single_Classes(Class_);
|
Classes single_Classes(Class_);
|
||||||
@ -832,5 +797,4 @@ Expression isvoid(Expression);
|
|||||||
Expression no_expr();
|
Expression no_expr();
|
||||||
Expression object(Symbol);
|
Expression object(Symbol);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -4,17 +4,18 @@
|
|||||||
#ifndef COOL_TREE_HANDCODE_H
|
#ifndef COOL_TREE_HANDCODE_H
|
||||||
#define COOL_TREE_HANDCODE_H
|
#define COOL_TREE_HANDCODE_H
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include "tree.h"
|
|
||||||
#include "cool.h"
|
#include "cool.h"
|
||||||
#include "stringtab.h"
|
#include "stringtab.h"
|
||||||
|
#include "tree.h"
|
||||||
|
#include <iostream>
|
||||||
#define yylineno curr_lineno;
|
#define yylineno curr_lineno;
|
||||||
extern int yylineno;
|
extern int yylineno;
|
||||||
|
|
||||||
inline Boolean copy_Boolean(Boolean b) { return b; }
|
inline Boolean copy_Boolean(Boolean b) { return b; }
|
||||||
inline void assert_Boolean(Boolean) {}
|
inline void assert_Boolean(Boolean) {}
|
||||||
inline void dump_Boolean(ostream& stream, int padding, Boolean b)
|
inline void dump_Boolean(ostream &stream, int padding, Boolean b) {
|
||||||
{ stream << pad(padding) << (int) b << "\n"; }
|
stream << pad(padding) << (int)b << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
void dump_Symbol(ostream &stream, int padding, Symbol b);
|
void dump_Symbol(ostream &stream, int padding, Symbol b);
|
||||||
void assert_Symbol(Symbol b);
|
void assert_Symbol(Symbol b);
|
||||||
@ -48,8 +49,6 @@ typedef Cases_class *Cases;
|
|||||||
virtual void cgen(ostream &) = 0; \
|
virtual void cgen(ostream &) = 0; \
|
||||||
virtual void dump_with_types(ostream &, int) = 0;
|
virtual void dump_with_types(ostream &, int) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define program_EXTRAS \
|
#define program_EXTRAS \
|
||||||
void cgen(ostream &); \
|
void cgen(ostream &); \
|
||||||
void dump_with_types(ostream &, int);
|
void dump_with_types(ostream &, int);
|
||||||
@ -60,42 +59,31 @@ virtual Symbol get_parent() = 0; \
|
|||||||
virtual Symbol get_filename() = 0; \
|
virtual Symbol get_filename() = 0; \
|
||||||
virtual void dump_with_types(ostream &, int) = 0;
|
virtual void dump_with_types(ostream &, int) = 0;
|
||||||
|
|
||||||
|
|
||||||
#define class__EXTRAS \
|
#define class__EXTRAS \
|
||||||
Symbol get_name() { return name; } \
|
Symbol get_name() { return name; } \
|
||||||
Symbol get_parent() { return parent; } \
|
Symbol get_parent() { return parent; } \
|
||||||
Symbol get_filename() { return filename; } \
|
Symbol get_filename() { return filename; } \
|
||||||
void dump_with_types(ostream &, int);
|
void dump_with_types(ostream &, int);
|
||||||
|
|
||||||
|
#define Feature_EXTRAS virtual void dump_with_types(ostream &, int) = 0;
|
||||||
|
|
||||||
#define Feature_EXTRAS \
|
#define Feature_SHARED_EXTRAS void dump_with_types(ostream &, int);
|
||||||
virtual void dump_with_types(ostream&,int) = 0;
|
|
||||||
|
|
||||||
|
#define Formal_EXTRAS virtual void dump_with_types(ostream &, int) = 0;
|
||||||
|
|
||||||
#define Feature_SHARED_EXTRAS \
|
#define formal_EXTRAS void dump_with_types(ostream &, int);
|
||||||
void dump_with_types(ostream&,int);
|
|
||||||
|
|
||||||
|
#define Case_EXTRAS virtual void dump_with_types(ostream &, int) = 0;
|
||||||
|
|
||||||
#define Formal_EXTRAS \
|
#define branch_EXTRAS void dump_with_types(ostream &, int);
|
||||||
virtual void dump_with_types(ostream&,int) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
#define formal_EXTRAS \
|
|
||||||
void dump_with_types(ostream&,int);
|
|
||||||
|
|
||||||
|
|
||||||
#define Case_EXTRAS \
|
|
||||||
virtual void dump_with_types(ostream& ,int) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
#define branch_EXTRAS \
|
|
||||||
void dump_with_types(ostream& ,int);
|
|
||||||
|
|
||||||
|
|
||||||
#define Expression_EXTRAS \
|
#define Expression_EXTRAS \
|
||||||
Symbol type; \
|
Symbol type; \
|
||||||
Symbol get_type() { return type; } \
|
Symbol get_type() { return type; } \
|
||||||
Expression set_type(Symbol s) { type = s; return this; } \
|
Expression set_type(Symbol s) { \
|
||||||
|
type = s; \
|
||||||
|
return this; \
|
||||||
|
} \
|
||||||
virtual void code(ostream &) = 0; \
|
virtual void code(ostream &) = 0; \
|
||||||
virtual void dump_with_types(ostream &, int) = 0; \
|
virtual void dump_with_types(ostream &, int) = 0; \
|
||||||
void dump_type(ostream &, int); \
|
void dump_type(ostream &, int); \
|
||||||
@ -105,5 +93,4 @@ Expression_class() { type = (Symbol) NULL; }
|
|||||||
void code(ostream &); \
|
void code(ostream &); \
|
||||||
void dump_with_types(ostream &, int);
|
void dump_with_types(ostream &, int);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -3,7 +3,27 @@
|
|||||||
as possible.
|
as possible.
|
||||||
*)
|
*)
|
||||||
|
|
||||||
class Main {
|
class A inherits IO {
|
||||||
|
attr_A_1 : Int <- 10;
|
||||||
|
attr_A_2 : Bool <- false;
|
||||||
|
attr_A_3 : A <- self;
|
||||||
|
method_common(x1: Int) : SELF_TYPE {
|
||||||
|
self
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class B inherits A {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class C inherits A {
|
||||||
|
attr_C_1 : String <- "This is C\n";
|
||||||
|
method_common(x1: Int) : SELF_TYPE {
|
||||||
|
self
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Main inherits IO {
|
||||||
main():Int { 0 };
|
main():Int { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
BIN
handouts/cool-runtime.pdf
Normal file
BIN
handouts/cool-runtime.pdf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user