* net/loveruby/cflat/compiler/TypeChecker.java: split IRGenerator.

* net/loveruby/cflat/compiler/IRGenerator.java: new class.
* net/loveruby/cflat/compiler/Compiler.java: call IRGenerator.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4135 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2009-04-12 08:49:23 +00:00
parent 8d208c36cc
commit 5a287a7b48
4 changed files with 110 additions and 29 deletions

View File

@ -1,3 +1,11 @@
Sun Apr 12 17:49:19 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/TypeChecker.java: split IRGenerator.
* net/loveruby/cflat/compiler/IRGenerator.java: new class.
* net/loveruby/cflat/compiler/Compiler.java: call IRGenerator.
Sun Apr 12 16:48:14 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/TypeChecker.java: simplify BinaryOp

View File

@ -113,8 +113,10 @@ public class Compiler {
ast.dump();
return;
}
new JumpResolver(errorHandler).resolve(ast);
String asm = generateAssembly(ast, opts);
// FIXME: generate IR tree
AST ir = new IRGenerator(errorHandler).compile(ast);
new JumpResolver(errorHandler).resolve(ir);
String asm = generateAssembly(ir, opts);
if (opts.mode() == CompilerMode.DumpAsm) {
System.out.println(asm);
return;

View File

@ -0,0 +1,90 @@
package net.loveruby.cflat.compiler;
import net.loveruby.cflat.ast.*;
import net.loveruby.cflat.type.*;
import net.loveruby.cflat.exception.*;
import java.util.*;
class IRGenerator extends Visitor {
protected ErrorHandler errorHandler;
protected TypeTable typeTable;
// #@@range/ctor{
public IRGenerator(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
// #@@}
protected void compile(StmtNode node) {
visitStmt(node);
}
protected void compile(ExprNode node) {
visitExpr(node);
}
// FIXME: generate IR tree
// #@@range/check_AST{
public AST compile(AST ast) throws SemanticException {
typeTable = ast.typeTable();
for (DefinedVariable var : ast.definedVariables()) {
visit(var);
}
for (DefinedFunction f : ast.definedFunctions()) {
compile(f.body());
}
if (errorHandler.errorOccured()) {
throw new SemanticException("IR generation failed.");
}
return ast;
}
// #@@}
public Void visit(OpAssignNode node) {
super.visit(node);
if (node.operator().equals("+") || node.operator().equals("-")) {
if (node.lhs().type().isDereferable()) {
node.setRHS(multiplyPtrBaseSize(node.rhs(), node.lhs()));
}
}
return null;
}
// #@@range/BinaryOpNode{
public Void visit(BinaryOpNode node) {
super.visit(node);
if (node.operator().equals("+") || node.operator().equals("-")) {
if (node.left().type().isDereferable()) {
node.setRight(multiplyPtrBaseSize(node.right(), node.left()));
}
else if (node.right().type().isDereferable()) {
node.setLeft(multiplyPtrBaseSize(node.left(), node.right()));
}
}
return null;
}
// #@@}
protected BinaryOpNode multiplyPtrBaseSize(ExprNode expr, ExprNode ptr) {
return new BinaryOpNode(expr, "*", ptrBaseSize(ptr));
}
protected IntegerLiteralNode ptrBaseSize(ExprNode ptr) {
return integerLiteral(ptr.location(),
typeTable.ptrDiffTypeRef(),
ptr.type().baseType().size());
}
protected IntegerLiteralNode integerLiteral(Location loc, TypeRef ref, long n) {
IntegerLiteralNode node = new IntegerLiteralNode(loc, ref, n);
bindType(node.typeNode());
return node;
}
protected void bindType(TypeNode t) {
t.setType(typeTable.get(t.typeRef()));
}
protected void error(Node n, String msg) {
errorHandler.error(n.location(), msg);
}
}

View File

@ -159,11 +159,10 @@ class TypeChecker extends Visitor {
super.visit(node);
if (! checkLHS(node.lhs())) return null;
if (! checkRHS(node.rhs())) return null;
if (node.operator().equals("+")
|| node.operator().equals("-")) {
if (node.lhs().type().isPointer()) {
if (! mustBeInteger(node.rhs(), node.operator())) return null;
node.setRHS(multiplyPtrBaseSize(node.rhs(), node.lhs()));
if (node.operator().equals("+") || node.operator().equals("-")) {
if (node.lhs().type().isDereferable()) {
mustBeInteger(node.rhs(), node.operator());
node.setRHS(integralPromotedExpr(node.rhs()));
return null;
}
}
@ -293,7 +292,8 @@ class TypeChecker extends Visitor {
return;
}
mustBeInteger(node.right(), node.operator());
node.setRight(multiplyPtrBaseSize(node.right(), node.left()));
// promote integer for pointer calculation
node.setRight(integralPromotedExpr(node.right()));
node.setType(node.left().type());
}
else if (node.right().type().isDereferable()) {
@ -306,7 +306,8 @@ class TypeChecker extends Visitor {
return;
}
mustBeInteger(node.left(), node.operator());
node.setLeft(multiplyPtrBaseSize(node.left(), node.right()));
// promote integer for pointer calculation
node.setLeft(integralPromotedExpr(node.left()));
node.setType(node.right().type());
}
else {
@ -314,10 +315,6 @@ class TypeChecker extends Visitor {
}
}
protected BinaryOpNode multiplyPtrBaseSize(ExprNode expr, ExprNode ptr) {
return new BinaryOpNode(integralPromotedExpr(expr), "*", ptrBaseSize(ptr));
}
protected ExprNode integralPromotedExpr(ExprNode expr) {
Type t = integralPromotion(expr.type());
if (t.isSameType(expr.type())) {
@ -328,22 +325,6 @@ class TypeChecker extends Visitor {
}
}
protected IntegerLiteralNode ptrBaseSize(ExprNode ptr) {
return integerLiteral(ptr.location(),
typeTable.ptrDiffTypeRef(),
ptr.type().baseType().size());
}
protected IntegerLiteralNode integerLiteral(Location loc, TypeRef ref, long n) {
IntegerLiteralNode node = new IntegerLiteralNode(loc, ref, n);
bindType(node.typeNode());
return node;
}
protected void bindType(TypeNode t) {
t.setType(typeTable.get(t.typeRef()));
}
// +, -, *, /, %, &, |, ^, <<, >>
// #@@range/expectsSameInteger{
protected void expectsSameInteger(BinaryOpNode node) {