summaryrefslogtreecommitdiff
path: root/chickadee/graphics/seagull/glsl.scm
diff options
context:
space:
mode:
Diffstat (limited to 'chickadee/graphics/seagull/glsl.scm')
-rw-r--r--chickadee/graphics/seagull/glsl.scm151
1 files changed, 151 insertions, 0 deletions
diff --git a/chickadee/graphics/seagull/glsl.scm b/chickadee/graphics/seagull/glsl.scm
new file mode 100644
index 0000000..50f75d6
--- /dev/null
+++ b/chickadee/graphics/seagull/glsl.scm
@@ -0,0 +1,151 @@
+;;; Chickadee Game Toolkit
+;;; Copyright © 2023 David Thompson <dthompson2@worcester.edu>
+;;;
+;;; Licensed under the Apache License, Version 2.0 (the "License");
+;;; you may not use this file except in compliance with the License.
+;;; You may obtain a copy of the License at
+;;;
+;;; http://www.apache.org/licenses/LICENSE-2.0
+;;;
+;;; Unless required by applicable law or agreed to in writing, software
+;;; distributed under the License is distributed on an "AS IS" BASIS,
+;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;;; See the License for the specific language governing permissions and
+;;; limitations under the License.
+
+;; CPS to GLSL emitter.
+(define-module (chickadee graphics seagull glsl)
+ #:use-module (chickadee graphics seagull cps)
+ #:use-module (chickadee graphics seagull primitives)
+ #:use-module (chickadee graphics seagull types)
+ #:use-module (chickadee graphics seagull utils)
+ #:use-module (ice-9 match)
+ #:use-module (language cps intmap)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-11)
+ #:export (emit-glsl))
+
+(define (indent level port)
+ (unless (= level 0)
+ (display " " port)
+ (indent (- level 1) port)))
+
+(define (variable-name id)
+ (format #f "v~a" id))
+
+(define (emit-glsl* graph k exp level port)
+ (define (emit-exp exp var type)
+ (match (pk 'emit-exp exp)
+ (#f #f)
+ (($ <cps-constant> val _)
+ (indent level port)
+ (format port "~a ~a = ~a;\n"
+ (type-glsl-name type)
+ (variable-name var)
+ (match val
+ (#t "true")
+ (#f "false")
+ (_ val))))
+ (($ <cps-values> (arg))
+ (indent level port)
+ (format port "~a ~a = ~a;\n"
+ (type-glsl-name type)
+ (variable-name var)
+ (variable-name arg)))
+ (($ <cps-assignment> from to)
+ (indent level port)
+ (format port "~a = ~a;\n" (variable-name from) (variable-name to)))
+ (($ <cps-primitive-call> op args _)
+ (let ((op* (lookup-primitive-operator op)))
+ (indent level port)
+ (format port "~a ~a = "
+ (type-glsl-name type)
+ (variable-name var))
+ (if (primitive-operator-infix? op*)
+ (match args
+ ;; Infix binary operator
+ ((a b)
+ (format port "~a ~a ~a;\n"
+ (variable-name a)
+ (primitive-operator-glsl-name op*)
+ (variable-name b))))
+ ;; Regular function call
+ (begin
+ (format port "~a(" (primitive-operator-glsl-name op*))
+ (let loop ((args args))
+ (match args
+ (() #t)
+ ((arg)
+ (display (variable-name arg) port))
+ ((arg . rest)
+ (format port "~a, " (variable-name arg))
+ (loop rest))))
+ (format port ");\n")))))
+ (($ <cps-function> body)
+ (match (intmap-ref graph body)
+ (($ <function-entry> _ params results start return type)
+ (indent level port)
+ (format port "function ~a(~a) {\n"
+ (variable-name var)
+ (string-join (append (map (lambda (param type)
+ (param-string 'in param type))
+ params (function-type-parameters type))
+ (map (lambda (result type)
+ (param-string 'out result type))
+ results (function-type-returns type)))
+ ", "))
+ (pk 'start-function-body)
+ (emit-glsl* graph start #f (+ level 1) port)
+ (pk 'done-function-body)
+ (indent level port)
+ (format port "}\n"))))))
+ (define (param-string qualifier var type)
+ (format #f "~a ~a ~a"
+ qualifier
+ (type-glsl-name type)
+ (variable-name var)))
+ (match (pk 'emit-cont (intmap-ref graph k))
+ (($ <arguments> () ($ <return> ()) ())
+ (indent level port)
+ (format port "return;\n"))
+ (($ <arguments> (var) ($ <return> (result)) (type))
+ (emit-exp exp var type)
+ (indent level port)
+ (format port "return;\n"))
+ (($ <arguments> (var) ($ <return> ()) (type))
+ (pk 'blah exp type)
+ (emit-exp exp var type)
+ (indent level port)
+ (indent level port)
+ (format port "return;\n"))
+ (($ <arguments> () ($ <continue> _ k* exp*) _)
+ (emit-exp exp #f #f)
+ (emit-glsl* graph k* exp* level port))
+ (($ <arguments> (var) ($ <continue> _ k* exp*) (type))
+ (emit-exp exp var type)
+ (emit-glsl* graph k* exp* level port))
+ (($ <arguments> (var) ($ <branch> _ test k-conseq k-alt) (type))
+ (emit-exp exp var type)
+ (indent level port)
+ (format port "if(~a) {\n" (variable-name test))
+ (emit-glsl* graph k-conseq #f (+ level 1) port)
+ (format port "} else {\n")
+ (emit-glsl* graph k-alt #f (+ level 1) port)
+ (format port "}\n"))))
+
+(define (emit-glsl graph)
+ (call-with-output-string
+ (lambda (port)
+ (emit-glsl* graph 0 #f 0 port))))
+
+;; (define test-cps
+;; (let ((int (lookup-type 'int)))
+;; (alist->intmap
+;; `((0 . ,(make-arguments '() (make-continue #f 1 (make-cps-constant 1))))
+;; (1 . ,(make-arguments '(0) (make-continue #f 3 (make-cps-constant 2))))
+;; (2 . ,(make-arguments '(1) (make-continue #f 5 (make-cps-primitive-call '+ '(0 1) int))))
+;; (3 . ,(make-arguments '(3) (make-continue #f 4 (make-cps-constant 3))))
+;; (4 . ,(make-arguments '(4) (make-continue #f 2 (make-cps-primitive-call '* '(3 4) int))))
+;; (5 . ,(make-arguments '(5) (make-continue #f #f (make-cps-values '(5)))))))))
+
+;; (emit-glsl test-cps)