27 octombrie 2014

Extensii pentru limbajul LET | EOPL3 Let language extensions: RECORD

RECORD
> data-structures.scm
;; in define-datatype
    ; Record
    (record-val
        (record (list-of (list-of symbol?) (list-of expval?)))
    )

;; independent function
    ; record
    (define expval->record (lambda (v)
        (cases expval v
            (record-val (record) record)
            (else (expval-extractor-error 'set v)))))


> lang.scm
; constructor for record
        (expression
            ("record" "{" (separated-list identifier ":" expression ";") "}")
        record-exp)
        ; end Record

;; observer: accessing a record
        (expression
            ("(" identifier "." identifier ")")
        access-exp)


> interp.scm
        ; record
        ; ((id1 id2 id3...) (val1 val2 val3...))
        ; returns the same thing but the members "val" are evaluated
        (record-exp (myids myvals)
              (record-val
                (list myids (map (lambda (myval) (value-of myval env)) myvals))
            )
          )

        ;; access record
        (access-exp (id id_inside)
            (letrec ((myrecord (expval->record (value-of (var-exp id) env)))
                    (myfun (lambda (ids vals)
                        (if (null? ids) "Error"
                            (if (eq? (car ids) id_inside) (car vals)
                            ;else
                            (myfun (cdr ids) (cdr vals)))))))
                    ; in
                    (myfun (car myrecord) (cadr myrecord)))
        )


> top.scm
;; in sloppy->expval
    ; for record ((id1 id2 id3...) (val1 val2 val3...))
    ((and (list? sloppy-val) (not (null? sloppy-val))
        (eq? (length sloppy-val) 2))   
        (record-val (list (car sloppy-val)
            (map (lambda (myelem) (sloppy->expval myelem)) (cadr sloppy-val)))))   
    ; end record


> tests.scm
;; test record
        (rec-test "let x=record{y:10; z:20} in x" ((y z) (10 20)))
        (rec-test2 "let x=record{y:10; z:20} in (x.z)" 20)
        (rec-test3 "zero?(record{y:10; z:20})" error)
        (rec-test4 "let y = record {ab:5; cd:30} in if zero?(2) then (y.ab) else (y.cd)" 30) ; 30 is the sloppy-value!!!

(run "let x=record{y:10; z:20} in (x.a)") ----> gives "Error"

Niciun comentariu: