make gensym API public
This commit is contained in:
parent
68f0eb97c9
commit
944111ba09
|
@ -107,6 +107,8 @@ bool pic_equal_p(pic_state *, pic_value, pic_value);
|
||||||
|
|
||||||
pic_sym pic_intern_cstr(pic_state *, const char *);
|
pic_sym pic_intern_cstr(pic_state *, const char *);
|
||||||
const char *pic_symbol_name(pic_state *, pic_sym);
|
const char *pic_symbol_name(pic_state *, pic_sym);
|
||||||
|
pic_sym pic_gensym(pic_state *, pic_sym);
|
||||||
|
bool pic_interned_p(pic_state *, pic_sym);
|
||||||
|
|
||||||
struct pic_string *pic_str_new(pic_state *, const char *, size_t);
|
struct pic_string *pic_str_new(pic_state *, const char *, size_t);
|
||||||
struct pic_string *pic_str_new_cstr(pic_state *, const char *);
|
struct pic_string *pic_str_new_cstr(pic_state *, const char *);
|
||||||
|
|
48
src/macro.c
48
src/macro.c
|
@ -1,7 +1,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "picrin.h"
|
#include "picrin.h"
|
||||||
#include "picrin/pair.h"
|
#include "picrin/pair.h"
|
||||||
|
@ -15,41 +14,6 @@
|
||||||
static pic_value macroexpand(pic_state *, pic_value, struct pic_senv *);
|
static pic_value macroexpand(pic_state *, pic_value, struct pic_senv *);
|
||||||
static pic_value macroexpand_list(pic_state *, pic_value, struct pic_senv *);
|
static pic_value macroexpand_list(pic_state *, pic_value, struct pic_senv *);
|
||||||
|
|
||||||
static pic_sym
|
|
||||||
new_uniq_sym(pic_state *pic, pic_sym base)
|
|
||||||
{
|
|
||||||
int s = ++pic->uniq_sym_count;
|
|
||||||
char *str;
|
|
||||||
pic_sym uniq;
|
|
||||||
|
|
||||||
str = (char *)pic_alloc(pic, strlen(pic_symbol_name(pic, base)) + (int)log10(s) + 3);
|
|
||||||
sprintf(str, "%s@%d", pic_symbol_name(pic, base), s);
|
|
||||||
|
|
||||||
/* don't put the symbol to pic->sym_tbl to keep it uninterned */
|
|
||||||
if (pic->slen >= pic->scapa) {
|
|
||||||
pic->scapa *= 2;
|
|
||||||
pic->sym_pool = pic_realloc(pic, pic->sym_pool, sizeof(const char *) * pic->scapa);
|
|
||||||
}
|
|
||||||
uniq = pic->slen++;
|
|
||||||
pic->sym_pool[uniq] = str;
|
|
||||||
|
|
||||||
return uniq;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
uniq_sym_p(pic_state *pic, pic_sym sym)
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
assert(sym >= 0);
|
|
||||||
|
|
||||||
name = pic->sym_pool[sym];
|
|
||||||
if (sym == pic_intern_cstr(pic, name))
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pic_senv *
|
struct pic_senv *
|
||||||
pic_null_syntactic_env(pic_state *pic)
|
pic_null_syntactic_env(pic_state *pic)
|
||||||
{
|
{
|
||||||
|
@ -132,14 +96,14 @@ new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up)
|
||||||
pic_error(pic, "syntax error");
|
pic_error(pic, "syntax error");
|
||||||
}
|
}
|
||||||
sym = pic_sym(v);
|
sym = pic_sym(v);
|
||||||
xh_put(senv->tbl, pic_symbol_name(pic, sym), (int)new_uniq_sym(pic, sym));
|
xh_put(senv->tbl, pic_symbol_name(pic, sym), (int)pic_gensym(pic, sym));
|
||||||
}
|
}
|
||||||
if (! pic_symbol_p(a)) {
|
if (! pic_symbol_p(a)) {
|
||||||
a = macroexpand(pic, a, up);
|
a = macroexpand(pic, a, up);
|
||||||
}
|
}
|
||||||
if (pic_symbol_p(a)) {
|
if (pic_symbol_p(a)) {
|
||||||
sym = pic_sym(a);
|
sym = pic_sym(a);
|
||||||
xh_put(senv->tbl, pic_symbol_name(pic, sym), (int)new_uniq_sym(pic, sym));
|
xh_put(senv->tbl, pic_symbol_name(pic, sym), (int)pic_gensym(pic, sym));
|
||||||
}
|
}
|
||||||
else if (! pic_nil_p(a)) {
|
else if (! pic_nil_p(a)) {
|
||||||
pic_error(pic, "syntax error");
|
pic_error(pic, "syntax error");
|
||||||
|
@ -308,7 +272,7 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
||||||
struct xh_entry *e;
|
struct xh_entry *e;
|
||||||
pic_sym uniq;
|
pic_sym uniq;
|
||||||
|
|
||||||
if (uniq_sym_p(pic, pic_sym(expr))) {
|
if (! pic_interned_p(pic, pic_sym(expr))) {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -322,7 +286,7 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
||||||
break;
|
break;
|
||||||
senv = senv->up;
|
senv = senv->up;
|
||||||
}
|
}
|
||||||
uniq = new_uniq_sym(pic, pic_sym(expr));
|
uniq = pic_gensym(pic, pic_sym(expr));
|
||||||
xh_put(senv->tbl, pic_symbol_name(pic, pic_sym(expr)), (int)uniq);
|
xh_put(senv->tbl, pic_symbol_name(pic, pic_sym(expr)), (int)uniq);
|
||||||
return pic_symbol_value(uniq);
|
return pic_symbol_value(uniq);
|
||||||
}
|
}
|
||||||
|
@ -515,7 +479,7 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
||||||
pic_error(pic, "binding to non-symbol object");
|
pic_error(pic, "binding to non-symbol object");
|
||||||
}
|
}
|
||||||
sym = pic_sym(a);
|
sym = pic_sym(a);
|
||||||
xh_put(senv->tbl, pic_symbol_name(pic, sym), (int)new_uniq_sym(pic, sym));
|
xh_put(senv->tbl, pic_symbol_name(pic, sym), (int)pic_gensym(pic, sym));
|
||||||
|
|
||||||
/* binding value */
|
/* binding value */
|
||||||
v = pic_cons(pic, pic_symbol_value(pic_syntax(car)->sym),
|
v = pic_cons(pic, pic_symbol_value(pic_syntax(car)->sym),
|
||||||
|
@ -534,7 +498,7 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
||||||
if (! pic_symbol_p(var)) {
|
if (! pic_symbol_p(var)) {
|
||||||
pic_error(pic, "binding to non-symbol object");
|
pic_error(pic, "binding to non-symbol object");
|
||||||
}
|
}
|
||||||
uniq = new_uniq_sym(pic, pic_sym(var));
|
uniq = pic_gensym(pic, pic_sym(var));
|
||||||
xh_put(senv->tbl, pic_symbol_name(pic, pic_sym(var)), (int)uniq);
|
xh_put(senv->tbl, pic_symbol_name(pic, pic_sym(var)), (int)uniq);
|
||||||
}
|
}
|
||||||
FALLTHROUGH;
|
FALLTHROUGH;
|
||||||
|
|
31
src/symbol.c
31
src/symbol.c
|
@ -1,5 +1,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "picrin.h"
|
#include "picrin.h"
|
||||||
#include "xhash/xhash.h"
|
#include "xhash/xhash.h"
|
||||||
|
@ -30,6 +32,35 @@ pic_intern_cstr(pic_state *pic, const char *str)
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pic_sym
|
||||||
|
pic_gensym(pic_state *pic, pic_sym base)
|
||||||
|
{
|
||||||
|
int s = ++pic->uniq_sym_count;
|
||||||
|
char *str;
|
||||||
|
pic_sym uniq;
|
||||||
|
|
||||||
|
str = (char *)pic_alloc(pic, strlen(pic_symbol_name(pic, base)) + (int)log10(s) + 3);
|
||||||
|
sprintf(str, "%s@%d", pic_symbol_name(pic, base), s);
|
||||||
|
|
||||||
|
/* don't put the symbol to pic->sym_tbl to keep it uninterned */
|
||||||
|
if (pic->slen >= pic->scapa) {
|
||||||
|
pic->scapa *= 2;
|
||||||
|
pic->sym_pool = pic_realloc(pic, pic->sym_pool, sizeof(const char *) * pic->scapa);
|
||||||
|
}
|
||||||
|
uniq = pic->slen++;
|
||||||
|
pic->sym_pool[uniq] = str;
|
||||||
|
|
||||||
|
return uniq;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
pic_interned_p(pic_state *pic, pic_sym sym)
|
||||||
|
{
|
||||||
|
assert(sym >= 0);
|
||||||
|
|
||||||
|
return sym == pic_intern_cstr(pic, pic_symbol_name(pic, sym));
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
pic_symbol_name(pic_state *pic, pic_sym sym)
|
pic_symbol_name(pic_state *pic, pic_sym sym)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue