mes.c, mes.mes: support quasiquote, unquote.
This commit is contained in:
parent
1513c0d5fb
commit
989cbab16a
119
mes.c
119
mes.c
|
@ -37,6 +37,7 @@
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
#define MACROS 1
|
#define MACROS 1
|
||||||
|
#define QUASIQUOTE 1
|
||||||
|
|
||||||
#ifndef QUOTE_SUGAR
|
#ifndef QUOTE_SUGAR
|
||||||
#define QUOTE_SUGAR 1
|
#define QUOTE_SUGAR 1
|
||||||
|
@ -74,7 +75,13 @@ scm scm_label = {ATOM, "label"};
|
||||||
scm scm_unspecified = {ATOM, "*unspecified*"};
|
scm scm_unspecified = {ATOM, "*unspecified*"};
|
||||||
scm scm_symbol_cond = {ATOM, "cond"};
|
scm scm_symbol_cond = {ATOM, "cond"};
|
||||||
scm scm_symbol_quote = {ATOM, "quote"};
|
scm scm_symbol_quote = {ATOM, "quote"};
|
||||||
|
#if QUASIQUOTE
|
||||||
|
scm scm_symbol_quasiquote = {ATOM, "quasiquote"};
|
||||||
|
scm scm_symbol_unquote = {ATOM, "unquote"};
|
||||||
|
#endif
|
||||||
|
#if MACROS
|
||||||
scm scm_macro = {ATOM, "*macro*"};
|
scm scm_macro = {ATOM, "*macro*"};
|
||||||
|
#endif
|
||||||
|
|
||||||
// PRIMITIVES
|
// PRIMITIVES
|
||||||
|
|
||||||
|
@ -147,6 +154,25 @@ quote (scm *x)
|
||||||
return cons (&scm_quote, x);
|
return cons (&scm_quote, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QUASIQUOTE
|
||||||
|
scm scm_unquote;
|
||||||
|
scm *
|
||||||
|
unquote (scm *x)
|
||||||
|
{
|
||||||
|
return cons (&scm_unquote, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
scm scm_quasiquote;
|
||||||
|
scm *
|
||||||
|
quasiquote (scm *x)
|
||||||
|
{
|
||||||
|
return cons (&scm_quasiquote, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
scm *eval_quasiquote (scm *, scm *);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//Library functions
|
//Library functions
|
||||||
scm scm_read;
|
scm scm_read;
|
||||||
|
|
||||||
|
@ -300,6 +326,21 @@ eval_ (scm *e, scm *a)
|
||||||
#endif // MACROS
|
#endif // MACROS
|
||||||
if (car (e) == &scm_symbol_quote)
|
if (car (e) == &scm_symbol_quote)
|
||||||
return cadr (e);
|
return cadr (e);
|
||||||
|
#if QUASIQUOTE
|
||||||
|
else if (car (e) == &scm_symbol_unquote)
|
||||||
|
return eval (cadr (e), a);
|
||||||
|
else if (car (e) == &scm_symbol_quasiquote) {
|
||||||
|
#if DEBUG
|
||||||
|
printf ("cadr e:");
|
||||||
|
display (cadr (e));
|
||||||
|
puts ("");
|
||||||
|
printf ("qq:");
|
||||||
|
display (eval_quasiquote (cadr (e), a));
|
||||||
|
puts ("");
|
||||||
|
#endif // DEBUG
|
||||||
|
return eval_quasiquote (cadr (e), a);
|
||||||
|
}
|
||||||
|
#endif // QUASIQUOTE
|
||||||
else if (car (e) == &scm_symbol_cond)
|
else if (car (e) == &scm_symbol_cond)
|
||||||
return evcon (cdr (e), a);
|
return evcon (cdr (e), a);
|
||||||
#if MACROS
|
#if MACROS
|
||||||
|
@ -376,6 +417,11 @@ scm scm_null_p = {FUNCTION1, "null", .function1 = &null_p};
|
||||||
scm scm_pair_p = {FUNCTION1, "pair", .function1 = &pair_p};
|
scm scm_pair_p = {FUNCTION1, "pair", .function1 = &pair_p};
|
||||||
scm scm_quote = {FUNCTION1, "quote", .function1 = "e};
|
scm scm_quote = {FUNCTION1, "quote", .function1 = "e};
|
||||||
|
|
||||||
|
#if QUASIQUOTE
|
||||||
|
scm scm_unquote = {FUNCTION1, "unquote", .function1 = &unquote};
|
||||||
|
scm scm_quasiquote = {FUNCTION1, "quasiquote", .function1 = &quasiquote};
|
||||||
|
#endif
|
||||||
|
|
||||||
scm scm_eval = {FUNCTION2, .name="eval", .function2 = &eval};
|
scm scm_eval = {FUNCTION2, .name="eval", .function2 = &eval};
|
||||||
scm scm_apply = {FUNCTION3, .name="apply", .function3 = &apply};
|
scm scm_apply = {FUNCTION3, .name="apply", .function3 = &apply};
|
||||||
|
|
||||||
|
@ -481,9 +527,25 @@ lookup (char *x, scm *a)
|
||||||
if (!strcmp (x, scm_label.name)) return &scm_label;
|
if (!strcmp (x, scm_label.name)) return &scm_label;
|
||||||
if (!strcmp (x, scm_nil.name)) return &scm_nil;
|
if (!strcmp (x, scm_nil.name)) return &scm_nil;
|
||||||
|
|
||||||
|
#if QUASIQUOTE
|
||||||
|
if (*x == '`') return &scm_symbol_quasiquote;
|
||||||
|
if (*x == ',') return &scm_symbol_unquote;
|
||||||
|
if (!strcmp (x, scm_symbol_unquote.name)) return &scm_symbol_unquote;
|
||||||
|
if (!strcmp (x, scm_symbol_quasiquote.name)) return &scm_symbol_quasiquote;
|
||||||
|
#endif
|
||||||
|
|
||||||
return make_atom (x);
|
return make_atom (x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scm *
|
||||||
|
lookup_char (int c, scm *a)
|
||||||
|
{
|
||||||
|
char buf[2];
|
||||||
|
buf[0] = c;
|
||||||
|
buf[1] = 0;
|
||||||
|
return lookup (buf, a);
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
list2str (scm *l)
|
list2str (scm *l)
|
||||||
{
|
{
|
||||||
|
@ -535,6 +597,18 @@ display_helper (scm *x, bool cont, char *sep, bool quote)
|
||||||
printf ("'");
|
printf ("'");
|
||||||
return display_helper (car (cdr (x)), cont, "", true);
|
return display_helper (car (cdr (x)), cont, "", true);
|
||||||
}
|
}
|
||||||
|
#if QUASIQUOTE
|
||||||
|
if (car (x) == &scm_symbol_quasiquote
|
||||||
|
|| car (x) == &scm_quasiquote) {
|
||||||
|
printf ("`");
|
||||||
|
return display_helper (car (cdr (x)), cont, "", true);
|
||||||
|
}
|
||||||
|
if (car (x) == &scm_symbol_unquote
|
||||||
|
|| car (x) == &scm_unquote) {
|
||||||
|
printf (",");
|
||||||
|
return display_helper (car (cdr (x)), cont, "", true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
if (!cont) printf ("(");
|
if (!cont) printf ("(");
|
||||||
display (car (x));
|
display (car (x));
|
||||||
|
@ -618,7 +692,13 @@ readword (int c, char* w, scm *a)
|
||||||
if (c == '(') {ungetchar (c); return lookup (w, a);}
|
if (c == '(') {ungetchar (c); return lookup (w, a);}
|
||||||
if (c == ')' && !w) {ungetchar (c); return &scm_nil;}
|
if (c == ')' && !w) {ungetchar (c); return &scm_nil;}
|
||||||
if (c == ')') {ungetchar (c); return lookup (w, a);}
|
if (c == ')') {ungetchar (c); return lookup (w, a);}
|
||||||
if (c == '\'' && !w) {return cons (lookup ("'", a),
|
if ((c == '\''
|
||||||
|
#if QUASIQUOTE
|
||||||
|
|| c == '`'
|
||||||
|
|| c == ','
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
&& !w) {return cons (lookup_char (c, a),
|
||||||
cons (readword (getchar (), w, a),
|
cons (readword (getchar (), w, a),
|
||||||
&scm_nil));}
|
&scm_nil));}
|
||||||
if (c == ';') {readcomment (c); return readword ('\n', w, a);}
|
if (c == ';') {readcomment (c); return readword ('\n', w, a);}
|
||||||
|
@ -690,6 +770,35 @@ minus (scm *a, scm *b)
|
||||||
scm scm_less_p = {FUNCTION2, .name="<", .function2 = &less_p};
|
scm scm_less_p = {FUNCTION2, .name="<", .function2 = &less_p};
|
||||||
scm scm_minus = {FUNCTION2, .name="-", .function2 = &minus};
|
scm scm_minus = {FUNCTION2, .name="-", .function2 = &minus};
|
||||||
|
|
||||||
|
#if QUASIQUOTE
|
||||||
|
scm *
|
||||||
|
eval_quasiquote (scm *e, scm *a)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf ("\nc:eval_quasiquote e=");
|
||||||
|
display (e);
|
||||||
|
if (pair_p (e) == &scm_t) {
|
||||||
|
printf ("\ncar (e)=");
|
||||||
|
display (car (e));
|
||||||
|
printf (" atom=");
|
||||||
|
display (atom_p (car (e)));
|
||||||
|
}
|
||||||
|
puts ("");
|
||||||
|
#endif
|
||||||
|
if (e == &scm_nil) return e;
|
||||||
|
else if (atom_p (e) == &scm_t) return e;
|
||||||
|
else if (atom_p (car (e)) == &scm_t)
|
||||||
|
return cons (car (e), eval_quasiquote (cdr (e), a));
|
||||||
|
else if (eq_p (caar (e), &scm_symbol_unquote) == &scm_t)
|
||||||
|
return cons (eval (cadar (e), a), &scm_nil);
|
||||||
|
else if (eq_p (caar (e), &scm_symbol_quote) == &scm_t)
|
||||||
|
return cons (cadar (e), &scm_nil);
|
||||||
|
else if (eq_p (caar (e), &scm_symbol_quasiquote) == &scm_t)
|
||||||
|
return cdar (e);
|
||||||
|
return cons (car (e), eval_quasiquote (cdr (e), a));
|
||||||
|
}
|
||||||
|
scm scm_eval_quasiquote = {FUNCTION2, .name="c:eval-quasiquote", .function2 = &eval_quasiquote};
|
||||||
|
#endif
|
||||||
|
|
||||||
scm *
|
scm *
|
||||||
add_environment (scm *a, char *name, scm* x)
|
add_environment (scm *a, char *name, scm* x)
|
||||||
|
@ -722,6 +831,14 @@ initial_environment ()
|
||||||
a = add_environment (a, "quote", &scm_quote);
|
a = add_environment (a, "quote", &scm_quote);
|
||||||
a = add_environment (a, "'", &scm_quote);
|
a = add_environment (a, "'", &scm_quote);
|
||||||
|
|
||||||
|
#if QUASIQUOTE
|
||||||
|
a = add_environment (a, "quasiquote", &scm_quasiquote);
|
||||||
|
a = add_environment (a, "unquote", &scm_unquote);
|
||||||
|
a = add_environment (a, ",", &scm_unquote);
|
||||||
|
a = add_environment (a, "`", &scm_quasiquote);
|
||||||
|
a = add_environment (a, "eval-quasiquote", &scm_eval_quasiquote);
|
||||||
|
#endif
|
||||||
|
|
||||||
a = add_environment (a, "evlis", &scm_evlis);
|
a = add_environment (a, "evlis", &scm_evlis);
|
||||||
a = add_environment (a, "evcon", &scm_evcon);
|
a = add_environment (a, "evcon", &scm_evcon);
|
||||||
a = add_environment (a, "pairlis", &scm_pairlis);
|
a = add_environment (a, "pairlis", &scm_pairlis);
|
||||||
|
|
14
mes.mes
14
mes.mes
|
@ -124,6 +124,8 @@
|
||||||
((atom (car e))
|
((atom (car e))
|
||||||
(cond
|
(cond
|
||||||
((eq (car e) 'quote) (cadr e))
|
((eq (car e) 'quote) (cadr e))
|
||||||
|
((eq (car e) 'unquote) (eval (cadr e) a))
|
||||||
|
((eq (car e) 'quasiquote) (eval-quasiquote (cadr e) a))
|
||||||
((eq (car e) 'cond) (evcon (cdr e) a))
|
((eq (car e) 'cond) (evcon (cdr e) a))
|
||||||
((pair (assoc (car e) (cdr (assoc '*macro* a))))
|
((pair (assoc (car e) (cdr (assoc '*macro* a))))
|
||||||
(c:eval
|
(c:eval
|
||||||
|
@ -135,6 +137,18 @@
|
||||||
(#t (apply (car e) (evlis (cdr e) a) a))))
|
(#t (apply (car e) (evlis (cdr e) a) a))))
|
||||||
(#t (apply (car e) (evlis (cdr e) a) a))))
|
(#t (apply (car e) (evlis (cdr e) a) a))))
|
||||||
|
|
||||||
|
(define (eval-quasiquote e a)
|
||||||
|
;; (display 'mes-eval-quasiquote:)
|
||||||
|
;; (display e)
|
||||||
|
;; (newline)
|
||||||
|
(cond ((null e) e)
|
||||||
|
((atom e) e)
|
||||||
|
((atom (car e)) (cons (car e) (eval-quasiquote (cdr e) a)))
|
||||||
|
((eq (caar e) 'unquote) (cons (eval (cadar e) a) '()))
|
||||||
|
((eq (caar e) 'quote) (cons (cadar e) '()))
|
||||||
|
((eq (caar e) 'quasiquote) (cons (cadar e) '()))
|
||||||
|
(#t (cons (car e) (eval-quasiquote (cdr e) a)))))
|
||||||
|
|
||||||
;; readenv et al works, but slows down dramatically
|
;; readenv et al works, but slows down dramatically
|
||||||
(define (DISABLED-readenv a)
|
(define (DISABLED-readenv a)
|
||||||
(readword (getchar) '() a))
|
(readword (getchar) '() a))
|
||||||
|
|
Loading…
Reference in a new issue