[racket] define-match-expander and embedded racket

From: Tim Brown (tim.brown at cityc.co.uk)
Date: Wed Jan 23 07:10:02 EST 2013

Folks,

I am trying to embed racket into a C program, and have a module which uses
"define-match-expander" (in conjunction with match).

The attached scripts seem to show an inconsistency between a module
that has been declared with declare_modules(...) and one that has been
imported with scheme_namespace_require(...). When ... represents the
"racket" module.

The attached code allows me to choose whether the language (or base)
module is pro-compiled, or required by name.

I get an error of the following when USE_RACO_CMOD=1 and USE_BASE_LANG=0:

$ USE_RACO_CMOD=1 USE_BASE_LANG=0 ./tim-test.sh
raco ctool v5.3.1 [3m], Copyright (c) 2004-2012 PLT Scheme Inc.
  [output to "racket_mod.h"]
raco ctool v5.3.1 [3m], Copyright (c) 2004-2012 PLT Scheme Inc.
  [output to "racket_base_mod.h"]
main: >
- using compiled C module
- is base module? 0
- not using compiled C module
 > scheme_namespace_require test-match-expander
test-match-expander/main.rkt:24:8: match: syntax error in pattern
   in: (syntax-list (? or-keyword?) b c)
   context...:
 
/usr2/local/racket-master/SunOS-5.10-i386/lib/racket/collects/racket/match/gen-match.rkt:68:29: 
mk
 
/usr2/local/racket-master/SunOS-5.10-i386/lib/racket/collects/racket/match/gen-match.rkt:47:15: 
for-loop
 
/usr2/local/racket-master/SunOS-5.10-i386/lib/racket/collects/racket/match/gen-match.rkt:23:0: 
go
 
/usr2/local/racket-master/SunOS-5.10-i386/lib/racket/collects/racket/private/modbeg.rkt:46:4
    standard-module-name-resolver

Any of the other options work swimmingly:

$ USE_RACO_CMOD=0 USE_BASE_LANG=0 ./tim-test.sh
(same with "USE_RACO_CMOD=0 USE_BASE_LANG=1 ./tim-test.sh"
  and "USE_RACO_CMOD=1 USE_BASE_LANG=1 ./tim-test.sh")

raco ctool v5.3.1 [3m], Copyright (c) 2004-2012 PLT Scheme Inc.
  [output to "racket_mod.h"]
raco ctool v5.3.1 [3m], Copyright (c) 2004-2012 PLT Scheme Inc.
  [output to "racket_base_mod.h"]
main: >
 > scheme_namespace_require racket
< scheme_namespace_require racket
 > scheme_namespace_require test-match-expander
'("OOORRR!" 
#<syntax:/usr2/ccl/iatm/iatm-MQ/wm_mq_iatm8/src/test-match-expander/main.rkt:23:13 
3> 
#<syntax:/usr2/ccl/iatm/iatm-MQ/wm_mq_iatm8/src/test-match-expander/main.rkt:23:15 
4>)
< scheme_namespace_require test-match-expander
main: < 42


That covers my 2^2 test cases!
Am I doing anything fundmentally dim here?

Tim Brown

Environments:
LINUX:
$ racketcgc
Welcome to Racket v5.3.1 [cgc].
 > (system-library-subpath)
#<path:x86_64-linux>
 > (banner)
"Welcome to Racket v5.3.1 [cgc].\n"
 >
$ uname -a
Linux timlinux 2.6.32-5-amd64 #1 SMP Sun Sep 23 10:07:46 UTC 2012 x86_64 
GNU/Linux

SOLARIS:
 > /usr/local/racket-master/SunOS-5.10-i386/bin/racketcgc
Welcome to Racket v5.3.1 [cgc].
 > (system-library-subpath)
#<path:i386-solaris>
 > (banner)
"Welcome to Racket v5.3.1 [cgc].\n"
$ uname -a
SunOS ...hostname... 5.10 Generic_138889-03 i86pc i386 i86pc

ATTACHED:
test_embedded_scheme.c:       as minimal a script as I can demonstrate my
                               problem
tim-test.sh :                 a shell script to build the needful
test-match-expander/main.rkt: Example using define-match-expander, from
                               racket docs


-- 
Tim Brown <tim.brown at cityc.co.uk>  | City Computing Limited            |
T: +44 20 8770 2110                | City House, Sutton Park Road      |
F: +44 20 8770 2130                | Sutton, Surrey, SM1 2AE, GB       |
-----------------------------------------------------------------------|
BEAUTY:  What's in your eye when you have a bee in your hand           |
-----------------------------------------------------------------------'
City Computing Limited registered in London No. 1767817.
Registered Office: City House, Sutton Park Road, Sutton, Surrey, SM1 2AE
VAT number 372 8290 34.
-------------- next part --------------
#include <scheme.h>

#if USE_RACO_CMOD
# if USE_BASE_LANG
#   include "racket_base_mod.h"
# else
#   include "racket_mod.h"
# endif
#endif

/*----------------------------------------------------------------------------*/
int trampoline_main(Scheme_Env* e, int c, char** v)
  {
#if USE_RACO_CMOD
  printf("- using compiled C module\n");
  printf("- is base module? %d\n", USE_BASE_LANG);
  declare_modules(e);
#endif

#if 1
  scheme_init_collection_paths(e, scheme_null);
#endif

#if !USE_RACO_CMOD
# if USE_BASE_LANG
#  define LANG_MODULE "racket/base"
# else
#  define LANG_MODULE "racket"
# endif
  printf("> scheme_namespace_require "LANG_MODULE"\n");
  scheme_namespace_require(scheme_intern_symbol(LANG_MODULE));
  printf("< scheme_namespace_require "LANG_MODULE"\n");
#else
  printf("- not using compiled C module \n");
#endif

#if 1
  printf("> scheme_namespace_require test-match-expander\n");
  scheme_namespace_require(scheme_intern_symbol("test-match-expander"));
  printf("< scheme_namespace_require test-match-expander\n");
#endif
  return 42;
  }

/*----------------------------------------------------------------------------*/
int main(int argc, char** argv)
  {
  int rv;
  int no_auto_statics = 1; /* ! no_auto_statics -> statics are watched by GC */
  printf("%s: >\n", __func__);
  rv = scheme_main_setup(no_auto_statics, trampoline_main, argc, (char**)argv);
  printf("%s: < %d\n", __func__, rv);
  return 0;
  }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tim-test.sh
Type: text/x-sh
Size: 1152 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20130123/828b0fd2/attachment-0001.bin>
-------------- next part --------------
#lang racket

; Ripped directly off from:
; http://docs.racket-lang.org/reference/match.html?q=match#%28form._%28%28lib._racket/match..rkt%29._match%29%29

(define-match-expander
  syntax-list
  (lambda (stx)
    (syntax-case stx ()
      [(_ elts ...)
       #'(? (lambda (x) (and (syntax? x)
                             (list? (syntax->list x))))
            (app syntax->list (list elts ...)))])))

(define (make-keyword-predicate keyword)
  (lambda (stx)
    (and (identifier? stx)
         (free-identifier=? stx keyword))))
(define or-keyword? (make-keyword-predicate #'or))
(define and-keyword? (make-keyword-predicate #'and))

     
(match #'(or 3 4)
       [(syntax-list (? or-keyword?) b c)
        (list "OOORRR!" b c)]
       [(syntax-list (? and-keyword?) b c)
        (list "AAANND!" b c)])

Posted on the users mailing list.