#lang s-exp "lang.ss"
(require "permission.ss")
(require "rbtree.ss")
(require "helpers.ss")
(define-struct env (bindings))
(define empty-env (make-env empty-rbtree))
(define (binding? datum)
(or (binding:constant? datum)
(binding:function? datum)))
(define-struct binding:constant
(name java-string permissions))
(define-struct binding:function
(name module-source min-arity var-arity? java-string permissions cps? ))
(define (binding-id a-binding)
(cond
[(binding:constant? a-binding)
(binding:constant-name a-binding)]
[(binding:function? a-binding)
(binding:function-name a-binding)]))
(define (env-extend an-env new-binding)
(make-env (rbtree-insert symbol< (env-bindings an-env) (binding-id new-binding) new-binding)))
(define (env-lookup an-env name)
(local [(define result (rbtree-lookup symbol< (env-bindings an-env) name))]
(cond [(pair? result)
(second result)]
[else
false])))
(define (env-remove an-env name)
(make-env (hash-remove (env-bindings an-env) name)))
(define (env-contains? an-env name)
(binding? (env-lookup an-env name)))
(define (env-keys an-env)
(map first (rbtree->list (env-bindings an-env))))
(define (env-extend-constant an-env id java-string)
(env-extend an-env
(make-binding:constant id java-string empty)))
(define (env-extend-function an-env id module-source min-arity var-arity? java-string)
(env-extend an-env
(make-binding:function id
module-source
min-arity
var-arity?
java-string
empty
false)))
(provide/contract
[binding? (any/c . -> . boolean?)]
[struct binding:constant ([name symbol?]
[java-string string?]
[permissions (listof permission?)])]
[struct binding:function ([name symbol?]
[module-source (or/c false/c string?)]
[min-arity natural-number/c]
[var-arity? boolean?]
[java-string string?]
[permissions (listof permission?)]
[cps? boolean?])]
[binding-id (binding? . -> . symbol?)]
[struct env ([bindings (listof binding?)])]
[empty-env env?]
[env-extend (env? binding? . -> . env?)]
[env-lookup (env? symbol? . -> . (or/c false/c binding?))]
[env-remove (env? symbol? . -> . env?)]
[env-contains? (env? symbol? . -> . boolean?)]
[env-keys (env? . -> . (listof symbol?))]
[env-extend-constant (env? symbol? string? . -> . env?)]
[env-extend-function (env? symbol? (or/c false/c string?) number? boolean? string?
. -> . env?)])