• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. Translation of SRFI-26

Stats

  • Locked Locked
  • Replies 3
  • Subscribers 143
  • Views 13189
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Translation of SRFI-26

tweeks
tweeks over 11 years ago

I am translating SRFI-26/cut.scm into SKILL++.  (See here for a description of how it's supposed to work, and here for a test suite).

This looked about right:

(define_syntax cut_internal
  (syntax_rules (X XXX)
    ((_ (slot_name ...) (proc arg ...))
     (lambda (slot_name ...) ((begin proc) arg ...)))
    ((_ (slot_name ...) (proc arg ...) XXX)
     (lambda (slot_name ... @rest rest_slot)
       (apply proc arg ... rest_slot)))
    ((_ (slot_name ...) (position ...) X se ...)
     (cut_internal (slot_name ... x) (position ... x) se ...))
    ((_ (slot_name ...) (position ...) nse se ...)
     (cut_internal (slot_name ...) (position ... nse) se ...))))

(define_syntax cut
  (syntax_rules ()
    ((cut slots_or_exprs ...)
     (cut_internal () () slots_or_exprs ...))))

It works on some cases:

((cut times 2 X) 3) => 6
((cut times 2 XXX) 2 3 4) => 48
((cut list 1 X 3 XXX) 2 4 5 6) => (1 2 3 4 5 6)

But this case fails:

((cut list 1 X 3 X 5) 2 4) => (1 2 3 2 5)

That should have been (1 2 3 4 5).

Can anyone help me fix the bug?

  • Cancel
Parents
  • tweeks
    tweeks over 11 years ago

    It appears define_syntax is not generating unique identifiers as it would for the SRFI-26 code. In particular,

    (cut list 1 X 3 X)
    

    Is supposed to expand to

    (lambda (x1 x2) ((begin list) 1 x1 3 x2))
    

    But instead it's expanding to

    (lambda (x x) ((begin list) 1 x 3 x))
    

    Which is an error in Guile, but SKILL++ allows it, binding both occurances of x to the first argument. (Interestingly, Emacs Lisp also permits (lambda (x x) ...), but it chooses the second argument for the x's.)

    Anyway, after several hours of getting nowhere, I gave up and used defmacro with explicit gensyms:

    (defmacro cut_internal (s p @rest r)
      (cond ((null? r)
             `(lambda (,@s) ((begin ,(car p)) ,@(cdr p))))
            ((equal? r '(XXX))
             (let ((v (gensym)))
               `(lambda (,@s @rest ,v)
                  (apply ,(car p) ,@(cdr p) ,v))))
            ((eq? (car r) 'X)
             (let ((v (gensym)))
               `(cut_internal ,(append1 s v) ,(append1 p v) ,@(cdr r))))
            (t
             `(cut_internal ,s ,(append1 p (car r)) ,@(cdr r)))))
    
    (defmacro cut (@rest slots_or_exprs)
      `(cut_internal () () ,@slots_or_exprs))
    

    Hygienic macros: nice idea, but they don't work in SKILL++ (yet?).

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • tweeks
    tweeks over 11 years ago

    It appears define_syntax is not generating unique identifiers as it would for the SRFI-26 code. In particular,

    (cut list 1 X 3 X)
    

    Is supposed to expand to

    (lambda (x1 x2) ((begin list) 1 x1 3 x2))
    

    But instead it's expanding to

    (lambda (x x) ((begin list) 1 x 3 x))
    

    Which is an error in Guile, but SKILL++ allows it, binding both occurances of x to the first argument. (Interestingly, Emacs Lisp also permits (lambda (x x) ...), but it chooses the second argument for the x's.)

    Anyway, after several hours of getting nowhere, I gave up and used defmacro with explicit gensyms:

    (defmacro cut_internal (s p @rest r)
      (cond ((null? r)
             `(lambda (,@s) ((begin ,(car p)) ,@(cdr p))))
            ((equal? r '(XXX))
             (let ((v (gensym)))
               `(lambda (,@s @rest ,v)
                  (apply ,(car p) ,@(cdr p) ,v))))
            ((eq? (car r) 'X)
             (let ((v (gensym)))
               `(cut_internal ,(append1 s v) ,(append1 p v) ,@(cdr r))))
            (t
             `(cut_internal ,s ,(append1 p (car r)) ,@(cdr r)))))
    
    (defmacro cut (@rest slots_or_exprs)
      `(cut_internal () () ,@slots_or_exprs))
    

    Hygienic macros: nice idea, but they don't work in SKILL++ (yet?).

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
No Data

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information