minischeme: add char
This commit is contained in:
parent
45cfd8ff11
commit
93cfe0d94a
4
Makefile
4
Makefile
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
miniscm-run-tests: miniscm/scm tests.scm
|
miniscm-run-tests: miniscm/scm tests.scm
|
||||||
./miniscm/scm < tests.scm
|
./miniscm/scm < tests.scm
|
||||||
miniscm/scm:
|
miniscm/scm: miniscm/miniscm.c
|
||||||
c89 -DSYSV -DInitFile=\"miniscm/init.scm\" miniscm/miniscm.c -o miniscm/scm
|
c89 -g -DSYSV -DInitFile=\"miniscm/init.scm\" miniscm/miniscm.c -o miniscm/scm
|
||||||
clean:
|
clean:
|
||||||
rm -f miniscm
|
rm -f miniscm
|
||||||
|
|
|
@ -17,6 +17,8 @@ designed to be used by a severely limited Scheme interpreter, which
|
||||||
* lacks ``call/cc``, ``call-with-values``, etc
|
* lacks ``call/cc``, ``call-with-values``, etc
|
||||||
* lacks user definable macros
|
* lacks user definable macros
|
||||||
* only uses required features from R3RS
|
* only uses required features from R3RS
|
||||||
|
(except ``open-input-port``, ``close-input-port``, ``read-char``,
|
||||||
|
``open-output-port``, ``close-output-port``, ``write-char``)
|
||||||
* has fixnums only
|
* has fixnums only
|
||||||
* minimizes the use of strings
|
* minimizes the use of strings
|
||||||
* does not use "load" recursively
|
* does not use "load" recursively
|
||||||
|
|
|
@ -73,6 +73,3 @@
|
||||||
(equal? (cdr x) (cdr y)))
|
(equal? (cdr x) (cdr y)))
|
||||||
(and (not (pair? y))
|
(and (not (pair? y))
|
||||||
(eqv? x y))))
|
(eqv? x y))))
|
||||||
|
|
||||||
(display "This is a limited version of MiniScheme used to run UNSLISP.")
|
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,13 @@
|
||||||
*--
|
*--
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* TODO: Add basic port operations.
|
||||||
|
*
|
||||||
|
* UNSLISP only needs one input port and one output port (besides stdin
|
||||||
|
* and stdout). The easiest thing to do is to make ports integers that
|
||||||
|
* reference a global list of FILE*.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here is System declaration.
|
* Here is System declaration.
|
||||||
* Please define exactly one symbol in the following section.
|
* Please define exactly one symbol in the following section.
|
||||||
|
@ -66,15 +73,18 @@
|
||||||
* Define or undefine following symbols as you need.
|
* Define or undefine following symbols as you need.
|
||||||
*/
|
*/
|
||||||
/* #define VERBOSE */ /* define this if you want verbose GC */
|
/* #define VERBOSE */ /* define this if you want verbose GC */
|
||||||
|
#define VERBOSE
|
||||||
#define AVOID_HACK_LOOP /* define this if your compiler is poor
|
#define AVOID_HACK_LOOP /* define this if your compiler is poor
|
||||||
* enougth to complain "do { } while (0)"
|
* enougth to complain "do { } while (0)"
|
||||||
* construction.
|
* construction.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define USE_SETJMP /* undef this if you do not want to use setjmp() */
|
#define USE_SETJMP /* undef this if you do not want to use setjmp() */
|
||||||
#define USE_QQUOTE /* undef this if you do not need quasiquote */
|
#define USE_QQUOTE /* undef this if you do not need quasiquote */
|
||||||
#define USE_MACRO /* undef this if you do not need macro */
|
#define USE_MACRO /* undef this if you do not need macro */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_QQUOTE
|
#ifdef USE_QQUOTE
|
||||||
/*--
|
/*--
|
||||||
* If your machine can't support "forward single quotation character"
|
* If your machine can't support "forward single quotation character"
|
||||||
|
@ -102,7 +112,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define banner "Hello, This is Mini-Scheme Interpreter Version 0.85k4-a.\n"
|
#define banner "Hello, This is Mini-Scheme Interpreter Version 0.85k4-a for UNSLISP.\n"
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -224,6 +234,7 @@ typedef struct cell *pointer;
|
||||||
# define T_MACRO 256 /* 0000000100000000 */
|
# define T_MACRO 256 /* 0000000100000000 */
|
||||||
#endif
|
#endif
|
||||||
#define T_PROMISE 512 /* 0000001000000000 */
|
#define T_PROMISE 512 /* 0000001000000000 */
|
||||||
|
#define T_CHAR 1024 /* 0000010000000000 */
|
||||||
#define T_ATOM 16384 /* 0100000000000000 */ /* only for gc */
|
#define T_ATOM 16384 /* 0100000000000000 */ /* only for gc */
|
||||||
#define CLRATOM 49151 /* 1011111111111111 */ /* only for gc */
|
#define CLRATOM 49151 /* 1011111111111111 */ /* only for gc */
|
||||||
#define MARK 32768 /* 1000000000000000 */
|
#define MARK 32768 /* 1000000000000000 */
|
||||||
|
@ -238,6 +249,7 @@ typedef struct cell *pointer;
|
||||||
|
|
||||||
#define isnumber(p) (type(p)&T_NUMBER)
|
#define isnumber(p) (type(p)&T_NUMBER)
|
||||||
#define ivalue(p) ((p)->_object._number._ivalue)
|
#define ivalue(p) ((p)->_object._number._ivalue)
|
||||||
|
#define ischar(p) (type(p)&T_CHAR)
|
||||||
|
|
||||||
#define ispair(p) (type(p)&T_PAIR)
|
#define ispair(p) (type(p)&T_PAIR)
|
||||||
#define car(p) ((p)->_object._cons._car)
|
#define car(p) ((p)->_object._cons._car)
|
||||||
|
@ -329,6 +341,18 @@ jmp_buf error_jmp;
|
||||||
#endif
|
#endif
|
||||||
char gc_verbose; /* if gc_verbose is not zero, print gc status */
|
char gc_verbose; /* if gc_verbose is not zero, print gc status */
|
||||||
|
|
||||||
|
stricmp(x, y)
|
||||||
|
char *x;
|
||||||
|
char *y;
|
||||||
|
{
|
||||||
|
for (; tolower((unsigned char)(*x++))
|
||||||
|
== tolower((unsigned char)(*y++));
|
||||||
|
x++, y++)
|
||||||
|
if (!*x)
|
||||||
|
break;
|
||||||
|
return *x - *y;
|
||||||
|
}
|
||||||
|
|
||||||
/* allocate new cell segment */
|
/* allocate new cell segment */
|
||||||
alloc_cellseg(n)
|
alloc_cellseg(n)
|
||||||
int n;
|
int n;
|
||||||
|
@ -526,6 +550,24 @@ char *q;
|
||||||
return (mk_number(atol(q)));
|
return (mk_number(atol(q)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make char */
|
||||||
|
pointer mk_char(name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
register pointer x = get_cell(NIL, NIL);
|
||||||
|
type(x) = (T_CHAR | T_ATOM);
|
||||||
|
|
||||||
|
if (stricmp(name, "space") == 0) {
|
||||||
|
ivalue(x) = ' ';
|
||||||
|
} else if (stricmp(name, "newline") == 0) {
|
||||||
|
ivalue(x) = '\n';
|
||||||
|
} else {
|
||||||
|
ivalue(x) = *name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
/* make constant */
|
/* make constant */
|
||||||
pointer mk_const(name)
|
pointer mk_const(name)
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -548,8 +590,11 @@ char *name;
|
||||||
sprintf(tmp, "0x%s", &name[1]);
|
sprintf(tmp, "0x%s", &name[1]);
|
||||||
sscanf(tmp, "%lx", &x);
|
sscanf(tmp, "%lx", &x);
|
||||||
return (mk_number(x));
|
return (mk_number(x));
|
||||||
} else
|
} else if (*name == '\\') { /* Character constant */
|
||||||
|
return (mk_char(&name[1]));
|
||||||
|
} else {
|
||||||
return (NIL);
|
return (NIL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -858,6 +903,16 @@ int f;
|
||||||
p = "#<CLOSURE>";
|
p = "#<CLOSURE>";
|
||||||
else if (iscontinuation(l))
|
else if (iscontinuation(l))
|
||||||
p = "#<CONTINUATION>";
|
p = "#<CONTINUATION>";
|
||||||
|
else if (ischar(l)) {
|
||||||
|
if (ivalue(l) == '\n')
|
||||||
|
p = "#\\newline";
|
||||||
|
else if (ivalue(l) == ' ')
|
||||||
|
p = "#\\space";
|
||||||
|
else {
|
||||||
|
p = strbuff;
|
||||||
|
sprintf(p, "#\\%c", ivalue(l));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (f < 0)
|
if (f < 0)
|
||||||
return strlen(p);
|
return strlen(p);
|
||||||
fputs(p, outfp);
|
fputs(p, outfp);
|
||||||
|
@ -948,6 +1003,11 @@ register pointer a, b;
|
||||||
return (ivalue(a) == ivalue(b));
|
return (ivalue(a) == ivalue(b));
|
||||||
else
|
else
|
||||||
return (0);
|
return (0);
|
||||||
|
} else if (ischar(a)) {
|
||||||
|
if (ischar(b))
|
||||||
|
return (ivalue(a) == ivalue(b));
|
||||||
|
else
|
||||||
|
return (0);
|
||||||
} else
|
} else
|
||||||
return (a == b);
|
return (a == b);
|
||||||
}
|
}
|
||||||
|
@ -1115,7 +1175,7 @@ register pointer a, b;
|
||||||
#define OP_GET_CLOSURE 101
|
#define OP_GET_CLOSURE 101
|
||||||
#define OP_CLOSUREP 102
|
#define OP_CLOSUREP 102
|
||||||
#define OP_MACROP 103
|
#define OP_MACROP 103
|
||||||
|
#define OP_CHAR 104
|
||||||
|
|
||||||
static FILE *tmpfp;
|
static FILE *tmpfp;
|
||||||
static int tok;
|
static int tok;
|
||||||
|
@ -1716,6 +1776,8 @@ register short op;
|
||||||
s_retbool(issymbol(car(args)));
|
s_retbool(issymbol(car(args)));
|
||||||
case OP_NUMBER: /* number? */
|
case OP_NUMBER: /* number? */
|
||||||
s_retbool(isnumber(car(args)));
|
s_retbool(isnumber(car(args)));
|
||||||
|
case OP_CHAR: /* char? */
|
||||||
|
s_retbool(ischar(car(args)));
|
||||||
case OP_STRING: /* string? */
|
case OP_STRING: /* string? */
|
||||||
s_retbool(isstring(car(args)));
|
s_retbool(isstring(car(args)));
|
||||||
case OP_PROC: /* procedure? */
|
case OP_PROC: /* procedure? */
|
||||||
|
@ -1958,6 +2020,7 @@ register short op;
|
||||||
fprintf(outfp, "'");
|
fprintf(outfp, "'");
|
||||||
args = cadr(args);
|
args = cadr(args);
|
||||||
s_goto(OP_P0LIST);
|
s_goto(OP_P0LIST);
|
||||||
|
#ifdef USE_QQUOTE
|
||||||
} else if (car(args) == QQUOTE && ok_abbrev(cdr(args))) {
|
} else if (car(args) == QQUOTE && ok_abbrev(cdr(args))) {
|
||||||
fprintf(outfp, "`");
|
fprintf(outfp, "`");
|
||||||
args = cadr(args);
|
args = cadr(args);
|
||||||
|
@ -1970,6 +2033,7 @@ register short op;
|
||||||
fprintf(outfp, ",@");
|
fprintf(outfp, ",@");
|
||||||
args = cadr(args);
|
args = cadr(args);
|
||||||
s_goto(OP_P0LIST);
|
s_goto(OP_P0LIST);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
fprintf(outfp, "(");
|
fprintf(outfp, "(");
|
||||||
s_save(OP_P1LIST, cdr(args), NIL);
|
s_save(OP_P1LIST, cdr(args), NIL);
|
||||||
|
@ -2045,6 +2109,7 @@ register short op;
|
||||||
++w;
|
++w;
|
||||||
args = cadr(args);
|
args = cadr(args);
|
||||||
s_goto(OP_P0_WIDTH);
|
s_goto(OP_P0_WIDTH);
|
||||||
|
#ifdef USE_QQUOTE
|
||||||
} else if (car(args) == QQUOTE
|
} else if (car(args) == QQUOTE
|
||||||
&& ok_abbrev(cdr(args))) {
|
&& ok_abbrev(cdr(args))) {
|
||||||
++w;
|
++w;
|
||||||
|
@ -2060,6 +2125,7 @@ register short op;
|
||||||
w += 2;
|
w += 2;
|
||||||
args = cadr(args);
|
args = cadr(args);
|
||||||
s_goto(OP_P0_WIDTH);
|
s_goto(OP_P0_WIDTH);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
++w;
|
++w;
|
||||||
s_save(OP_P1_WIDTH, cdr(args), NIL);
|
s_save(OP_P1_WIDTH, cdr(args), NIL);
|
||||||
|
@ -2231,10 +2297,11 @@ pointer (*dispatch_table[])() = {
|
||||||
opexe_6, /* OP_P1_WIDTH, */
|
opexe_6, /* OP_P1_WIDTH, */
|
||||||
opexe_6, /* OP_GET_CLOSURE, */
|
opexe_6, /* OP_GET_CLOSURE, */
|
||||||
opexe_6, /* OP_CLOSUREP, */
|
opexe_6, /* OP_CLOSUREP, */
|
||||||
#ifdef USE_MACRO
|
/* OP_MACROP is kept in to fill in a slot. Will return illegal
|
||||||
|
* operator when macros are disabled. */
|
||||||
opexe_6, /* OP_MACROP, */
|
opexe_6, /* OP_MACROP, */
|
||||||
#endif
|
|
||||||
|
opexe_3 /* OP_CHAR */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2382,6 +2449,7 @@ init_procs()
|
||||||
mk_proc(OP_MACROP, "macro?"); /* a.k */
|
mk_proc(OP_MACROP, "macro?"); /* a.k */
|
||||||
#endif
|
#endif
|
||||||
mk_proc(OP_QUIT, "quit");
|
mk_proc(OP_QUIT, "quit");
|
||||||
|
mk_proc(OP_CHAR, "char?");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue