Hey guys,

(first time poster)

I have been learning how the Racket Syntax Framework works and trying to make a 
custom language. What I am currently trying to make is a small Object Oriented 
language which has classes and so on. I don't want to use the built-in classes 
as I want to alter the OO meaning once I got my language going … Anyway, the 
goal would be to have something similar to this:

(CLASS
        (FIELD x 1)
        (FIELD y 1)
        (METHOD (x?) x)
        (METHOD (x! new) (set! x new)))

Both fields and methods are kept in a hash table for lookup. So what I would 
want is that in the above method "x?" the identifier x is recognised as not 
"lexically bound" and thus refers to the field x. So during syntax 
transformation I can take some action to fetch the value of that field in the 
field lookup table. However, I can't seem to make the test for "lexically 
bound" work. It always returns false. So take for example the method "x!", in 
that case it would fail to recognise that the value of the identifier "new" is 
given by the local parameter and would also try to lookup new in the field 
lookup table of the object. However, it should only try to lookup x.

I guess it's hard to grasp what I mean, so I have made a simplified version of 
what I have. Remember that I have stripped down most to make it more 
understandable, so this code does not create classes in any way but it is 
structured exactly like my original code. I might therefore seem weird to use 
so many syntax-classes as they are superfluous here, but in my implementation 
there is a lot more stuff going on which require them.


#lang racket

(require (for-syntax syntax/parse))

(define-for-syntax (lexically-bound? stx)
  (define expanded (local-expand stx (syntax-local-context) #f))
  (and (identifier? expanded)
       (not (eq? #f (identifier-binding expanded)))))

(define-syntax (CLASS stx)
  
  ;; Literal
  
  (define-syntax-class (literal)
    (pattern value:boolean)
    (pattern value:char)
    (pattern value:integer)
    (pattern value:number)
    (pattern value:str))
  
  ;; Object Expression (validates all expressions inside a class)
    
  (define-syntax-class (class-expr)
    
    #:datum-literals (define)
    #:commit
    
    (pattern value:literal
             #:with <value> #'value)
    (pattern value:id
             #:with <value> (begin (display #'value) (newline)
                                   (display (lexically-bound? #'value)) 
(newline)
                                   (if (lexically-bound? #'value) #'value 
#'(void))))
    (pattern (define name:id arg:class-expr)
             #:with <value> #'(define name arg.<value>))
    (pattern (operator:id arg:class-expr ...)
             #:with <value> #'(operator arg.<value> ...)))
  
  ;; Method Class
  
  (define-syntax-class (class-method)
      
      #:datum-literals (METHOD)
      
      (pattern (METHOD (name:id arg:id ...) body:class-expr ...)
               #:with <value> #'(define (name arg ...) body.<value> ...)))
  
  ;;;;; Class Parser
  
  (syntax-parse 
   stx
   
   #:datum-literals (CLASS)
   
   [(CLASS <method>:class-method)
    #'<method>.<value>]))



;; Example Case

(CLASS
 (METHOD (test a b) (define c 1) a b c d))


In the example above, what I want is that a, b and c are recognised as 
"lexically bound" and d is not. Then I can transform d to something that 
fetches the "d" entry in the fields hash map of the object. However, when this 
code is run all 4 are returned as unbound.

If I would add:

(define a 1)
(define b 1)
(define c 1)
(define d 1)

before the CLASS definition then it works, so the check to see if they are 
lexically bound should be correct. Therefore, I am thinking that I am 
approaching my problem incorrectly.


Thanks for any response,

Christophe


p.s. If I make incorrect use of syntax-classes feel free to let me know.
____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to