blob: 32b24c75aaa40fa3c17c63c4699b08e5d70416e3 [file] [log] [blame]
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { assert } from "chai";
import Lexer from "./lexer";
import { TokenType } from "./token";
describe("lexer", () => {
describe("skipped content", () => {
it("skips whitespace", () => {
let input = " \t\r\n\t \tOpKill\t\n\t \r ";
let l = new Lexer(input);
let t = l.next();
assert.equal(t.type, TokenType.kOp);
assert.equal(t.line, 2);
assert.equal(t.data.name, "OpKill");
t = l.next();
assert.equal(t.type, TokenType.kEOF);
assert.equal(t.line, 3);
});
it("skips ; comments", () => {
let input = `; start with comment
OpKill ; end of line comment
; another comment
%1`;
let l = new Lexer(input);
let t = l.next();
assert.equal(t.type, TokenType.kOp);
assert.equal(t.data.name, "OpKill");
assert.equal(t.line, 2);
t = l.next();
assert.equal(t.type, TokenType.kResultId);
assert.equal(t.data.name, "1");
assert.equal(t.data.val, 1);
assert.equal(t.line, 4);
});
});
describe("numerics", () => {
it("parses floats", () => {
let input = ["0.0", "0.", ".0", "5.7", "5.", ".7", "-0.0", "-.0",
"-0.", "-5.7", "-5.", "-.7"];
let results = [0.0, 0.0, 0.0, 5.7, 5.0, 0.7, 0.0, 0.0, 0.0, -5.7, -5.0,
-0.7];
input.forEach((val, idx) => {
let l = new Lexer(val);
let t = l.next();
assert.equal(t.type, TokenType.kFloatLiteral,
`expected ${val} to be a float got ${t.type}`);
assert.equal(t.data, results[idx],
`expected ${results[idx]} === ${t.data}`);
t = l.next();
assert.equal(t.type, TokenType.kEOF);
assert.equal(t.data, undefined);
});
});
it("handles invalid floats", () => {
let input = [".", "-."];
input.forEach((val) => {
let l = new Lexer(val);
let t = l.next();
assert.notEqual(t.type, TokenType.kFloatLiteral,
`expect ${val} to not match type float`);
});
});
it("parses integers", () => {
let input = ["0", "-0", "123", "-123", "2147483647", "-2147483648",
"4294967295", "0x00", "0x24"];
let results = [0, 0, 123, -123,2147483647, -2147483648, 4294967295,
0x0, 0x24];
input.forEach((val, idx) => {
let l = new Lexer(val);
let t = l.next();
assert.equal(t.type, TokenType.kIntegerLiteral,
`expected ${val} to be an integer got ${t.type}`);
assert.equal(t.data, results[idx],
`expected ${results[idx]} === ${t.data}`);
t = l.next();
assert.equal(t.type, TokenType.kEOF);
assert.equal(t.data, undefined);
});
});
});
it("matches result_ids", () => {
let input = `%123
%001
%main
%_a_b_c`;
let result = [
{name: "123", val: 123},
{name: "001", val: 1},
{name: "main", val: undefined},
{name: "_a_b_c", val: undefined}
];
let l = new Lexer(input);
for (let i = 0; i < result.length; ++i) {
let t = l.next();
assert.equal(t.type, TokenType.kResultId);
assert.equal(t.data.name, result[i].name);
assert.equal(t.data.val, result[i].val);
}
});
it("matches punctuation", () => {
let input = "=";
let results = [TokenType.kEqual];
let l = new Lexer(input);
for (let i = 0; i < results.length; ++i) {
let t = l.next();
assert.equal(t.type, results[i]);
assert.equal(t.line, i + 1);
}
let t = l.next();
assert.equal(t.type, TokenType.kEOF);
});
describe("strings", () => {
it("matches strings", () => {
let input = "\"GLSL.std.450\"";
let l = new Lexer(input);
let t = l.next();
assert.equal(t.type, TokenType.kStringLiteral);
assert.equal(t.data, "GLSL.std.450");
});
it("handles unfinished strings", () => {
let input = "\"GLSL.std.450";
let l = new Lexer(input);
let t = l.next();
assert.equal(t.type, TokenType.kError);
});
it("handles escapes", () => {
let input = `"embedded\\"quote"
"embedded\\\\slash"
"embedded\\nchar"`;
let results = [`embedded\"quote`, `embedded\\slash`, `embeddednchar`];
let l = new Lexer(input);
for (let i = 0; i < results.length; ++i) {
let t = l.next();
assert.equal(t.type, TokenType.kStringLiteral, results[i]);
assert.equal(t.data, results[i]);
}
});
});
it("matches keywords", () => {
let input = "GLSL Function";
let results = ["GLSL", "Function"];
let l = new Lexer(input);
for (let i = 0; i < results.length; ++i) {
let t = l.next();
assert.equal(t.type, TokenType.kIdentifier, results[i]);
assert.equal(t.data, results[i]);
}
});
});