mirror of https://github.com/aamine/cbc
r4875@macbookpro: aamine | 2009-05-18 05:10:22 +0900
* net/loveruby/cflat/compiler/TypeChecker.java: allow ptr-ptr. * net/loveruby/cflat/compiler/IRGenerator.java: implement ptr-ptr. * net/loveruby/cflat/type/VoidType.java: VoidType#size is 1. * net/loveruby/cflat/ast/ExprNode.java: new helper method #baseType. git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4225 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
parent
e8f60b1e9f
commit
7af5ebc4a9
11
ChangeLog
11
ChangeLog
|
|
@ -1,3 +1,14 @@
|
|||
Mon May 18 04:52:25 2009 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/compiler/TypeChecker.java: allow ptr-ptr.
|
||||
|
||||
* net/loveruby/cflat/compiler/IRGenerator.java: implement ptr-ptr.
|
||||
|
||||
* net/loveruby/cflat/type/VoidType.java: VoidType#size is 1.
|
||||
|
||||
* net/loveruby/cflat/ast/ExprNode.java: new helper method
|
||||
#baseType.
|
||||
|
||||
Mon May 18 03:50:55 2009 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/sysdep/x86/CodeGenerator.java (optimize):
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ abstract public class ExprNode extends Node {
|
|||
protected Type origType() { return type(); }
|
||||
|
||||
public long allocSize() { return type().allocSize(); }
|
||||
public long baseSize() { return type().baseType().size(); }
|
||||
|
||||
public boolean isConstant() { return false; }
|
||||
public boolean isParameter() { return false; }
|
||||
|
|
|
|||
|
|
@ -565,13 +565,21 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
Expr right = transformExpr(node.right());
|
||||
Expr left = transformExpr(node.left());
|
||||
if (node.operator().equals("+") || node.operator().equals("-")) {
|
||||
if (node.left().type().isPointer()) {
|
||||
right = new Bin(ptrDiffType(), Op.MUL,
|
||||
right, ptrDiff(node.left().type().baseType().size()));
|
||||
if (node.left().isPointer() && node.right().isPointer()) {
|
||||
Expr tmp = new Bin(asmType(node.type()),
|
||||
Op.internBinary(node.operator(),
|
||||
node.type().isSigned()),
|
||||
left, right);
|
||||
return new Bin(ptrDiffType(), Op.S_DIV,
|
||||
tmp, ptrDiff(node.left().baseSize()));
|
||||
}
|
||||
else if (node.right().type().isPointer()) {
|
||||
else if (node.left().isPointer()) {
|
||||
right = new Bin(ptrDiffType(), Op.MUL,
|
||||
right, ptrDiff(node.left().baseSize()));
|
||||
}
|
||||
else if (node.right().isPointer()) {
|
||||
left = new Bin(ptrDiffType(), Op.MUL,
|
||||
left, ptrDiff(node.right().type().baseType().size()));
|
||||
left, ptrDiff(node.right().baseSize()));
|
||||
}
|
||||
}
|
||||
return new Bin(asmType(node.type()),
|
||||
|
|
|
|||
|
|
@ -288,25 +288,25 @@ class TypeChecker extends Visitor {
|
|||
* * integer + pointer
|
||||
* * integer - integer
|
||||
* * pointer - integer
|
||||
* * pointer - pointer
|
||||
*/
|
||||
protected void expectsSameIntegerOrPointerDiff(BinaryOpNode node) {
|
||||
if (node.left().type().isPointer()) {
|
||||
if (node.left().type().baseType().isVoid()) {
|
||||
wrongTypeError(node.left(), node.operator());
|
||||
private void expectsSameIntegerOrPointerDiff(BinaryOpNode node) {
|
||||
if (node.left().isPointer() && node.right().isPointer()) {
|
||||
if (node.operator().equals("+")) {
|
||||
error(node, "invalid operation: pointer + pointer");
|
||||
return;
|
||||
}
|
||||
node.setType(typeTable.ptrDiffType());
|
||||
}
|
||||
else if (node.left().isPointer()) {
|
||||
mustBeInteger(node.right(), node.operator());
|
||||
// promote integer for pointer calculation
|
||||
node.setRight(integralPromotedExpr(node.right()));
|
||||
node.setType(node.left().type());
|
||||
}
|
||||
else if (node.right().type().isPointer()) {
|
||||
else if (node.right().isPointer()) {
|
||||
if (node.operator().equals("-")) {
|
||||
error(node, "invalid operation integer-pointer");
|
||||
return;
|
||||
}
|
||||
if (node.right().type().baseType().isVoid()) {
|
||||
wrongTypeError(node.right(), node.operator());
|
||||
error(node, "invalid operation: integer - pointer");
|
||||
return;
|
||||
}
|
||||
mustBeInteger(node.left(), node.operator());
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ public class VoidType extends Type {
|
|||
public boolean isVoid() { return true; }
|
||||
|
||||
public long size() {
|
||||
throw new Error("VoidType#size called");
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import stdio;
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
int x, y;
|
||||
void *p = &x;
|
||||
void *q = &y;
|
||||
|
||||
printf("%d", q - p);
|
||||
printf(";%d", q - (p + 1));
|
||||
printf(";%d", q - (1 + p));
|
||||
printf(";%d", q - (p - 1));
|
||||
puts("");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -209,6 +209,7 @@ test_22_pointer() {
|
|||
assert_out "1;2;3;4;5;6;77;78" ./ptrmemb
|
||||
assert_out "7" ./ptrmemb2
|
||||
assert_out "OK;OK;OK;OK" ./addressof
|
||||
assert_out "-4;-5;-5;-3" ./ptrdiff
|
||||
assert_compile_error deref-semcheck1.cb
|
||||
assert_compile_error deref-semcheck2.cb
|
||||
assert_compile_error deref-semcheck3.cb
|
||||
|
|
|
|||
Loading…
Reference in New Issue