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

Create classes for syntax nodes, variables, assignment #1

Merged
merged 8 commits into from
Oct 23, 2017

Conversation

davepagurek
Copy link
Member

@davepagurek davepagurek commented Oct 20, 2017

General structure:

  • every node in a glsl program ends up as a SyntaxNode of some kind (e.g. variable reference, assignment, function)
  • each statement knows what it references so a header can be computed

Todo:

  • recognize builtins
  • fit local variables into the structure
  • make the test actually work (@AndrewMcBurney how do I reference the files in src?)
  • think harder about how scopes should work
  • think about how to write this in a less verbose way
  • might have to import chai-string for tests. not sure though because I haven't got that far yet

@armcburney armcburney self-requested a review October 21, 2017 02:26
@@ -0,0 +1,21 @@
import SyntaxNode from './syntaxnode';
import { Variable } from './variable';
Copy link
Member

Choose a reason for hiding this comment

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

Can you remove the {} from the Variable one to be consistent, please?

Copy link
Member Author

Choose a reason for hiding this comment

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

Variable exports two things. You can only use the no bracket version of you export one thing with export default. I could split the two exports into two files but they're coupled enough that I thought they should go in one. Thoughts?

Copy link
Member

@armcburney armcburney Oct 21, 2017

Choose a reason for hiding this comment

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

Ahh, that's why - I didn't realize there were multiple exports in variable.ts. I'd be a fan of splitting it up into separate files for different exports (SRP), but given that the code is coupled like you said, I'm okay with either 👍

}

public source(): string {
return `${this.lhs.source()} = ${this.rhs.source()};`;
Copy link
Member

Choose a reason for hiding this comment

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

Do you need to reference this explicitly, or is TypeScript smart enough to figure out you're referring to the particular instance in question, given that it's an instance method for the class?

Copy link
Member Author

Choose a reason for hiding this comment

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

You need this explicitly

Copy link
Member Author

Choose a reason for hiding this comment

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

Sad js reaccs only

Copy link
Member

Choose a reason for hiding this comment

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

😢

src/calder.ts Outdated
export namespace Calder {
export class Variable { }
}
export * from './variable';
Copy link
Member

Choose a reason for hiding this comment

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

Any reason for removing the namespace?

Copy link
Member Author

Choose a reason for hiding this comment

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

Adding stuff to namespaces is nice but it makes it kind of weird importing from another file, because of your class adds to a namespace, the file is no longer a module you can import

src/function.ts Outdated
public dependencies(): Set<Variable> {
return this.statements.reduce(
(union, statement) => new Set([...union, ...statement.dependencies()]),
new Set());
Copy link
Member

Choose a reason for hiding this comment

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

A bit of a style nitpick here, but could you write the code this way instead?

        return this.statements.reduce((union, statement) =>
            new Set([...union, ...statement.dependencies()]),
            new Set()
        );

Copy link
Member Author

Choose a reason for hiding this comment

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

What's the reasoning? imo it looks a bit weird visually pairing the return value of the lambda with the next parameter in the function

Copy link
Member

Choose a reason for hiding this comment

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

I like putting the lambda parameters on the same line as the function call reduce. Just seems like a convention for JavaScript arrow functions: 1, 2, 3.

src/function.ts Outdated
import SyntaxNode from './syntaxnode';

export default class Function implements SyntaxNode {
public readonly name: string;
Copy link
Member

Choose a reason for hiding this comment

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

Ahhh TypeScript has C#'s readonly 😍

@@ -0,0 +1,6 @@
import Variable from './variable';
Copy link
Member

Choose a reason for hiding this comment

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

So here, you're importing all of the code from in variable.ts, right? This includes the exported enum Qualifier. Should you do import import { Variable } from './variable'; instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

update for reference later: we moved out Qualifier so Variable is a default export now

@@ -0,0 +1,6 @@
import Variable from './variable';

export default interface SyntaxNode {
Copy link
Member

Choose a reason for hiding this comment

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

Nice interface! 💯

src/variable.ts Outdated
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
export enum Qualifier {
Copy link
Member

Choose a reason for hiding this comment

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

I know this is coupled to Variable, but I'd be a fan of splitting this up into another file, since we're exporting it as part of variable.ts's public interface. It could technically be used in a context outside of a Variable instance, despite being tightly coupled to Variable. Seems like a code smell. 👃

I'd recommend splitting this up into two files, and requiring Qualifier in Variable, or making this enum private to Variable. I don't know 100% what we'll want to use Qualifier for in the future (outside of the Variable class), so you're probably in the best place to make the judgment call.

InOut = 'inout'
}

export default Qualifier;
Copy link
Member Author

Choose a reason for hiding this comment

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

rip you cant export default enum in TS but you can do this for some reason: microsoft/TypeScript#3320

Copy link
Member

Choose a reason for hiding this comment

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

Sad ts reaccs only

@@ -0,0 +1,28 @@
import { expect } from 'chai';
import * as cgl from './calder';
Copy link
Member

Choose a reason for hiding this comment

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

Just for clarification, is this is how people will interface with our library in the future?

Copy link
Member Author

Choose a reason for hiding this comment

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

We'll probably want to make some builders later, but for now, yeah

const shader = new cgl.Shader(new cgl.Function('main', [
new cgl.Assignment(
new cgl.Reference(glPosition),
new cgl.Reference(vertexPosition))]));
Copy link
Member

@armcburney armcburney Oct 21, 2017

Choose a reason for hiding this comment

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

There are a lot of braces here - and while I love lisp (emacs is bae 😍), I think this would have improved readability with some of the braces lined up with the indents:

const shader = new cgl.Shader(
  new cgl.Function('main', [
    new cgl.Assignment(
      new cgl.Reference(glPosition),
      new cgl.Reference(vertexPosition)
    )
  ])
);

or even more concisely (although I'm a bigger fan of the first):

const shader = new cgl.Shader(
  new cgl.Function('main', [
    new cgl.Assignment(new cgl.Reference(glPosition), new cgl.Reference(vertexPosition))
  ])
);

"noImplicitAny": true
"noImplicitAny": true,
"strictNullChecks": true,
"lib": ["es5", "es6", "dom"]
Copy link
Member

Choose a reason for hiding this comment

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

Nice 👍

new cgl.Assignment(
new cgl.Reference(glPosition),
new cgl.Reference(vertexPosition))]));
const shader = new cgl.Shader(
Copy link
Member

Choose a reason for hiding this comment

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

Nice commit name 😂

src/function.ts Outdated

export default class Function implements SyntaxNode {
public readonly name: string;
private statements: SyntaxNode[];
Copy link
Member

Choose a reason for hiding this comment

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

Can you change this type to be a Statement[]? You'd need to create a new SyntaxNode type, but it would avoid being able to do wacky stuff like having just a list of References. If you feel that this might be better addressed in a future PR, can you add a TODO?

Copy link
Member Author

Choose a reason for hiding this comment

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

Makes sense. I could make two subtypes Statement and Expression that for now are the exact same as the super for now maybe?

Copy link
Member Author

Choose a reason for hiding this comment

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

actually I realize the interfaces aren't exactly the same, Expression has a return type. Statement is a class now that just adds a semicolon to a SyntaxNode. I took the semicolon out of the Assignment class because I realize you can have those in the middle of statements too.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually Statement probably shouldn't JUST be a semicolon because ifs and whiles also are statements. Going to make that a separate issue for now though

Copy link
Member Author

Choose a reason for hiding this comment

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

src/variable.ts Outdated

export class Variable {
export default class Variable {
Copy link
Member

Choose a reason for hiding this comment

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

Will we have a separate type for local variables, or will we just extend this type to handle global and local variables?

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 think we could maybe extend this one, but I haven't thought through too hard to see what differences there would need to be

@davepagurek
Copy link
Member Author

Ok tests work now!

import typescript from "gulp-typescript";

const src = ["./src/**/*.ts", "./test/**/*.ts"];
const src = ["./src/**/*.ts"];
const test = ["./test/**/*.js"]
Copy link
Member

Choose a reason for hiding this comment

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

Nice 👍

src/type.ts Outdated
Mat3 = 'mat3',
Mat4 = 'mat4',
Sampler2D = 'sampler2D',
SamplerCube = 'SamplerCube'
Copy link
Member

Choose a reason for hiding this comment

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

Should this be SamplerCube = 'samplerCube'?

@@ -1,10 +0,0 @@
import { expect } from 'chai';
Copy link
Member

Choose a reason for hiding this comment

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

Rip test/test.spec.ts 💀 October 2017 - October 2017

Copy link
Member Author

Choose a reason for hiding this comment

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

😢

Copy link
Member

@armcburney armcburney left a comment

Choose a reason for hiding this comment

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

Tests pass, comments addressed. LGTM :shipit:

Copy link
Member

@abhimadan abhimadan left a comment

Choose a reason for hiding this comment

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

LGTM!

@davepagurek davepagurek merged commit d007bb1 into master Oct 23, 2017
@davepagurek davepagurek deleted the initial-setup branch October 23, 2017 01:46
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants