-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Benjamin Wilson Friedman edited this page Apr 29, 2021
·
12 revisions
Overall, the flow should look something like this.
- We've been thinking:
Env -> Env -> (Env,Expr) -> Env
- where
type Env = [(Key,Expr)]
- and
type Expr = AST representation of a program
- verbose semantic domain is:
UniversalEnv -> ShaderPassedEnv -> (ShaderEnv,ShaderExpr) -> ShaderResultEnv
- every shader gets the universal env, plus whatever prior environment the prior stage passes along, and the specific shader stage environment an expression is evaluated within (fragment, vertex, etc.).
program := env [shader] -- global environment + shaders
env := [func]
unitName := String -- Fragment, Vertex... This won't be defined by the user.
shaderEnvs := [(unitName, env)] -- This will be written in the language, but won't be written by the user
shader := unitName name expr -- a shader contains it's functions (decl & def) and it's primary expr (corresponding to main)
name := String
cmpop := == | != | <= | >= | < | >
bitop := & | \| | ^
logiop := And | Or
arithop := + | - | * | /
shaderComp := .
binop := arithop | cmpop | logiop | bitop | shaderComp
unop := FlipBits | Not
vdim := 2 | 3 | 4
floatType := Float | Double
discreteType := Bool | Int | UInt
baseType := floatType | discreteType
type := baseType | baseType[int] | Vec vdim baseType | Mat vdim vdim floatType
typeDecl := name [name : type] -- may or may not include this...
func := name signature expr
signature := type | type -> signature
lit := int | bool | float | double -- Literal value
expr := lit |
name | -- name of let bound name, function name, etc.
(expr,...,expr) | -- N-ary vector (tuple) or mat | 2 <= N <= 4
unop expr | -- Unary operator application
let name : type = expr \n expr | -- let binding
name(expr,...,expr) -- prefix app
expr binop expr -- infix app
name[(name | int)] -- structure access
//...\n -- single-line comment
/*...*/ -- block comment
if expr then expr else expr -- branching
for (int) do (?:|name|) (expr) -- produces a value from evaluating expr 'int' times, e.x. let x = 1+x \n let x = 1+x \n ... let x = 1+x \n x (optional index name can be given after do
[expr] -- lists, which correspond to arrays
-
(.)
as function composition. I believe we can implement this by combining the exprs of both functions in the proper order, and adding a let to represent the params -
(.) as shader composition.
shaderA . shaderBproduces a new shader C, where
C = exprA . exprB`, but the environments are passed along, (TODO, not done yet, needs work, can use semantic domain to help reason about this part)
TODO...
- UV checking is going to be limited to what's defined within the pipeline, so it'll be a partial UV checker.
- from the AST, produce the corresponding GLSL program in concrete syntax.
- put together a wrapped WebGL app (or some other GL context) to demonstrate and observe whether output shaders behave as expected
TODO...