Skip to content

Instantly share code, notes, and snippets.

@samdphillips
Created February 4, 2025 19:08
Show Gist options
  • Save samdphillips/ec302bcd4ab4943d2591145f8edff806 to your computer and use it in GitHub Desktop.
Save samdphillips/ec302bcd4ab4943d2591145f8edff806 to your computer and use it in GitHub Desktop.
Scheme to C function translation

Fixed Arity Definition

(define (foo x) body ...)

==>

SCM foo(int nr, SCM k, SCM x)
{
  if (nr != 1) arity_error();

  body ...
}

Varying Arity Definition

(define (foo* . x) body ...)

==>

SCM foo_star(int nr, SCM k, SCM a, SCM b, SCM c, SCM d, SCM rest)
{
  SCM x;
  switch (nr) {
      case 0:
        x = NIL;
        break;
      case 1:
        x = SCM_cons(a, NIL);
        break;
      case 2:
        x = SCM_cons(a, SCM_cons(b, NIL));
        break;
      case 3:
        x = SCM_cons(a, SCM_cons(b, SCM_cons(c, NIL)));
        break;
      case 4:
        x = SCM_cons(a, SCM_cons(b, SCM_cons(c, SCM_cons(d, NIL))));
        break;
      default:
        x = SCM_cons(a, SCM_cons(b, SCM_cons(c, SCM_cons(d, rest))));
        break;
  }

  body ...
}

Direct Call

global or some other "known" function

(foo x)

==>

foo(1, k, x);

Indirect call

f is a SCM value unknown what it calls.

(f x)

==>

// SCM_PROC_UNWRAP checks that f is an SCM procedure and extracts the function
// pointer.
SCM (*fun1)(int, SCM, SCM) = SCM_PROC_UNWRAP(f);
fun1(1, k, x);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment