Changeset 235249 in webkit


Ignore:
Timestamp:
Aug 23, 2018 2:43:03 PM (6 years ago)
Author:
mmaxfield@apple.com
Message:

[WSL] Ternary expressions appear to be unimplemented
https://bugs.webkit.org/show_bug.cgi?id=178981

Reviewed by Saam Barati.

Implement ternary statements. These can be both lvalues and rvalues. (a ? b : c ? d : e)
is parsed as (a ? b : (c ? d : e)).

  • WebGPUShadingLanguageRI/All.js:
  • WebGPUShadingLanguageRI/Checker.js:

(Checker.prototype.visitTernaryExpression):

  • WebGPUShadingLanguageRI/Evaluator.js:

(Evaluator.prototype.visitTernaryExpression):

  • WebGPUShadingLanguageRI/NormalUsePropertyResolver.js:

(NormalUsePropertyResolver.prototype.visitTernaryExpression):
(NormalUsePropertyResolver):

  • WebGPUShadingLanguageRI/Parse.js:

(parsePossibleTernaryConditional):

  • WebGPUShadingLanguageRI/PropertyResolver.js:

(PropertyResolver.prototype._visitRValuesWithinLValue.RValueFinder.prototype.visitTernaryExpression):
(PropertyResolver.prototype._visitRValuesWithinLValue.RValueFinder):
(PropertyResolver.prototype._visitRValuesWithinLValue):

  • WebGPUShadingLanguageRI/Rewriter.js:

(Rewriter.prototype.visitTernaryExpression):

  • WebGPUShadingLanguageRI/SPIRV.html:
  • WebGPUShadingLanguageRI/Test.html:
  • WebGPUShadingLanguageRI/Test.js:
  • WebGPUShadingLanguageRI/Visitor.js:

(Visitor.prototype.visitProtocolDecl):

  • WebGPUShadingLanguageRI/index.html:
Location:
trunk/Tools
Files:
13 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r235243 r235249  
     12018-08-23  Myles C. Maxfield  <mmaxfield@apple.com>
     2
     3        [WSL] Ternary expressions appear to be unimplemented
     4        https://bugs.webkit.org/show_bug.cgi?id=178981
     5
     6        Reviewed by Saam Barati.
     7
     8        Implement ternary statements. These can be both lvalues and rvalues. (a ? b : c ? d : e)
     9        is parsed as (a ? b : (c ? d : e)).
     10
     11        * WebGPUShadingLanguageRI/All.js:
     12        * WebGPUShadingLanguageRI/Checker.js:
     13        (Checker.prototype.visitTernaryExpression):
     14        * WebGPUShadingLanguageRI/Evaluator.js:
     15        (Evaluator.prototype.visitTernaryExpression):
     16        * WebGPUShadingLanguageRI/NormalUsePropertyResolver.js:
     17        (NormalUsePropertyResolver.prototype.visitTernaryExpression):
     18        (NormalUsePropertyResolver):
     19        * WebGPUShadingLanguageRI/Parse.js:
     20        (parsePossibleTernaryConditional):
     21        * WebGPUShadingLanguageRI/PropertyResolver.js:
     22        (PropertyResolver.prototype._visitRValuesWithinLValue.RValueFinder.prototype.visitTernaryExpression):
     23        (PropertyResolver.prototype._visitRValuesWithinLValue.RValueFinder):
     24        (PropertyResolver.prototype._visitRValuesWithinLValue):
     25        * WebGPUShadingLanguageRI/Rewriter.js:
     26        (Rewriter.prototype.visitTernaryExpression):
     27        * WebGPUShadingLanguageRI/SPIRV.html:
     28        * WebGPUShadingLanguageRI/Test.html:
     29        * WebGPUShadingLanguageRI/Test.js:
     30        * WebGPUShadingLanguageRI/Visitor.js:
     31        (Visitor.prototype.visitProtocolDecl):
     32        * WebGPUShadingLanguageRI/index.html:
     33
    1342018-08-22  Ryosuke Niwa  <rniwa@webkit.org>
    235
  • trunk/Tools/WebGPUShadingLanguageRI/All.js

    r235237 r235249  
    154154load("SynthesizeCopyConstructorOperator.js");
    155155load("SynthesizeDefaultConstructorOperator.js");
     156load("TernaryExpression.js");
    156157load("TrapStatement.js");
    157158load("TypeDef.js");
  • trunk/Tools/WebGPUShadingLanguageRI/Checker.js

    r235237 r235249  
    649649        return result;
    650650    }
     651
     652    visitTernaryExpression(node)
     653    {
     654        this._requireBool(node.predicate);
     655        let bodyType = node.bodyExpression.visit(this);
     656        let elseType = node.elseExpression.visit(this);
     657        if (!bodyType)
     658            throw new Error("Ternary expression body has no type: " + node.bodyExpression);
     659        if (!elseType)
     660            throw new Error("Ternary expression else has no type: " + node.elseExpression);
     661        if (!bodyType.equalsWithCommit(elseType))
     662            throw new WTypeError("Body and else clause of ternary statement don't have the same type: " + node);
     663        node.isLValue = node.bodyExpression.isLValue && node.elseExpression.isLValue;
     664        return bodyType;
     665    }
    651666   
    652667    visitCallExpression(node)
  • trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js

    r235096 r235249  
    143143        return result;
    144144    }
     145
     146    visitTernaryExpression(node)
     147    {
     148        if (node.predicate.visit(this).loadValue())
     149            return node.bodyExpression.visit(this);
     150        return node.elseExpression.visit(this);
     151       
     152    }
    145153   
    146154    visitVariableRef(node)
  • trunk/Tools/WebGPUShadingLanguageRI/NormalUsePropertyResolver.js

    r222169 r235249  
    3535        return super.visitIndexExpression(node).rewriteAfterCloning();
    3636    }
     37
     38    visitTernaryExpression(node)
     39    {
     40        let result = super.visitTernaryExpression(node);
     41        result.isLValue = node.isLValue;
     42        return result;
     43    }
    3744}
    3845
  • trunk/Tools/WebGPUShadingLanguageRI/Parse.js

    r235144 r235249  
    521521        if (!operator)
    522522            return predicate;
    523         return new TernaryExpression(operator, predicate, parsePossibleAssignment(), parsePossibleAssignment());
     523        let bodyExpression = parsePossibleAssignment();
     524        consume(":");
     525        let elseExpression = parsePossibleAssignment();
     526        return new TernaryExpression(operator, predicate, bodyExpression, elseExpression);
    524527    }
    525528   
  • trunk/Tools/WebGPUShadingLanguageRI/PropertyResolver.js

    r222750 r235249  
    5959            {
    6060                visit(node.lValue);
     61            }
     62
     63            visitTernaryExpression(node)
     64            {
    6165            }
    6266        }
  • trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js

    r235237 r235249  
    165165        return result;
    166166    }
     167
     168    visitTernaryExpression(node)
     169    {
     170        return new TernaryExpression(node.origin, node.predicate.visit(this), node.bodyExpression.visit(this), node.elseExpression.visit(this));
     171    }
    167172   
    168173    _handlePropertyAccessExpression(result, node)
  • trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html

    r235237 r235249  
    137137    <script src="SynthesizeCopyConstructorOperator.js"></script>
    138138    <script src="SynthesizeDefaultConstructorOperator.js"></script>
     139    <script src="TernaryExpression.js"></script>
    139140    <script src="TrapStatement.js"></script>
    140141    <script src="TypeDef.js"></script>
  • trunk/Tools/WebGPUShadingLanguageRI/TernaryExpression.js

    r235248 r235249  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2525"use strict";
    2626
    27 class NormalUsePropertyResolver extends Rewriter {
    28     visitDotExpression(node)
     27class TernaryExpression extends Expression {
     28    constructor(origin, predicate, bodyExpression, elseExpression)
    2929    {
    30         return super.visitDotExpression(node).rewriteAfterCloning();
     30        super(origin);
     31        this._predicate = predicate;
     32        this._bodyExpression = bodyExpression;
     33        this._elseExpression = elseExpression;
     34        this._isLValue = null; // We use null to indicate that we don't know yet.
    3135    }
    3236   
    33     visitIndexExpression(node)
     37    get predicate() { return this._predicate; }
     38    get bodyExpression() { return this._bodyExpression; }
     39    get elseExpression() { return this._elseExpression; }
     40    get isLValue() { return this._isLValue; }
     41    set isLValue(value) { this._isLValue = value; }
     42   
     43    toString()
    3444    {
    35         return super.visitIndexExpression(node).rewriteAfterCloning();
     45        return "(" + this.predicate + ") ? (" + this.bodyExpression + ") : (" + this.elseExpression + ")";
    3646    }
    3747}
    38 
  • trunk/Tools/WebGPUShadingLanguageRI/Test.html

    r235237 r235249  
    131131<script src="SynthesizeCopyConstructorOperator.js"></script>
    132132<script src="SynthesizeDefaultConstructorOperator.js"></script>
     133<script src="TernaryExpression.js"></script>
    133134<script src="TrapStatement.js"></script>
    134135<script src="TypeDef.js"></script>
  • trunk/Tools/WebGPUShadingLanguageRI/Test.js

    r235237 r235249  
    197197        `),
    198198        (e) => e instanceof WSyntaxError);
     199}
     200
     201tests.ternaryExpression = function() {
     202    let program = doPrep(`
     203        int foo(int x)
     204        {
     205            return x < 3 ? 4 : 5;
     206        }
     207        int bar(int x)
     208        {
     209            int y = 1;
     210            int z = 2;
     211            (x < 3 ? y : z) = 7;
     212            return y;
     213        }
     214        int baz(int x)
     215        {
     216            return x < 10 ? 11 : x < 12 ? 14 : 15;
     217        }
     218        int quux(int x)
     219        {
     220            return 3 < 4 ? x : 5;
     221        }
     222    `);
     223    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 767)]), 5);
     224    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 2)]), 4);
     225    checkInt(program, callFunction(program, "bar", [], [makeInt(program, 2)]), 7);
     226    checkInt(program, callFunction(program, "bar", [], [makeInt(program, 8)]), 1);
     227    checkInt(program, callFunction(program, "baz", [], [makeInt(program, 8)]), 11);
     228    checkInt(program, callFunction(program, "baz", [], [makeInt(program, 9)]), 11);
     229    checkInt(program, callFunction(program, "baz", [], [makeInt(program, 10)]), 14);
     230    checkInt(program, callFunction(program, "baz", [], [makeInt(program, 11)]), 14);
     231    checkInt(program, callFunction(program, "baz", [], [makeInt(program, 12)]), 15);
     232    checkInt(program, callFunction(program, "baz", [], [makeInt(program, 13)]), 15);
     233    checkInt(program, callFunction(program, "quux", [], [makeInt(program, 14)]), 14);
     234    checkFail(
     235        () => doPrep(`
     236            int foo()
     237            {
     238                int x;
     239                (4 < 5 ? x : 7) = 8;
     240            }
     241        `),
     242        (e) => e instanceof WTypeError);
     243    checkFail(
     244        () => doPrep(`
     245            int foo()
     246            {
     247                int x;
     248                float y;
     249                return 4 < 5 ? x : y;
     250            }
     251        `),
     252        (e) => e instanceof WTypeError);
     253    checkFail(
     254        () => doPrep(`
     255            int foo()
     256            {
     257                return 4 < 5 ? 6 : 7.0;
     258            }
     259        `),
     260        (e) => e instanceof WTypeError);
    199261}
    200262
  • trunk/Tools/WebGPUShadingLanguageRI/Visitor.js

    r235237 r235249  
    163163        node.ptr.visit(this);
    164164    }
     165
     166    visitTernaryExpression(node)
     167    {
     168        node.predicate.visit(this);
     169        node.bodyExpression.visit(this);
     170        node.elseExpression.visit(this);
     171    }
    165172   
    166173    _handlePropertyAccessExpression(node)
  • trunk/Tools/WebGPUShadingLanguageRI/index.html

    r235237 r235249  
    131131<script src="SynthesizeCopyConstructorOperator.js"></script>
    132132<script src="SynthesizeDefaultConstructorOperator.js"></script>
     133<script src="TernaryExpression.js"></script>
    133134<script src="TrapStatement.js"></script>
    134135<script src="TypeDef.js"></script>
Note: See TracChangeset for help on using the changeset viewer.