Skip to content
This repository has been archived by the owner on May 9, 2018. It is now read-only.

Adds support for basic structs #25

Merged
merged 6 commits into from
Nov 11, 2017
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/assignment.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Expression from './expression';
import Variable from './variable';
import Type from './type';
import Interface from './interface';
import Reference from './reference';
import Set from './util/set';
import Type from './type';

export default class Assignment implements Expression {
private lhs: Reference;
Expand All @@ -14,7 +14,7 @@ export default class Assignment implements Expression {
this.rhs = rhs;
}

public dependencies(): Set<Variable> {
public dependencies(): Set<Interface> {
return this.rhs.dependencies().union(this.lhs.dependencies());
}

Expand Down
8 changes: 4 additions & 4 deletions src/block.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Variable from './variable';
import Expression from './expression';
import Interface 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[];
Expand All @@ -20,11 +20,11 @@ export default class Block implements Expression {
return Type.Void;
}

public dependencies(): Set<Variable> {
public dependencies(): Set<Interface> {
return this.statements.reduce((union, statement) => (
union.addAll(statement.dependencies())
),
new Set<Variable>()
new Set<Interface>()
);
}

Expand Down
2 changes: 2 additions & 0 deletions src/calder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 Interface } 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';
10 changes: 5 additions & 5 deletions src/function.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Variable from './variable';
import SyntaxNode from './syntaxnode';
import Statement from './statement';
import Interface 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;
Expand All @@ -12,11 +12,11 @@ export default class Function implements SyntaxNode {
this.statements = statements;
}

public dependencies(): Set<Variable> {
public dependencies(): Set<Interface> {
return this.statements.reduce((union, statement) => (
union.addAll(statement.dependencies())
),
new Set<Variable>()
new Set<Interface>()
);
}

Expand Down
8 changes: 4 additions & 4 deletions src/if.ts
Original file line number Diff line number Diff line change
@@ -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 Interface from './interface';
import Set from './util/set';
import Type from './type';

export default class If implements Expression {
private condition: Expression;
Expand All @@ -19,7 +19,7 @@ export default class If implements Expression {
return Type.Void;
}

public dependencies(): Set<Variable> {
public dependencies(): Set<Interface> {
return this.condition.dependencies()
.union(this.thenBlock.dependencies())
.union(this.elseBlock.dependencies());
Expand Down
27 changes: 27 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Hashable from './util/hashable';
import Qualifier from './qualifier';
import Type from './type';
import Variable from './variable';

export default class Interface implements Hashable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename this class InterfaceVariable? Interface is a really generic name.

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just store the variable and read these off the variable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to expose the variable as part of the public interface (even if readonly). Also, I didn't want to breach the law of demeter.

Copy link
Member Author

@armcburney armcburney Nov 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can change it if we want, but it would propagate to a lot of changes in the current code which utilizes the old Variable class. I was trying to go for "least amount of changes to other code" while creating this new class.

this.variable = variable;
}

public declaration(): string {
return `${this.qualifier} ${this.variable.declaration()}`;
}

public hashCode(): string {
return this.declaration();
}
}
10 changes: 5 additions & 5 deletions src/reference.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import Variable from './variable';
import Type from './type';
import Expression from './expression';
import Interface from './interface';
import Set from './util/set';
import Type from './type';

export default class Reference implements Expression {
private variable: Variable;
private variable: Interface;

constructor(variable: Variable) {
constructor(variable: Interface) {
this.variable = variable;
}

public dependencies(): Set<Variable> {
public dependencies(): Set<Interface> {
return new Set([this.variable]);
}

Expand Down
4 changes: 2 additions & 2 deletions src/shader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Variable from './variable';
import Function from './function';
import Interface from './interface';
import Qualifier from './qualifier';
import Type from './type';

Expand All @@ -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()}`;
Expand Down
6 changes: 3 additions & 3 deletions src/statement.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import SyntaxNode from './syntaxnode';
import Variable from './variable';
import Interface from './interface';
import Set from './util/set';
import SyntaxNode from './syntaxnode';

export default class Statement implements SyntaxNode {
private node: SyntaxNode;
Expand All @@ -9,7 +9,7 @@ export default class Statement implements SyntaxNode {
this.node = node;
}

public dependencies(): Set<Variable> {
public dependencies(): Set<Interface> {
return this.node.dependencies();
}

Expand Down
34 changes: 34 additions & 0 deletions src/struct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Interface from './interface';
import Qualifier from './qualifier';
import Set from './util/set';
import SyntaxNode from './syntaxnode';
import Variable from './variable';

/**
* struct type-name {
* members
* } struct-name;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I'm wrong but the struct-name at the end makes an instance of the struct, when we really just want the type. e.g.

// define the struct
struct s {
  int x;
};

// now make an instance
s some_instance;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, my bad - good catch

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and also change the comment :)

*/
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<Interface> {
return new Set<Interface>();
}

public source(): string {
return `${this.qualifier} struct ${this.name} {` +
this.members
.map(member => member.declaration())
.join('\n') +
'};';
}
}
4 changes: 2 additions & 2 deletions src/syntaxnode.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Variable from './variable';
import Interface from './interface';
import Set from './util/set';

export default interface SyntaxNode {
dependencies(): Set<Variable>;
dependencies(): Set<Interface>;
source(): string;
}
5 changes: 3 additions & 2 deletions src/type.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// TODO: Deal with structs and arrays
// TODO: Deal with arrays
enum Type {
Void = 'void',
Bool = 'bool',
Expand All @@ -17,7 +17,8 @@ enum Type {
Mat3 = 'mat3',
Mat4 = 'mat4',
Sampler2D = 'sampler2D',
SamplerCube = 'samplerCube'
SamplerCube = 'samplerCube',
Struct = 'struct'
}

export default Type;
15 changes: 3 additions & 12 deletions src/variable.ts
Original file line number Diff line number Diff line change
@@ -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};`;
}
}
8 changes: 4 additions & 4 deletions src/while.ts
Original file line number Diff line number Diff line change
@@ -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 Interface from './interface';
import Set from './util/set';
import Type from './type';

export default class While implements Expression {
protected condition: Expression;
Expand All @@ -17,7 +17,7 @@ export default class While implements Expression {
return Type.Void;
}

public dependencies(): Set<Variable> {
public dependencies(): Set<Interface> {
return this.condition.dependencies().union(this.loopBlock.dependencies());
}

Expand Down
4 changes: 2 additions & 2 deletions test/assignment.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.Interface(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.Interface(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'rhs'))
)
);

Expand Down
12 changes: 6 additions & 6 deletions test/block.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.Interface(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.Interface(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'b'))
)
]);

Expand All @@ -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.Interface(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.Interface(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'b'))
)
)
]);
Expand All @@ -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.Interface(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.Interface(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Vec4, 'b'))
)
)
]);
Expand Down
16 changes: 8 additions & 8 deletions test/dowhile.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@ 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 conditionInterface = new cgl.Interface(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'condition'));
const someInterface1 = new cgl.Interface(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'someInterface1'));
const doWhileStmt = new cgl.DoWhile(
new cgl.Reference(conditionVariable),
new cgl.Reference(conditionInterface),
new cgl.Block([
new cgl.Statement(
new cgl.Assignment(new cgl.Reference(conditionVariable), new cgl.Reference(someVariable1))
new cgl.Assignment(new cgl.Reference(conditionInterface), new cgl.Reference(someInterface1))
)
])
);

const dependencyNames = [...doWhileStmt.dependencies()]
.map(dependency => dependency.name)
.sort();
expect(dependencyNames).to.eql(['condition', 'someVariable1']);
expect(dependencyNames).to.eql(['condition', 'someInterface1']);
});
});

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.Interface(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'a'));
const b = new cgl.Interface(cgl.Qualifier.In, new cgl.Variable(cgl.Type.Bool, 'b'));
const doWhileStmt = new cgl.DoWhile(
new cgl.Reference(a),
new cgl.Block([
Expand All @@ -37,5 +37,5 @@ describe('DoWhile', () => {

expect(doWhileStmt.source()).to.equalIgnoreSpaces('do { a=b; } while (a)');
});
})
});
});
Loading