mirror of https://github.com/aamine/cbc
* net/loveruby/cflat/compiler/TypeChecker.java: allow ptr + int, ptr - int.
* net/loveruby/cflat/ast/BinaryOpNode.java: new method #setType. git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3770 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
parent
ea681c1f96
commit
46109b45b1
|
@ -1,3 +1,10 @@
|
|||
Wed Jan 2 04:03:10 2008 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/compiler/TypeChecker.java: allow ptr + int,
|
||||
ptr - int.
|
||||
|
||||
* net/loveruby/cflat/ast/BinaryOpNode.java: new method #setType.
|
||||
|
||||
Wed Jan 2 03:17:46 2008 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/compiler/TypeResolver.java: pass ErrorHandler
|
||||
|
|
2
ToDo
2
ToDo
|
@ -164,7 +164,7 @@
|
|||
- validate struct/union member (ct.memb)
|
||||
- validate struct/union member (ct->memb)
|
||||
- check duplicated struct/union members
|
||||
* ptr + int; ptr - int
|
||||
- ptr + int; ptr - int
|
||||
* check return type
|
||||
* check if assignable
|
||||
- op for various types
|
||||
|
|
|
@ -3,6 +3,7 @@ import net.loveruby.cflat.type.Type;
|
|||
|
||||
abstract public class BinaryOpNode extends Node {
|
||||
protected Node left, right;
|
||||
protected Type type;
|
||||
|
||||
public BinaryOpNode(Node l, Node r) {
|
||||
super();
|
||||
|
@ -11,7 +12,13 @@ abstract public class BinaryOpNode extends Node {
|
|||
}
|
||||
|
||||
public Type type() {
|
||||
return left.type();
|
||||
return (type != null) ? type : left.type();
|
||||
}
|
||||
|
||||
public void setType(Type type) {
|
||||
if (this.type != null)
|
||||
throw new Error("BinaryOp#setType called twice");
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Node left() {
|
||||
|
|
|
@ -57,7 +57,7 @@ class TypeChecker extends Visitor {
|
|||
|
||||
public void visit(SwitchNode node) {
|
||||
super.visit(node);
|
||||
mustBeIntegerAlike(node.cond());
|
||||
mustBeScalar(node.cond());
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -160,88 +160,141 @@ class TypeChecker extends Visitor {
|
|||
// Binary Operator Nodes
|
||||
//
|
||||
|
||||
// FIXME: ptr + int
|
||||
public void visit(PlusNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsSameIntegerOrPointerDiff(node);
|
||||
}
|
||||
|
||||
// FIXME: ptr + int
|
||||
public void visit(MinusNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsSameIntegerOrPointerDiff(node);
|
||||
}
|
||||
|
||||
public void visit(MulNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsSameInteger(node);
|
||||
}
|
||||
|
||||
public void visit(DivNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsSameInteger(node);
|
||||
}
|
||||
|
||||
public void visit(ModNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsSameInteger(node);
|
||||
}
|
||||
|
||||
public void visit(BitwiseAndNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsSameInteger(node);
|
||||
}
|
||||
|
||||
public void visit(BitwiseOrNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsSameInteger(node);
|
||||
}
|
||||
|
||||
public void visit(BitwiseXorNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsSameInteger(node);
|
||||
}
|
||||
|
||||
public void visit(LShiftNode node) {
|
||||
super.visit(node);
|
||||
expectsSameInteger(node);
|
||||
}
|
||||
|
||||
public void visit(RShiftNode node) {
|
||||
super.visit(node);
|
||||
expectsSameInteger(node);
|
||||
}
|
||||
|
||||
public void visit(EqNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsComparableScalars(node);
|
||||
}
|
||||
|
||||
public void visit(NotEqNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsComparableScalars(node);
|
||||
}
|
||||
|
||||
public void visit(LtNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsComparableScalars(node);
|
||||
}
|
||||
|
||||
public void visit(LtEqNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsComparableScalars(node);
|
||||
}
|
||||
|
||||
public void visit(GtNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsComparableScalars(node);
|
||||
}
|
||||
|
||||
public void visit(GtEqNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsComparableScalars(node);
|
||||
}
|
||||
|
||||
public void visit(LogicalAndNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsComparableScalars(node);
|
||||
}
|
||||
|
||||
public void visit(LogicalOrNode node) {
|
||||
expectsSameType(node);
|
||||
super.visit(node);
|
||||
expectsComparableScalars(node);
|
||||
}
|
||||
|
||||
protected void expectsSameType(BinaryOpNode node) {
|
||||
resolve(node.left());
|
||||
resolve(node.right());
|
||||
Type r = node.right().type();
|
||||
Type l = node.left().type();
|
||||
if (r.equals(l)) {
|
||||
return;
|
||||
// +, -
|
||||
protected void expectsSameIntegerOrPointerDiff(BinaryOpNode node) {
|
||||
if (node.left().type().isPointer()) {
|
||||
mustBeInteger(node.right());
|
||||
node.setType(node.left().type());
|
||||
}
|
||||
else if (r.isCompatible(l)) { // insert cast on right expr
|
||||
node.setRight(newCastNode(l, node.right()));
|
||||
}
|
||||
else if (l.isCompatible(r)) { // insert cast on left expr
|
||||
node.setLeft(newCastNode(r, node.left()));
|
||||
else if (node.right().type().isPointer()) {
|
||||
mustBeInteger(node.left());
|
||||
node.setType(node.right().type());
|
||||
}
|
||||
else {
|
||||
incompatibleTypeError(l, r);
|
||||
expectsSameInteger(node);
|
||||
}
|
||||
}
|
||||
|
||||
// *, /, %, &, |, ^, <<, >>
|
||||
protected void expectsSameInteger(BinaryOpNode node) {
|
||||
mustBeInteger(node.left());
|
||||
mustBeInteger(node.right());
|
||||
insertImplicitCast(node);
|
||||
}
|
||||
|
||||
// ==, !=, <, <=, >, >=, &&, ||
|
||||
protected void expectsComparableScalars(BinaryOpNode node) {
|
||||
mustBeScalar(node.left());
|
||||
mustBeScalar(node.right());
|
||||
insertImplicitCast(node);
|
||||
}
|
||||
|
||||
protected void insertImplicitCast(BinaryOpNode node) {
|
||||
Node r = node.right();
|
||||
Node l = node.left();
|
||||
if (r.type().equals(l.type())) {
|
||||
return;
|
||||
}
|
||||
else if (r.type().isCompatible(l.type())) {
|
||||
// insert cast on right expr
|
||||
node.setRight(newCastNode(l.type(), r));
|
||||
}
|
||||
else if (l.type().isCompatible(r.type())) {
|
||||
// insert cast on left expr
|
||||
node.setLeft(newCastNode(r.type(), l));
|
||||
}
|
||||
else {
|
||||
incompatibleTypeError(l.type(), r.type());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,24 +303,24 @@ class TypeChecker extends Visitor {
|
|||
//
|
||||
|
||||
public void visit(PrefixIncNode node) {
|
||||
expectsIntOperand(node);
|
||||
expectsScalarOperand(node);
|
||||
}
|
||||
|
||||
public void visit(SuffixIncNode node) {
|
||||
expectsIntOperand(node);
|
||||
expectsScalarOperand(node);
|
||||
}
|
||||
|
||||
public void visit(PrefixDecNode node) {
|
||||
expectsIntOperand(node);
|
||||
expectsScalarOperand(node);
|
||||
}
|
||||
|
||||
public void visit(SuffixDecNode node) {
|
||||
expectsIntOperand(node);
|
||||
expectsScalarOperand(node);
|
||||
}
|
||||
|
||||
protected void expectsIntOperand(UnaryOpNode node) {
|
||||
protected void expectsScalarOperand(UnaryOpNode node) {
|
||||
resolve(node.expr());
|
||||
mustBeIntegerAlike(node.expr());
|
||||
mustBeScalar(node.expr());
|
||||
}
|
||||
|
||||
public void visit(FuncallNode node) {
|
||||
|
@ -387,7 +440,7 @@ class TypeChecker extends Visitor {
|
|||
notIntegerError(node.type());
|
||||
}
|
||||
|
||||
protected void mustBeIntegerAlike(Node node) {
|
||||
protected void mustBeScalar(Node node) {
|
||||
if (node.type().isInteger()) return;
|
||||
if (node.type().isPointer()) return;
|
||||
notIntegerError(node.type());
|
||||
|
|
Loading…
Reference in New Issue