09 decembrie 2014

Eopl3: chapter 9.4 solution to exercise 9.16

Adding overloading of methods.
Idea: each method name is stored as methodName*nrParam (thus there can be many possible methods with the same name but different number of parameters.

> classes.scm______________________________________________________

;; when saving a method, *nrParam is appended to method-name

  (define method-decls->method-env
    (lambda (m-decls super-name field-names)
      (map
        (lambda (m-decl) ;; ex 9.16
          (cases method-decl m-decl
            (a-method-decl (method-name vars body)
                ;; append *nrParam to the method-name
                (let ((newMethodName (string-append (symbol->string method-name) "*" (number->string (length vars)))))
                  (list (string->symbol newMethodName)
                    (a-method vars body super-name field-names))))))
        m-decls)))


> interp.scm _______________________________________________________

;; initialize will called as initialize*0 or otherwise, depending on how the object is instantiated from class

        (new-object-exp (class-name rands)
          (let ((args (values-of-exps rands env))
                (obj (new-object class-name)))
            (apply-method
    (find-method class-name (string->symbol (string-append (symbol->string 'initialize) "*" (number->string (length rands)))))
              obj
              args)
            obj))

;; regular method call also will point to the method with the nr of parameters used for call

        (method-call-exp (obj-exp method-name rands)
          (let ((args (values-of-exps rands env))
                (obj (value-of obj-exp env))
                (nrParam (length rands)))
            (apply-method
              (find-method (object->class-name obj)
                (string->symbol(string-append (symbol->string method-name) "*" (number->string nrParam))))
              obj
              args)))

Example of test:___________________________________________________

class c1 extends object
    field x
    field y
    method initialize () % before it would save only this init, ignoring the 2nd one, result was 10
        begin
         set x = 11;
         set y = 12
        end
    method initialize (param)
        begin
         set x = param;
         set y = 12
        end
    method m1 ()
        -(x,1)
    method m1 (param)
        -(x,param)

let o2 = new c1(7) in send o2 m1(4)        % 3, overloading

Niciun comentariu: