C language syntax in Common Lisp
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src
test
.gitignore
COPYING
README.org
package.lisp
with-c-syntax-test.asd
with-c-syntax.asd

README.org

概要

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.

License

Copyright (c) 2014 YOKOTA Yuki <y2q.actionman@gmail.com>

This program is free software. It comes without any warranty, to the extent permitted by applicable law. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2, as published by Sam Hocevar. See the COPYING file for more details.

Further Information

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