I have looked at this twice now, and I don't understand what you're trying to achieve here. Perhaps a series of examples would help.
On Mar 3, 2014, at 1:57 AM, Chrisophe Vandenberghe <chv...@gmail.com> wrote: > Anyone got any ideas here? > > On 25 Feb 2014, at 22:32, Chrisophe Vandenberghe <chv...@gmail.com> wrote: > >> >> Hi, >> >> I found a solution to the first problem where the parameter of the method >> are now recognised as "lexically bound". However, it seems like a dirty hack >> as i have to pass the arg list explicitly when checking the body >> expressions. Furthermore, this does not solve the issue when methods contain >> id bindings in the body. Any suggestions? I could keep a list during syntax >> parsing and whenever a define is found it adds to that list and then simply >> check if the id is in that list, but again that seems a very dirty hack. >> >> #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-for-syntax (local-parameter? stx pars-stx) >> (ormap (lambda (par) (bound-identifier=? stx par)) (syntax-e pars-stx))) >> >> (define-syntax (CLASS stx) >> >> ;; Literal >> >> (define-syntax-class (literal) >> (pattern value:boolean) >> (pattern value:char) >> (pattern value:integer) >> (pattern value:number) >> (pattern value:str)) >> >> ;; Arg List >> >> (define-splicing-syntax-class (arg-list) >> (pattern (~seq arg:id ...))) >> >> ;; Class Expression (validates all expressions inside a class) >> >> (define-syntax-class (class-expr args) >> >> #:datum-literals (define) >> #:commit >> >> (pattern value:literal >> #:with <value> #'value) >> (pattern value:id >> #:with <value> (begin ;(display #'value) (newline) >> ;(display (lexically-bound? #'value)) >> (newline) >> ;(display (local-parameter? #'value args)) >> (newline) >> (if (or (lexically-bound? #'value) >> (local-parameter? #'value args)) >> #'value >> #'(void)))) >> (pattern (define name:id (~var arg (class-expr args))) >> #:with <value> #'(define name arg.<value>)) >> (pattern (operator:id (~var arg (class-expr args)) ...) >> #:with <value> #'(operator arg.<value> ...))) >> >> ;; Method Class >> >> (define-syntax-class (class-method) >> >> #:datum-literals (METHOD) >> >> (pattern (METHOD (name:id (~var arg-list arg-list)) (~var body >> (class-expr #'arg-list)) ...) >> #:with <value> #'(define (name arg-list.arg ...) body.<value> >> ...))) >> >> ;;;;; Class Parser >> >> (syntax-parse >> stx >> >> #:datum-literals (CLASS) >> >> [(CLASS <method>:class-method) >> #'<method>.<value>])) >> >> (CLASS >> (METHOD (test a b) (define c 1) (list a b c d))) >> >> (test 1 2) >> >> On 25 Feb 2014, at 15:54, Chrisophe Vandenberghe <chv...@gmail.com> wrote: >> >>> 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 ____________________ Racket Users list: http://lists.racket-lang.org/users