diff --git a/internal/shader/shader.go b/internal/shader/shader.go index 912f4e6cc..5c03d19dd 100644 --- a/internal/shader/shader.go +++ b/internal/shader/shader.go @@ -41,6 +41,8 @@ type function struct { in []string out []string block *block + + ir shaderir.Func } type compileState struct { @@ -63,6 +65,8 @@ type block struct { funcs []function pos token.Pos outer *block + + ir shaderir.Block } type ParseError struct { @@ -105,6 +109,14 @@ func (cs *compileState) parse(f *ast.File) { for _, d := range f.Decls { cs.parseDecl(&cs.global, d, true) } + + if len(cs.errs) > 0 { + return + } + + for _, f := range cs.global.funcs { + cs.ir.Funcs = append(cs.ir.Funcs, f.ir) + } } func (cs *compileState) parseDecl(b *block, d ast.Decl, global bool) { @@ -233,17 +245,19 @@ func (cs *compileState) parseFunc(d *ast.FuncDecl, block *block) function { } } - cs.ir.Funcs = append(cs.ir.Funcs, shaderir.Func{ - Index: len(cs.ir.Funcs), - InParams: inT, - OutParams: outT, - }) + b := cs.parseBlock(block, d.Body) return function{ - name: d.Name.Name, - in: in, - out: out, - //block: cs.parseBlock(block, d.Body), + name: d.Name.Name, + in: in, + out: out, + block: b, + ir: shaderir.Func{ + Index: len(cs.ir.Funcs), + InParams: inT, + OutParams: outT, + Block: b.ir, + }, } } @@ -289,14 +303,22 @@ func (cs *compileState) parseBlock(outer *block, b *ast.BlockStmt) *block { case *ast.DeclStmt: cs.parseDecl(block, l.Decl, false) case *ast.ReturnStmt: - var exprs []ast.Expr for _, r := range l.Results { - exprs = append(exprs, r) + e := cs.parseExpr(r) + block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{ + Type: shaderir.Assign, + Exprs: []shaderir.Expr{ + { + Type: shaderir.LocalVariable, + Index: 1, // TODO: Fix this + }, + e, + }, + }) } - /*block.stmts = append(block.stmts, stmt{ - stmtType: stmtReturn, - exprs: exprs, - })*/ + block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{ + Type: shaderir.Return, + }) } } @@ -346,3 +368,23 @@ func (s *compileState) detectType(b *block, expr ast.Expr) typ { return typ{} } } + +func (cs *compileState) parseExpr(expr ast.Expr) shaderir.Expr { + switch e := expr.(type) { + case *ast.CallExpr: + return shaderir.Expr{ + Type: shaderir.Call, + Exprs: []shaderir.Expr{ + cs.parseExpr(e.Fun), + }, + } + case *ast.Ident: + return shaderir.Expr{ + Type: shaderir.BuiltinFuncExpr, + BuiltinFunc: shaderir.BuiltinFunc(e.Name), + } + default: + cs.addError(expr.Pos(), fmt.Sprintf("detecting expression not implemented: %#v", e)) + } + return shaderir.Expr{} +} diff --git a/internal/shader/shader_test.go b/internal/shader/shader_test.go index 323d32d42..f6cc65cf0 100644 --- a/internal/shader/shader_test.go +++ b/internal/shader/shader_test.go @@ -49,6 +49,22 @@ func Foo(foo vec2) vec4 { VS: `void F0(in vec2 l0, out vec4 l1) { }`, FS: `void F0(in vec2 l0, out vec4 l1) { +}`, + }, + { + Name: "func body", + Src: `package main + +func Foo(foo vec2) vec4 { + return vec4(foo, 0, 1); +}`, + VS: `void F0(in vec2 l0, out vec4 l1) { + l1 = vec4(l0, 0, 1); + return; +}`, + FS: `void F0(in vec2 l0, out vec4 l1) { + l1 = vec4(l0, 0, 1); + return; }`, }, }