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:
Minero Aoki 2009-05-17 20:10:28 +00:00
parent e8f60b1e9f
commit 7af5ebc4a9
7 changed files with 53 additions and 16 deletions

View File

@ -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):

View File

@ -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; }

View File

@ -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()),

View File

@ -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());

View File

@ -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) {

16
test/ptrdiff.cb Normal file
View File

@ -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;
}

View File

@ -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