;; Kathi Fisler ;; Powerpoint exercise ;; Stage 3 : dynamic content without lambdas ;; September 23, 2005 ;;;;;;;;;;;;;;; THE INTERFACE LANGUAGE ;;;;;;;;;;;;;;;;;;;;;;; ;; print-string : string -> void ;; prints string and a newline to the screen (define (print-string str) (printf "~a~n" str)) ;; print-newline : -> void ;; prints a newline on the screen (define (print-newline) (printf "~n")) ;; print-unnumbered-strings : list[string] -> void ;; prints a list of strings to the screen, each prefixed with a - (define (print-unnumbered-strings strlist) (for-each (lambda (str) (printf "- ~a~n" str)) strlist)) ;; print-numbered-strings : list[string] -> void ;; prints a list of strings to the screen, each prefixed with ;; a number (in consecutive increasing order) (define (print-numbered-strings strlist label) (cond [(empty? strlist) void] [(cons? strlist) (begin (printf "~a. ~a~n" label (first strlist)) (print-numbered-strings (rest strlist) (+ 1 label)))])) ;; await-click : -> void ;; mimics a mouse click by waiting for the user to type a character (define (await-click) (read)) ;;;;;;;;;;;; THE DATA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; a slide is a (make-slide slide-title slide-body) (define-struct slide (title body)) ;; a slide-title is either ;; - a string, or ;; - a (make-varstring string symbol) (define-struct varstring (base varname)) ;; a slide-body is either ;; - a string (paragraph), or ;; - a (make-pointlist list[string] boolean) (define-struct pointlist (points numbered?)) ;; A cmd is ;; - (make-display slide) ;; - (make-timecond (time->boolean) list[cmd] list[cmd]) (define-struct display (slide)) (define-struct timecond (time-limit within-time over-time)) ;; A talk is a (make-talk list[symbol] list[cmd]) (define-struct talk (vars cmds)) ;;;;;;;;;;;;;;; PROGRAMS ;;;;;;;;;;;;;;;;;;;;;;;;;;; (define talk3 (let ([make-intro-slide (make-slide "Hand Evals in DrScheme" "Hand evaluation helps you learn how Scheme reduces programs to values")] [make-arith-eg-slide (make-slide (make-varstring "Example" 'example-index) (make-pointlist (list "(+ (* 2 3) 6)" "(+ 6 6)" "12") false))] [make-func-eg-slide (make-slide (make-varstring "Example" 'example-index) (make-pointlist (list "(define (foo x) (+ x 3))" "(* (foo 5) 4)" "(* (+ 5 3) 4)" "(* 8 4)" "32") false))] [make-summary-slide (make-slide "Summary: How to Hand Eval" (make-pointlist (list "Find the innermost expression" "Evaluate one step" "Repeat until have a value") true))]) (make-talk (list 'example-index) (list (make-display make-intro-slide) (make-timecond (lambda (time-in-talk) (> 5 time-in-talk)) (list (make-display make-arith-eg-slide)) empty) (make-display make-func-eg-slide) (make-display make-summary-slide))))) ;;;;;;;;;; INTERFACE HELPERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; print-slide-title : string -> void ;; displays title of slide on screen (define (print-slide-title atitle) (begin (print-string (string-append "Title: " (cond [(string? atitle) atitle] [(varstring? atitle) (let ([currval (lookup-var (varstring-varname atitle))]) (begin (update-var (varstring-varname atitle) (+ 1 currval)) (string-append (varstring-base atitle) " " (number->string currval))))]))) (print-newline))) ;; print-slide-body : slide-body -> void ;; displays contents of body on screen (define (print-slide-body body) (cond [(string? body) (print-string body)] [(pointlist? body) (cond [(pointlist-numbered? body) (print-numbered-strings (pointlist-points body) 1)] [else (print-unnumbered-strings (pointlist-points body))])])) ;; print-slide : slide -> void ;; displays contents of slide on screen (define (print-slide aslide) (begin (print-string "------------------------------") (print-slide-title (slide-title aslide)) (print-slide-body (slide-body aslide)) (print-string "------------------------------"))) ;; end-show : -> void ;; displays end of show message on screen (define (end-show) (print-string "End of show")) ;;;;;;;;;;;;;;;; INTERPRETER ;;;;;;;;;;;;;;;;;;;;;;;;;; (define start-time 0) ;; elapsed-time : -> number ;; returns the elapsed seconds since the recorded start time (define (elapsed-time) (- (current-seconds) start-time)) ;------------------------------------------------------ ;; A var is (make-var symbol number) (define-struct var (name val)) ;; vars is a list[var] (define vars empty) ;; init-vars : list[symbol] -> void ;; create a variable struct for each programmer-specified variable (define (init-vars symlist) (set! vars (map (lambda (name) (make-var name 1)) symlist))) ;; lookup-var : symbol -> number ;; produces number associated with given variable name (define (lookup-var varname) (let ([varstructs (filter (lambda (avar) (eq? varname (var-name avar))) vars)]) (cond [(cons? varstructs) (var-val (first varstructs))] [else (error 'lookup-var (format "variable ~a not defined" varname))]))) ;; update-var : symbol number -> void ;; change value of named var to given number (define (update-var varname newval) (set! vars (map (lambda (avar) (cond [(symbol=? varname (var-name avar)) (make-var varname newval)] [else avar])) vars))) ;------------------------------------------------------ ;; run-cmd : cmd -> void ;; executes the given command (define (run-cmd cmd) (cond [(display? cmd) (begin (print-slide (display-slide cmd)) (await-click))] [(timecond? cmd) (cond [((timecond-time-limit cmd) (elapsed-time)) (run-cmdlist (timecond-within-time cmd))] [else (run-cmdlist (timecond-over-time cmd))])])) ;; run-cmdlist : list[cmd] -> void ;; executes every command in a list (define (run-cmdlist cmd-lst) (cond [(empty? cmd-lst) void] [(cons? cmd-lst) (begin (run-cmd (first cmd-lst))) (run-cmdlist (rest cmd-lst))])) ;; run-talk : talk -> void ;; executes the commands in a talk then displays end-of-show message (define (run-talk a-talk) (begin (init-vars (talk-vars a-talk)) (set! start-time (current-seconds)) (run-cmdlist (talk-cmds a-talk)) (end-show)))