#lang scheme (provide jvalue nothing nothing? jstring jstring? jnumber jnumber? jbool jbool? jnull jnull? jarray jarray? jobject jobject? is-null? get-string get-int get-bool get-double get-object get-array) (define nothing 'nothing) (define (nothing? x) (eq? x nothing)) (define-struct jvalue (type data)) (define (jtype-eq? value jtype) (and (jvalue? value) (eq? jtype (jvalue-type value)))) (define (jstring? value) (jtype-eq? value 'jstring)) (define (jstring value) (if (string? value) (make-jvalue 'jstring value) (error "jstring expects type string : " value))) (define (jnumber? value) (jtype-eq? value 'jnumber)) (define (jnumber value) (if (number? value) (make-jvalue 'jnumber value) (error "jnumber expects type number : " value))) (define (jbool? value) (jtype-eq? value 'jbool)) (define (jbool value) (if (boolean? value) (make-jvalue 'jbool value) (error "jbool expects type boolean : " value))) (define (jnull? value) (jtype-eq? value 'jnull)) (define (jnull) (make-jvalue 'jnull null)) (define (jobject? value) (and (jtype-eq? value 'jobject) (andmap (hash-map (λ (k v) (and (string? k) (jvalue? v))) (jvalue-data value))))) (define (jobject value) (if (hash? value) (make-jvalue 'jobject value) (error "jobject expects type hash : " value))) (define (jarray? x) (and (jtype-eq? x 'jarray) (andmap jvalue? (jvalue-data x)))) (define (jarray value) (if (list? value) (make-jvalue 'jarray value) (error "jobject expects type array : " value))) (define (get-string value) (if (jstring? value) (jvalue-data value) nothing)) (define (get-int value) (if (jnumber? value) (truncate (jvalue-data value)) nothing)) (define (get-double value) (if (jnumber? value) (jvalue-data value) nothing)) (define (get-bool value) (if (jbool? value) (jvalue-data value) nothing)) (define (get-object value) (if (jobject? value) (jvalue-data value) nothing)) (define (get-array value) (if (jarray? value) (jvalue-data value) nothing)) (define is-null? jnull?)