with-c-syntax

2016-02-08

??

with-c-syntax ?? Common Lisp ? C ????????????????? ???????????????????????????

??? C ??????????? ISO C 90 ? freestanding ?????? ??????????????

Abstract

with-c-syntax is a fun package which introduces the C language syntax into Common Lisp. (Yes, this package is not for practical coding, I think.)

At this stage, this package has almost all features of ISO C 90 freestanding implementation. (The lacking part is the full implementation of the C Preprocessor.)

Loading

Libraries depending on

  • asdf
  • cl-yacc
  • alexandria

Load with ASDF

(load "with-c-syntax.asd")

(asdf:load-system :with-c-syntax)

Running tests

(asdf:test-system :with-c-syntax)

Examples

Hello World

  CL-USER> (with-c-syntax:use-reader)     ; enables #{ }# reader macros.
  #<readtable @ #x1000122b162>
  CL-USER> (with-c-syntax:with-c-syntax ()
  #{
    format (t, "Hello World!");
  }#)

  Hello World!
  NIL
  CL-USER> (with-c-syntax:unuse-reader)   ; disables #{ }# reader macros.
  #<readtable @ #x10000208b02>
  CL-USER> 

Summing from 1 to 100.

Because of using reader macros, this example may confuse the repl of slime. I tried this on SBCL's native repl.

  ,* (with-c-syntax:use-reader)

  #<READTABLE {1003B9FA63}>
  ,* (with-c-syntax:with-c-syntax ()
  #{
    int i, sum = 0;

    for (i = 0; i <= 100; ++ i )
      sum += i;
    return sum;
  }#)

  5050
  ,* (with-c-syntax:unuse-reader)

  #<READTABLE {10000009C3}>
  *  

Duff's Device

  (with-c-syntax:use-reader)
  (defun w-c-s-duff-device (to-seq from-seq cnt)
    (with-c-syntax:with-c-syntax ()
      #{
      int * to = & to-seq;
      int * from = & from-seq;

      int n = (cnt + 7) / 8;
      n = floor(n);           /* Lisp's CL:/ produces rational */
      switch (cnt % 8) {
      case 0 :    do {    * to ++ = * from ++;
      case 7 :            * to ++ = * from ++;
      case 6 :            * to ++ = * from ++;
      case 5 :            * to ++ = * from ++;
      case 4 :            * to ++ = * from ++;
      case 3 :            * to ++ = * from ++;
      case 2 :            * to ++ = * from ++;
      case 1 :            * to ++ = * from ++;
        } while (-- n > 0);
      }
      }#)
    to-seq)
  (with-c-syntax:unuse-reader)

  (setf arr1 (make-array 20 :initial-element 1))
  (setf arr2 (make-array 20 :initial-element 2))
  (w-c-s-duff-device arr1 arr2 10)

  arr1 ;; => #(2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1)

API

Macro with-c-syntax

Syntax

with-c-syntax (&key keyword-case entry-form try-add-{}) form* => result*

Arguments and Values

keyword-case
one of :upcase, :downcase, :preserve, or :invert. The default is the current readtable case.
entry-form
a form.
try-add-{}
a boolean.
forms
forms interpreted by this macro.
results
the values returned by the forms

Description

This macro is a entry point of the with-c-syntax system. forms are interpreted as C syntax, executed, and return values.

keyword-case specifies case sensitivity. Especially, if :upcase is specified, some case-insensitive feature is enabled for convenience.

entry-form is inserted as an entry point when compiling a translation unit.

If try-add-{} is t and an error occurred at parsing, with-c-syntax adds '{' and '}' into the head and tail of form respectively, and tries to parse again.

Function use-reader

Syntax

use-reader &key level case => readtable

Arguments and Values

level
one of 0, 1, 2, 3, :conservative, :aggressive, :overkill, or :insane. The default is specified by *default-reader-level*.
case
one of :upcase, :downcase, :preserve, :invert, or nil. The default is nil.

Description

This macro establishes a C syntax reader.

use-reader introduces a dispatching macro character '#{'. Inside '#{' and '}#', the reader uses completely different syntax, and wrapped with with-c-syntax form.

Syntax Levels

For inside '#{' and '}#', four syntaxes are defined. These syntaxes are selected by the infix parameter of the '#{' dispatching macro character. If it not specified, The default is the level specified at use-reader.

If you interest for what syntaxes are defined, Please see the "Further Information" links at bottom.

Syntax Cases

When case is not nil, the specified case is used as the readtable-case inside '#{' and '}#', and the case is passed to the wrapping with-c-syntax form.

When case is nil, the readtable-case of *readtable* at using '#{' is used.

Side Effects

Changes *readtable*.

Notes

There is no support for trigraphs or digraphs.

See Also

with-c-syntax, unuse-reader.

Function unuse-reader

Syntax

unuse-reader <no arguments> => readtable

Arguments and Values

readtable
a readtable

Description

Disposes the C reader established by use-reader, and restores the previous readtable.

Side Effects

Changes *readtable*.

See Also

unuse-reader.

Further Information

Please see: https://github.com/y2q-actionman/with-c-syntax/wiki

Author
YOKOTA Yuki <y2q.actionman@gmail.com>
License
WTFPL