# HG changeset patch # User Aziz K?ksal # Date 1200409542 -3600 # Node ID 29cc5bf3ce89eda9653a5af282501a08917944a2 # Parent b4c9f1cb19c6f96a1c993c55633f793b224557c7 Refactored StringExpression. Added error message MSG.StringPostfixMismatch. Refactored parseAssignExpression(). diff -r b4c9f1cb19c6 -r 29cc5bf3ce89 trunk/src/dil/Messages.d --- a/trunk/src/dil/Messages.d Tue Jan 15 12:10:46 2008 +0100 +++ b/trunk/src/dil/Messages.d Tue Jan 15 16:05:42 2008 +0100 @@ -102,6 +102,7 @@ auto UTF32FileMustBeDivisibleBy4 = "the byte length of a UTF-32 source file must be divisible by 4."; // Parser messages: auto ModuleDeclarationNotFirst = "a module declaration is only allowed as the first declaration in a file"; + auto StringPostfixMismatch = "string literal has mistmatching postfix character"; auto ExpectedIdAfterTypeDot = "expected identifier after '(Type).', not '{}'"; auto ExpectedModuleIdentifier = "expected module identifier, not '{}'"; auto IllegalDeclaration = "illegal Declaration found: {}"; diff -r b4c9f1cb19c6 -r 29cc5bf3ce89 trunk/src/dil/ast/Expressions.d --- a/trunk/src/dil/ast/Expressions.d Tue Jan 15 12:10:46 2008 +0100 +++ b/trunk/src/dil/ast/Expressions.d Tue Jan 15 16:05:42 2008 +0100 @@ -734,23 +734,12 @@ class StringExpression : Expression { - Token*[] stringTokens; - this() - { mixin(set_kind); } - - /// Constructor used in parsing phase. - this(Token*[] stringTokens) - { - this(); - this.stringTokens = stringTokens; - } - ubyte[] str; /// The string data. Type charType; /// The character type of the string. - // Constructors used in semantic phase. + this(ubyte[] str, Type charType) { - this(); + mixin(set_kind); this.str = str; this.charType = charType; type = new TypeSArray(charType, str.length); @@ -760,10 +749,12 @@ { this(cast(ubyte[])str, Types.Char); } + this(wchar[] str) { this(cast(ubyte[])str, Types.Wchar); } + this(dchar[] str) { this(cast(ubyte[])str, Types.Dchar); @@ -771,10 +762,8 @@ char[] getString() { - char[] buffer; - foreach (token; stringTokens) - buffer ~= token.str[0..$-1]; - return buffer; + // TODO: convert to char[] if charType !is Types.Char. + return cast(char[])str; } } diff -r b4c9f1cb19c6 -r 29cc5bf3ce89 trunk/src/dil/parser/Parser.d --- a/trunk/src/dil/parser/Parser.d Tue Jan 15 12:10:46 2008 +0100 +++ b/trunk/src/dil/parser/Parser.d Tue Jan 15 16:05:42 2008 +0100 @@ -2700,8 +2700,7 @@ error(MID.ExpectedButFound, "Expression", token.srcText); e = new EmptyExpression(); if (!trying) - { - // Insert a dummy token and don't consume current one. + { // Insert a dummy token and don't consume current one. begin = lexer.insertEmptyTokenBefore(token); this.prevToken = begin; } @@ -2716,13 +2715,14 @@ Expression parseExpression() { + alias parseAssignExpression parseNext; auto begin = token; - auto e = parseAssignExpression(); + auto e = parseNext(); while (token.type == T.Comma) { auto comma = token; nT(); - e = new CommaExpression(e, parseAssignExpression(), comma); + e = new CommaExpression(e, parseNext(), comma); set(e, begin); } return e; @@ -2730,56 +2730,41 @@ Expression parseAssignExpression() { + alias parseAssignExpression parseNext; auto begin = token; auto e = parseCondExpression(); - while (1) + switch (token.type) { - switch (token.type) - { - case T.Assign: - nT(); e = new AssignExpression(e, parseAssignExpression()); - break; - case T.LShiftAssign: - nT(); e = new LShiftAssignExpression(e, parseAssignExpression()); - break; - case T.RShiftAssign: - nT(); e = new RShiftAssignExpression(e, parseAssignExpression()); - break; - case T.URShiftAssign: - nT(); e = new URShiftAssignExpression(e, parseAssignExpression()); - break; - case T.OrAssign: - nT(); e = new OrAssignExpression(e, parseAssignExpression()); - break; - case T.AndAssign: - nT(); e = new AndAssignExpression(e, parseAssignExpression()); - break; - case T.PlusAssign: - nT(); e = new PlusAssignExpression(e, parseAssignExpression()); - break; - case T.MinusAssign: - nT(); e = new MinusAssignExpression(e, parseAssignExpression()); - break; - case T.DivAssign: - nT(); e = new DivAssignExpression(e, parseAssignExpression()); - break; - case T.MulAssign: - nT(); e = new MulAssignExpression(e, parseAssignExpression()); - break; - case T.ModAssign: - nT(); e = new ModAssignExpression(e, parseAssignExpression()); - break; - case T.XorAssign: - nT(); e = new XorAssignExpression(e, parseAssignExpression()); - break; - case T.CatAssign: - nT(); e = new CatAssignExpression(e, parseAssignExpression()); - break; - default: - return e; - } - set(e, begin); + case T.Assign: + nT(); e = new AssignExpression(e, parseNext()); break; + case T.LShiftAssign: + nT(); e = new LShiftAssignExpression(e, parseNext()); break; + case T.RShiftAssign: + nT(); e = new RShiftAssignExpression(e, parseNext()); break; + case T.URShiftAssign: + nT(); e = new URShiftAssignExpression(e, parseNext()); break; + case T.OrAssign: + nT(); e = new OrAssignExpression(e, parseNext()); break; + case T.AndAssign: + nT(); e = new AndAssignExpression(e, parseNext()); break; + case T.PlusAssign: + nT(); e = new PlusAssignExpression(e, parseNext()); break; + case T.MinusAssign: + nT(); e = new MinusAssignExpression(e, parseNext()); break; + case T.DivAssign: + nT(); e = new DivAssignExpression(e, parseNext()); break; + case T.MulAssign: + nT(); e = new MulAssignExpression(e, parseNext()); break; + case T.ModAssign: + nT(); e = new ModAssignExpression(e, parseNext()); break; + case T.XorAssign: + nT(); e = new XorAssignExpression(e, parseNext()); break; + case T.CatAssign: + nT(); e = new CatAssignExpression(e, parseNext()); break; + default: + return e; } + set(e, begin); return e; } @@ -3210,13 +3195,25 @@ nT(); break; case T.String: - Token*[] stringLiterals; - do + char[] str = token.str; + char postfix = token.pf; + nT(); + while (token.type == T.String) { - stringLiterals ~= token; + if (postfix == '\0') + postfix = token.pf; + else if (token.pf && token.pf != postfix) + error(token, MSG.StringPostfixMismatch); + str ~= token.str; nT(); - } while (token.type == T.String) - e = new StringExpression(stringLiterals); + } + switch (postfix) + { // TODO: convert string + case 'w': e = new StringExpression(/+toUTF16+/(str)); break; + case 'd': e = new StringExpression(/+toUTF32+/(str)); break; + case 'c': + default: e = new StringExpression(str); break; + } break; case T.LBracket: Expression[] values; @@ -3354,15 +3351,13 @@ break; case T.LParen: if (tokenAfterParenIs(T.LBrace)) // Check for "(...) {" - { + { // ( ParameterList ) FunctionBody auto parameters = parseParameterList(); - // ( ParameterList ) FunctionBody auto funcBody = parseFunctionBody(); e = new FunctionLiteralExpression(null, parameters, funcBody); } else - { - // ( Expression ) + { // ( Expression ) nT(); e = parseExpression(); require(T.RParen); @@ -3403,8 +3398,7 @@ error(MID.ExpectedButFound, "Expression", token.srcText); e = new EmptyExpression(); if (!trying) - { - // Insert a dummy token and don't consume current one. + { // Insert a dummy token and don't consume current one. begin = lexer.insertEmptyTokenBefore(token); this.prevToken = begin; }