ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/microscheme/scheme.c
(Generate patch)

Comparing cvsroot/microscheme/scheme.c (file contents):
Revision 1.63 by root, Wed Dec 2 12:16:24 2015 UTC vs.
Revision 1.66 by root, Mon Dec 7 18:10:57 2015 UTC

16 * (MINISCM) This is a revised and modified version by Akira KIDA. 16 * (MINISCM) This is a revised and modified version by Akira KIDA.
17 * (MINISCM) current version is 0.85k4 (15 May 1994) 17 * (MINISCM) current version is 0.85k4 (15 May 1994)
18 * 18 *
19 */ 19 */
20 20
21#define _GNU_SOURCE 1
22#define _POSIX_C_SOURCE 200201 21#define _POSIX_C_SOURCE 200201
23#define _XOPEN_SOURCE 600 22#define _XOPEN_SOURCE 600
24 23#define _GNU_SOURCE 1 /* for malloc mremap */
25 24
26#define SCHEME_SOURCE 25#define SCHEME_SOURCE
27#include "scheme-private.h" 26#include "scheme-private.h"
28#ifndef WIN32 27#ifndef WIN32
29# include <unistd.h> 28# include <unistd.h>
220 T_FOREIGN, 219 T_FOREIGN,
221 T_PORT, 220 T_PORT,
222 T_VECTOR, 221 T_VECTOR,
223 T_PROMISE, 222 T_PROMISE,
224 T_ENVIRONMENT, 223 T_ENVIRONMENT,
224 T_SPECIAL, // #t, #f, '(), eof-object
225 225
226 T_NUM_SYSTEM_TYPES 226 T_NUM_SYSTEM_TYPES
227}; 227};
228 228
229#define T_MASKTYPE 0x000f 229#define T_MASKTYPE 0x001f
230#define T_SYNTAX 0x0010 230#define T_SYNTAX 0x0020
231#define T_IMMUTABLE 0x0020 231#define T_IMMUTABLE 0x0040
232#define T_ATOM 0x0040 /* only for gc */ 232#define T_ATOM 0x0080 /* only for gc */
233#define T_MARK 0x0080 /* only for gc */ 233//#define T_MARK 0x0080 /* only for gc */
234 234
235/* num, for generic arithmetic */ 235/* num, for generic arithmetic */
236struct num 236struct num
237{ 237{
238 IVALUE ivalue; 238 IVALUE ivalue;
384 384
385static pointer cadar (pointer p) { return car (cdr (car (p))); } 385static pointer cadar (pointer p) { return car (cdr (car (p))); }
386static pointer caddr (pointer p) { return car (cdr (cdr (p))); } 386static pointer caddr (pointer p) { return car (cdr (cdr (p))); }
387static pointer cdaar (pointer p) { return cdr (car (car (p))); } 387static pointer cdaar (pointer p) { return cdr (car (car (p))); }
388 388
389static pointer cadddr (pointer p) { return car (car (car (cdr (p)))); }
390
389INTERFACE void 391INTERFACE void
390set_car (pointer p, pointer q) 392set_car (pointer p, pointer q)
391{ 393{
392 CELL(p)->object.cons.car = CELL (q); 394 CELL(p)->object.cons.car = CELL (q);
393} 395}
509 511
510#define is_atom(p) (typeflag (p) & T_ATOM) 512#define is_atom(p) (typeflag (p) & T_ATOM)
511#define setatom(p) set_typeflag ((p), typeflag (p) | T_ATOM) 513#define setatom(p) set_typeflag ((p), typeflag (p) | T_ATOM)
512#define clratom(p) set_typeflag ((p), typeflag (p) & ~T_ATOM) 514#define clratom(p) set_typeflag ((p), typeflag (p) & ~T_ATOM)
513 515
516#if 1
517#define is_mark(p) (CELL(p)->mark)
518#define setmark(p) (CELL(p)->mark = 1)
519#define clrmark(p) (CELL(p)->mark = 0)
520#else
514#define is_mark(p) (typeflag (p) & T_MARK) 521#define is_mark(p) (typeflag (p) & T_MARK)
515#define setmark(p) set_typeflag ((p), typeflag (p) | T_MARK) 522#define setmark(p) set_typeflag ((p), typeflag (p) | T_MARK)
516#define clrmark(p) set_typeflag ((p), typeflag (p) & ~T_MARK) 523#define clrmark(p) set_typeflag ((p), typeflag (p) & ~T_MARK)
524#endif
517 525
518INTERFACE int 526INTERFACE int
519is_immutable (pointer p) 527is_immutable (pointer p)
520{ 528{
521 return typeflag (p) & T_IMMUTABLE && USE_ERROR_CHECKING; 529 return typeflag (p) & T_IMMUTABLE && USE_ERROR_CHECKING;
927 last = newp + segsize - 1; 935 last = newp + segsize - 1;
928 936
929 for (p = newp; p <= last; p++) 937 for (p = newp; p <= last; p++)
930 { 938 {
931 pointer cp = POINTER (p); 939 pointer cp = POINTER (p);
940 clrmark (cp);
932 set_typeflag (cp, T_PAIR); 941 set_typeflag (cp, T_PAIR);
933 set_car (cp, NIL); 942 set_car (cp, NIL);
934 set_cdr (cp, POINTER (p + 1)); 943 set_cdr (cp, POINTER (p + 1));
935 } 944 }
936 945
2937/* ========== Evaluation Cycle ========== */ 2946/* ========== Evaluation Cycle ========== */
2938 2947
2939ecb_cold static int 2948ecb_cold static int
2940xError_1 (SCHEME_P_ const char *s, pointer a) 2949xError_1 (SCHEME_P_ const char *s, pointer a)
2941{ 2950{
2942#if USE_ERROR_HOOK
2943 pointer x;
2944 pointer hdl = SCHEME_V->ERROR_HOOK;
2945#endif
2946
2947#if USE_PRINTF 2951#if USE_PRINTF
2948#if SHOW_ERROR_LINE 2952#if SHOW_ERROR_LINE
2949 char sbuf[STRBUFFSIZE]; 2953 char sbuf[STRBUFFSIZE];
2950 2954
2951 /* make sure error is not in REPL */ 2955 /* make sure error is not in REPL */
2966 } 2970 }
2967#endif 2971#endif
2968#endif 2972#endif
2969 2973
2970#if USE_ERROR_HOOK 2974#if USE_ERROR_HOOK
2971 x = find_slot_in_env (SCHEME_A_ SCHEME_V->envir, hdl, 1); 2975 pointer x = find_slot_in_env (SCHEME_A_ SCHEME_V->envir, SCHEME_V->ERROR_HOOK, 1);
2972 2976
2973 if (x != NIL) 2977 if (x != NIL)
2974 { 2978 {
2975 pointer code = a 2979 pointer code = a
2976 ? cons (cons (SCHEME_V->QUOTE, cons (a, NIL)), NIL) 2980 ? cons (cons (SCHEME_V->QUOTE, cons (a, NIL)), NIL)
3220 3224
3221#define s_retbool(tf) s_return ((tf) ? S_T : S_F) 3225#define s_retbool(tf) s_return ((tf) ? S_T : S_F)
3222 3226
3223#if EXPERIMENT 3227#if EXPERIMENT
3224 3228
3225typedef void *stream[1];
3226
3227#define stream_init() { 0 }
3228
3229ecb_cold static void
3230stream_put (void **s, uint8_t byte)
3231{
3232 uint32_t *sp = *s;
3233 uint32_t size = sizeof (uint32_t) * 2;
3234 uint32_t offs = size;
3235
3236 if (ecb_expect_true (sp))
3237 {
3238 offs = sp[0];
3239 size = sp[1];
3240 }
3241
3242 if (ecb_expect_false (offs == size))
3243 {
3244 size *= 2;
3245 sp = realloc (sp, size);
3246 *s = sp;
3247 sp[1] = size;
3248
3249 }
3250
3251 ((uint8_t *)sp)[offs++] = byte;
3252 sp[0] = offs;
3253}
3254
3255#define stream_data(s) ((char *)(s)[0] + sizeof (uint32_t) * 2)
3256#define stream_size(s) (((uint32_t *)(s)[0])[0] - sizeof (uint32_t) * 2)
3257#define stream_free(s) free (s[0])
3258
3259// calculates a (preferably small) integer that makes it possible to find
3260// the symbol again. if pointers were offsets into a memory area... until
3261// then, we return segment number in the low bits, and offset in the high
3262// bits
3263static uint32_t
3264symbol_id (SCHEME_P_ pointer sym)
3265{
3266 struct cell *p = CELL (sym);
3267 int i;
3268
3269 for (i = SCHEME_V->last_cell_seg; i >= 0; --i)
3270 if (SCHEME_V->cell_seg[i] <= p && p < SCHEME_V->cell_seg[i] + SCHEME_V->cell_segsize[i])
3271 {
3272 printf ("seg %d ofs %d/%d\n",i,(p - SCHEME_V->cell_seg[i]),SCHEME_V->cell_segsize[i]);//D
3273 return i | ((p - SCHEME_V->cell_seg[i]) << CELL_NSEGMENT_LOG);
3274 }
3275
3276 abort ();
3277}
3278
3279static void
3280compile (SCHEME_P_ stream s, pointer x)
3281{
3282 if (x == NIL)
3283 {
3284 stream_put (s, 0);
3285 return;
3286 }
3287
3288 if (is_syntax (x))
3289 {
3290 stream_put (s, 1);
3291 stream_put (s, syntaxnum (x));
3292 return;
3293 }
3294
3295 switch (type (x))
3296 {
3297 case T_INTEGER:
3298 stream_put (s, 2);
3299 stream_put (s, 0);
3300 stream_put (s, 0);
3301 stream_put (s, 0);
3302 stream_put (s, 0);
3303 return;
3304
3305 case T_SYMBOL:
3306 {
3307 uint32_t sym = symbol_id (SCHEME_A_ x);
3308 printf ("sym %x\n", sym);//D
3309
3310 stream_put (s, 3);
3311
3312 while (sym > 0x7f)
3313 {
3314 stream_put (s, sym | 0x80);
3315 sym >>= 8;
3316 }
3317
3318 stream_put (s, sym);
3319 }
3320 return;
3321
3322 case T_PAIR:
3323 stream_put (s, 4);
3324 while (x != NIL)
3325 {
3326 compile (SCHEME_A_ s, car (x));
3327 x = cdr (x);
3328 }
3329 stream_put (s, 0xff);
3330 return;
3331
3332 default:
3333 stream_put (s, 5);
3334 stream_put (s, type (x));
3335 stream_put (s, 0);
3336 stream_put (s, 0);
3337 stream_put (s, 0);
3338 stream_put (s, 0);
3339 break;
3340 }
3341}
3342
3343static int
3344compile_closure (SCHEME_P_ pointer p)
3345{
3346 stream s = stream_init ();
3347
3348 printatom (SCHEME_A_ p, 1);//D
3349 compile (SCHEME_A_ s, car (p));
3350
3351 FILE *xxd = popen ("xxd", "we");
3352 fwrite (stream_data (s), 1, stream_size (s), xxd);
3353 fclose (xxd);
3354
3355 return stream_size (s);
3356}
3357
3358static int 3229static int
3359dtree (SCHEME_P_ int indent, pointer x) 3230dtree (SCHEME_P_ int indent, pointer x)
3360{ 3231{
3361 int c; 3232 int c;
3362 3233
3408 default: 3279 default:
3409 printf ("unhandled type %d\n", type (x)); 3280 printf ("unhandled type %d\n", type (x));
3410 break; 3281 break;
3411 } 3282 }
3412} 3283}
3284
3285#define DUMP(t) do { printf ("DUMP %s:%d\n", __FILE__, __LINE__); dtree (SCHEME_A_ 0, (t)); } while (0)
3286
3287typedef void *stream[1];
3288
3289#define stream_init() { 0 }
3290#define stream_data(s) ((char *)(s)[0] + sizeof (uint32_t) * 2)
3291#define stream_size(s) (((uint32_t *)(s)[0])[0] - sizeof (uint32_t) * 2)
3292#define stream_free(s) free (s[0])
3293
3294ecb_cold static void
3295stream_put (stream s, uint8_t byte)
3296{
3297 uint32_t *sp = *s;
3298 uint32_t size = sizeof (uint32_t) * 2;
3299 uint32_t offs = size;
3300
3301 if (ecb_expect_true (sp))
3302 {
3303 offs = sp[0];
3304 size = sp[1];
3305 }
3306
3307 if (ecb_expect_false (offs == size))
3308 {
3309 size *= 2;
3310 sp = realloc (sp, size);
3311 *s = sp;
3312 sp[1] = size;
3313
3314 }
3315
3316 ((uint8_t *)sp)[offs++] = byte;
3317 sp[0] = offs;
3318}
3319
3320ecb_cold static void
3321stream_put_v (stream s, uint32_t v)
3322{
3323 while (v > 0x7f)
3324 {
3325 stream_put (s, v | 0x80);
3326 v >>= 7;
3327 }
3328
3329 stream_put (s, v);
3330}
3331
3332ecb_cold static void
3333stream_put_tv (stream s, int bop, uint32_t v)
3334{
3335 printf ("put tv %d %d\n", bop, v);//D
3336 stream_put (s, bop);
3337 stream_put_v (s, v);
3338}
3339
3340ecb_cold static void
3341stream_put_stream (stream s, stream o)
3342{
3343 uint32_t i;
3344
3345 for (i = 0; i < stream_size (o); ++i)
3346 stream_put (s, stream_data (o)[i]);
3347
3348 stream_free (o);
3349}
3350
3351ecb_cold static uint32_t
3352cell_id (SCHEME_P_ pointer x)
3353{
3354 struct cell *p = CELL (x);
3355 int i;
3356
3357 for (i = SCHEME_V->last_cell_seg; i >= 0; --i)
3358 if (SCHEME_V->cell_seg[i] <= p && p < SCHEME_V->cell_seg[i] + SCHEME_V->cell_segsize[i])
3359 return i | ((p - SCHEME_V->cell_seg[i]) << CELL_NSEGMENT_LOG);
3360
3361 abort ();
3362}
3363
3364// calculates a (preferably small) integer that makes it possible to find
3365// the symbol again. if pointers were offsets into a memory area... until
3366// then, we return segment number in the low bits, and offset in the high
3367// bits.
3368// also, this function must never return 0.
3369ecb_cold static uint32_t
3370symbol_id (SCHEME_P_ pointer sym)
3371{
3372 return cell_id (SCHEME_A_ sym);
3373}
3374
3375enum byteop
3376{
3377 BOP_NIL,
3378 BOP_INTEGER,
3379 BOP_SYMBOL,
3380 BOP_DATUM,
3381 BOP_LIST_BEG,
3382 BOP_LIST_END,
3383 BOP_IF,
3384 BOP_AND,
3385 BOP_OR,
3386 BOP_CASE,
3387 BOP_COND,
3388 BOP_LET,
3389 BOP_LETAST,
3390 BOP_LETREC,
3391 BOP_DEFINE,
3392 BOP_MACRO,
3393 BOP_SET,
3394 BOP_BEGIN,
3395 BOP_LAMBDA,
3396 BOP_OP,
3397};
3398
3399ecb_cold static void compile_expr (SCHEME_P_ stream s, pointer x);
3400
3401ecb_cold static void
3402compile_list (SCHEME_P_ stream s, pointer x)
3403{
3404 // TODO: improper list
3405
3406 for (; x != NIL; x = cdr (x))
3407 {
3408 stream t = stream_init ();
3409 compile_expr (SCHEME_A_ t, car (x));
3410 stream_put_v (s, stream_size (t));
3411 stream_put_stream (s, t);
3412 }
3413
3414 stream_put_v (s, 0);
3415}
3416
3417static void
3418compile_if (SCHEME_P_ stream s, pointer cond, pointer ift, pointer iff)
3419{
3420 stream sift = stream_init (); compile_expr (SCHEME_A_ sift, ift);
3421
3422 stream_put (s, BOP_IF);
3423 compile_expr (SCHEME_A_ s, cond);
3424 stream_put_v (s, stream_size (sift));
3425 stream_put_stream (s, sift);
3426 compile_expr (SCHEME_A_ s, iff);
3427}
3428
3429typedef uint32_t stream_fixup;
3430
3431static stream_fixup
3432stream_put_fixup (stream s)
3433{
3434 stream_put (s, 0);
3435 stream_put (s, 0);
3436
3437 return stream_size (s);
3438}
3439
3440static void
3441stream_fix_fixup (stream s, stream_fixup fixup, uint32_t target)
3442{
3443 target -= fixup;
3444 assert (target < (1 << 14));
3445 stream_data (s)[fixup - 2] = target | 0x80;
3446 stream_data (s)[fixup - 1] = target >> 7;
3447}
3448
3449static void
3450compile_and_or (SCHEME_P_ stream s, int and, pointer x)
3451{
3452 for (; cdr (x) != NIL; x = cdr (x))
3453 {
3454 stream t = stream_init ();
3455 compile_expr (SCHEME_A_ t, car (x));
3456 stream_put_v (s, stream_size (t));
3457 stream_put_stream (s, t);
3458 }
3459
3460 stream_put_v (s, 0);
3461}
3462
3463static void
3464compile_case (SCHEME_P_ stream s, pointer x)
3465{
3466 compile_expr (SCHEME_A_ s, caar (x));
3467
3468 for (;;)
3469 {
3470 x = cdr (x);
3471
3472 if (x == NIL)
3473 break;
3474
3475 compile_expr (SCHEME_A_ s, caar (x));
3476 stream t = stream_init (); compile_expr (SCHEME_A_ t, cdar (x));
3477 stream_put_v (s, stream_size (t));
3478 stream_put_stream (s, t);
3479 }
3480
3481 stream_put_v (s, 0);
3482}
3483
3484static void
3485compile_cond (SCHEME_P_ stream s, pointer x)
3486{
3487 for ( ; x != NIL; x = cdr (x))
3488 {
3489 compile_expr (SCHEME_A_ s, caar (x));
3490 stream t = stream_init (); compile_expr (SCHEME_A_ t, cdar (x));
3491 stream_put_v (s, stream_size (t));
3492 stream_put_stream (s, t);
3493 }
3494
3495 stream_put_v (s, 0);
3496}
3497
3498static pointer
3499lookup (SCHEME_P_ pointer x)
3500{
3501 x = find_slot_in_env (SCHEME_A_ SCHEME_V->envir, x, 1);
3502
3503 if (x != NIL)
3504 x = slot_value_in_env (x);
3505
3506 return x;
3507}
3508
3509ecb_cold static void
3510compile_expr (SCHEME_P_ stream s, pointer x)
3511{
3512 if (x == NIL)
3513 {
3514 stream_put (s, BOP_NIL);
3515 return;
3516 }
3517
3518 if (is_pair (x))
3519 {
3520 pointer head = car (x);
3521
3522 if (is_syntax (head))
3523 {
3524 x = cdr (x);
3525
3526 switch (syntaxnum (head))
3527 {
3528 case OP_IF0: /* if */
3529 stream_put_v (s, BOP_IF);
3530 compile_if (SCHEME_A_ s, car (x), cadr (x), caddr (x));
3531 break;
3532
3533 case OP_OR0: /* or */
3534 stream_put_v (s, BOP_OR);
3535 compile_and_or (SCHEME_A_ s, 0, x);
3536 break;
3537
3538 case OP_AND0: /* and */
3539 stream_put_v (s, BOP_AND);
3540 compile_and_or (SCHEME_A_ s, 1, x);
3541 break;
3542
3543 case OP_CASE0: /* case */
3544 stream_put_v (s, BOP_CASE);
3545 compile_case (SCHEME_A_ s, x);
3546 break;
3547
3548 case OP_COND0: /* cond */
3549 stream_put_v (s, BOP_COND);
3550 compile_cond (SCHEME_A_ s, x);
3551 break;
3552
3553 case OP_LET0: /* let */
3554 case OP_LET0AST: /* let* */
3555 case OP_LET0REC: /* letrec */
3556 switch (syntaxnum (head))
3557 {
3558 case OP_LET0: stream_put (s, BOP_LET ); break;
3559 case OP_LET0AST: stream_put (s, BOP_LETAST); break;
3560 case OP_LET0REC: stream_put (s, BOP_LETREC); break;
3561 }
3562
3563 {
3564 pointer bindings = car (x);
3565 pointer body = cadr (x);
3566
3567 for (x = bindings; x != NIL; x = cdr (x))
3568 {
3569 pointer init = NIL;
3570 pointer var = car (x);
3571
3572 if (is_pair (var))
3573 {
3574 init = cdr (var);
3575 var = car (var);
3576 }
3577
3578 stream_put_v (s, symbol_id (SCHEME_A_ var));
3579 compile_expr (SCHEME_A_ s, init);
3580 }
3581
3582 stream_put_v (s, 0);
3583 compile_expr (SCHEME_A_ s, body);
3584 }
3585 break;
3586
3587 case OP_DEF0: /* define */
3588 case OP_MACRO0: /* macro */
3589 stream_put (s, syntaxnum (head) == OP_DEF0 ? BOP_DEFINE : BOP_MACRO);
3590 stream_put_v (s, cell_id (SCHEME_A_ car (x)));
3591 compile_expr (SCHEME_A_ s, cadr (x));
3592 break;
3593
3594 case OP_SET0: /* set! */
3595 stream_put (s, BOP_SET);
3596 stream_put_v (s, symbol_id (SCHEME_A_ car (x)));
3597 compile_expr (SCHEME_A_ s, cadr (x));
3598 break;
3599
3600 case OP_BEGIN: /* begin */
3601 stream_put (s, BOP_BEGIN);
3602 compile_list (SCHEME_A_ s, x);
3603 return;
3604
3605 case OP_DELAY: /* delay */
3606 abort ();
3607 break;
3608
3609 case OP_QUOTE: /* quote */
3610 stream_put_tv (s, BOP_DATUM, cell_id (SCHEME_A_ x));
3611 break;
3612
3613 case OP_LAMBDA: /* lambda */
3614 {
3615 pointer formals = car (x);
3616 pointer body = cadr (x);
3617
3618 stream_put (s, BOP_LAMBDA);
3619
3620 for (; is_pair (formals); formals = cdr (formals))
3621 stream_put_v (s, symbol_id (SCHEME_A_ car (formals)));
3622
3623 stream_put_v (s, 0);
3624 stream_put_v (s, formals == NIL ? 0 : symbol_id (SCHEME_A_ formals));
3625
3626 compile_expr (SCHEME_A_ s, body);
3627 }
3628 break;
3629
3630 case OP_C0STREAM:/* cons-stream */
3631 abort ();
3632 break;
3633 }
3634
3635 return;
3636 }
3637
3638 pointer m = lookup (SCHEME_A_ head);
3639
3640 if (is_macro (m))
3641 {
3642 s_save (SCHEME_A_ OP_DEBUG2, SCHEME_V->args, SCHEME_V->code);
3643 SCHEME_V->code = m;
3644 SCHEME_V->args = cons (x, NIL);
3645 Eval_Cycle (SCHEME_A_ OP_APPLY);
3646 x = SCHEME_V->value;
3647 compile_expr (SCHEME_A_ s, SCHEME_V->value);
3648 return;
3649 }
3650
3651 stream_put (s, BOP_LIST_BEG);
3652
3653 for (; x != NIL; x = cdr (x))
3654 compile_expr (SCHEME_A_ s, car (x));
3655
3656 stream_put (s, BOP_LIST_END);
3657 return;
3658 }
3659
3660 switch (type (x))
3661 {
3662 case T_INTEGER:
3663 {
3664 IVALUE iv = ivalue_unchecked (x);
3665 iv = iv < 0 ? ((~(uint32_t)iv) << 1) | 1 : (uint32_t)iv << 1;
3666 stream_put_tv (s, BOP_INTEGER, iv);
3667 }
3668 return;
3669
3670 case T_SYMBOL:
3671 if (0)
3672 {
3673 // no can do without more analysis
3674 pointer m = lookup (SCHEME_A_ x);
3675
3676 if (is_proc (m))
3677 {
3678 printf ("compile proc %s %d\n", procname(m), procnum(m));
3679 stream_put_tv (s, BOP_SYMBOL, BOP_OP + procnum (m));
3680 }
3681 else
3682 stream_put_tv (s, BOP_SYMBOL, symbol_id (SCHEME_A_ x));
3683 }
3684
3685 stream_put_tv (s, BOP_SYMBOL, symbol_id (SCHEME_A_ x));
3686 return;
3687
3688 default:
3689 stream_put_tv (s, BOP_DATUM, cell_id (SCHEME_A_ x));
3690 break;
3691 }
3692}
3693
3694ecb_cold static int
3695compile_closure (SCHEME_P_ pointer p)
3696{
3697 stream s = stream_init ();
3698
3699 compile_list (SCHEME_A_ s, cdar (p));
3700
3701 FILE *xxd = popen ("xxd", "we");
3702 fwrite (stream_data (s), 1, stream_size (s), xxd);
3703 fclose (xxd);
3704
3705 return stream_size (s);
3706}
3707
3413#endif 3708#endif
3414 3709
3415/* syntax, eval, core, ... */ 3710/* syntax, eval, core, ... */
3416ecb_hot static int 3711ecb_hot static int
3417opexe_0 (SCHEME_P_ enum scheme_opcodes op) 3712opexe_0 (SCHEME_P_ enum scheme_opcodes op)
3427 uint32_t len = compile_closure (SCHEME_A_ car (args)); 3722 uint32_t len = compile_closure (SCHEME_A_ car (args));
3428 printf ("len = %d\n", len); 3723 printf ("len = %d\n", len);
3429 printf ("\n"); 3724 printf ("\n");
3430 s_return (S_T); 3725 s_return (S_T);
3431 } 3726 }
3727
3728 case OP_DEBUG2:
3729 return -1;
3432#endif 3730#endif
3731
3433 case OP_LOAD: /* load */ 3732 case OP_LOAD: /* load */
3434 if (file_interactive (SCHEME_A)) 3733 if (file_interactive (SCHEME_A))
3435 { 3734 {
3436 putstr (SCHEME_A_ "Loading "); 3735 putstr (SCHEME_A_ "Loading ");
3437 putstr (SCHEME_A_ strvalue (car (args))); 3736 putstr (SCHEME_A_ strvalue (car (args)));
3569 s_save (SCHEME_A_ OP_DOMACRO, NIL, NIL); 3868 s_save (SCHEME_A_ OP_DOMACRO, NIL, NIL);
3570 SCHEME_V->args = cons (SCHEME_V->code, NIL); 3869 SCHEME_V->args = cons (SCHEME_V->code, NIL);
3571 SCHEME_V->code = SCHEME_V->value; 3870 SCHEME_V->code = SCHEME_V->value;
3572 s_goto (OP_APPLY); 3871 s_goto (OP_APPLY);
3573 } 3872 }
3574 else 3873
3575 {
3576 SCHEME_V->code = cdr (SCHEME_V->code); 3874 SCHEME_V->code = cdr (SCHEME_V->code);
3577 s_goto (OP_E1ARGS); 3875 s_goto (OP_E1ARGS);
3578 }
3579 3876
3580 case OP_E1ARGS: /* eval arguments */ 3877 case OP_E1ARGS: /* eval arguments */
3581 args = cons (SCHEME_V->value, args); 3878 args = cons (SCHEME_V->value, args);
3582 3879
3583 if (is_pair (SCHEME_V->code)) /* continue */ 3880 if (is_pair (SCHEME_V->code)) /* continue */
3594 SCHEME_V->args = cdr (args); 3891 SCHEME_V->args = cdr (args);
3595 s_goto (OP_APPLY); 3892 s_goto (OP_APPLY);
3596 } 3893 }
3597 3894
3598#if USE_TRACING 3895#if USE_TRACING
3599
3600 case OP_TRACING: 3896 case OP_TRACING:
3601 { 3897 {
3602 int tr = SCHEME_V->tracing; 3898 int tr = SCHEME_V->tracing;
3603 3899
3604 SCHEME_V->tracing = ivalue_unchecked (car (args)); 3900 SCHEME_V->tracing = ivalue_unchecked (car (args));
3605 s_return (mk_integer (SCHEME_A_ tr)); 3901 s_return (mk_integer (SCHEME_A_ tr));
3606 } 3902 }
3607
3608#endif 3903#endif
3609 3904
3610 case OP_APPLY: /* apply 'code' to 'args' */ 3905 case OP_APPLY: /* apply 'code' to 'args' */
3611#if USE_TRACING 3906#if USE_TRACING
3612 if (SCHEME_V->tracing) 3907 if (SCHEME_V->tracing)
3666 else if (is_continuation (SCHEME_V->code)) /* CONTINUATION */ 3961 else if (is_continuation (SCHEME_V->code)) /* CONTINUATION */
3667 { 3962 {
3668 ss_set_cont (SCHEME_A_ cont_dump (SCHEME_V->code)); 3963 ss_set_cont (SCHEME_A_ cont_dump (SCHEME_V->code));
3669 s_return (args != NIL ? car (args) : NIL); 3964 s_return (args != NIL ? car (args) : NIL);
3670 } 3965 }
3671 else 3966
3672 Error_0 ("illegal function"); 3967 Error_0 ("illegal function");
3673 3968
3674 case OP_DOMACRO: /* do macro */ 3969 case OP_DOMACRO: /* do macro */
3675 SCHEME_V->code = SCHEME_V->value; 3970 SCHEME_V->code = SCHEME_V->value;
3676 s_goto (OP_EVAL); 3971 s_goto (OP_EVAL);
3677 3972
3798 SCHEME_V->value = SCHEME_V->code; 4093 SCHEME_V->value = SCHEME_V->code;
3799 SCHEME_V->code = is_symbol (car (SCHEME_V->code)) ? cadr (SCHEME_V->code) : car (SCHEME_V->code); 4094 SCHEME_V->code = is_symbol (car (SCHEME_V->code)) ? cadr (SCHEME_V->code) : car (SCHEME_V->code);
3800 s_goto (OP_LET1); 4095 s_goto (OP_LET1);
3801 4096
3802 case OP_LET1: /* let (calculate parameters) */ 4097 case OP_LET1: /* let (calculate parameters) */
4098 case OP_LET1REC: /* letrec (calculate parameters) */
3803 args = cons (SCHEME_V->value, args); 4099 args = cons (SCHEME_V->value, args);
3804 4100
3805 if (is_pair (SCHEME_V->code)) /* continue */ 4101 if (is_pair (SCHEME_V->code)) /* continue */
3806 { 4102 {
3807 if (!is_pair (car (SCHEME_V->code)) || !is_pair (cdar (SCHEME_V->code))) 4103 if (!is_pair (car (SCHEME_V->code)) || !is_pair (cdar (SCHEME_V->code)))
3808 Error_1 ("Bad syntax of binding spec in let :", car (SCHEME_V->code)); 4104 Error_1 ("Bad syntax of binding spec in let/letrec:", car (SCHEME_V->code));
3809 4105
3810 s_save (SCHEME_A_ OP_LET1, args, cdr (SCHEME_V->code)); 4106 s_save (SCHEME_A_ op, args, cdr (SCHEME_V->code));
3811 SCHEME_V->code = cadar (SCHEME_V->code); 4107 SCHEME_V->code = cadar (SCHEME_V->code);
3812 SCHEME_V->args = NIL; 4108 SCHEME_V->args = NIL;
3813 s_goto (OP_EVAL); 4109 s_goto (OP_EVAL);
3814 } 4110 }
3815 else /* end */ 4111
3816 { 4112 /* end */
3817 args = reverse_in_place (SCHEME_A_ NIL, args); 4113 args = reverse_in_place (SCHEME_A_ NIL, args);
3818 SCHEME_V->code = car (args); 4114 SCHEME_V->code = car (args);
3819 SCHEME_V->args = cdr (args); 4115 SCHEME_V->args = cdr (args);
3820 s_goto (OP_LET2); 4116 s_goto (op == OP_LET1 ? OP_LET2 : OP_LET2REC);
3821 }
3822 4117
3823 case OP_LET2: /* let */ 4118 case OP_LET2: /* let */
3824 new_frame_in_env (SCHEME_A_ SCHEME_V->envir); 4119 new_frame_in_env (SCHEME_A_ SCHEME_V->envir);
3825 4120
3826 for (x = is_symbol (car (SCHEME_V->code)) ? cadr (SCHEME_V->code) : car (SCHEME_V->code), y = args; 4121 for (x = is_symbol (car (SCHEME_V->code)) ? cadr (SCHEME_V->code) : car (SCHEME_V->code), y = args;
3830 if (is_symbol (car (SCHEME_V->code))) /* named let */ 4125 if (is_symbol (car (SCHEME_V->code))) /* named let */
3831 { 4126 {
3832 for (x = cadr (SCHEME_V->code), args = NIL; x != NIL; x = cdr (x)) 4127 for (x = cadr (SCHEME_V->code), args = NIL; x != NIL; x = cdr (x))
3833 { 4128 {
3834 if (!is_pair (x)) 4129 if (!is_pair (x))
3835 Error_1 ("Bad syntax of binding in let :", x); 4130 Error_1 ("Bad syntax of binding in let:", x);
3836 4131
3837 if (!is_list (SCHEME_A_ car (x))) 4132 if (!is_list (SCHEME_A_ car (x)))
3838 Error_1 ("Bad syntax of binding in let :", car (x)); 4133 Error_1 ("Bad syntax of binding in let:", car (x));
3839 4134
3840 args = cons (caar (x), args); 4135 args = cons (caar (x), args);
3841 } 4136 }
3842 4137
3843 x = mk_closure (SCHEME_A_ cons (reverse_in_place (SCHEME_A_ NIL, args), cddr (SCHEME_V->code)), 4138 x = mk_closure (SCHEME_A_ cons (reverse_in_place (SCHEME_A_ NIL, args), cddr (SCHEME_V->code)),
3860 SCHEME_V->code = cdr (SCHEME_V->code); 4155 SCHEME_V->code = cdr (SCHEME_V->code);
3861 s_goto (OP_BEGIN); 4156 s_goto (OP_BEGIN);
3862 } 4157 }
3863 4158
3864 if (!is_pair (car (SCHEME_V->code)) || !is_pair (caar (SCHEME_V->code)) || !is_pair (cdaar (SCHEME_V->code))) 4159 if (!is_pair (car (SCHEME_V->code)) || !is_pair (caar (SCHEME_V->code)) || !is_pair (cdaar (SCHEME_V->code)))
3865 Error_1 ("Bad syntax of binding spec in let* :", car (SCHEME_V->code)); 4160 Error_1 ("Bad syntax of binding spec in let*:", car (SCHEME_V->code));
3866 4161
3867 s_save (SCHEME_A_ OP_LET1AST, cdr (SCHEME_V->code), car (SCHEME_V->code)); 4162 s_save (SCHEME_A_ OP_LET1AST, cdr (SCHEME_V->code), car (SCHEME_V->code));
3868 SCHEME_V->code = car (cdaar (SCHEME_V->code)); 4163 SCHEME_V->code = car (cdaar (SCHEME_V->code));
3869 s_goto (OP_EVAL); 4164 s_goto (OP_EVAL);
3870 4165
3881 s_save (SCHEME_A_ OP_LET2AST, args, SCHEME_V->code); 4176 s_save (SCHEME_A_ OP_LET2AST, args, SCHEME_V->code);
3882 SCHEME_V->code = cadar (SCHEME_V->code); 4177 SCHEME_V->code = cadar (SCHEME_V->code);
3883 SCHEME_V->args = NIL; 4178 SCHEME_V->args = NIL;
3884 s_goto (OP_EVAL); 4179 s_goto (OP_EVAL);
3885 } 4180 }
3886 else /* end */ 4181
4182 /* end */
3887 { 4183
3888 SCHEME_V->code = args; 4184 SCHEME_V->code = args;
3889 SCHEME_V->args = NIL; 4185 SCHEME_V->args = NIL;
3890 s_goto (OP_BEGIN); 4186 s_goto (OP_BEGIN);
3891 }
3892 4187
3893 case OP_LET0REC: /* letrec */ 4188 case OP_LET0REC: /* letrec */
3894 new_frame_in_env (SCHEME_A_ SCHEME_V->envir); 4189 new_frame_in_env (SCHEME_A_ SCHEME_V->envir);
3895 SCHEME_V->args = NIL; 4190 SCHEME_V->args = NIL;
3896 SCHEME_V->value = SCHEME_V->code; 4191 SCHEME_V->value = SCHEME_V->code;
3897 SCHEME_V->code = car (SCHEME_V->code); 4192 SCHEME_V->code = car (SCHEME_V->code);
3898 s_goto (OP_LET1REC); 4193 s_goto (OP_LET1REC);
3899 4194
3900 case OP_LET1REC: /* letrec (calculate parameters) */ 4195 /* OP_LET1REC handled by OP_LET1 */
3901 args = cons (SCHEME_V->value, args);
3902
3903 if (is_pair (SCHEME_V->code)) /* continue */
3904 {
3905 if (!is_pair (car (SCHEME_V->code)) || !is_pair (cdar (SCHEME_V->code)))
3906 Error_1 ("Bad syntax of binding spec in letrec :", car (SCHEME_V->code));
3907
3908 s_save (SCHEME_A_ OP_LET1REC, args, cdr (SCHEME_V->code));
3909 SCHEME_V->code = cadar (SCHEME_V->code);
3910 SCHEME_V->args = NIL;
3911 s_goto (OP_EVAL);
3912 }
3913 else /* end */
3914 {
3915 args = reverse_in_place (SCHEME_A_ NIL, args);
3916 SCHEME_V->code = car (args);
3917 SCHEME_V->args = cdr (args);
3918 s_goto (OP_LET2REC);
3919 }
3920 4196
3921 case OP_LET2REC: /* letrec */ 4197 case OP_LET2REC: /* letrec */
3922 for (x = car (SCHEME_V->code), y = args; y != NIL; x = cdr (x), y = cdr (y)) 4198 for (x = car (SCHEME_V->code), y = args; y != NIL; x = cdr (x), y = cdr (y))
3923 new_slot_in_env (SCHEME_A_ caar (x), car (y)); 4199 new_slot_in_env (SCHEME_A_ caar (x), car (y));
3924 4200
5091 case OP_RDSEXPR: 5367 case OP_RDSEXPR:
5092 switch (SCHEME_V->tok) 5368 switch (SCHEME_V->tok)
5093 { 5369 {
5094 case TOK_EOF: 5370 case TOK_EOF:
5095 s_return (S_EOF); 5371 s_return (S_EOF);
5096 /* NOTREACHED */
5097 5372
5098 case TOK_VEC: 5373 case TOK_VEC:
5099 s_save (SCHEME_A_ OP_RDVEC, NIL, NIL); 5374 s_save (SCHEME_A_ OP_RDVEC, NIL, NIL);
5100 /* fall through */ 5375 /* fall through */
5101 5376
5104 5379
5105 if (SCHEME_V->tok == TOK_RPAREN) 5380 if (SCHEME_V->tok == TOK_RPAREN)
5106 s_return (NIL); 5381 s_return (NIL);
5107 else if (SCHEME_V->tok == TOK_DOT) 5382 else if (SCHEME_V->tok == TOK_DOT)
5108 Error_0 ("syntax error: illegal dot expression"); 5383 Error_0 ("syntax error: illegal dot expression");
5109 else 5384
5110 {
5111 SCHEME_V->nesting_stack[SCHEME_V->file_i]++; 5385 SCHEME_V->nesting_stack[SCHEME_V->file_i]++;
5112 s_save (SCHEME_A_ OP_RDLIST, NIL, NIL); 5386 s_save (SCHEME_A_ OP_RDLIST, NIL, NIL);
5113 s_goto (OP_RDSEXPR); 5387 s_goto (OP_RDSEXPR);
5114 }
5115 5388
5116 case TOK_QUOTE: 5389 case TOK_QUOTE:
5117 s_save (SCHEME_A_ OP_RDQUOTE, NIL, NIL); 5390 s_save (SCHEME_A_ OP_RDQUOTE, NIL, NIL);
5118 SCHEME_V->tok = token (SCHEME_A); 5391 SCHEME_V->tok = token (SCHEME_A);
5119 s_goto (OP_RDSEXPR); 5392 s_goto (OP_RDSEXPR);
5125 { 5398 {
5126 s_save (SCHEME_A_ OP_RDQQUOTEVEC, NIL, NIL); 5399 s_save (SCHEME_A_ OP_RDQQUOTEVEC, NIL, NIL);
5127 SCHEME_V->tok = TOK_LPAREN; 5400 SCHEME_V->tok = TOK_LPAREN;
5128 s_goto (OP_RDSEXPR); 5401 s_goto (OP_RDSEXPR);
5129 } 5402 }
5130 else 5403
5131 s_save (SCHEME_A_ OP_RDQQUOTE, NIL, NIL); 5404 s_save (SCHEME_A_ OP_RDQQUOTE, NIL, NIL);
5132
5133 s_goto (OP_RDSEXPR); 5405 s_goto (OP_RDSEXPR);
5134 5406
5135 case TOK_COMMA: 5407 case TOK_COMMA:
5136 s_save (SCHEME_A_ OP_RDUNQUOTE, NIL, NIL); 5408 s_save (SCHEME_A_ OP_RDUNQUOTE, NIL, NIL);
5137 SCHEME_V->tok = token (SCHEME_A); 5409 SCHEME_V->tok = token (SCHEME_A);
5148 case TOK_DOTATOM: 5420 case TOK_DOTATOM:
5149 SCHEME_V->strbuff[0] = '.'; 5421 SCHEME_V->strbuff[0] = '.';
5150 s_return (mk_atom (SCHEME_A_ readstr_upto (SCHEME_A_ 1, DELIMITERS))); 5422 s_return (mk_atom (SCHEME_A_ readstr_upto (SCHEME_A_ 1, DELIMITERS)));
5151 5423
5152 case TOK_STRATOM: 5424 case TOK_STRATOM:
5425 //TODO: haven't checked whether the garbage collector could interfere and free x
5426 gc (SCHEME_A_ NIL, NIL); //TODO: superheavyhanded
5153 x = readstrexp (SCHEME_A_ '|'); 5427 x = readstrexp (SCHEME_A_ '|');
5154 //TODO: haven't checked whether the garbage collector could interfere
5155 s_return (mk_atom (SCHEME_A_ strvalue (x))); 5428 s_return (mk_atom (SCHEME_A_ strvalue (x)));
5156 5429
5157 case TOK_DQUOTE: 5430 case TOK_DQUOTE:
5158 x = readstrexp (SCHEME_A_ '"'); 5431 x = readstrexp (SCHEME_A_ '"');
5159 5432
5167 { 5440 {
5168 pointer f = find_slot_in_env (SCHEME_A_ SCHEME_V->envir, SCHEME_V->SHARP_HOOK, 1); 5441 pointer f = find_slot_in_env (SCHEME_A_ SCHEME_V->envir, SCHEME_V->SHARP_HOOK, 1);
5169 5442
5170 if (f == NIL) 5443 if (f == NIL)
5171 Error_0 ("undefined sharp expression"); 5444 Error_0 ("undefined sharp expression");
5172 else 5445
5173 {
5174 SCHEME_V->code = cons (slot_value_in_env (f), NIL); 5446 SCHEME_V->code = cons (slot_value_in_env (f), NIL);
5175 s_goto (OP_EVAL); 5447 s_goto (OP_EVAL);
5176 }
5177 } 5448 }
5178 5449
5179 case TOK_SHARP_CONST: 5450 case TOK_SHARP_CONST:
5180 if ((x = mk_sharp_const (SCHEME_A_ readstr_upto (SCHEME_A_ 0, DELIMITERS))) == NIL) 5451 if ((x = mk_sharp_const (SCHEME_A_ readstr_upto (SCHEME_A_ 0, DELIMITERS))) == NIL)
5181 Error_0 ("undefined sharp expression"); 5452 Error_0 ("undefined sharp expression");
5182 else 5453
5183 s_return (x); 5454 s_return (x);
5184 5455
5185 default: 5456 default:
5186 Error_0 ("syntax error: illegal token"); 5457 Error_0 ("syntax error: illegal token");
5187 } 5458 }
5188 5459
5743 6014
5744ecb_cold int 6015ecb_cold int
5745scheme_init (SCHEME_P) 6016scheme_init (SCHEME_P)
5746{ 6017{
5747 int i, n = sizeof (dispatch_table) / sizeof (dispatch_table[0]); 6018 int i, n = sizeof (dispatch_table) / sizeof (dispatch_table[0]);
5748 pointer x;
5749 6019
5750 /* this memset is not strictly correct, as we assume (intcache) 6020 /* this memset is not strictly correct, as we assume (intcache)
5751 * that memset 0 will also set pointers to 0, but memset does 6021 * that memset 0 will also set pointers to 0, but memset does
5752 * of course not guarantee that. screw such systems. 6022 * of course not guarantee that. screw such systems.
5753 */ 6023 */
5788 SCHEME_V->envir = NIL; 6058 SCHEME_V->envir = NIL;
5789 SCHEME_V->value = NIL; 6059 SCHEME_V->value = NIL;
5790 SCHEME_V->tracing = 0; 6060 SCHEME_V->tracing = 0;
5791 6061
5792 /* init NIL */ 6062 /* init NIL */
5793 set_typeflag (NIL, T_ATOM | T_MARK); 6063 set_typeflag (NIL, T_SPECIAL | T_ATOM);
5794 set_car (NIL, NIL); 6064 set_car (NIL, NIL);
5795 set_cdr (NIL, NIL); 6065 set_cdr (NIL, NIL);
5796 /* init T */ 6066 /* init T */
5797 set_typeflag (S_T, T_ATOM | T_MARK); 6067 set_typeflag (S_T, T_SPECIAL | T_ATOM);
5798 set_car (S_T, S_T); 6068 set_car (S_T, S_T);
5799 set_cdr (S_T, S_T); 6069 set_cdr (S_T, S_T);
5800 /* init F */ 6070 /* init F */
5801 set_typeflag (S_F, T_ATOM | T_MARK); 6071 set_typeflag (S_F, T_SPECIAL | T_ATOM);
5802 set_car (S_F, S_F); 6072 set_car (S_F, S_F);
5803 set_cdr (S_F, S_F); 6073 set_cdr (S_F, S_F);
5804 /* init EOF_OBJ */ 6074 /* init EOF_OBJ */
5805 set_typeflag (S_EOF, T_ATOM | T_MARK); 6075 set_typeflag (S_EOF, T_SPECIAL | T_ATOM);
5806 set_car (S_EOF, S_EOF); 6076 set_car (S_EOF, S_EOF);
5807 set_cdr (S_EOF, S_EOF); 6077 set_cdr (S_EOF, S_EOF);
5808 /* init sink */ 6078 /* init sink */
5809 set_typeflag (S_SINK, T_PAIR | T_MARK); 6079 set_typeflag (S_SINK, T_PAIR);
5810 set_car (S_SINK, NIL); 6080 set_car (S_SINK, NIL);
5811 6081
5812 /* init c_nest */ 6082 /* init c_nest */
5813 SCHEME_V->c_nest = NIL; 6083 SCHEME_V->c_nest = NIL;
5814 6084
5815 SCHEME_V->oblist = oblist_initial_value (SCHEME_A); 6085 SCHEME_V->oblist = oblist_initial_value (SCHEME_A);
5816 /* init global_env */ 6086 /* init global_env */
5817 new_frame_in_env (SCHEME_A_ NIL); 6087 new_frame_in_env (SCHEME_A_ NIL);
5818 SCHEME_V->global_env = SCHEME_V->envir; 6088 SCHEME_V->global_env = SCHEME_V->envir;
5819 /* init else */ 6089 /* init else */
5820 x = mk_symbol (SCHEME_A_ "else"); 6090 new_slot_in_env (SCHEME_A_ mk_symbol (SCHEME_A_ "else"), S_T);
5821 new_slot_in_env (SCHEME_A_ x, S_T);
5822 6091
5823 { 6092 {
5824 static const char *syntax_names[] = { 6093 static const char *syntax_names[] = {
5825 "lambda", "quote", "define", "if", "begin", "set!", 6094 "lambda", "quote", "define", "if", "begin", "set!",
5826 "let", "let*", "letrec", "cond", "delay", "and", 6095 "let", "let*", "letrec", "cond", "delay", "and",

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines