Newsgroups: comp.lang.lisp.x,comp.lang.lisp,comp.lang.scheme,comp.lang.scheme.c,comp.lang.tcl,comp.lang.perl,comp.lang.python
Path: cantaloupe.srv.cs.cmu.edu!rochester!udel!news.mathworks.com!newsfeed.internetmci.com!in1.uu.net!world!gjc
From: gjc@world.std.com (George J Carrette)
Subject: A language extensibility benchmark
Message-ID: <DLuKxo.DnE@world.std.com>
Organization: The World Public Access UNIX, Brookline, MA
Date: Sat, 27 Jan 1996 16:10:36 GMT
Lines: 114
Xref: glinda.oz.cs.cmu.edu comp.lang.lisp.x:1710 comp.lang.lisp:20618 comp.lang.scheme:14923 comp.lang.scheme.c:726 comp.lang.tcl:41731 comp.lang.python:8323

This is a language extensibility benchmark, previously posted
as an attachment from a Netscape browser that mangled mime type
into something absurd. The challenge is to write equivalent functions
in C as extensions for your favorite interpreter and compare for
readability, transparency, brevity, and maintainability.


/* name:    siodx.c
   purpose: demonstrate interpreter extension facility.
   author:  George Carrette, gjc@mci.newscorp.com 
   uses:    ftp://ftp.std.com/pub/gjc/siod_tar.gz

The exersize is to present a complete solution for the following:
 [1] the makefile section required.
 [2] the interpreted code needed to load and test the extension.
 [3] source code for bootstrapping the extension.
 [4] source code to compute fib(n) using simple recursion.
 [5] source code to compute a string_toupper(s)
 [6] source code to compute a double_array_rms(a)

The exersize is to be graded on the inspection obviousness of the solutions,
brevity, straightforward use of the C language, and the general ease of use
demonstrated.

An important bonus is awarded if the solutions may be easily invoked from
both interpreted code and other C coded parts of the system, especially
focusing on other extensions.

[1] makefile

siodx.so: siodx.o
	$(LD) -o siodx.so -shared siodx.o -lsiod -lm -lc

siodx.o: siodx.c
	$(CC) -c -I/usr/local/include siodx.c

[2] load and test

#!/usr/local/bin/htqs
(require-so "siodx.so")
(print (fib 20))
(print (string_toupper "fooBar"))
(define a (cons-array 3 'double))
(aset a 0 1)
(aset a 1 -2)
(aset a 2 3)
(print (double_array_rms a))

*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "siod.h"

/* [3] bootstrap, and declare for other C programmers to use. */

LISP fib(LISP);
LISP string_toupper(LISP);
LISP double_array_rms(LISP);

void init_siodx(void)
{init_subr_1("fib",fib);
 init_subr_1("string_toupper",string_toupper);
 init_subr_1("double_array_rms",double_array_rms);}

/* [4] */

LISP fib(LISP n)
{return((!NULLP(lessp(n,flocons(2.0))))
	? n
	: plus(fib(difference(n,flocons(1.0))),
	       fib(difference(n,flocons(2.0)))));}

/* [5] */

LISP string_toupper(LISP s1)
{LISP s2;
 long j,n;
 char *p1,*p2;
 p1 = get_c_string_dim(s1,&n);
 s2 = strcons(n,NULL);
 p2 = get_c_string(s2);
 for(j=0;j<n;++j)
   p2[j] = toupper(p1[j]);
 return(s2);}

/* [6] */

LISP double_array_rms(LISP a)
{long j,n;
 double r,*p;
 if (!TYPEP(a,tc_double_array)) err("not a double array",a);
 for(j=0,
     r=0.0,
     n=a->storage_as.double_array.dim,
     p=a->storage_as.double_array.data;
     j<n;
     ++j)
   r += p[j] * p[j];
 return(flocons(sqrt(r/n)));}












