www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3577] New: Wrong precedence for opPow

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3577

           Summary: Wrong precedence for opPow
           Product: D
           Version: future
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: wrong-code
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: dsimcha yahoo.com



opPow does not follow mathematically correct precendence.

import std.stdio;

void main() {
    writeln( 2 * 2.0L ^^ 3 + 1);  // 65
    writeln( 2.0L ^^ 3 * 2 + 1);  // 17
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 05 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3577


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au



PATCH: To give it higher precedence than *, but lower than unary operators, so
that both of the examples return 17, just create a parsePowExp() function in
parse.c.

----
Expression *Parser::parseMulExp()
{   Expression *e;
    Expression *e2;
    Loc loc = this->loc;

    e = parsePowExp();
    while (1)
    {
    switch (token.value)
    {
        case TOKmul: nextToken(); e2 = parsePowExp(); e = new MulExp(loc,e,e2);
continue;
        case TOKdiv: nextToken(); e2 = parsePowExp(); e = new DivExp(loc,e,e2);
continue;
        case TOKmod: nextToken(); e2 = parsePowExp(); e = new ModExp(loc,e,e2);
continue;
        default:
        break;
    }
    break;
    }
    return e;
}

Expression *Parser::parsePowExp()
{   Expression *e;
    Expression *e2;
    Loc loc = this->loc;

    e = parseUnaryExp();
    while (1)
    {
    switch (token.value)
    {
        case TOKpow: nextToken(); e2 = parseUnaryExp(); e = new
PowExp(loc,e,e2); continue;
        default:
        break;
    }
    break;
    }
    return e;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 05 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3577




To make it right-associative, change the key line in parsePowExp into:
---
        case TOKpow: nextToken(); e2 = parsePowExp(); e = new PowExp(loc,e,e2);
continue;

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 05 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3577




Created an attachment (id=529)
Patch against svn 304

This fixes most of the issues with ^^. It's still necessary to import std.math,
but pretty much everything else works.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 21 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3577




TEST CASES FOR TEST SUITE (Note: doesn't include any of the runtime tests)
-----------------------------
// Tests for ^^
// TODO: These tests should not require import std.math.
import std.math;

// Test float ^^ int
static assert( 27.0 ^^ 5 == 27.0 * 27.0 * 27.0 * 27.0 * 27.0); 

// Check the typing rules.
static assert( is (typeof(2.0^^7) == double));
static assert( is (typeof(7^^3) == int));

static assert( is (typeof(7L^^3) == long));
static assert( is (typeof(7^^3L) == long));
enum short POW_SHORT_1=3;
enum short POW_SHORT_3=7;
static assert( is (typeof(POW_SHORT_1 * POW_SHORT_1) ==
typeof(POW_SHORT_1*POW_SHORT_1)));

static assert( is (typeof(7.0^^3) == double));
static assert( is (typeof(7.0L^^3) == real));
static assert( is (typeof(7.0f^^3) == float));
static assert( is (typeof(POW_SHORT_1^^3.1) == double));
static assert( is (typeof(POW_SHORT_1^^3.1f) == float));
static assert( is (typeof(2.1f ^^ POW_SHORT_1) == float));
static assert( is (typeof(7.0f^^3.1) == double));
static assert( is (typeof(7.0^^3.1f) == double));
static assert( is (typeof(7.0f^^3.1f) == float));
static assert( is (typeof(7.0f^^3.1L) == real));
static assert( is (typeof(7.0L^^3.1f) == real));
// Check typing for special cases
static assert( is (typeof(7.0f^^2) == float));
static assert( is (typeof(7.0f^^1.0) == double));
static assert( is (typeof(1^^0.5f) == float));
static assert( is (typeof(7^^0.5f) == float));
static assert( is (typeof(3L^^0.5) == double));

static assert(POW_SHORT_1 ^^ 2 == 9);
static assert(4.0 ^^ POW_SHORT_1 == 4.0*4.0*4.0);

// ^^ has higher precedence than multiply
static assert( 2 * 2 ^^ 3 + 1 == 17);
static assert( 2 ^^ 3 * 2 + 1 == 17); 
// ^^ has higher precedence than negate
static assert( -2 ^^ 3 * 2 - 1 == -17);

// ^^ is right associative
static assert( 2 ^^ 3 ^^ 2 == 2 ^^ 9);
static assert( 2.0 ^^ -3 ^^ 2 == 2.0 ^^ -9);

// 1 ^^ n is always 1, even if n is negative
static assert( 1 ^^ -5 == 1);

// -1 ^^ n gets transformed into  n & 1 ? -1 : 1
// even if n is negative
static assert( (-1) ^^ -5 == -1);
static assert( (-1) ^^ -4 == 1);
static assert( (-1) ^^ 0 == 1);

// Other integers raised to negative powers create an error
static assert( !is(typeof(2 ^^ -5)));
static assert( !is(typeof((-2) ^^ -4)));

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 21 2009
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3577


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla digitalmars.com
         Resolution|                            |FIXED



11:20:41 PST ---
Fixed dmd 2.038

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 31 2009