├── .gitignore ├── asm.bash ├── build.bash ├── c2nasm.bash ├── codegen.bash ├── doc └── report.pdf ├── lib ├── antlr-4.6-complete.jar ├── lib.s └── library.c ├── optim.bash ├── readme.md ├── semantic.bash ├── src └── com │ └── mercy │ └── compiler │ ├── AST │ ├── ArefNode.java │ ├── AssignNode.java │ ├── BinaryOpNode.java │ ├── BlockNode.java │ ├── BoolLiteralNode.java │ ├── BreakNode.java │ ├── ClassDefNode.java │ ├── ContinueNode.java │ ├── CreatorNode.java │ ├── DefinitionNode.java │ ├── ExprNode.java │ ├── ExprStmtNode.java │ ├── ForNode.java │ ├── FuncallNode.java │ ├── FunctionDefNode.java │ ├── IfNode.java │ ├── IntegerLiteralNode.java │ ├── LHSNode.java │ ├── LiteralNode.java │ ├── Location.java │ ├── LogicalAndNode.java │ ├── LogicalOrNode.java │ ├── MemberNode.java │ ├── Node.java │ ├── NodeDesign.txt │ ├── PrefixOpNode.java │ ├── ReturnNode.java │ ├── StmtNode.java │ ├── StringLiteralNode.java │ ├── SuffixOpNode.java │ ├── UnaryOpNode.java │ ├── VariableDefNode.java │ ├── VariableNode.java │ └── WhileNode.java │ ├── BackEnd │ ├── Allocator.java │ ├── BasicBlock.java │ ├── ControlFlowAnalyzer.java │ ├── DataFlowAnalyzer.java │ ├── IRBuilder.java │ ├── InstructionEmitter.java │ ├── NaiveAllocator.java │ ├── RegisterConfig.java │ └── Translator.java │ ├── Entity │ ├── ClassEntity.java │ ├── Entity.java │ ├── FunctionEntity.java │ ├── MemberEntity.java │ ├── ParameterEntity.java │ ├── Scope.java │ ├── StringConstantEntity.java │ └── VariableEntity.java │ ├── FrontEnd │ ├── AST.java │ ├── ASTBuilder.java │ ├── ASTVisitor.java │ ├── OutputIrrelevantMaker.java │ ├── ParserErrorListener.java │ ├── SymbolResolver.java │ ├── TypeChecker.java │ └── Visitor.java │ ├── INS │ ├── Add.java │ ├── And.java │ ├── Bin.java │ ├── CJump.java │ ├── Call.java │ ├── Cmp.java │ ├── Comment.java │ ├── Div.java │ ├── Instruction.java │ ├── Jmp.java │ ├── Label.java │ ├── Lea.java │ ├── Mod.java │ ├── Move.java │ ├── Mul.java │ ├── Neg.java │ ├── Not.java │ ├── Operand │ │ ├── Address.java │ │ ├── Immediate.java │ │ ├── Operand.java │ │ ├── Reference.java │ │ └── Register.java │ ├── Or.java │ ├── Pop.java │ ├── Push.java │ ├── Return.java │ ├── Sal.java │ ├── Sar.java │ ├── Sub.java │ └── Xor.java │ ├── IR │ ├── Addr.java │ ├── Assign.java │ ├── Binary.java │ ├── CJump.java │ ├── Call.java │ ├── Expr.java │ ├── IR.java │ ├── IntConst.java │ ├── Jump.java │ ├── Label.java │ ├── Mem.java │ ├── Return.java │ ├── StrConst.java │ ├── Unary.java │ └── Var.java │ ├── Main.java │ ├── Option.java │ ├── Parser │ ├── Malic.g4 │ ├── Malic.tokens │ ├── MalicBaseListener.java │ ├── MalicLexer.java │ ├── MalicLexer.tokens │ ├── MalicListener.java │ └── MalicParser.java │ ├── Type │ ├── ArrayType.java │ ├── BoolType.java │ ├── ClassType.java │ ├── FunctionType.java │ ├── IntegerType.java │ ├── NullType.java │ ├── StringType.java │ ├── Type.java │ └── VoidType.java │ └── Utility │ ├── InternalError.java │ ├── LibFunction.java │ ├── Pair.java │ ├── SemanticError.java │ └── Triple.java ├── test └── com │ └── mercy │ └── compiler │ ├── BackEnd │ └── FinalTest.java │ └── FrontEnd │ └── SemanticTest.java └── testcase ├── coverall.c ├── final ├── a-function-call.mx ├── a-function-call.out ├── array_test1-mahaojun.in ├── array_test1-mahaojun.mx ├── array_test1-mahaojun.out ├── array_test2-mahaojun.in ├── array_test2-mahaojun.mx ├── array_test2-mahaojun.out ├── basicopt1-5100309127-hetianxing.mx ├── basicopt1-5100309127-hetianxing.out ├── builtin-5140519064-youyurong.in ├── builtin-5140519064-youyurong.mx ├── builtin-5140519064-youyurong.out ├── class_test-mahaojun.mx ├── class_test-mahaojun.out ├── cnf-lp.mx ├── cnf-lp.out ├── common_assign.in ├── common_assign.mx ├── common_assign.out ├── expr-5110309085-jintianxing.mx ├── expr-5110309085-jintianxing.out ├── function_test-huyuncong.in ├── function_test-huyuncong.mx ├── function_test-huyuncong.out ├── gcd-5090379042-jiaxiao.mx ├── gcd-5090379042-jiaxiao.out ├── gcd-modified.mx ├── gcd-modified.out ├── hanoi-5100379110-daibo.in ├── hanoi-5100379110-daibo.mx ├── hanoi-5100379110-daibo.out ├── hashmap-5100309127-hetianxing.mx ├── hashmap-5100309127-hetianxing.out ├── heapsort-5100379110-daibo.in ├── heapsort-5100379110-daibo.mx ├── heapsort-5100379110-daibo.out ├── heiye.mx ├── heiye.out ├── horse-5100309153-yanghuan.in ├── horse-5100309153-yanghuan.mx ├── horse-5100309153-yanghuan.out ├── horse2-5100309153-yanghuan.in ├── horse2-5100309153-yanghuan.mx ├── horse2-5100309153-yanghuan.out ├── horse3-5100309153-yanghuan.in ├── horse3-5100309153-yanghuan.mx ├── horse3-5100309153-yanghuan.out ├── lvalue2-5110379024-wuhang.mx ├── lvalue2-5110379024-wuhang.out ├── magic-5100309153-yanghuan.mx ├── magic-5100309153-yanghuan.out ├── manyarguments-5100379110-daibo.mx ├── manyarguments-5100379110-daibo.out ├── maxflow-5100379110-daibo.mx ├── maxflow-5100379110-daibo.out ├── merge_sort.in ├── merge_sort.mx ├── merge_sort.out ├── mics-515030910117-zhenglianmin.in ├── mics-515030910117-zhenglianmin.mx ├── mics-515030910117-zhenglianmin.out ├── multiarray-5100309153-yanghuan.mx ├── multiarray-5100309153-yanghuan.out ├── pi-5090379042-jiaxiao.mx ├── pi-5090379042-jiaxiao.out ├── point-5140309561-sunxingyuan.mx ├── point-5140309561-sunxingyuan.out ├── prime-5100309153-yanghuan.in ├── prime-5100309153-yanghuan.mx ├── prime-5100309153-yanghuan.out ├── qsort-5100379110-daibo.mx ├── qsort-5100379110-daibo.out ├── queens-5100379110-daibo.mx ├── queens-5100379110-daibo.out ├── sha1.in ├── sha1.mx ├── sha1.out ├── statement_test-huyuncong.in ├── statement_test-huyuncong.mx ├── statement_test-huyuncong.out ├── string_test-huyuncong.in ├── string_test-huyuncong.mx ├── string_test-huyuncong.out ├── superloop-5090379042-jiaxiao.in ├── superloop-5090379042-jiaxiao.mx ├── superloop-5090379042-jiaxiao.out ├── tak-5090379042-jiaxiao.in ├── tak-5090379042-jiaxiao.mx ├── tak-5090379042-jiaxiao.out ├── twinprime-5090379042-jiaxiao.mx ├── twinprime-5090379042-jiaxiao.out ├── useless.in ├── useless.mx ├── useless.out ├── vector-5140519064-youyurong.mx ├── vector-5140519064-youyurong.out ├── xbulgarian-5110379024-wuhang.mx ├── xbulgarian-5110379024-wuhang.out ├── yingsihao.mx ├── yingsihao.out ├── zspill2-5100379110-daibo.mx └── zspill2-5100379110-daibo.out ├── semantic ├── error │ ├── arrop-1-5100379071-puyouer.mx │ ├── asiop-1-5100379071-puyouer.mx │ ├── asiop-2-5100379071-puyouer.mx │ ├── asiop-3-5120309049-liaochao.mx │ ├── asiop-4-5120309049-liaochao.mx │ ├── asiop-5-5100379071-puyouer.mx │ ├── asiop-6-5100379071-puyouer.mx │ ├── asiop-7-5120309049-liaochao.mx │ ├── biop-1-5100379071-puyouer.mx │ ├── bitop-1-5120309049-liaochao.mx │ ├── boop-1-5120309049-liaochao.mx │ ├── class-1-5100379071-puyouer.mx │ ├── class-2-5120309049-liaochao.mx │ ├── class-5-515030910117-zhenglianmin.mx │ ├── class-6-515030910117-zhenglianmin.mx │ ├── class-7-515030910117-zhenglianmin..mx │ ├── constructor-chenxinhao.mx │ ├── creator-515030910117-zhenglianmin..mx │ ├── ctrflow-1-5100379071-puyouer.mx │ ├── ctrflow-2-5120309049-liaochao.mx │ ├── ctrflow-3-5100379071-puyouer.mx │ ├── ctrflow-4-5120309049-liaochao.mx │ ├── ctrflow-5-5120309049-liaochao.mx │ ├── fldop-1-5120309049-liaochao.mx │ ├── func-1-5100379071-puyouer.mx │ ├── func-2-5120309049-liaochao.mx │ ├── func-3-5100379071-puyouer.mx │ ├── func-4-5100379071-puyouer.mx │ ├── func-5-5100309127-hetianxing.mx │ ├── func-6-5130309059-lijiajun.mx │ ├── func-7-5140309552-wancheng.mx │ ├── incop-1-5120309049-liaochao.mx │ ├── relop-1-5120309049-liaochao.mx │ ├── relop-2-5120309049-liaochao.mx │ ├── scope-1-5140519064-youyurong.mx │ ├── scope-1-515030910117-zhenglianmin.mx │ ├── scope-2-5140519064-youyurong.mx │ ├── selfref-5090379042-jiaxiao.mill │ ├── var-1-5110379024-wuhang.mx │ ├── var-2-5100309127-hetianxing.mx │ ├── var-3-5120309049-liaochao.mx │ └── var-4-5140309552-wancheng.mx ├── manual.c └── pass │ ├── basic_test-yurongyou.mx │ ├── basicopt1-5100309127-hetianxing.mx │ ├── blank-515030910117-zhenglianmin.mx │ ├── builtin-5140519064-youyurong.mx │ ├── bulgarian-5110379024-wuhang.mx │ ├── class-1-515030910117-zhenglianmin..mx │ ├── class-2-515030910117-zhenglianmin..mx │ ├── expr-5110309085-jintianxing.mx │ ├── hanoi-5100379110-daibo.mx │ ├── hashmap-5100309127-hetianxing.mx │ ├── heapsort-5100379110-daibo.mx │ ├── horse-5100309153-yanghuan.mx │ ├── horse2-5100309153-yanghuan.mx │ ├── horse3-5100309153-yanghuan.mx │ ├── lvalue2-5110379024-wuhang.mx │ ├── magic-5100309153-yanghuan.mx │ ├── maxflow-5100379110-daibo.mx │ ├── naive-xianzang.mx │ ├── noname-xuzhenjia.mx │ ├── prime-5100309153-yanghuan.mx │ ├── qsort-5100379110-daibo.mx │ ├── queens-5100379110-daibo.mx │ ├── spill2-5100379110-daibo.mx │ ├── superloop-5090379042-jiaxiao.mx │ ├── tak-5090379042-jiaxiao.mx │ ├── twinprime-5090379042-jiaxiao.mx │ ├── vector-youyurong.mx │ └── zk.mx └── test.c /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | out 3 | bin 4 | *.iml 5 | 6 | note.txt 7 | 8 | ./*.out 9 | *.asm 10 | *.o 11 | 12 | 13 | a.out 14 | main.c 15 | debug.c 16 | in.txt 17 | -------------------------------------------------------------------------------- /asm.bash: -------------------------------------------------------------------------------- 1 | nasm -felf64 $1.asm && gcc $1.o && time ./a.out 2 | -------------------------------------------------------------------------------- /build.bash: -------------------------------------------------------------------------------- 1 | # this script is called when the judge is building your compiler. 2 | # no argument will be passed in. 3 | 4 | # compile 5 | set -e 6 | cd "$(dirname "$0")" 7 | mkdir -p bin 8 | find ./src -name *.java | javac -d bin -classpath "lib/antlr-4.6-complete.jar" @/dev/stdin 9 | 10 | # make jar 11 | cd bin 12 | jar xf ../lib/antlr-4.6-complete.jar 13 | rm -rf ./META-INF/ 14 | jar cef com.mercy.compiler.Main Malic.jar . 15 | cp Malic.jar .. 16 | -------------------------------------------------------------------------------- /c2nasm.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # thanks to http://stackoverflow.com/a/20743090 3 | # thanks to https://github.com/diogovk/c2nasm 4 | # install objconv: https://github.com/vertis/objconv 5 | # 6 | # $1: source code 7 | 8 | set -e 9 | C_FILE="$1" 10 | BASE_NAME="${C_FILE%.*}" 11 | O_FILE="$BASE_NAME.o" 12 | NASM_FILE="$BASE_NAME.asm" 13 | gcc -Werror=implicit-function-declaration -fno-asynchronous-unwind-tables "$2" -c -o "$O_FILE" "$C_FILE" 14 | objconv -fnasm "$O_FILE" "$NASM_FILE" 15 | sed -i 's|st(0)|st0 |g' "$NASM_FILE" 16 | sed -i 's|noexecute| |g' "$NASM_FILE" 17 | sed -i 's|execute| |g' "$NASM_FILE" 18 | sed -i 's|: function||g' "$NASM_FILE" 19 | sed -i 's|?_|L_|g' "$NASM_FILE" 20 | sed -i -n '/SECTION .eh_frame/q;p' "$NASM_FILE" 21 | sed -i 's|;.*||g' "$NASM_FILE" 22 | sed -i 's/^M//g' "$NASM_FILE" 23 | sed -i 's|\s\+$||g' "$NASM_FILE" 24 | sed -i 's|align=1||g' "$NASM_FILE" 25 | rm "$O_FILE" 26 | cat $NASM_FILE 27 | #nasm -felf64 main.asm && gcc main.o && ./a.out 28 | -------------------------------------------------------------------------------- /codegen.bash: -------------------------------------------------------------------------------- 1 | set -e 2 | cd "$(dirname "$0")" 3 | cat > testcase/test.c # save everything in stdin to test.c 4 | java -jar Malic.jar -in testcase/test.c -out out.asm 5 | cat out.asm 6 | -------------------------------------------------------------------------------- /doc/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merrymercy/compiler2017/f04d8876b6f7bafca42823ac21848d654bdef272/doc/report.pdf -------------------------------------------------------------------------------- /lib/antlr-4.6-complete.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merrymercy/compiler2017/f04d8876b6f7bafca42823ac21848d654bdef272/lib/antlr-4.6-complete.jar -------------------------------------------------------------------------------- /lib/library.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | unsigned char *__lib_str_operator_ADD(unsigned char *a, unsigned char *b) { 5 | int l1 = *(((int *)a) - 1); 6 | int l2 = *(((int *)b) - 1); 7 | int l3 = l1 + l2; 8 | 9 | unsigned char *ret = (unsigned char *)malloc(l3 + 1 + sizeof(int)); 10 | *((int *)ret) = l3; 11 | ret = ret + sizeof(int); 12 | for (int i = 0; i < l1; i++) 13 | ret[i] = a[i]; 14 | ret = ret + l1; 15 | for (int i = 0; i < l2; i++) 16 | ret[i] = b[i]; 17 | ret[l2] = 0; 18 | return ret - l1; 19 | } 20 | 21 | unsigned char *__lib_str_substring(unsigned char *a, long low, long high) { 22 | int l = high - low + 1; 23 | 24 | unsigned char *ret = (unsigned char *)malloc(l + 1 + sizeof(int)); 25 | *((int *)ret) = l; 26 | ret = ret + sizeof(int); 27 | a += low; 28 | for (int i = 0; i < l; i++) 29 | ret[i] = a[i]; 30 | ret[l] = 0; 31 | return ret; 32 | } 33 | 34 | unsigned char *toString(long x) { 35 | unsigned char *ret = (unsigned char*)malloc(12 + sizeof(int)); 36 | ret += sizeof(int); 37 | unsigned char *p = ret; 38 | 39 | if (x < 0) { 40 | *p++ = '-'; 41 | x = -x; 42 | } 43 | 44 | if (x == 0) 45 | *p++ = '0'; 46 | 47 | unsigned char *begin = p; 48 | while (x) { 49 | int next = x / 10; 50 | *p++ = '0' + x - next * 10; 51 | x = next; 52 | } 53 | *p = 0; 54 | *(((int *)ret) - 1) = p - ret; 55 | 56 | p--; 57 | while (begin <= p) { 58 | char t = *begin; 59 | *begin = *p; 60 | *p = t; 61 | begin++; 62 | p--; 63 | } 64 | 65 | return ret; 66 | } 67 | 68 | int main() { 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /optim.bash: -------------------------------------------------------------------------------- 1 | set -e 2 | cd "$(dirname "$0")" 3 | cat > testcase/test.c # save everything in stdin to test.c 4 | java -jar Malic.jar -in testcase/test.c -out out.asm 5 | cat out.asm 6 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Malic for compiler 2017 2 | 3 | A compiler for the course [Compiler 2017](http://acm.sjtu.edu.cn/wiki/Compiler_2017) at ACM Class, SJTU. 4 | 5 | The source is a java-like language. 6 | The target is x86-64 NASM. 7 | 8 | With various optimizations, this compiler was ranked first in the performance competition of the course. 9 | 10 | ## Optimization 11 | * Instruction selection 12 | * Function inlining 13 | * Control flow analysis 14 | * redundant jump elimination 15 | * Dataflow analysis 16 | * common sub-expression elimination 17 | * constant propagation and folding 18 | * dead code elimination 19 | * Register Allocation 20 | * a full implementation of George, Lal; Appel, Andrew W. (May 1996). *"Iterated Register Coalescing“* 21 | 22 | for more details, please refer to [my report](doc/report.pdf) 23 | 24 | ## Build 25 | ``` 26 | bash build.bash 27 | ``` 28 | 29 | ## Usage 30 | ``` 31 | Usage: java -jar Malic.jar [options] 32 | Options: 33 | -in : M* language source code 34 | -out : x86-64 NASM output 35 | -help : print this help page 36 | ``` 37 | -------------------------------------------------------------------------------- /semantic.bash: -------------------------------------------------------------------------------- 1 | # this script is called when the judge wants our compiler to compile a source file. 2 | # print the compiled source, i.e. asm code, directly to stdout. 3 | # don't print anything other to stdout. 4 | # if you would like to print some debug information, please go to stderr. 5 | # $1 is the path to the source file. 6 | # $2 is the path to the target file. 7 | 8 | set -e 9 | cd "$(dirname "$0")" 10 | cat > testcase/test.c # save everything in stdin to test.c 11 | java -jar Malic.jar -in testcase/test.c -out out.asm 12 | $CCHK 13 | 14 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/ArefNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | import com.mercy.compiler.Type.Type; 5 | 6 | /** 7 | * Created by mercy on 17-3-21. 8 | */ 9 | public class ArefNode extends LHSNode { 10 | private ExprNode expr, index; 11 | 12 | public ArefNode(ExprNode expr, ExprNode index) { 13 | this.expr = expr; 14 | this.index = index; 15 | } 16 | 17 | public ArefNode(ExprNode expr, ExprNode index, Type type) { 18 | this.expr = expr; 19 | this.index = index; 20 | this.type = type; 21 | } 22 | 23 | public ExprNode expr() { return expr; } 24 | public ExprNode index() { return index; } 25 | 26 | public boolean isMultiDimension() { 27 | return (expr instanceof ArefNode); 28 | } 29 | 30 | public ExprNode baseExpr() { 31 | return isMultiDimension() ? ((ArefNode)expr).baseExpr() : expr; 32 | } 33 | 34 | public Location location() { 35 | return expr.location(); 36 | } 37 | 38 | public E accept(ASTVisitor visitor) { 39 | return visitor.visit(this); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/AssignNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | import com.mercy.compiler.Type.Type; 5 | 6 | /** 7 | * Created by mercy on 17-3-18. 8 | */ 9 | public class AssignNode extends ExprNode { 10 | private ExprNode lhs, rhs; 11 | 12 | public AssignNode(ExprNode lhs, ExprNode rhs) { 13 | super(); 14 | this.lhs = lhs; 15 | this.rhs = rhs; 16 | } 17 | 18 | public ExprNode lhs() { 19 | return lhs; 20 | } 21 | public void setLhs(ExprNode lhs) { 22 | this.lhs = lhs; 23 | } 24 | 25 | public ExprNode rhs() { 26 | return rhs; 27 | } 28 | public void setRhs(ExprNode rhs) { 29 | this.rhs = rhs; 30 | } 31 | 32 | @Override 33 | public Type type() { 34 | return lhs.type(); 35 | } 36 | 37 | @Override 38 | public Location location() { 39 | return lhs.location(); 40 | } 41 | 42 | @Override 43 | public E accept(ASTVisitor visitor) { 44 | return visitor.visit(this); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/BinaryOpNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | import com.mercy.compiler.Type.Type; 5 | import com.mercy.compiler.Utility.InternalError; 6 | 7 | /** 8 | * Created by mercy on 17-3-18. 9 | */ 10 | public class BinaryOpNode extends ExprNode { 11 | public enum BinaryOp { 12 | ADD, SUB, MUL, DIV, MOD, 13 | LSHIFT, RSHIFT, LT, GT, LE, GE, EQ, NE, 14 | BIT_AND, BIT_XOR, BIT_OR, 15 | LOGIC_AND, LOGIC_OR 16 | } 17 | 18 | private BinaryOp operator; 19 | private ExprNode left, right; 20 | private Type type; 21 | 22 | public BinaryOpNode(ExprNode left, BinaryOp op, ExprNode right) { 23 | super(); 24 | this.operator = op; 25 | this.left = left; 26 | this.right = right; 27 | } 28 | 29 | public BinaryOpNode(Type t, ExprNode left, BinaryOp op, ExprNode right) { 30 | super(); 31 | this.type = t; 32 | this.operator = op; 33 | this.left = left; 34 | this.right = right; 35 | } 36 | 37 | public BinaryOp operator() { 38 | return operator; 39 | } 40 | 41 | public void setOperator(BinaryOp operator) { 42 | this.operator = operator; 43 | } 44 | 45 | public ExprNode left() { 46 | return left; 47 | } 48 | 49 | public void setLeft(ExprNode left) { 50 | this.left = left; 51 | } 52 | 53 | public ExprNode right() { 54 | return right; 55 | } 56 | 57 | public void setRight(ExprNode right) { 58 | this.right = right; 59 | } 60 | 61 | public void setType(Type type) { 62 | if (this.type != null) 63 | throw new InternalError("BinaryOp#setType called twice"); 64 | this.type = type; 65 | } 66 | 67 | @Override 68 | public Type type() { 69 | return (type != null) ? type : left.type(); 70 | } 71 | 72 | @Override 73 | public Location location() { 74 | return left.location(); 75 | } 76 | 77 | @Override 78 | public E accept(ASTVisitor visitor) { 79 | return visitor.visit(this); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/BlockNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.Entity.Scope; 4 | import com.mercy.compiler.FrontEnd.ASTVisitor; 5 | 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | 9 | /** 10 | * Created by mercy on 17-3-18. 11 | */ 12 | public class BlockNode extends StmtNode { 13 | private List stmts; 14 | private Scope scope; 15 | 16 | public BlockNode(Location loc, List stmts) { 17 | super(loc); 18 | this.stmts = stmts; 19 | } 20 | 21 | public static BlockNode wrapBlock(StmtNode node) { 22 | if (node == null) 23 | return null; //new BlockNode(new Location(0,0), new LinkedList<>()); 24 | 25 | if (node instanceof BlockNode) { 26 | return (BlockNode) node; 27 | } else { 28 | return new BlockNode(node.location(), 29 | new LinkedList() {{ 30 | add(node); 31 | }}); 32 | } 33 | } 34 | 35 | public List stmts() { 36 | return stmts; 37 | } 38 | 39 | public Scope scope() { 40 | return scope; 41 | } 42 | public void setScope(Scope scope) { 43 | this.scope = scope; 44 | } 45 | 46 | 47 | @Override 48 | public S accept(ASTVisitor visitor) { 49 | return visitor.visit(this); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/BoolLiteralNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | import com.mercy.compiler.Type.BoolType; 5 | 6 | /** 7 | * Created by mercy on 17-3-23. 8 | */ 9 | public class BoolLiteralNode extends LiteralNode { 10 | private boolean value; 11 | 12 | public BoolLiteralNode(Location loc, boolean value) { 13 | super(loc, new BoolType()); 14 | this.value = value; 15 | } 16 | 17 | public boolean value() { 18 | return value; 19 | } 20 | 21 | @Override 22 | public E accept(ASTVisitor visitor) { 23 | return visitor.visit(this); 24 | } 25 | } -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/BreakNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | public class BreakNode extends StmtNode { 9 | public BreakNode(Location loc) { 10 | super(loc); 11 | } 12 | 13 | @Override 14 | public S accept(ASTVisitor visitor) { 15 | return visitor.visit(this); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/ClassDefNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.Entity.ClassEntity; 4 | import com.mercy.compiler.FrontEnd.ASTVisitor; 5 | 6 | /** 7 | * Created by mercy on 17-3-18. 8 | */ 9 | public class ClassDefNode extends DefinitionNode { 10 | private ClassEntity entity; // store all information in entity 11 | 12 | public ClassDefNode(ClassEntity entity) { 13 | super(entity.location(), entity.name()); 14 | this.entity = entity; 15 | } 16 | 17 | public ClassEntity entity() { 18 | return entity; 19 | } 20 | 21 | @Override 22 | public S accept(ASTVisitor visitor) { 23 | return visitor.visit(this); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/ContinueNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | public class ContinueNode extends StmtNode { 9 | public ContinueNode(Location loc) { 10 | super(loc); 11 | } 12 | 13 | @Override 14 | public S accept(ASTVisitor visitor) { 15 | return visitor.visit(this); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/CreatorNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | import com.mercy.compiler.Type.Type; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by mercy on 17-3-18. 10 | */ 11 | public class CreatorNode extends ExprNode { 12 | private Location location; 13 | private Type type; 14 | private List exprs; 15 | private int total; 16 | 17 | public CreatorNode(Location loc, Type type, List exprs, int total) { 18 | this.location = loc; 19 | this.type = type; 20 | this.exprs = exprs; 21 | this.total = total; 22 | } 23 | 24 | @Override 25 | public Type type() { 26 | return type; 27 | } 28 | 29 | public List exprs() { 30 | return exprs; 31 | } 32 | 33 | public void setExprs(List exprs) { 34 | this.exprs = exprs; 35 | } 36 | 37 | public int total() { 38 | return total; 39 | } 40 | 41 | @Override 42 | public Location location() { 43 | return location; 44 | } 45 | 46 | @Override 47 | public E accept(ASTVisitor visitor) { 48 | return visitor.visit(this); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/DefinitionNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-23. 7 | */ 8 | abstract public class DefinitionNode extends StmtNode { 9 | protected String name; 10 | 11 | public DefinitionNode(Location loc, String name) { 12 | super(loc); 13 | this.name = name; 14 | } 15 | 16 | public String name() { 17 | return name; 18 | } 19 | 20 | abstract public S accept(ASTVisitor visitor); 21 | } 22 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/ExprNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | import com.mercy.compiler.Type.Type; 5 | 6 | /** 7 | * Created by mercy on 17-3-18. 8 | */ 9 | abstract public class ExprNode extends Node { 10 | private boolean isAssignable = false; 11 | public ExprNode() { 12 | super(); 13 | } 14 | 15 | abstract public Type type(); 16 | 17 | public long allocSize() { return type().allocSize(); } 18 | 19 | public boolean isConstant() { 20 | return false; 21 | } 22 | public boolean isParameter() { 23 | return false; 24 | } 25 | 26 | public boolean isLvalue() { 27 | return false; 28 | } 29 | public boolean isAssignable() { 30 | return isAssignable; 31 | } 32 | public boolean isLoadable() { 33 | return false; 34 | } 35 | 36 | public void setAssignable(boolean isAssignable) { 37 | this.isAssignable = isAssignable; 38 | } 39 | 40 | abstract public E accept(ASTVisitor visitor); 41 | } 42 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/ExprStmtNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | public class ExprStmtNode extends StmtNode { 9 | private ExprNode expr; 10 | 11 | public ExprStmtNode(Location loc, ExprNode expr) { 12 | super(loc); 13 | this.expr = expr; 14 | } 15 | 16 | public void setExpr(ExprNode expr) { 17 | this.expr = expr; 18 | } 19 | 20 | public ExprNode expr() { 21 | return expr; 22 | } 23 | 24 | @Override 25 | public S accept(ASTVisitor visitor) { 26 | return visitor.visit(this); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/ForNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | public class ForNode extends StmtNode { 9 | private ExprNode init, cond, incr; 10 | private StmtNode body; 11 | 12 | public ForNode(Location loc, ExprNode init, ExprNode cond, ExprNode incr, StmtNode body) { 13 | super(loc); 14 | this.init = init; 15 | this.cond = cond; 16 | this.incr = incr; 17 | this.body = BlockNode.wrapBlock(body); 18 | } 19 | 20 | public ExprNode init() { 21 | return init; 22 | } 23 | 24 | public ExprNode cond() { 25 | return cond; 26 | } 27 | 28 | public ExprNode incr() { 29 | return incr; 30 | } 31 | 32 | public StmtNode body() { 33 | return body; 34 | } 35 | 36 | @Override 37 | public S accept(ASTVisitor visitor) { 38 | return visitor.visit(this); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/FuncallNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | import com.mercy.compiler.Type.FunctionType; 5 | import com.mercy.compiler.Type.Type; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by mercy on 17-3-18. 11 | */ 12 | public class FuncallNode extends ExprNode { 13 | private ExprNode expr; 14 | private List args; 15 | 16 | public FuncallNode(ExprNode expr, List args) { 17 | this.expr = expr; 18 | this.args = args; 19 | } 20 | 21 | public ExprNode expr() { 22 | return expr; 23 | } 24 | 25 | public List args() { 26 | return args; 27 | } 28 | 29 | public void addThisPointer(ExprNode expr) { 30 | args.add(0, expr); 31 | } 32 | 33 | @Override 34 | public Type type() { 35 | return functionType().entity().returnType(); 36 | } 37 | 38 | public FunctionType functionType() { 39 | return (FunctionType)expr.type(); 40 | } 41 | 42 | @Override 43 | public Location location() { 44 | return expr.location(); 45 | } 46 | 47 | @Override 48 | public E accept(ASTVisitor visitor) { 49 | return visitor.visit(this); 50 | } 51 | } -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/FunctionDefNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.Entity.FunctionEntity; 4 | import com.mercy.compiler.FrontEnd.ASTVisitor; 5 | 6 | /** 7 | * Created by mercy on 17-3-23. 8 | */ 9 | public class FunctionDefNode extends DefinitionNode { 10 | private FunctionEntity entity; 11 | 12 | public FunctionDefNode(FunctionEntity entity) { 13 | super(entity.location(), entity.name()); 14 | this.entity = entity; 15 | } 16 | 17 | public FunctionEntity entity() { 18 | return entity; 19 | } 20 | 21 | @Override 22 | public S accept(ASTVisitor visitor) { 23 | return visitor.visit(this); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/IfNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | public class IfNode extends StmtNode { 9 | private ExprNode cond; 10 | private StmtNode thenBody, elseBody; 11 | 12 | public IfNode(Location loc, ExprNode c, StmtNode t, StmtNode e) { 13 | super(loc); 14 | this.cond = c; 15 | this.thenBody = BlockNode.wrapBlock(t); 16 | this.elseBody = BlockNode.wrapBlock(e); 17 | } 18 | 19 | public ExprNode cond() { 20 | return cond; 21 | } 22 | 23 | public StmtNode thenBody() { 24 | return thenBody; 25 | } 26 | 27 | public StmtNode elseBody() { 28 | return elseBody; 29 | } 30 | 31 | @Override 32 | public S accept(ASTVisitor visitor) { 33 | return visitor.visit(this); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/IntegerLiteralNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | import com.mercy.compiler.Type.IntegerType; 5 | 6 | /** 7 | * Created by mercy on 17-3-18. 8 | */ 9 | public class IntegerLiteralNode extends LiteralNode { 10 | private long value; 11 | 12 | public IntegerLiteralNode(Location loc, long value) { 13 | super(loc, new IntegerType()); 14 | this.value = value; 15 | } 16 | 17 | public long value() { 18 | return value; 19 | } 20 | 21 | @Override 22 | public E accept(ASTVisitor visitor) { 23 | return visitor.visit(this); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/LHSNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.Type.Type; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | abstract public class LHSNode extends ExprNode { 9 | protected Type type; 10 | 11 | @Override 12 | public Type type() { 13 | return type; 14 | } 15 | 16 | public void setType(Type t) { 17 | this.type = t; 18 | } 19 | 20 | public long allocSize() { return type.allocSize(); } 21 | 22 | @Override 23 | public boolean isLvalue() { return true; } 24 | 25 | @Override 26 | public boolean isAssignable() { return true; } 27 | } 28 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/LiteralNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.Type.Type; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | abstract public class LiteralNode extends ExprNode { 9 | protected Location location; 10 | protected Type type; 11 | 12 | public LiteralNode(Location loc, Type type) { 13 | super(); 14 | this.location = loc; 15 | this.type = type; 16 | } 17 | 18 | @Override 19 | public boolean isConstant() { 20 | return true; 21 | } 22 | 23 | @Override 24 | public Location location() { 25 | return location; 26 | } 27 | 28 | @Override 29 | public Type type() { 30 | return type; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/Location.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import org.antlr.v4.runtime.ParserRuleContext; 4 | import org.antlr.v4.runtime.Token; 5 | import org.antlr.v4.runtime.tree.TerminalNode; 6 | 7 | /** 8 | * Created by mercy on 17-3-18. 9 | */ 10 | public class Location { 11 | private int line; 12 | private int column; 13 | 14 | public Location(int line, int column) { 15 | this.line = line; 16 | this.column = column; 17 | } 18 | 19 | public Location(Token token) { 20 | this.line = token.getLine(); 21 | this.column = token.getCharPositionInLine(); 22 | } 23 | 24 | public Location(ParserRuleContext ctx) { 25 | this(ctx.start); 26 | } 27 | 28 | public Location(TerminalNode terminal) { 29 | this(terminal.getSymbol()); 30 | } 31 | 32 | public int line() { 33 | return line; 34 | } 35 | 36 | public int column() { 37 | return column; 38 | } 39 | 40 | public String toString() { 41 | return "line " + line + ":" + column + " "; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/LogicalAndNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | public class LogicalAndNode extends BinaryOpNode { 9 | public LogicalAndNode(ExprNode left, ExprNode right) { 10 | super(left, BinaryOp.LOGIC_AND, right); 11 | } 12 | 13 | @Override 14 | public E accept(ASTVisitor visitor) { 15 | return visitor.visit(this); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/LogicalOrNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | public class LogicalOrNode extends BinaryOpNode { 9 | public LogicalOrNode(ExprNode left, ExprNode right) { 10 | super(left, BinaryOp.LOGIC_OR, right); 11 | } 12 | 13 | @Override 14 | public E accept(ASTVisitor visitor) { 15 | return visitor.visit(this); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/MemberNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.Entity.Entity; 4 | import com.mercy.compiler.FrontEnd.ASTVisitor; 5 | 6 | /** 7 | * Created by mercy on 17-3-18. 8 | */ 9 | public class MemberNode extends LHSNode { 10 | private ExprNode expr; 11 | private String member; 12 | private Entity entity; 13 | 14 | public MemberNode(ExprNode expr, String member) { 15 | this.expr = expr; 16 | this.member = member; 17 | } 18 | 19 | public ExprNode expr() { 20 | return expr; 21 | } 22 | 23 | public String member() { 24 | return member; 25 | } 26 | 27 | public Entity entity() { 28 | return entity; 29 | } 30 | 31 | public void setEntity(Entity entity) { 32 | this.entity = entity; 33 | } 34 | 35 | @Override 36 | public boolean isAssignable() { 37 | return !entity.type().isFunction(); 38 | } 39 | 40 | @Override 41 | public Location location() { 42 | return expr.location(); 43 | } 44 | 45 | @Override 46 | public E accept(ASTVisitor visitor) { 47 | return visitor.visit(this); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/Node.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | /** 4 | * Created by mercy on 17-3-18. 5 | */ 6 | abstract public class Node { 7 | public Node() { 8 | } 9 | 10 | protected boolean isOutputIrrelevant = false; 11 | 12 | public boolean outputIrrelevant() { 13 | return isOutputIrrelevant; 14 | } 15 | public void setOutputIrrelevant(boolean outputIrrelevant) { 16 | isOutputIrrelevant = outputIrrelevant; 17 | } 18 | 19 | abstract public Location location(); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/NodeDesign.txt: -------------------------------------------------------------------------------- 1 | AST 2 | 3 | Node 4 | ExprNode 5 | AssignNode 6 | BinaryOpNode 7 | LogicalAndNode 8 | LogicalOrNode 9 | FuncallNode 10 | LiteralNode 11 | IntegerLiteralNode 12 | StringLiteralNode 13 | LHSNode 14 | ArefNode 15 | VariableNode 16 | MemberNode 17 | CreatorNode 18 | UnaryOpNode 19 | PrefixOpNode 20 | SuffixOpNode 21 | StmtNode 22 | BlockNode 23 | BreakNode 24 | ContinueNode 25 | ExprStmtNode 26 | ForNode 27 | IfNode 28 | ReturnNode 29 | WhileNode 30 | DefinitionNode 31 | ClassDefNode 32 | FunctionDefNode 33 | VariableDefNode 34 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/PrefixOpNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | 4 | import com.mercy.compiler.FrontEnd.ASTVisitor; 5 | 6 | /** 7 | * Created by mercy on 17-3-18. 8 | */ 9 | public class PrefixOpNode extends UnaryOpNode { 10 | public PrefixOpNode(UnaryOp op, ExprNode expr) { 11 | super(op, expr); 12 | } 13 | 14 | @Override 15 | public E accept(ASTVisitor visitor) { 16 | return visitor.visit(this); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/ReturnNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | public class ReturnNode extends StmtNode { 9 | protected ExprNode expr; 10 | 11 | public ReturnNode(Location loc, ExprNode expr) { 12 | super(loc); 13 | this.expr = expr; 14 | } 15 | 16 | public ExprNode expr() { 17 | return expr; 18 | } 19 | 20 | public void setExpr(ExprNode expr) { 21 | this.expr = expr; 22 | } 23 | 24 | @Override 25 | public S accept(ASTVisitor visitor) { 26 | return visitor.visit(this); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/StmtNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | abstract public class StmtNode extends Node { 9 | protected Location location; 10 | 11 | public StmtNode(Location loc) { 12 | this.location = loc; 13 | } 14 | 15 | @Override 16 | public Location location() { 17 | return location; 18 | } 19 | 20 | abstract public S accept(ASTVisitor visitor); 21 | } 22 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/StringLiteralNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.Entity.StringConstantEntity; 4 | import com.mercy.compiler.FrontEnd.ASTVisitor; 5 | import com.mercy.compiler.Type.StringType; 6 | 7 | /** 8 | * Created by mercy on 17-3-18. 9 | */ 10 | public class StringLiteralNode extends LiteralNode { 11 | private String value; 12 | private StringConstantEntity entity; 13 | 14 | public StringLiteralNode(Location loc, String value) { 15 | super(loc, new StringType()); 16 | this.value = value; 17 | } 18 | 19 | public String value() { 20 | return value; 21 | } 22 | 23 | public StringConstantEntity entity() { 24 | return entity; 25 | } 26 | 27 | public void setEntity(StringConstantEntity entity) { 28 | this.entity = entity; 29 | } 30 | 31 | @Override 32 | public E accept(ASTVisitor visitor) { 33 | return visitor.visit(this); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/SuffixOpNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | public class SuffixOpNode extends UnaryOpNode { 9 | public SuffixOpNode(UnaryOp op, ExprNode expr) { 10 | super(op, expr); 11 | } 12 | 13 | @Override 14 | public E accept(ASTVisitor visitor) { 15 | return visitor.visit(this); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/UnaryOpNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | import com.mercy.compiler.Type.Type; 5 | 6 | /** 7 | * Created by mercy on 17-3-18. 8 | */ 9 | public class UnaryOpNode extends ExprNode { 10 | public enum UnaryOp { 11 | PRE_INC, PRE_DEC, SUF_INC, SUF_DEC, 12 | MINUS, ADD, LOGIC_NOT, BIT_NOT 13 | } 14 | 15 | private UnaryOp operator; 16 | private ExprNode expr; 17 | private Type type; 18 | private long amount; 19 | 20 | public UnaryOpNode(UnaryOp op, ExprNode expr) { 21 | this.operator = op; 22 | this.expr = expr; 23 | amount = 1; 24 | } 25 | 26 | public UnaryOp operator() { 27 | return operator; 28 | } 29 | 30 | @Override 31 | public Type type() { 32 | return expr.type(); 33 | } 34 | 35 | public ExprNode expr() { 36 | return expr; 37 | } 38 | public void setExpr(ExprNode expr) { 39 | this.expr = expr; 40 | } 41 | 42 | public long amount() { 43 | return amount; 44 | } 45 | public void setAmount(long amount) { 46 | this.amount = amount; 47 | } 48 | 49 | @Override 50 | public Location location() { 51 | return expr.location(); 52 | } 53 | 54 | @Override 55 | public E accept(ASTVisitor visitor) { 56 | return visitor.visit(this); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/VariableDefNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.Entity.VariableEntity; 4 | import com.mercy.compiler.FrontEnd.ASTVisitor; 5 | 6 | /** 7 | * Created by mercy on 17-3-18. 8 | */ 9 | public class VariableDefNode extends DefinitionNode { 10 | private VariableEntity entity; 11 | 12 | public VariableDefNode(VariableEntity entity) { 13 | super(entity.location(), entity.name()); 14 | this.entity = entity; 15 | 16 | } 17 | 18 | public VariableEntity entity() { 19 | return entity; 20 | } 21 | 22 | @Override 23 | public S accept(ASTVisitor visitor) { 24 | return visitor.visit(this); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/VariableNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.Entity.Entity; 4 | import com.mercy.compiler.Entity.ParameterEntity; 5 | import com.mercy.compiler.FrontEnd.ASTVisitor; 6 | import com.mercy.compiler.Type.Type; 7 | import com.mercy.compiler.Utility.InternalError; 8 | 9 | /** 10 | * Created by mercy on 17-3-18. 11 | */ 12 | 13 | public class VariableNode extends LHSNode { 14 | private Location location; 15 | private String name; 16 | private Entity entity; 17 | private ParameterEntity thisPointer = null; 18 | 19 | public VariableNode(Location loc, String name) { 20 | this.location = loc; 21 | this.name = name; 22 | } 23 | 24 | public VariableNode(Entity var) { 25 | this.entity = var; 26 | this.name = var.name(); 27 | } 28 | 29 | public VariableNode(Entity var, Location loc) { 30 | this.entity = var; 31 | this.location = loc; 32 | this.name = var.name(); 33 | } 34 | 35 | 36 | public String name() { 37 | return name; 38 | } 39 | 40 | public Entity entity() { 41 | if (entity == null) { 42 | throw new InternalError("Vairable.entity == null"); 43 | } 44 | return entity; 45 | } 46 | 47 | public void setEntity(Entity entity) { 48 | this.entity = entity; 49 | } 50 | 51 | public void setThisPointer(ParameterEntity entity) { 52 | this.thisPointer = entity; 53 | } 54 | 55 | public ParameterEntity getThisPointer() { 56 | return thisPointer; 57 | } 58 | 59 | public boolean isMember() { 60 | return thisPointer != null; 61 | } 62 | 63 | @Override 64 | public Type type() { 65 | return entity.type(); 66 | } 67 | 68 | @Override 69 | public Location location() { 70 | return location; 71 | } 72 | 73 | @Override 74 | public E accept(ASTVisitor visitor) { 75 | return visitor.visit(this); 76 | } 77 | } -------------------------------------------------------------------------------- /src/com/mercy/compiler/AST/WhileNode.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.AST; 2 | 3 | import com.mercy.compiler.FrontEnd.ASTVisitor; 4 | 5 | /** 6 | * Created by mercy on 17-3-18. 7 | */ 8 | public class WhileNode extends StmtNode { 9 | private StmtNode body; 10 | private ExprNode cond; 11 | 12 | public WhileNode(Location loc, ExprNode cond, StmtNode body) { 13 | super(loc); 14 | this.cond = cond; 15 | this.body = BlockNode.wrapBlock(body); 16 | } 17 | 18 | public StmtNode body() { 19 | return body; 20 | } 21 | 22 | public ExprNode cond() { 23 | return cond; 24 | } 25 | 26 | @Override 27 | public S accept(ASTVisitor visitor) { 28 | return visitor.visit(this); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/com/mercy/compiler/BackEnd/BasicBlock.java: -------------------------------------------------------------------------------- 1 | package com.mercy.compiler.BackEnd; 2 | 3 | import com.mercy.compiler.INS.Instruction; 4 | import com.mercy.compiler.INS.Label; 5 | import com.mercy.compiler.INS.Operand.Reference; 6 | 7 | import java.util.HashSet; 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | /** 13 | * Created by mercy on 17-5-23. 14 | */ 15 | public class BasicBlock { 16 | private List predecessor = new LinkedList<>(); 17 | private List successor = new LinkedList<>(); 18 | private Label label; 19 | private List ins = new LinkedList<>(); 20 | private List