# HG changeset patch # User Anders Halager # Date 1209750862 -7200 # Node ID 9e90694f5da05ec8b82fba6ec5571fc7cf5441b0 # Parent 06dda301ea61263046d6f4074e686d4990223959 Parse array indexing, and allow reading from arrays diff -r 06dda301ea61 -r 9e90694f5da0 ast/Exp.d --- a/ast/Exp.d Fri May 02 19:51:58 2008 +0200 +++ b/ast/Exp.d Fri May 02 19:54:22 2008 +0200 @@ -18,7 +18,7 @@ Deref, IntegerLit, MemberReference, - ArrayReference, + Index, Identifier, ArrayIdentifier, PointerIdentifier, @@ -306,26 +306,31 @@ private DType myType; } -class ArrayReference : Exp +class IndexExp : Exp { - this(Exp target, IntegerLit pos) + this(Exp target, Exp index) { - super(ExpType.ArrayReference); + super(ExpType.Index); this.target = target; - this.pos = pos; + this.index = index; } - override DType type() { return target.type(); } + override DType type() + { + assert(target.type().isArray(), "Can only index arrays"); + DArray array = target.type().asArray(); + return array.arrayOf; + } Exp simplify() { target = target.simplify; - pos.simplify; + index = index.simplify; return this; } Exp target; - IntegerLit pos; + Exp index; } class CastExp : Exp @@ -364,7 +369,7 @@ override DType type() { - return pointerOf.type.getPointerTo; + return pointerOf.type.getPointerTo(); } Identifier pointerOf; diff -r 06dda301ea61 -r 9e90694f5da0 gen/CodeGen.d --- a/gen/CodeGen.d Fri May 02 19:51:58 2008 +0200 +++ b/gen/CodeGen.d Fri May 02 19:54:22 2008 +0200 @@ -281,6 +281,9 @@ case ExpType.AssignExp: auto assignExp = cast(AssignExp)exp; return buildAssign(assignExp.identifier, assignExp.exp); + case ExpType.Index: + auto indexExp = cast(IndexExp)exp; + return b.buildLoad(getPointer(exp), "."); case ExpType.CallExp: auto callExp = cast(CallExp)exp; auto func_sym = exp.env.find(cast(Identifier)callExp.exp); @@ -498,6 +501,14 @@ auto derefExp = cast(DerefExp)exp; auto target = getPointer(derefExp.exp); return b.buildLoad(target, "deref"); + case ExpType.Index: + auto indexExp = cast(IndexExp)exp; + auto array = getPointer(indexExp.target); + auto index = genExpression(indexExp.index); + Value[2] gep_indices; + gep_indices[0] = ConstantInt.Get(IntegerType.Int32, 0, false); + gep_indices[1] = index; + return b.buildGEP(array, gep_indices[], "index"); case ExpType.MemberReference: auto mem = cast(MemberReference)exp; Stdout(mem.target).newline; diff -r 06dda301ea61 -r 9e90694f5da0 parser/Action.d --- a/parser/Action.d Fri May 02 19:51:58 2008 +0200 +++ b/parser/Action.d Fri May 02 19:54:22 2008 +0200 @@ -276,6 +276,15 @@ } /** + Called when function calls are encountered. + */ + ExprT actOnIndexEpr(ExprT array, ref Token left_bracket, ExprT index, + ref Token right_bracket) + { + return null; + } + + /** Cast expression. */ ExprT actOnCastExpr(Id type, ExprT exp) diff -r 06dda301ea61 -r 9e90694f5da0 parser/Parser.d --- a/parser/Parser.d Fri May 02 19:51:58 2008 +0200 +++ b/parser/Parser.d Fri May 02 19:54:22 2008 +0200 @@ -348,7 +348,7 @@ private: // -- Expression parsing -- // - Exp parseExpIdentifier(Exp target) + Exp parsePostfixExp(Exp target) { switch(lexer.peek.type) { @@ -359,11 +359,16 @@ Token op = lexer.next; Id member = Id(lexer.next); Exp exp = action.actOnMemberReference(target, op.location, member); - return parseExpIdentifier(exp); + return parsePostfixExp(exp); default: Token t = lexer.peek(1); throw error(__LINE__, "Expected identifier after '.'").tok(t); } + case Tok.OpenBracket: + Token open = lexer.next; + Exp index = parseExpression(); + Token close = require(Tok.CloseBracket); + return action.actOnIndexEpr(target, open, index, close); default: return target; } @@ -400,7 +405,7 @@ else if (next.type == Tok.Identifier) { Exp value = action.actOnIdentifierExp(Id(next)); - Exp iden = parseExpIdentifier(value); + Exp iden = parsePostfixExp(value); switch(lexer.peek.type) { case Tok.OpenParentheses: diff -r 06dda301ea61 -r 9e90694f5da0 sema/AstAction.d --- a/sema/AstAction.d Fri May 02 19:51:58 2008 +0200 +++ b/sema/AstAction.d Fri May 02 19:54:22 2008 +0200 @@ -160,4 +160,10 @@ { return new CastExp(new Identifier(id.tok), cast(Exp)exp ); } + + override ExprT actOnIndexEpr(ExprT arr, ref Token, ExprT index, ref Token) + { + return new IndexExp(cast(Exp)arr, cast(Exp)index); + } } + diff -r 06dda301ea61 -r 9e90694f5da0 sema/DType.d --- a/sema/DType.d Fri May 02 19:51:58 2008 +0200 +++ b/sema/DType.d Fri May 02 19:54:22 2008 +0200 @@ -50,10 +50,6 @@ /// Return a DInteger if this is one, otherwise return null DInteger asInteger() { return null; } - // Is this type a DPointer - //bool isPointer() { return false; } - // DPointer asPointer() { return null; } - int opEquals(Object o) { if (auto t = cast(DType)o) @@ -90,6 +86,9 @@ */ bool hasImplicitConversionTo(DType that) { return false; } + /** + Get a type representing a pointer to this type (from int to int*) + */ DPointer getPointerTo() { if(myPointer !is null) @@ -97,7 +96,11 @@ myPointer = new DPointer(this); return myPointer; } + private DPointer myPointer; + /** + Get a type representing a static array of this type with length 'size' + */ DArray getAsArray(int size) { if(size in myArray) @@ -105,6 +108,7 @@ myArray[size] = new DArray(this, size); return myArray[size]; } + private DArray[int] myArray; static DInteger Bool, @@ -113,9 +117,6 @@ static DType Void; - private DPointer myPointer; - private DArray[int] myArray; - static this() { Void = new DType("void"); diff -r 06dda301ea61 -r 9e90694f5da0 sema/SymbolTableBuilder.d --- a/sema/SymbolTableBuilder.d Fri May 02 19:51:58 2008 +0200 +++ b/sema/SymbolTableBuilder.d Fri May 02 19:54:22 2008 +0200 @@ -59,9 +59,9 @@ DType typeOf(Identifier id, Scope sc) { if(auto i = cast(PointerIdentifier)id) - return new DPointer(typeOf(i.pointerOf, sc)); + return (typeOf(i.pointerOf, sc)).getPointerTo(); if(auto i = cast(ArrayIdentifier)id) - return new DArray(typeOf(i.arrayOf, sc), i.size); + return typeOf(i.arrayOf, sc).getAsArray(i.size); return sc.findType(id); } } diff -r 06dda301ea61 -r 9e90694f5da0 sema/Visitor.d --- a/sema/Visitor.d Fri May 02 19:51:58 2008 +0200 +++ b/sema/Visitor.d Fri May 02 19:54:22 2008 +0200 @@ -84,6 +84,8 @@ return visitPointerIdentifier(cast(PointerIdentifier)exp); case ExpType.ArrayIdentifier: return visitArrayIdentifier(cast(ArrayIdentifier)exp); + case ExpType.Index: + return visitIndexExp(cast(IndexExp)exp); case ExpType.MemberReference: return visitMemberReference(cast(MemberReference)exp); default: @@ -309,6 +311,17 @@ return ExpT.init; } + ExpT visitIndexExp(IndexExp exp) + { + visitExp(exp.target); + visitExp(exp.index); + + static if (is(ExpT == void)) + return; + else + return ExpT.init; + } + ExpT visitMemberReference(MemberReference mem) { visitExp(mem.target);