Mercurial > projects > dang
changeset 143:d76cc5cad4fc
Added partial support for switches.
Added support for extern(C) in CodeGen.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Mon, 21 Jul 2008 01:05:20 +0200 |
parents | 1e48315c36fc |
children | 6e6355fb5f0f |
files | ast/Stmt.d basic/Attribute.d gen/CodeGen.d parser/Action.d parser/Parser.d sema/AstAction.d sema/Visitor.d |
diffstat | 7 files changed, 128 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/ast/Stmt.d Sun Jul 20 23:41:53 2008 +0200 +++ b/ast/Stmt.d Mon Jul 21 01:05:20 2008 +0200 @@ -175,16 +175,17 @@ cond = target; } - void addCase(IntegerLit[] values, Stmt[] stmts) + void addCase(Exp[] values, Stmt[] stmts) { - long[] new_values; - foreach (lit; values) - new_values ~= Integer.parse(lit.get); - cases ~= Case(values, stmts, new_values); +// long[] new_values; +// foreach (lit; values) +// new_values ~= Integer.parse(lit.get); +// cases ~= Case(values, stmts, new_values); + cases ~= Case(values, stmts); // Make sure there is no two cases with the same value // Does it belong here? - new_values = new_values.dup; +/+ new_values = new_values.dup; Array.sort(new_values); long[] all_values = Array.unionOf(old_values, new_values); if (all_values.length != old_values.length + new_values.length) @@ -211,6 +212,7 @@ throw e;+/ } old_values = all_values; + +/ } void setDefault(Stmt[] stmts) @@ -241,7 +243,7 @@ struct Case { - IntegerLit[] values; + Exp[] values; Stmt[] stmts; long[] values_converted; bool followedByDefault = false;
--- a/basic/Attribute.d Sun Jul 20 23:41:53 2008 +0200 +++ b/basic/Attribute.d Mon Jul 21 01:05:20 2008 +0200 @@ -61,7 +61,37 @@ void setExtern(Extern e) { - att &= ~e; + att &= 0xFF7C0FFF; + att |= e; + } + + Extern getExtern() + { + Extern e = Extern.D; + switch(bsf(0xF0000000 | att >> 12)) + { + case 0: + e = Extern.C; + break; + case 1: + e = Extern.CPlusPlus; + break; + case 2: + e = Extern.D; + break; + case 3: + e = Extern.Windows; + break; + case 4: + e = Extern.Pascal; + break; + case 5: + e = Extern.System; + break; + default: + break; + } + return e; } void setStatic() { att &= ~Static; }
--- a/gen/CodeGen.d Sun Jul 20 23:41:53 2008 +0200 +++ b/gen/CodeGen.d Mon Jul 21 01:05:20 2008 +0200 @@ -12,6 +12,7 @@ ast.Module : DModule = Module; import basic.SmallArray, + basic.Attribute, basic.LiteralParsing; import lexer.Token; @@ -116,7 +117,7 @@ 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.sym.getMangledFQN()); + auto llfunc = m.addFunction(func_t, symbolName(fd)); foreach (i, p; fd.funcArgs) { @@ -173,7 +174,7 @@ return; llvm(funcDecl.type); - auto llfunc = m.getNamedFunction(funcDecl.sym.getMangledFQN()); + auto llfunc = m.getNamedFunction(symbolName(funcDecl)); auto func_tp = cast(PointerType)llfunc.type; auto func_t = cast(FunctionType)func_tp.elementType(); auto ret_t = func_t.returnType(); @@ -327,7 +328,7 @@ foreach (i, arg; callExp.args) args[i] = genExpression(arg).value; llvm(type); - auto f = m.getNamedFunction(sym.getMangledFQN()); + auto f = m.getNamedFunction(symbolName(callExp.exp)); DFunction f_type = type.asFunction(); bool isVoid = f_type.returnType is DType.Void; // BUG: doesn't do implicit type-conversion on args @@ -537,8 +538,8 @@ auto sw = cast(SwitchStmt)stmt; Value cond = genExpression(sw.cond).value; - auto func_name = stmt.env.parentFunction().identifier.get; - Function func = m.getNamedFunction(func_name); + auto fc = stmt.env.parentFunction(); + Function func = m.getNamedFunction(symbolName(fc)); BasicBlock oldBB = b.getInsertBlock(); BasicBlock defBB; @@ -747,7 +748,16 @@ /// Get the mangled name of a function char[] symbolName(FuncDecl f) { - return f.sym.getMangledFQN(); + if (f.att.getExtern == Extern.D) + return f.sym.getMangledFQN(); + return f.sym.getName; + } + + char[] symbolName(Exp f) + { + if (f.getSymbol.decl.att.getExtern == Extern.D) + return f.getSymbol.getMangledFQN(); + return f.getSymbol.getName; } /**
--- a/parser/Action.d Sun Jul 20 23:41:53 2008 +0200 +++ b/parser/Action.d Mon Jul 21 01:05:20 2008 +0200 @@ -277,16 +277,16 @@ return null; } - StmtT actOnStartOfSwitchStmt() + StmtT actOnStartOfSwitchStmt(ExprT exp) { return null; } - void actOnCaseStmt() + void actOnCaseStmt(StmtT stmt, ExprT[] exps, StmtT[] stmts) { } - void actOnDefaultStmt() + void actOnDefaultStmt(StmtT stmt, StmtT[] stmts) { }
--- a/parser/Parser.d Sun Jul 20 23:41:53 2008 +0200 +++ b/parser/Parser.d Mon Jul 21 01:05:20 2008 +0200 @@ -133,7 +133,6 @@ t = lexer.peek; } - if (t.isBasicType || t.isIdentifier) { Id type; @@ -532,8 +531,57 @@ } else if(t.isSwitch) { - messages.report(UnexpectedTok, lexer.peek.location).arg(lexer.next.getType); - return null; + lexer.next; + require(Tok.OpenParentheses); + auto target = parseExpression(); + auto res = action.actOnStartOfSwitchStmt(target); + require(Tok.CloseParentheses); + require(Tok.OpenBrace); + while (true) + { + Stmt[] statements; + if (skip(Tok.Default)) + { + require(Tok.Colon); + statements.length = 0; + while (lexer.peek.type != Tok.Case + && lexer.peek.type != Tok.Default + && lexer.peek.type != Tok.CloseBrace) + statements ~= parseStatement(); + action.actOnDefaultStmt(res, statements); + continue; + } + + Token _case = lexer.peek; + if (_case.type != Tok.Case) + break; + lexer.next(); + + Exp[] literals; + do + { + Exp e = parseExpression(); +// IntegerLit lit = cast(IntegerLit)e; +// if (lit is null) +// messages.report(CaseValueMustBeInt, lexer.peek.location).arg(lexer.next.getType); +// else + literals ~= e; + } + while (skip(Tok.Comma)); + require(Tok.Colon); + + while (lexer.peek.type != Tok.Case + && lexer.peek.type != Tok.Default + && lexer.peek.type != Tok.CloseBrace) + statements ~= parseStatement(); + + action.actOnCaseStmt(res, literals, statements); + + if (lexer.peek.type == Tok.CloseBrace) + break; + } + require(Tok.CloseBrace); + return res; } else {
--- a/sema/AstAction.d Sun Jul 20 23:41:53 2008 +0200 +++ b/sema/AstAction.d Mon Jul 21 01:05:20 2008 +0200 @@ -173,6 +173,23 @@ return new DeclStmt(d); } + override StmtT actOnStartOfSwitchStmt(ExprT exp) + { + return new SwitchStmt(cast(Exp)exp); + } + + override void actOnCaseStmt(StmtT stmt, ExprT[] exps, StmtT[] stmts) + { + auto sw = cast(SwitchStmt)stmt; + sw.addCase(cast(Exp[])exps, cast(Stmt[])stmts); + } + + override void actOnDefaultStmt(StmtT stmt, StmtT[] stmts) + { + auto sw = cast(SwitchStmt)stmt; + sw.setDefault(cast(Stmt[])stmts); + } + // -- Expressions -- override ExprT actOnNumericConstant(Token c) {