# HG changeset patch # User Anders Johnsen # Date 1209662749 -7200 # Node ID 381975d76baf692ab5c7def539cacd138075973f # Parent 3fdf20b08a81154ad918f28ad58042a112659cb0 A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing... diff -r 3fdf20b08a81 -r 381975d76baf ast/Exp.d --- a/ast/Exp.d Tue Apr 29 20:15:22 2008 +0200 +++ b/ast/Exp.d Thu May 01 19:25:49 2008 +0200 @@ -21,6 +21,7 @@ Identifier, AssignExp, CallExp, + CastExp, } class Exp @@ -144,6 +145,8 @@ Mul, Div, Mod, } + char[][] getOp = ["=","==","!=","<","<=",">",">=","+","-","*","/","%"]; + this(Operator op, Exp left, Exp right) { super(ExpType.Binary); @@ -157,6 +160,17 @@ if (myType) return myType; + if (op == Operator.Eq || + op == Operator.Ne || + op == Operator.Lt || + op == Operator.Le || + op == Operator.Gt || + op == Operator.Ge) + { + myType = DType.Bool; + return myType; + } + DType l = left.type; DType r = right.type; if (l is r) @@ -167,6 +181,7 @@ myType = l; else return null; + return myType; } char[] resultType() @@ -225,6 +240,8 @@ override DType type() { return DType.Int; } + + Token token; char[] name; } @@ -254,6 +271,8 @@ myType = t; // no error reporting here else assert(0, "Referencing non-existant member"); + + return myType; } Identifier child; @@ -283,6 +302,31 @@ IntegerLit pos; } +class CastExp : Exp +{ + this(Identifier castType, Exp exp) + { + super(ExpType.CastExp); + this.castType = castType; + this.exp = exp; + } + + override DType type() + { + return env.findType(this.castType); + } + + Exp simplify() + { + castType.simplify; + exp.simplify; + return this; + } + + Identifier castType; + Exp exp; +} + class Identifier : Exp { this(Token t) diff -r 3fdf20b08a81 -r 381975d76baf dang/compiler.d --- a/dang/compiler.d Tue Apr 29 20:15:22 2008 +0200 +++ b/dang/compiler.d Thu May 01 19:25:49 2008 +0200 @@ -19,6 +19,7 @@ import sema.Visitor, sema.AstAction, sema.SymbolTableBuilder, + sema.ImplicitCast, sema.Declarations; import dang.OptParse; @@ -170,6 +171,7 @@ (new SymbolTableBuilder).visit(decls); (new Declarations).visit(decls); + (new ImplicitCast).visit(decls); foreach(decl ; decls) decl.simplify(); diff -r 3fdf20b08a81 -r 381975d76baf gen/CodeGen.d --- a/gen/CodeGen.d Tue Apr 29 20:15:22 2008 +0200 +++ b/gen/CodeGen.d Thu May 01 19:25:49 2008 +0200 @@ -77,6 +77,45 @@ auto temp = FunctionType.Get(Type.Void, [BytePtr, BytePtr, Type.Int32, Type.Int32]); llvm_memcpy = m.addFunction(temp, "llvm.memcpy.i32"); + auto registerFunc = + (FuncDecl fd) + { + Type[] param_types; + foreach (i, p; fd.funcArgs) + { + DType t = p.env.find(p.identifier).type; + if(auto st = cast(DStruct)t) + { + Type pointer = PointerType.Get(llvm(st)); + param_types ~= pointer; + } + else + param_types ~= llvm(t); + } + auto ret_t = fd.env.find(fd.identifier).type; + if(auto st = cast(DStruct)ret_t) + ret_t = DType.Void; + else if(auto f = cast(DFunction)ret_t) + ret_t = f.returnType; + auto func_t = FunctionType.Get(llvm(ret_t), param_types); + auto llfunc = m.addFunction(func_t, fd.identifier.get); + + foreach (i, p; fd.funcArgs) + { + if(i == 0 && fd.sret) + llfunc.addParamAttr(0, ParamAttr.StructRet); + + DType t = p.env.find(p.identifier).type; + if(auto st = cast(DStruct)t) + { + if(i == 0 && fd.sret) + continue; + llfunc.addParamAttr(i,ParamAttr.ByVal); + } + } + }; + auto visitor = new VisitFuncDecls(registerFunc); + visitor.visit(decls); // Before beginning we move all top level var-decls to the start // and then we generate the var-decls first // partition is NOT required to be stable, but that should not create @@ -217,7 +256,7 @@ auto left = genExpression(binaryExp.left); auto right = genExpression(binaryExp.right); - sextSmallerToLarger(left, right); +// sextSmallerToLarger(left, right); OpBuilder op = opToLLVM[binaryExp.op]; @@ -248,6 +287,29 @@ if(callExp.sret) return b.buildCall(m.getNamedFunction(func_sym.id.get), args, ""); return b.buildCall(m.getNamedFunction(func_sym.id.get), args, ".call"); + case ExpType.CastExp: + auto castExp = cast(CastExp)exp; + auto value = genExpression(castExp.exp); + + if(!castExp.type.hasImplicitConversionTo(castExp.type)) + assert(0, "Invalid cast"); + + Stdout(castExp.type.byteSize).newline; + Stdout(castExp.type.name).newline; + Stdout(castExp.exp.type.byteSize).newline; + Stdout(castExp.exp.type.name).newline; + + Stdout(value).newline; + + Value v; + if(castExp.exp.type.byteSize <= castExp.type.byteSize) + v = b.buildZExt(value, llvm(castExp.type), "cast"); + else + v = b.buildTrunc(value, llvm(castExp.type), "cast"); + + Stdout(v).newline; + return v; + case ExpType.Identifier: auto identifier = cast(Identifier)exp; auto sym = exp.env.find(identifier); @@ -473,6 +535,9 @@ Value t = getPointer(target); Value v = genExpression(exp); + Stdout(v).newline; + Stdout(t).newline; + auto a = cast(PointerType)t.type; assert(a, "Assing to type have to be of type PointerType"); @@ -546,8 +611,14 @@ else if (auto s = t.asStruct) { SmallArray!(Type, 8) members; + DType[] array; + array.length = s.members.length; + foreach(m; s.members) - members ~= llvm(m.type); + array[m.index] = m.type; + + foreach(m; array) + members ~= llvm(m); Type res = StructType.Get(members.unsafe()); type_map[t] = res; @@ -570,7 +641,7 @@ Type res = FunctionType.Get(ret_t, params.unsafe()); type_map[t] = res; - auto llfunc = m.addFunction(res, f.name); +/* auto llfunc = m.addFunction(res, f.name); foreach (i, param; f.params) if (param.isStruct) @@ -581,7 +652,7 @@ llfunc.removeParamAttr(0, ParamAttr.ByVal); llfunc.addParamAttr(0, ParamAttr.StructRet); } - +*/ return res; } assert(0, "Only integers, structs and functions are supported"); diff -r 3fdf20b08a81 -r 381975d76baf lexer/Keyword.d --- a/lexer/Keyword.d Tue Apr 29 20:15:22 2008 +0200 +++ b/lexer/Keyword.d Thu May 01 19:25:49 2008 +0200 @@ -39,6 +39,7 @@ "switch" : Tok.Switch, "case" : Tok.Case, "default" : Tok.Default, - "return" : Tok.Return + "return" : Tok.Return, + "cast" : Tok.Cast ]; } diff -r 3fdf20b08a81 -r 381975d76baf lexer/Token.d --- a/lexer/Token.d Tue Apr 29 20:15:22 2008 +0200 +++ b/lexer/Token.d Thu May 01 19:25:49 2008 +0200 @@ -137,7 +137,7 @@ If, Else, While, Switch, Case, Default, - Return, + Return, Cast, } @@ -187,6 +187,7 @@ Tok.Return:"Return", Tok.Struct:"Struct", Tok.Colon:"Colon", - Tok.Seperator:"Seperator" + Tok.Seperator:"Seperator", + Tok.Cast:"Cast" ]; } diff -r 3fdf20b08a81 -r 381975d76baf parser/Action.d --- a/parser/Action.d Tue Apr 29 20:15:22 2008 +0200 +++ b/parser/Action.d Thu May 01 19:25:49 2008 +0200 @@ -242,6 +242,14 @@ { return null; } + + /** + Cast expression. + */ + ExprT actOnCastExpr(Id type, ExprT exp) + { + return null; + } } /** diff -r 3fdf20b08a81 -r 381975d76baf parser/Parser.d --- a/parser/Parser.d Tue Apr 29 20:15:22 2008 +0200 +++ b/parser/Parser.d Thu May 01 19:25:49 2008 +0200 @@ -373,6 +373,8 @@ return iden; } } + else if (next.type == Tok.Cast) + return parseCast(); else if (next.type == Tok.Integer) return action.actOnNumericConstant(next); @@ -380,6 +382,18 @@ assert(0, "Should not happen"); } + Exp parseCast() + { + require(Tok.OpenParentheses); + auto next = lexer.next; + if(!next.isBasicType && !next.isIdentifier) + throw error(__LINE__, "Expected cast type, not "~next.get).tok(next); + + require(Tok.CloseParentheses); + auto exp = P(); + return action.actOnCastExpr(Id(next), exp); + } + struct UnOp { Tok tokenType; diff -r 3fdf20b08a81 -r 381975d76baf sema/AstAction.d --- a/sema/AstAction.d Tue Apr 29 20:15:22 2008 +0200 +++ b/sema/AstAction.d Thu May 01 19:25:49 2008 +0200 @@ -138,4 +138,9 @@ Exp[] arguments = cast(Exp[])args.dup; return new CallExp(f, arguments); } + + override ExprT actOnCastExpr(Id id, ExprT exp) + { + return new CastExp(new Identifier(id.tok), cast(Exp)exp ); + } } diff -r 3fdf20b08a81 -r 381975d76baf sema/DType.d --- a/sema/DType.d Tue Apr 29 20:15:22 2008 +0200 +++ b/sema/DType.d Thu May 01 19:25:49 2008 +0200 @@ -120,7 +120,8 @@ override bool hasImplicitConversionTo(DType that) { if (auto o = cast(DInteger)that) - return this.bits >= o.bits; + return true; +// return this.bits >= o.bits; return false; } diff -r 3fdf20b08a81 -r 381975d76baf sema/Declarations.d --- a/sema/Declarations.d Tue Apr 29 20:15:22 2008 +0200 +++ b/sema/Declarations.d Thu May 01 19:25:49 2008 +0200 @@ -37,6 +37,7 @@ if (d.init) visitExp(d.init); } + override void visitFuncDecl(FuncDecl f) { visitExp(f.identifier); @@ -45,6 +46,11 @@ visitStmt(stmt); } + override void visitCastExp(CastExp exp) + { + visitExp(exp.exp); + } + override void visitMemberReference(MemberReference m) { switch(m.target.expType) diff -r 3fdf20b08a81 -r 381975d76baf sema/Visitor.d --- a/sema/Visitor.d Tue Apr 29 20:15:22 2008 +0200 +++ b/sema/Visitor.d Thu May 01 19:25:49 2008 +0200 @@ -74,6 +74,8 @@ return visitAssignExp(cast(AssignExp)exp); case ExpType.CallExp: return visitCallExp(cast(CallExp)exp); + case ExpType.CastExp: + return visitCastExp(cast(CastExp)exp); case ExpType.Identifier: return visitIdentifier(cast(Identifier)exp); case ExpType.MemberReference: @@ -236,6 +238,16 @@ return ExpT.init; } + ExpT visitCastExp(CastExp exp) + { + visitExp(exp.castType); + visitExp(exp.exp); + static if (is(ExpT == void)) + return; + else + return ExpT.init; + } + ExpT visitNegateExp(NegateExp exp) { visitExp(exp.exp); diff -r 3fdf20b08a81 -r 381975d76baf tests/code/basic_types_2.d --- a/tests/code/basic_types_2.d Tue Apr 29 20:15:22 2008 +0200 +++ b/tests/code/basic_types_2.d Thu May 01 19:25:49 2008 +0200 @@ -12,6 +12,8 @@ c = stoi(a); c = stoi(b); + + return 3; } long itol(int x) { return x; } diff -r 3fdf20b08a81 -r 381975d76baf tools/AstPrinter.d --- a/tools/AstPrinter.d Tue Apr 29 20:15:22 2008 +0200 +++ b/tools/AstPrinter.d Thu May 01 19:25:49 2008 +0200 @@ -104,9 +104,11 @@ { case ExpType.Binary: auto binaryExp = cast(BinaryExp)exp; + print("("); printExp(binaryExp.left); - print([binaryExp.op] ~ " "); + print(" " ~ binaryExp.getOp[binaryExp.op] ~ " "); printExp(binaryExp.right); + print(")"); break; case ExpType.IntegerLit: auto integetLit = cast(IntegerLit)exp; @@ -146,6 +148,14 @@ } print(")"); break; + case ExpType.CastExp: + auto castExp = cast(CastExp)exp; + print("cast"); + print("("); + printExp(castExp.castType); + print(")"); + printExp(castExp.exp); + break; } }