diff --git a/src/assignment.ts b/src/assignment.ts index fab08f9..0bd1060 100644 --- a/src/assignment.ts +++ b/src/assignment.ts @@ -1,8 +1,8 @@ import Expression from './expression'; -import Variable from './variable'; -import Type from './type'; +import InterfaceVariable from './interface'; import Reference from './reference'; import Set from './util/set'; +import Type from './type'; export default class Assignment implements Expression { private lhs: Reference; @@ -14,7 +14,7 @@ export default class Assignment implements Expression { this.rhs = rhs; } - public dependencies(): Set { + public dependencies(): Set { return this.rhs.dependencies().union(this.lhs.dependencies()); } diff --git a/src/block.ts b/src/block.ts index 1f5d267..0c4a22d 100644 --- a/src/block.ts +++ b/src/block.ts @@ -1,8 +1,8 @@ -import Variable from './variable'; import Expression from './expression'; +import InterfaceVariable from './interface'; +import Set from './util/set'; import Statement from './statement'; import Type from './type'; -import Set from './util/set'; export default class Block implements Expression { private statements: Statement[]; @@ -20,11 +20,11 @@ export default class Block implements Expression { return Type.Void; } - public dependencies(): Set { + public dependencies(): Set { return this.statements.reduce((union, statement) => ( union.addAll(statement.dependencies()) ), - new Set() + new Set() ); } diff --git a/src/calder.ts b/src/calder.ts index 030d387..af55a41 100644 --- a/src/calder.ts +++ b/src/calder.ts @@ -33,8 +33,10 @@ export { default as Shader } from './shader'; export { default as Qualifier } from './qualifier'; export { default as Type } from './type'; export { default as If } from './if' +export { default as InterfaceVariable } from './interface'; export { default as Block } from './block' export { default as While } from './while' export { default as DoWhile } from './dowhile' +export { default as Struct } from './struct' export { default as ShaderPipelineBuilder } from './shaderpipelinebuilder'; export { default as ShaderPipeline } from './shaderpipeline'; diff --git a/src/function.ts b/src/function.ts index ba476e7..2727f3c 100644 --- a/src/function.ts +++ b/src/function.ts @@ -1,7 +1,7 @@ -import Variable from './variable'; -import SyntaxNode from './syntaxnode'; -import Statement from './statement'; +import InterfaceVariable from './interface'; import Set from './util/set'; +import Statement from './statement'; +import SyntaxNode from './syntaxnode'; export default class Function implements SyntaxNode { public readonly name: string; @@ -12,11 +12,11 @@ export default class Function implements SyntaxNode { this.statements = statements; } - public dependencies(): Set { + public dependencies(): Set { return this.statements.reduce((union, statement) => ( union.addAll(statement.dependencies()) ), - new Set() + new Set() ); } diff --git a/src/if.ts b/src/if.ts index dff534a..efc046a 100644 --- a/src/if.ts +++ b/src/if.ts @@ -1,8 +1,8 @@ -import Variable from './variable'; -import Expression from './expression'; import Block from './block'; -import Type from './type'; +import Expression from './expression'; +import InterfaceVariable from './interface'; import Set from './util/set'; +import Type from './type'; export default class If implements Expression { private condition: Expression; @@ -19,7 +19,7 @@ export default class If implements Expression { return Type.Void; } - public dependencies(): Set { + public dependencies(): Set { return this.condition.dependencies() .union(this.thenBlock.dependencies()) .union(this.elseBlock.dependencies()); diff --git a/src/interface.ts b/src/interface.ts new file mode 100644 index 0000000..121f15b --- /dev/null +++ b/src/interface.ts @@ -0,0 +1,27 @@ +import Hashable from './util/hashable'; +import Qualifier from './qualifier'; +import Type from './type'; +import Variable from './variable'; + +export default class InterfaceVariable implements Hashable { + public readonly name: string; + public readonly qualifier: Qualifier; + public readonly kind: Type; + private variable: Variable; + + // TODO: typecheck kind + constructor(qualifier: Qualifier, variable: Variable) { + this.qualifier = qualifier; + this.name = variable.name; + this.kind = variable.kind; + this.variable = variable; + } + + public declaration(): string { + return `${this.qualifier} ${this.variable.declaration()}`; + } + + public hashCode(): string { + return this.declaration(); + } +} diff --git a/src/reference.ts b/src/reference.ts index c53b412..105d28e 100644 --- a/src/reference.ts +++ b/src/reference.ts @@ -1,16 +1,16 @@ -import Variable from './variable'; -import Type from './type'; import Expression from './expression'; +import InterfaceVariable from './interface'; import Set from './util/set'; +import Type from './type'; export default class Reference implements Expression { - private variable: Variable; + private variable: InterfaceVariable; - constructor(variable: Variable) { + constructor(variable: InterfaceVariable) { this.variable = variable; } - public dependencies(): Set { + public dependencies(): Set { return new Set([this.variable]); } diff --git a/src/shader.ts b/src/shader.ts index c7fc45e..8a8af7c 100644 --- a/src/shader.ts +++ b/src/shader.ts @@ -1,5 +1,5 @@ -import Variable from './variable'; import Function from './function'; +import InterfaceVariable from './interface'; import Qualifier from './qualifier'; import Type from './type'; @@ -8,7 +8,7 @@ export default class Shader { constructor(main: Function = new Function('main')) { this.main = main; - } + } public source(): string { return `${this.header()}\n${this.main.source()}`; diff --git a/src/statement.ts b/src/statement.ts index 44df6d6..c72c4b5 100644 --- a/src/statement.ts +++ b/src/statement.ts @@ -1,6 +1,6 @@ -import SyntaxNode from './syntaxnode'; -import Variable from './variable'; +import InterfaceVariable from './interface'; import Set from './util/set'; +import SyntaxNode from './syntaxnode'; export default class Statement implements SyntaxNode { private node: SyntaxNode; @@ -9,7 +9,7 @@ export default class Statement implements SyntaxNode { this.node = node; } - public dependencies(): Set { + public dependencies(): Set { return this.node.dependencies(); } diff --git a/src/struct.ts b/src/struct.ts new file mode 100644 index 0000000..29e6f72 --- /dev/null +++ b/src/struct.ts @@ -0,0 +1,34 @@ +import InterfaceVariable from './interface'; +import Qualifier from './qualifier'; +import Set from './util/set'; +import SyntaxNode from './syntaxnode'; +import Variable from './variable'; + +/** + * struct type-name { + * members + * }; + */ +export default class Struct implements SyntaxNode { + public readonly name: string; + public readonly qualifier: Qualifier; + private members: Variable[]; + + constructor(qualifier: Qualifier, name: string, members: Variable[]) { + this.qualifier = qualifier + this.name = name; + this.members = members; + } + + public dependencies(): Set { + return new Set(); + } + + public source(): string { + return `${this.qualifier} struct ${this.name} {` + + this.members + .map(member => member.declaration()) + .join('\n') + + '};'; + } +} diff --git a/src/syntaxnode.ts b/src/syntaxnode.ts index 220ba33..7f9b7d3 100644 --- a/src/syntaxnode.ts +++ b/src/syntaxnode.ts @@ -1,7 +1,7 @@ -import Variable from './variable'; +import InterfaceVariable from './interface'; import Set from './util/set'; export default interface SyntaxNode { - dependencies(): Set; + dependencies(): Set; source(): string; } diff --git a/src/type.ts b/src/type.ts index df42f7d..d20320a 100644 --- a/src/type.ts +++ b/src/type.ts @@ -1,4 +1,4 @@ -// TODO: Deal with structs and arrays +// TODO: Deal with arrays enum Type { Void = 'void', Bool = 'bool', @@ -17,7 +17,8 @@ enum Type { Mat3 = 'mat3', Mat4 = 'mat4', Sampler2D = 'sampler2D', - SamplerCube = 'samplerCube' + SamplerCube = 'samplerCube', + Struct = 'struct' } export default Type; diff --git a/src/variable.ts b/src/variable.ts index 6d2c93c..6f36bd2 100644 --- a/src/variable.ts +++ b/src/variable.ts @@ -1,24 +1,15 @@ -import Qualifier from './qualifier'; import Type from './type'; -import Hashable from './util/hashable'; -export default class Variable implements Hashable { +export default class Variable { public readonly name: string; - public readonly qualifier: Qualifier; public readonly kind: Type; - // TODO: typecheck kind - constructor(qualifier: Qualifier, kind: Type, name: string) { + constructor(kind: Type, name: string) { this.kind = kind; - this.qualifier = qualifier; this.name = name; } public declaration(): string { - return `${this.qualifier} ${this.kind} ${this.name};`; - } - - public hashCode(): string { - return this.declaration(); + return `${this.kind} ${this.name};`; } } diff --git a/src/while.ts b/src/while.ts index 4334b5c..c30d536 100644 --- a/src/while.ts +++ b/src/while.ts @@ -1,8 +1,8 @@ -import Variable from './variable'; -import Expression from './expression'; import Block from './block'; -import Type from './type'; +import Expression from './expression'; +import InterfaceVariable from './interface'; import Set from './util/set'; +import Type from './type'; export default class While implements Expression { protected condition: Expression; @@ -17,7 +17,7 @@ export default class While implements Expression { return Type.Void; } - public dependencies(): Set { + public dependencies(): Set { return this.condition.dependencies().union(this.loopBlock.dependencies()); } diff --git a/test/assignment.spec.js b/test/assignment.spec.js index c53790e..34db029 100644 --- a/test/assignment.spec.js +++ b/test/assignment.spec.js @@ -6,10 +6,10 @@ describe('Assignment', () => { it('references both the left and right hand sides', () => { const assignment = new cgl.Assignment( new cgl.Reference( - new cgl.Variable(cgl.Qualifier.In, cgl.Type.Vec4, 'lhs') + new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'lhs')) ), new cgl.Reference( - new cgl.Variable(cgl.Qualifier.In, cgl.Type.Vec4, 'rhs') + new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'rhs')) ) ); diff --git a/test/block.spec.js b/test/block.spec.js index c1499e0..0e7d5c8 100644 --- a/test/block.spec.js +++ b/test/block.spec.js @@ -6,10 +6,10 @@ describe('Block', () => { it('references all included statements', () => { const block = new cgl.Block([ new cgl.Reference( - new cgl.Variable(cgl.Qualifier.In, cgl.Type.Vec4, 'a') + new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'a')) ), new cgl.Reference( - new cgl.Variable(cgl.Qualifier.In, cgl.Type.Vec4, 'b') + new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'b')) ) ]); @@ -32,12 +32,12 @@ describe('Block', () => { const block = new cgl.Block([ new cgl.Statement( new cgl.Reference( - new cgl.Variable(cgl.Qualifier.In, cgl.Type.Vec4, 'a') + new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'a')) ) ), new cgl.Statement( new cgl.Reference( - new cgl.Variable(cgl.Qualifier.In, cgl.Type.Vec4, 'b') + new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'b')) ) ) ]); @@ -57,12 +57,12 @@ describe('Block', () => { const block = new cgl.Block([ new cgl.Statement( new cgl.Reference( - new cgl.Variable(cgl.Qualifier.In, cgl.Type.Vec4, 'a') + new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'a')) ) ), new cgl.Statement( new cgl.Reference( - new cgl.Variable(cgl.Qualifier.In, cgl.Type.Vec4, 'b') + new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'b')) ) ) ]); diff --git a/test/dowhile.spec.js b/test/dowhile.spec.js index 8a239b4..30b8893 100644 --- a/test/dowhile.spec.js +++ b/test/dowhile.spec.js @@ -4,13 +4,13 @@ import * as cgl from '../src/calder'; describe('DoWhile', () => { describe('dependencies', () => { it('includes both the then and else blocks', () => { - const conditionVariable = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'condition'); - const someVariable1 = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'someVariable1'); + const conditionInterfaceVariable = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'condition')); + const someInterfaceVariable1 = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'someInterfaceVariable1')); const doWhileStmt = new cgl.DoWhile( - new cgl.Reference(conditionVariable), + new cgl.Reference(conditionInterfaceVariable), new cgl.Block([ new cgl.Statement( - new cgl.Assignment(new cgl.Reference(conditionVariable), new cgl.Reference(someVariable1)) + new cgl.Assignment(new cgl.Reference(conditionInterfaceVariable), new cgl.Reference(someInterfaceVariable1)) ) ]) ); @@ -18,14 +18,14 @@ describe('DoWhile', () => { const dependencyNames = [...doWhileStmt.dependencies()] .map(dependency => dependency.name) .sort(); - expect(dependencyNames).to.eql(['condition', 'someVariable1']); + expect(dependencyNames).to.eql(['condition', 'someInterfaceVariable1']); }); }); describe('source', () => { it('is well formed', () => { - const a = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'a'); - const b = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'b'); + const a = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'a')); + const b = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'b')); const doWhileStmt = new cgl.DoWhile( new cgl.Reference(a), new cgl.Block([ @@ -37,5 +37,5 @@ describe('DoWhile', () => { expect(doWhileStmt.source()).to.equalIgnoreSpaces('do { a=b; } while (a)'); }); - }) + }); }); diff --git a/test/function.spec.js b/test/function.spec.js index c6f54cb..83ec20d 100644 --- a/test/function.spec.js +++ b/test/function.spec.js @@ -2,8 +2,8 @@ import { expect } from 'chai'; import * as cgl from '../src/calder'; function basicMain() { - const glPosition = new cgl.Variable(cgl.Qualifier.Out, cgl.Type.Vec4, 'gl_Position'); - const vertexPosition = new cgl.Variable(cgl.Qualifier.Attribute, cgl.Type.Vec4, 'vertexPosition'); + const glPosition = new cgl.InterfaceVariable(cgl.Qualifier.Out, new cgl.Variable(cgl.Type.Vec4, 'gl_Position')); + const vertexPosition = new cgl.InterfaceVariable(cgl.Qualifier.Attribute, new cgl.Variable(cgl.Type.Vec4, 'vertexPosition')); const main = new cgl.Function('main', [ new cgl.Assignment( new cgl.Reference(glPosition), diff --git a/test/if.spec.js b/test/if.spec.js index 2cb71d3..04fbc75 100644 --- a/test/if.spec.js +++ b/test/if.spec.js @@ -4,19 +4,19 @@ import * as cgl from '../src/calder'; describe('If', () => { describe('dependencies', () => { it('includes both the then and else blocks', () => { - const conditionVariable = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'condition'); - const someVariable1 = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'someVariable1'); - const someVariable2 = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'someVariable2'); + const conditionInterfaceVariable = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'condition')); + const someInterfaceVariable1 = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'someInterfaceVariable1')); + const someInterfaceVariable2 = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'someInterfaceVariable2')); const ifStmt = new cgl.If( - new cgl.Reference(conditionVariable), + new cgl.Reference(conditionInterfaceVariable), new cgl.Block([ new cgl.Statement( - new cgl.Assignment(new cgl.Reference(conditionVariable), new cgl.Reference(someVariable1)) + new cgl.Assignment(new cgl.Reference(conditionInterfaceVariable), new cgl.Reference(someInterfaceVariable1)) ) ]), new cgl.Block([ new cgl.Statement( - new cgl.Assignment(new cgl.Reference(conditionVariable), new cgl.Reference(someVariable2)) + new cgl.Assignment(new cgl.Reference(conditionInterfaceVariable), new cgl.Reference(someInterfaceVariable2)) ) ]) ); @@ -24,17 +24,17 @@ describe('If', () => { const dependencyNames = [...ifStmt.dependencies()] .map(dependency => dependency.name) .sort(); - expect(dependencyNames).to.eql(['condition', 'someVariable1', 'someVariable2']); + expect(dependencyNames).to.eql(['condition', 'someInterfaceVariable1', 'someInterfaceVariable2']); }); it('excludes the else block if none is present', () => { - const conditionVariable = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'condition'); - const someVariable1 = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'someVariable1'); + const conditionInterfaceVariable = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'condition')); + const someInterfaceVariable1 = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'someInterfaceVariable1')); const ifStmt = new cgl.If( - new cgl.Reference(conditionVariable), + new cgl.Reference(conditionInterfaceVariable), new cgl.Block([ new cgl.Statement( - new cgl.Assignment(new cgl.Reference(conditionVariable), new cgl.Reference(someVariable1)) + new cgl.Assignment(new cgl.Reference(conditionInterfaceVariable), new cgl.Reference(someInterfaceVariable1)) ) ]) ); @@ -42,14 +42,14 @@ describe('If', () => { const dependencyNames = [...ifStmt.dependencies()] .map(dependency => dependency.name) .sort(); - expect(dependencyNames).to.eql(['condition', 'someVariable1']); + expect(dependencyNames).to.eql(['condition', 'someInterfaceVariable1']); }); }); describe('source', () => { it('has no else block if none is provided', () => { - const a = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'a'); - const b = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'b'); + const a = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'a')); + const b = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'b')); const ifStmt = new cgl.If( new cgl.Reference(a), new cgl.Block([ @@ -61,12 +61,12 @@ describe('If', () => { expect(ifStmt.source()).to.equalIgnoreSpaces('if (a) { a=b; }'); }); - }) + }); describe('source', () => { it('has no else block if an empty block is provided', () => { - const a = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'a'); - const b = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'b'); + const a = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'a')); + const b = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'b')); const ifStmt = new cgl.If( new cgl.Reference(a), new cgl.Block([ @@ -79,5 +79,5 @@ describe('If', () => { expect(ifStmt.source()).to.equalIgnoreSpaces('if (a) { a=b; }'); }); - }) + }); }); diff --git a/test/reference.spec.js b/test/reference.spec.js index 3108ea5..647caa9 100644 --- a/test/reference.spec.js +++ b/test/reference.spec.js @@ -5,7 +5,7 @@ describe('Reference', () => { describe('dependencies', () => { it('references the contained variable', () => { const ref = new cgl.Reference( - new cgl.Variable(cgl.Qualifier.In, cgl.Type.Vec4, 'test') + new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'test')) ); expect( diff --git a/test/shader.spec.js b/test/shader.spec.js index 60de593..fb928ab 100644 --- a/test/shader.spec.js +++ b/test/shader.spec.js @@ -6,8 +6,8 @@ chai.use(chaiString); const { expect } = chai; function basicShader() { - const glPosition = new cgl.Variable(cgl.Qualifier.Out, 'vec4', 'gl_Position'); - const vertexPosition = new cgl.Variable(cgl.Qualifier.Attribute, 'vec4', 'vertexPosition'); + const glPosition = new cgl.InterfaceVariable(cgl.Qualifier.Out, new cgl.Variable('vec4', 'gl_Position')); + const vertexPosition = new cgl.InterfaceVariable(cgl.Qualifier.Attribute, new cgl.Variable('vec4', 'vertexPosition')); const shader = new cgl.Shader( new cgl.Function('main', [ new cgl.Statement( diff --git a/test/shaderpipelinebuilder.spec.js b/test/shaderpipelinebuilder.spec.js index b0dfb36..7f4ff42 100644 --- a/test/shaderpipelinebuilder.spec.js +++ b/test/shaderpipelinebuilder.spec.js @@ -4,11 +4,11 @@ import * as cgl from '../src/calder'; describe('ShaderPipelineBuilder', () => { describe('checkInputsAndOutputs', () => { it('has all fragment shader outputs in vertex shader inputs', () => { - const ptColour = new cgl.Variable(cgl.Qualifier.Out, cgl.Type.Vec4, 'colour'); - const glPosition = new cgl.Variable(cgl.Qualifier.Out, cgl.Type.Vec4, 'gl_Position'); - const vertexPosition = new cgl.Variable(cgl.Qualifier.Attribute, cgl.Type.Vec4, 'vertexPosition'); - const colour = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Vec4, 'colour'); - const outColour = new cgl.Variable(cgl.Qualifier.Out, cgl.Type.Vec4, 'outColour'); + const ptColour = new cgl.InterfaceVariable(cgl.Qualifier.Out, new cgl.Variable(cgl.Type.Vec4, 'colour')); + const glPosition = new cgl.InterfaceVariable(cgl.Qualifier.Out, new cgl.Variable(cgl.Type.Vec4, 'gl_Position')); + const vertexPosition = new cgl.InterfaceVariable(cgl.Qualifier.Attribute, new cgl.Variable(cgl.Type.Vec4, 'vertexPosition')); + const colour = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'colour')); + const outColour = new cgl.InterfaceVariable(cgl.Qualifier.Out, new cgl.Variable(cgl.Type.Vec4, 'outColour')); const vertexShader = new cgl.Shader( new cgl.Function('main', [ @@ -44,10 +44,10 @@ describe('ShaderPipelineBuilder', () => { }); it('has some fragment shader outputs not in vertex shader inputs', () => { - const glPosition = new cgl.Variable(cgl.Qualifier.Out, cgl.Type.Vec4, 'gl_Position'); - const vertexPosition = new cgl.Variable(cgl.Qualifier.Attribute, cgl.Type.Vec4, 'vertexPosition'); - const depth = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Float, 'depth'); - const outDepth = new cgl.Variable(cgl.Qualifier.Out, cgl.Type.Float, 'outDepth'); + const glPosition = new cgl.InterfaceVariable(cgl.Qualifier.Out, new cgl.Variable(cgl.Type.Vec4, 'gl_Position')); + const vertexPosition = new cgl.InterfaceVariable(cgl.Qualifier.Attribute, new cgl.Variable(cgl.Type.Vec4, 'vertexPosition')); + const depth = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Float, 'depth')); + const outDepth = new cgl.InterfaceVariable(cgl.Qualifier.Out, new cgl.Variable(cgl.Type.Float, 'outDepth')); const vertexShader = new cgl.Shader( new cgl.Function('main', [ diff --git a/test/struct.spec.js b/test/struct.spec.js new file mode 100644 index 0000000..43cc432 --- /dev/null +++ b/test/struct.spec.js @@ -0,0 +1,20 @@ +import { expect } from 'chai'; +import * as cgl from '../src/calder'; + +describe('Struct', () => { + describe('source', () => { + const a = new cgl.Variable(cgl.Type.Bool, 'a'); + const b = new cgl.Variable(cgl.Type.Bool, 'b'); + + it('is well formed', () => { + const structure = new cgl.Struct(cgl.Qualifier.Const, 'structName', [a, b]); + + expect(structure.source()).to.equalIgnoreSpaces( + `const struct structName { + bool a; + bool b; + };` + ); + }); + }); +}); diff --git a/test/while.spec.js b/test/while.spec.js index d0cff8b..19f7a12 100644 --- a/test/while.spec.js +++ b/test/while.spec.js @@ -4,13 +4,13 @@ import * as cgl from '../src/calder'; describe('While', () => { describe('dependencies', () => { it('includes both the then and else blocks', () => { - const conditionVariable = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'condition'); - const someVariable1 = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'someVariable1'); + const conditionInterfaceVariable = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'condition')); + const someInterfaceVariable1 = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'someInterfaceVariable1')); const whileStmt = new cgl.While( - new cgl.Reference(conditionVariable), + new cgl.Reference(conditionInterfaceVariable), new cgl.Block([ new cgl.Statement( - new cgl.Assignment(new cgl.Reference(conditionVariable), new cgl.Reference(someVariable1)) + new cgl.Assignment(new cgl.Reference(conditionInterfaceVariable), new cgl.Reference(someInterfaceVariable1)) ) ]) ); @@ -18,14 +18,14 @@ describe('While', () => { const dependencyNames = [...whileStmt.dependencies()] .map(dependency => dependency.name) .sort(); - expect(dependencyNames).to.eql(['condition', 'someVariable1']); + expect(dependencyNames).to.eql(['condition', 'someInterfaceVariable1']); }); }); describe('source', () => { it('is well formed', () => { - const a = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'a'); - const b = new cgl.Variable(cgl.Qualifier.In, cgl.Type.Bool, 'b'); + const a = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'a')); + const b = new cgl.InterfaceVariable(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'b')); const whileStmt = new cgl.While( new cgl.Reference(a), new cgl.Block([ @@ -37,5 +37,5 @@ describe('While', () => { expect(whileStmt.source()).to.equalIgnoreSpaces('while (a) { a=b; }'); }); - }) + }); });