<!--
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL GLSL Conformance Tests - Reserved Words</title>
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<link rel="stylesheet" href="../../../resources/glsl-feature-tests.css"/>
<script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script id="vertexShader0" type="text/something-not-javascript">
struct $replaceMe {
  vec4 $replaceMe;
};
struct Foo {
  $replaceMe $replaceMe;
};
attribute vec4 position;
void main()
{
    Foo f;
    f.$replaceMe.$replaceMe = position;
    gl_Position = f.$replaceMe.$replaceMe;
}
</script>
<script id="fragmentShader0" type="text/something-not-javascript">
precision mediump float;
vec4 $replaceMe() {
    return vec4(0,1,0,1);
}
void main()
{
    gl_FragColor = $replaceMe();
}
</script>
<script id="vertexShader1" type="text/something-not-javascript">
attribute vec4 $replaceMe;
void main()
{
    gl_Position = $replaceMe;
}
</script>
<script id="fragmentShader1" type="text/something-not-javascript">
precision mediump float;
vec4 foo(vec4 $replaceMe) {
  return $replaceMe;
}
void main()
{
    gl_FragColor = foo(vec4(1,0,1,1));
}
</script>
<script id="vertexShader2" type="text/something-not-javascript">
varying vec4 $replaceMe;
attribute vec4 position;
void main()
{
    gl_Position = position;
    $replaceMe = position;
}
</script>
<script id="fragmentShader2" type="text/something-not-javascript">
precision mediump float;
varying vec4 $replaceMe;
void main()
{
    gl_FragColor = $replaceMe;
}
</script>
<script id="vertexShader3" type="text/something-not-javascript">
attribute vec4 position;
void main()
{
    gl_Position = position;
}
</script>
<script id="fragmentShader3" type="text/something-not-javascript">
precision mediump float;
uniform vec4 $replaceMe;
void main()
{
    gl_FragColor = $replaceMe;
}
</script>
<script>
"use strict";
var GLSL_1_0_17_words = [
  "attribute",
  "const",
  "uniform",
  "varying",
  "break",
  "continue",
  "do",
  "for",
  "while",
  "if",
  "else",
  "in",
  "out",
  "inout",
  "float",
  "int",
  "void",
  "bool",
  "true",
  "false",
  "lowp",
  "mediump",
  "highp",
  "precision",
  "invariant",
  "discard",
  "return",
  "mat2",
  "mat3",
  "mat4",
  "vec2",
  "vec3",
  "vec4",
  "ivec2",
  "ivec3",
  "ivec4",
  "bvec2",
  "bvec3",
  "bvec4",
  "sampler2D",
  "samplerCube",
  "struct"
]

var GLSL_1_0_17_FutureWords = [
  "asm",
  "class",
  "union",
  "enum",
  "typedef",
  "template",
  "this",
  "packed",
  "goto",
  "switch",
  "default",
  "inline",
  "noinline",
  "volatile",
  "public",
  "static",
  "extern",
  "external",
  "interface",
  "flat",
  "long",
  "short",
  "double",
  "half",
  "fixed",
  "unsigned",
  "superp",
  "input",
  "output",
  "hvec2",
  "hvec3",
  "hvec4",
  "dvec2",
  "dvec3",
  "dvec4",
  "fvec2",
  "fvec3",
  "fvec4",
  "sampler1D",
  "sampler3D",
  "sampler1DShadow",
  "sampler2DShadow",
  "sampler2DRect",
  "sampler3DRect",
  "sampler2DRectShadow",
  "sizeof",
  "cast",
  "namespace",
  "using",
  "__foo",      // something that has 2 underscores
  "foo__bar",   // something that has 2 underscores
  "gl_foo",     // something that starts with gl_
  "webgl_foo"   // something that starts with webgl_
];

description();

var wtu = WebGLTestUtils;
var gl = wtu.create3DContext();

var reservedWordsLists = [
  GLSL_1_0_17_words,
  GLSL_1_0_17_FutureWords
];

var reservedWords = [];
for (var ii = 0; ii < reservedWordsLists.length; ++ii) {
  var list = reservedWordsLists[ii];
  for (var jj = 0; jj < list.length; ++jj) {
    reservedWords.push(list[jj]);
  }
}

var src = [];
for (var ii = 0; ii < 4; ++ii) {
  var vsrc = document.getElementById("vertexShader" + ii).text;
  var fsrc = document.getElementById("fragmentShader" + ii).text;
  src.push({vsrc: vsrc, fsrc: fsrc});
}

var wordNdx = 0;

function testNextWord() {
  if (wordNdx >= reservedWords.length) {
    finishTest();
    return;
  }
  testWord(reservedWords[wordNdx]);
  ++wordNdx;
  setTimeout(testNextWord, 0);
}
testNextWord();

function testWord(word) {
  debug("");
  debug("testing: " + word);

  for (var ii = 0; ii < src.length; ++ii) {
    var vs = src[ii].vsrc.replace(/\$replaceMe/g, word);
    var fs = src[ii].fsrc.replace(/\$replaceMe/g, word);

    var success = true;
    var program = wtu.loadProgram(gl, vs, fs, function(msg) {
      //debug(msg);
      success = false;
    }, true);
    if (success) {
      testFailed("shader with: '" + word + "' compiled even though it should not");
    } else {
      testPassed("shader with: '" + word + "' correctly failed to compile");
    }
    if (program) {
      gl.deleteProgram(program);
    }
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no GL errors");
  }
}

var successfullyParsed = true;
</script>
</body>
</html>
