Squashed 'extlib/benz/' changes from 414f790..057b5f2
057b5f2 Merge pull request #245 from picrin-scheme/heap-symbol
c91f6cd [bugfix] build failure in debug mode
b1849c4 pic_sym is not a pointer
e353b07 s/pic_sym/pic_sym_ptr/g
a11fb91 [bugfix] irep->name is missed to mark
1820a25 [bugfix] wrong type specified for cxt->syms
b8d2b8e better error messages against invalid use of auxiliary syntax
d9ade33 mark only interned symbols and some specisl uninterned symbols
da2217b move symbol constants to pic_state
78b035b [bugfix] pic_intern must count up reference of the return value
bbdc663 rename internal object
ba01821 s/SYMBOL_P/SYMBOLP/g, s/PAIR_P/PAIRP/g
1af32d1 improve error message
dd09fbf don't malloc in pic_interned_p
7f51070 turn on GC
7460e81 add gc on/off flag
f3742db move symbol-related macros to symbol.h
ded6759 remove pic_sym_value
ec97d07 remove pic_symbol_value
28bd059 heap symbol seems working (with GC stopped)
e0d6fe9 change pic_intern interface
6750693 remove pic_ungensym
4ea7d3c add irep->syms
ede7a99 use dictionary for senv->map
b3cb50c use dictionaries for temporary import table
fc698b5 use dictionary for rec->data
1b814d4 use dictionary for lib->exports
7ae1af4 use dictionaries for pic->globals and pic->macros
74f9979 remove 'struct pic_macro'. define-syntax spec is changed.
86136c5 some procedures are moved to contrib/
da99761 gather all includes of standard headers into picrin.h
7df8d77 add dictionary-map and dictionary-for-each
b625ff8 revert 48f0ec90
. dicitonary is now symbol-to-object structure
f7657d7 [prepare] dictionary is to be changed to have only symbols for its keys
git-subtree-dir: extlib/benz
git-subtree-split: 057b5f29110ab3f75513573d291ea18acb782357
This commit is contained in:
parent
536d59c7d4
commit
5b7f5ad1f9
4
attr.c
4
attr.c
|
@ -24,13 +24,13 @@ pic_attr(pic_state *pic, pic_value obj)
|
|||
pic_value
|
||||
pic_attr_ref(pic_state *pic, pic_value obj, const char *key)
|
||||
{
|
||||
return pic_dict_ref(pic, pic_attr(pic, obj), pic_sym_value(pic_intern_cstr(pic, key)));
|
||||
return pic_dict_ref(pic, pic_attr(pic, obj), pic_intern_cstr(pic, key));
|
||||
}
|
||||
|
||||
void
|
||||
pic_attr_set(pic_state *pic, pic_value obj, const char *key, pic_value v)
|
||||
{
|
||||
pic_dict_set(pic, pic_attr(pic, obj), pic_sym_value(pic_intern_cstr(pic, key)), v);
|
||||
pic_dict_set(pic, pic_attr(pic, obj), pic_intern_cstr(pic, key), v);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
|
2
blob.c
2
blob.c
|
@ -2,8 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/blob.h"
|
||||
#include "picrin/pair.h"
|
||||
|
|
2
bool.c
2
bool.c
|
@ -2,8 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/pair.h"
|
||||
#include "picrin/vector.h"
|
||||
|
|
34
boot.c
34
boot.c
|
@ -24,7 +24,8 @@ my $src = <<'EOL';
|
|||
val))))))
|
||||
|
||||
(define (er-macro-transformer f)
|
||||
(lambda (expr use-env mac-env)
|
||||
(lambda (mac-env)
|
||||
(lambda (expr use-env)
|
||||
|
||||
(define rename
|
||||
(memoize
|
||||
|
@ -38,7 +39,7 @@ my $src = <<'EOL';
|
|||
#f
|
||||
(identifier=? use-env x use-env y))))
|
||||
|
||||
(f expr rename compare)))
|
||||
(f expr rename compare))))
|
||||
|
||||
(define-syntax syntax-error
|
||||
(er-macro-transformer
|
||||
|
@ -50,7 +51,8 @@ my $src = <<'EOL';
|
|||
(lambda (expr r c)
|
||||
(list (r 'define-syntax) (cadr expr)
|
||||
(list (r 'lambda) '_
|
||||
(list (r 'error) "invalid use of auxiliary syntax"))))))
|
||||
(list (r 'lambda) '_
|
||||
(list (r 'error) (list (r 'string-append) "invalid use of auxiliary syntax: '" (symbol->string (cadr expr)) "'"))))))))
|
||||
|
||||
(define-auxiliary-syntax else)
|
||||
(define-auxiliary-syntax =>)
|
||||
|
@ -308,13 +310,10 @@ my $src = <<'EOL';
|
|||
(let* ((old-bindings
|
||||
(current-dynamic-environment))
|
||||
(binding
|
||||
(let ((dict (dictionary)))
|
||||
(for-each
|
||||
(lambda (parameter value)
|
||||
(dictionary-set! dict parameter (list (parameter value #f))))
|
||||
(map (lambda (parameter value)
|
||||
(cons parameter (parameter value #f)))
|
||||
parameters
|
||||
values)
|
||||
dict))
|
||||
values))
|
||||
(new-bindings
|
||||
(cons binding old-bindings)))
|
||||
(dynamic-wind
|
||||
|
@ -425,7 +424,8 @@ const char pic_boot[] =
|
|||
" val))))))\n"
|
||||
"\n"
|
||||
" (define (er-macro-transformer f)\n"
|
||||
" (lambda (expr use-env mac-env)\n"
|
||||
" (lambda (mac-env)\n"
|
||||
" (lambda (expr use-env)\n"
|
||||
"\n"
|
||||
" (define rename\n"
|
||||
" (memoize\n"
|
||||
|
@ -439,7 +439,7 @@ const char pic_boot[] =
|
|||
" #f\n"
|
||||
" (identifier=? use-env x use-env y))))\n"
|
||||
"\n"
|
||||
" (f expr rename compare)))\n"
|
||||
" (f expr rename compare))))\n"
|
||||
"\n"
|
||||
" (define-syntax syntax-error\n"
|
||||
" (er-macro-transformer\n"
|
||||
|
@ -451,7 +451,8 @@ const char pic_boot[] =
|
|||
" (lambda (expr r c)\n"
|
||||
" (list (r 'define-syntax) (cadr expr)\n"
|
||||
" (list (r 'lambda) '_\n"
|
||||
" (list (r 'error) \"invalid use of auxiliary syntax\"))))))\n"
|
||||
" (list (r 'lambda) '_\n"
|
||||
" (list (r 'error) (list (r 'string-append) \"invalid use of auxiliary syntax: '\" (symbol->string (cadr expr)) \"'\"))))))))\n"
|
||||
"\n"
|
||||
" (define-auxiliary-syntax else)\n"
|
||||
" (define-auxiliary-syntax =>)\n"
|
||||
|
@ -709,13 +710,10 @@ const char pic_boot[] =
|
|||
" (let* ((old-bindings\n"
|
||||
" (current-dynamic-environment))\n"
|
||||
" (binding\n"
|
||||
" (let ((dict (dictionary)))\n"
|
||||
" (for-each\n"
|
||||
" (lambda (parameter value)\n"
|
||||
" (dictionary-set! dict parameter (list (parameter value #f))))\n"
|
||||
" (map (lambda (parameter value)\n"
|
||||
" (cons parameter (parameter value #f)))\n"
|
||||
" parameters\n"
|
||||
" values)\n"
|
||||
" dict))\n"
|
||||
" values))\n"
|
||||
" (new-bindings\n"
|
||||
" (cons binding old-bindings)))\n"
|
||||
" (dynamic-wind\n"
|
||||
|
|
299
codegen.c
299
codegen.c
|
@ -8,6 +8,8 @@
|
|||
#include "picrin/proc.h"
|
||||
#include "picrin/lib.h"
|
||||
#include "picrin/macro.h"
|
||||
#include "picrin/dict.h"
|
||||
#include "picrin/symbol.h"
|
||||
|
||||
#if PIC_NONE_IS_FALSE
|
||||
# define OP_PUSHNONE OP_PUSHFALSE
|
||||
|
@ -34,13 +36,11 @@ typedef struct analyze_scope {
|
|||
typedef struct analyze_state {
|
||||
pic_state *pic;
|
||||
analyze_scope *scope;
|
||||
pic_sym rCONS, rCAR, rCDR, rNILP;
|
||||
pic_sym rSYMBOL_P, rPAIR_P;
|
||||
pic_sym rADD, rSUB, rMUL, rDIV;
|
||||
pic_sym rEQ, rLT, rLE, rGT, rGE, rNOT;
|
||||
pic_sym rVALUES, rCALL_WITH_VALUES;
|
||||
pic_sym sCALL, sTAILCALL, sCALL_WITH_VALUES, sTAILCALL_WITH_VALUES;
|
||||
pic_sym sGREF, sLREF, sCREF, sRETURN;
|
||||
pic_sym *rCONS, *rCAR, *rCDR, *rNILP;
|
||||
pic_sym *rSYMBOLP, *rPAIRP;
|
||||
pic_sym *rADD, *rSUB, *rMUL, *rDIV;
|
||||
pic_sym *rEQ, *rLT, *rLE, *rGT, *rGE, *rNOT;
|
||||
pic_sym *rVALUES, *rCALL_WITH_VALUES;
|
||||
} analyze_state;
|
||||
|
||||
static bool push_scope(analyze_state *, pic_value);
|
||||
|
@ -51,7 +51,7 @@ static void pop_scope(analyze_state *);
|
|||
} while (0)
|
||||
|
||||
#define register_renamed_symbol(pic, state, slot, lib, id) do { \
|
||||
pic_sym sym, gsym; \
|
||||
pic_sym *sym, *gsym; \
|
||||
sym = pic_intern_cstr(pic, id); \
|
||||
if (! pic_find_rename(pic, lib->env, sym, &gsym)) { \
|
||||
pic_errorf(pic, "internal error! native VM procedure not found: %s", id); \
|
||||
|
@ -63,7 +63,7 @@ static analyze_state *
|
|||
new_analyze_state(pic_state *pic)
|
||||
{
|
||||
analyze_state *state;
|
||||
xh_entry *it;
|
||||
pic_sym *sym;
|
||||
|
||||
state = pic_alloc(pic, sizeof(analyze_state));
|
||||
state->pic = pic;
|
||||
|
@ -74,8 +74,8 @@ new_analyze_state(pic_state *pic)
|
|||
register_renamed_symbol(pic, state, rCAR, pic->PICRIN_BASE, "car");
|
||||
register_renamed_symbol(pic, state, rCDR, pic->PICRIN_BASE, "cdr");
|
||||
register_renamed_symbol(pic, state, rNILP, pic->PICRIN_BASE, "null?");
|
||||
register_renamed_symbol(pic, state, rSYMBOL_P, pic->PICRIN_BASE, "symbol?");
|
||||
register_renamed_symbol(pic, state, rPAIR_P, pic->PICRIN_BASE, "pair?");
|
||||
register_renamed_symbol(pic, state, rSYMBOLP, pic->PICRIN_BASE, "symbol?");
|
||||
register_renamed_symbol(pic, state, rPAIRP, pic->PICRIN_BASE, "pair?");
|
||||
register_renamed_symbol(pic, state, rADD, pic->PICRIN_BASE, "+");
|
||||
register_renamed_symbol(pic, state, rSUB, pic->PICRIN_BASE, "-");
|
||||
register_renamed_symbol(pic, state, rMUL, pic->PICRIN_BASE, "*");
|
||||
|
@ -89,20 +89,10 @@ new_analyze_state(pic_state *pic)
|
|||
register_renamed_symbol(pic, state, rVALUES, pic->PICRIN_BASE, "values");
|
||||
register_renamed_symbol(pic, state, rCALL_WITH_VALUES, pic->PICRIN_BASE, "call-with-values");
|
||||
|
||||
register_symbol(pic, state, sCALL, "call");
|
||||
register_symbol(pic, state, sTAILCALL, "tail-call");
|
||||
register_symbol(pic, state, sCALL_WITH_VALUES, "call-with-values");
|
||||
register_symbol(pic, state, sTAILCALL_WITH_VALUES, "tailcall-with-values");
|
||||
register_symbol(pic, state, sGREF, "gref");
|
||||
register_symbol(pic, state, sLREF, "lref");
|
||||
register_symbol(pic, state, sCREF, "cref");
|
||||
register_symbol(pic, state, sRETURN, "return");
|
||||
|
||||
/* push initial scope */
|
||||
push_scope(state, pic_nil_value());
|
||||
|
||||
for (it = xh_begin(&pic->globals); it != NULL; it = xh_next(it)) {
|
||||
pic_sym sym = xh_key(it, pic_sym);
|
||||
pic_dict_for_each (sym, pic->globals) {
|
||||
xv_push(&state->scope->locals, &sym);
|
||||
}
|
||||
|
||||
|
@ -120,14 +110,14 @@ static bool
|
|||
analyze_args(pic_state *pic, pic_value formals, bool *varg, xvect *args, xvect *locals)
|
||||
{
|
||||
pic_value v, t;
|
||||
pic_sym sym;
|
||||
pic_sym *sym;
|
||||
|
||||
for (v = formals; pic_pair_p(v); v = pic_cdr(pic, v)) {
|
||||
t = pic_car(pic, v);
|
||||
if (! pic_sym_p(t)) {
|
||||
return false;
|
||||
}
|
||||
sym = pic_sym(t);
|
||||
sym = pic_sym_ptr(t);
|
||||
xv_push(args, &sym);
|
||||
}
|
||||
if (pic_nil_p(v)) {
|
||||
|
@ -135,7 +125,7 @@ analyze_args(pic_state *pic, pic_value formals, bool *varg, xvect *args, xvect *
|
|||
}
|
||||
else if (pic_sym_p(v)) {
|
||||
*varg = true;
|
||||
sym = pic_sym(v);
|
||||
sym = pic_sym_ptr(v);
|
||||
xv_push(locals, &sym);
|
||||
}
|
||||
else {
|
||||
|
@ -153,9 +143,9 @@ push_scope(analyze_state *state, pic_value formals)
|
|||
bool varg;
|
||||
xvect args, locals, captures;
|
||||
|
||||
xv_init(&args, sizeof(pic_sym));
|
||||
xv_init(&locals, sizeof(pic_sym));
|
||||
xv_init(&captures, sizeof(pic_sym));
|
||||
xv_init(&args, sizeof(pic_sym *));
|
||||
xv_init(&locals, sizeof(pic_sym *));
|
||||
xv_init(&captures, sizeof(pic_sym *));
|
||||
|
||||
if (analyze_args(pic, formals, &varg, &args, &locals)) {
|
||||
scope = pic_alloc(pic, sizeof(analyze_scope));
|
||||
|
@ -194,9 +184,9 @@ pop_scope(analyze_state *state)
|
|||
}
|
||||
|
||||
static bool
|
||||
lookup_scope(analyze_scope *scope, pic_sym sym)
|
||||
lookup_scope(analyze_scope *scope, pic_sym *sym)
|
||||
{
|
||||
pic_sym *arg, *local;
|
||||
pic_sym **arg, **local;
|
||||
size_t i;
|
||||
|
||||
/* args */
|
||||
|
@ -215,9 +205,9 @@ lookup_scope(analyze_scope *scope, pic_sym sym)
|
|||
}
|
||||
|
||||
static void
|
||||
capture_var(analyze_scope *scope, pic_sym sym)
|
||||
capture_var(analyze_scope *scope, pic_sym *sym)
|
||||
{
|
||||
pic_sym *var;
|
||||
pic_sym **var;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < xv_size(&scope->captures); ++i) {
|
||||
|
@ -232,7 +222,7 @@ capture_var(analyze_scope *scope, pic_sym sym)
|
|||
}
|
||||
|
||||
static int
|
||||
find_var(analyze_state *state, pic_sym sym)
|
||||
find_var(analyze_state *state, pic_sym *sym)
|
||||
{
|
||||
analyze_scope *scope = state->scope;
|
||||
int depth = 0;
|
||||
|
@ -251,13 +241,13 @@ find_var(analyze_state *state, pic_sym sym)
|
|||
}
|
||||
|
||||
static void
|
||||
define_var(analyze_state *state, pic_sym sym)
|
||||
define_var(analyze_state *state, pic_sym *sym)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
analyze_scope *scope = state->scope;
|
||||
|
||||
if (lookup_scope(scope, sym)) {
|
||||
pic_warnf(pic, "redefining variable: ~s", pic_sym_value(sym));
|
||||
pic_warnf(pic, "redefining variable: ~s", pic_obj_value(sym));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -273,17 +263,17 @@ analyze(analyze_state *state, pic_value obj, bool tailpos)
|
|||
pic_state *pic = state->pic;
|
||||
size_t ai = pic_gc_arena_preserve(pic);
|
||||
pic_value res;
|
||||
pic_sym tag;
|
||||
pic_sym *tag;
|
||||
|
||||
res = analyze_node(state, obj, tailpos);
|
||||
|
||||
tag = pic_sym(pic_car(pic, res));
|
||||
tag = pic_sym_ptr(pic_car(pic, res));
|
||||
if (tailpos) {
|
||||
if (tag == pic->sIF || tag == pic->sBEGIN || tag == state->sTAILCALL || tag == state->sTAILCALL_WITH_VALUES || tag == state->sRETURN) {
|
||||
if (tag == pic->sIF || tag == pic->sBEGIN || tag == pic->sTAILCALL || tag == pic->sTAILCALL_WITH_VALUES || tag == pic->sRETURN) {
|
||||
/* pass through */
|
||||
}
|
||||
else {
|
||||
res = pic_list2(pic, pic_symbol_value(state->sRETURN), res);
|
||||
res = pic_list2(pic, pic_obj_value(pic->sRETURN), res);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,31 +284,31 @@ analyze(analyze_state *state, pic_value obj, bool tailpos)
|
|||
}
|
||||
|
||||
static pic_value
|
||||
analyze_global_var(analyze_state *state, pic_sym sym)
|
||||
analyze_global_var(analyze_state *state, pic_sym *sym)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
|
||||
return pic_list2(pic, pic_symbol_value(state->sGREF), pic_sym_value(sym));
|
||||
return pic_list2(pic, pic_obj_value(pic->sGREF), pic_obj_value(sym));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
analyze_local_var(analyze_state *state, pic_sym sym)
|
||||
analyze_local_var(analyze_state *state, pic_sym *sym)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
|
||||
return pic_list2(pic, pic_symbol_value(state->sLREF), pic_sym_value(sym));
|
||||
return pic_list2(pic, pic_obj_value(pic->sLREF), pic_obj_value(sym));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
analyze_free_var(analyze_state *state, pic_sym sym, int depth)
|
||||
analyze_free_var(analyze_state *state, pic_sym *sym, int depth)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
|
||||
return pic_list3(pic, pic_symbol_value(state->sCREF), pic_int_value(depth), pic_sym_value(sym));
|
||||
return pic_list3(pic, pic_obj_value(pic->sCREF), pic_int_value(depth), pic_obj_value(sym));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
analyze_var(analyze_state *state, pic_sym sym)
|
||||
analyze_var(analyze_state *state, pic_sym *sym)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
int depth;
|
||||
|
@ -340,10 +330,10 @@ static pic_value
|
|||
analyze_defer(analyze_state *state, pic_value name, pic_value formal, pic_value body)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
const pic_sym sNOWHERE = pic_intern_cstr(pic, " nowhere ");
|
||||
pic_sym *sNOWHERE = pic_intern_cstr(pic, "<<nowhere>>");
|
||||
pic_value skel;
|
||||
|
||||
skel = pic_list2(pic, pic_sym_value(state->sGREF), pic_sym_value(sNOWHERE));
|
||||
skel = pic_list2(pic, pic_obj_value(pic->sGREF), pic_obj_value(sNOWHERE));
|
||||
|
||||
pic_push(pic, pic_list4(pic, name, formal, body, skel), state->scope->defer);
|
||||
|
||||
|
@ -382,13 +372,13 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v
|
|||
|
||||
if (push_scope(state, formals)) {
|
||||
analyze_scope *scope = state->scope;
|
||||
pic_sym *var;
|
||||
pic_sym **var;
|
||||
size_t i;
|
||||
|
||||
args = pic_nil_value();
|
||||
for (i = xv_size(&scope->args); i > 0; --i) {
|
||||
var = xv_get(&scope->args, i - 1);
|
||||
pic_push(pic, pic_sym_value(*var), args);
|
||||
pic_push(pic, pic_obj_value(*var), args);
|
||||
}
|
||||
|
||||
varg = scope->varg
|
||||
|
@ -396,20 +386,20 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v
|
|||
: pic_false_value();
|
||||
|
||||
/* To know what kind of local variables are defined, analyze body at first. */
|
||||
body = analyze(state, pic_cons(pic, pic_sym_value(pic->rBEGIN), body_exprs), true);
|
||||
body = analyze(state, pic_cons(pic, pic_obj_value(pic->rBEGIN), body_exprs), true);
|
||||
|
||||
analyze_deferred(state);
|
||||
|
||||
locals = pic_nil_value();
|
||||
for (i = xv_size(&scope->locals); i > 0; --i) {
|
||||
var = xv_get(&scope->locals, i - 1);
|
||||
pic_push(pic, pic_sym_value(*var), locals);
|
||||
pic_push(pic, pic_obj_value(*var), locals);
|
||||
}
|
||||
|
||||
captures = pic_nil_value();
|
||||
for (i = xv_size(&scope->captures); i > 0; --i) {
|
||||
var = xv_get(&scope->captures, i - 1);
|
||||
pic_push(pic, pic_sym_value(*var), captures);
|
||||
pic_push(pic, pic_obj_value(*var), captures);
|
||||
}
|
||||
|
||||
pop_scope(state);
|
||||
|
@ -418,7 +408,7 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v
|
|||
pic_errorf(pic, "invalid formal syntax: ~s", args);
|
||||
}
|
||||
|
||||
return pic_list7(pic, pic_sym_value(pic->sLAMBDA), name, args, locals, varg, captures, body);
|
||||
return pic_list7(pic, pic_obj_value(pic->sLAMBDA), name, args, locals, varg, captures, body);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -438,7 +428,7 @@ analyze_lambda(analyze_state *state, pic_value obj)
|
|||
}
|
||||
|
||||
static pic_value
|
||||
analyze_declare(analyze_state *state, pic_sym var)
|
||||
analyze_declare(analyze_state *state, pic_sym *var)
|
||||
{
|
||||
define_var(state, var);
|
||||
|
||||
|
@ -450,7 +440,7 @@ analyze_define(analyze_state *state, pic_value obj)
|
|||
{
|
||||
pic_state *pic = state->pic;
|
||||
pic_value var, val;
|
||||
pic_sym sym;
|
||||
pic_sym *sym;
|
||||
|
||||
if (pic_length(pic, obj) != 3) {
|
||||
pic_errorf(pic, "syntax error");
|
||||
|
@ -460,19 +450,19 @@ analyze_define(analyze_state *state, pic_value obj)
|
|||
if (! pic_sym_p(var)) {
|
||||
pic_errorf(pic, "syntax error");
|
||||
} else {
|
||||
sym = pic_sym(var);
|
||||
sym = pic_sym_ptr(var);
|
||||
}
|
||||
var = analyze_declare(state, sym);
|
||||
|
||||
if (pic_pair_p(pic_list_ref(pic, obj, 2))
|
||||
&& pic_sym_p(pic_list_ref(pic, pic_list_ref(pic, obj, 2), 0))
|
||||
&& pic_sym(pic_list_ref(pic, pic_list_ref(pic, obj, 2), 0)) == pic->rLAMBDA) {
|
||||
&& pic_sym_ptr(pic_list_ref(pic, pic_list_ref(pic, obj, 2), 0)) == pic->rLAMBDA) {
|
||||
pic_value formals, body_exprs;
|
||||
|
||||
formals = pic_list_ref(pic, pic_list_ref(pic, obj, 2), 1);
|
||||
body_exprs = pic_list_tail(pic, pic_list_ref(pic, obj, 2), 2);
|
||||
|
||||
val = analyze_defer(state, pic_sym_value(sym), formals, body_exprs);
|
||||
val = analyze_defer(state, pic_obj_value(sym), formals, body_exprs);
|
||||
} else {
|
||||
if (pic_length(pic, obj) != 3) {
|
||||
pic_errorf(pic, "syntax error");
|
||||
|
@ -480,7 +470,7 @@ analyze_define(analyze_state *state, pic_value obj)
|
|||
val = analyze(state, pic_list_ref(pic, obj, 2), false);
|
||||
}
|
||||
|
||||
return pic_list3(pic, pic_symbol_value(pic->sSETBANG), var, val);
|
||||
return pic_list3(pic, pic_obj_value(pic->sSETBANG), var, val);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -505,7 +495,7 @@ analyze_if(analyze_state *state, pic_value obj, bool tailpos)
|
|||
if_true = analyze(state, if_true, tailpos);
|
||||
if_false = analyze(state, if_false, tailpos);
|
||||
|
||||
return pic_list4(pic, pic_symbol_value(pic->sIF), cond, if_true, if_false);
|
||||
return pic_list4(pic, pic_obj_value(pic->sIF), cond, if_true, if_false);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -521,7 +511,7 @@ analyze_begin(analyze_state *state, pic_value obj, bool tailpos)
|
|||
case 2:
|
||||
return analyze(state, pic_list_ref(pic, obj, 1), tailpos);
|
||||
default:
|
||||
seq = pic_list1(pic, pic_symbol_value(pic->sBEGIN));
|
||||
seq = pic_list1(pic, pic_obj_value(pic->sBEGIN));
|
||||
for (obj = pic_cdr(pic, obj); ! pic_nil_p(obj); obj = pic_cdr(pic, obj)) {
|
||||
if (pic_nil_p(pic_cdr(pic, obj))) {
|
||||
tail = tailpos;
|
||||
|
@ -554,7 +544,7 @@ analyze_set(analyze_state *state, pic_value obj)
|
|||
var = analyze(state, var, false);
|
||||
val = analyze(state, val, false);
|
||||
|
||||
return pic_list3(pic, pic_symbol_value(pic->sSETBANG), var, val);
|
||||
return pic_list3(pic, pic_obj_value(pic->sSETBANG), var, val);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -565,7 +555,7 @@ analyze_quote(analyze_state *state, pic_value obj)
|
|||
if (pic_length(pic, obj) != 2) {
|
||||
pic_errorf(pic, "syntax error");
|
||||
}
|
||||
return pic_list2(pic, pic_sym_value(pic->sQUOTE), pic_list_ref(pic, obj, 1));
|
||||
return pic_list2(pic, pic_obj_value(pic->sQUOTE), pic_list_ref(pic, obj, 1));
|
||||
}
|
||||
|
||||
#define ARGC_ASSERT_GE(n) do { \
|
||||
|
@ -577,7 +567,7 @@ analyze_quote(analyze_state *state, pic_value obj)
|
|||
#define FOLD_ARGS(sym) do { \
|
||||
obj = analyze(state, pic_car(pic, args), false); \
|
||||
pic_for_each (arg, pic_cdr(pic, args)) { \
|
||||
obj = pic_list3(pic, pic_symbol_value(sym), obj, \
|
||||
obj = pic_list3(pic, pic_obj_value(sym), obj, \
|
||||
analyze(state, arg, false)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
@ -591,7 +581,7 @@ analyze_add(analyze_state *state, pic_value obj, bool tailpos)
|
|||
ARGC_ASSERT_GE(0);
|
||||
switch (pic_length(pic, obj)) {
|
||||
case 1:
|
||||
return pic_list2(pic, pic_symbol_value(pic->sQUOTE), pic_int_value(0));
|
||||
return pic_list2(pic, pic_obj_value(pic->sQUOTE), pic_int_value(0));
|
||||
case 2:
|
||||
return analyze(state, pic_car(pic, pic_cdr(pic, obj)), tailpos);
|
||||
default:
|
||||
|
@ -610,7 +600,7 @@ analyze_sub(analyze_state *state, pic_value obj)
|
|||
ARGC_ASSERT_GE(1);
|
||||
switch (pic_length(pic, obj)) {
|
||||
case 2:
|
||||
return pic_list2(pic, pic_symbol_value(pic->sMINUS),
|
||||
return pic_list2(pic, pic_obj_value(pic->sMINUS),
|
||||
analyze(state, pic_car(pic, pic_cdr(pic, obj)), false));
|
||||
default:
|
||||
args = pic_cdr(pic, obj);
|
||||
|
@ -628,7 +618,7 @@ analyze_mul(analyze_state *state, pic_value obj, bool tailpos)
|
|||
ARGC_ASSERT_GE(0);
|
||||
switch (pic_length(pic, obj)) {
|
||||
case 1:
|
||||
return pic_list2(pic, pic_symbol_value(pic->sQUOTE), pic_int_value(1));
|
||||
return pic_list2(pic, pic_obj_value(pic->sQUOTE), pic_int_value(1));
|
||||
case 2:
|
||||
return analyze(state, pic_car(pic, pic_cdr(pic, obj)), tailpos);
|
||||
default:
|
||||
|
@ -662,14 +652,14 @@ analyze_call(analyze_state *state, pic_value obj, bool tailpos)
|
|||
{
|
||||
pic_state *pic = state->pic;
|
||||
pic_value seq, elt;
|
||||
pic_sym call;
|
||||
pic_sym *call;
|
||||
|
||||
if (! tailpos) {
|
||||
call = state->sCALL;
|
||||
call = pic->sCALL;
|
||||
} else {
|
||||
call = state->sTAILCALL;
|
||||
call = pic->sTAILCALL;
|
||||
}
|
||||
seq = pic_list1(pic, pic_symbol_value(call));
|
||||
seq = pic_list1(pic, pic_obj_value(call));
|
||||
pic_for_each (elt, obj) {
|
||||
seq = pic_cons(pic, analyze(state, elt, false), seq);
|
||||
}
|
||||
|
@ -686,7 +676,7 @@ analyze_values(analyze_state *state, pic_value obj, bool tailpos)
|
|||
return analyze_call(state, obj, false);
|
||||
}
|
||||
|
||||
seq = pic_list1(pic, pic_symbol_value(state->sRETURN));
|
||||
seq = pic_list1(pic, pic_obj_value(pic->sRETURN));
|
||||
pic_for_each (v, pic_cdr(pic, obj)) {
|
||||
seq = pic_cons(pic, analyze(state, v, false), seq);
|
||||
}
|
||||
|
@ -698,20 +688,20 @@ analyze_call_with_values(analyze_state *state, pic_value obj, bool tailpos)
|
|||
{
|
||||
pic_state *pic = state->pic;
|
||||
pic_value prod, cnsm;
|
||||
pic_sym call;
|
||||
pic_sym *call;
|
||||
|
||||
if (pic_length(pic, obj) != 3) {
|
||||
pic_errorf(pic, "wrong number of arguments");
|
||||
}
|
||||
|
||||
if (! tailpos) {
|
||||
call = state->sCALL_WITH_VALUES;
|
||||
call = pic->sCALL_WITH_VALUES;
|
||||
} else {
|
||||
call = state->sTAILCALL_WITH_VALUES;
|
||||
call = pic->sTAILCALL_WITH_VALUES;
|
||||
}
|
||||
prod = analyze(state, pic_list_ref(pic, obj, 1), false);
|
||||
cnsm = analyze(state, pic_list_ref(pic, obj, 2), false);
|
||||
return pic_list3(pic, pic_symbol_value(call), prod, cnsm);
|
||||
return pic_list3(pic, pic_obj_value(call), prod, cnsm);
|
||||
}
|
||||
|
||||
#define ARGC_ASSERT(n) do { \
|
||||
|
@ -728,12 +718,12 @@ analyze_call_with_values(analyze_state *state, pic_value obj, bool tailpos)
|
|||
|
||||
#define CONSTRUCT_OP1(op) \
|
||||
pic_list2(pic, \
|
||||
pic_symbol_value(op), \
|
||||
pic_obj_value(op), \
|
||||
analyze(state, pic_list_ref(pic, obj, 1), false))
|
||||
|
||||
#define CONSTRUCT_OP2(op) \
|
||||
pic_list3(pic, \
|
||||
pic_symbol_value(op), \
|
||||
pic_obj_value(op), \
|
||||
analyze(state, pic_list_ref(pic, obj, 1), false), \
|
||||
analyze(state, pic_list_ref(pic, obj, 2), false))
|
||||
|
||||
|
@ -744,7 +734,7 @@ analyze_node(analyze_state *state, pic_value obj, bool tailpos)
|
|||
|
||||
switch (pic_type(obj)) {
|
||||
case PIC_TT_SYMBOL: {
|
||||
return analyze_var(state, pic_sym(obj));
|
||||
return analyze_var(state, pic_sym_ptr(obj));
|
||||
}
|
||||
case PIC_TT_PAIR: {
|
||||
pic_value proc;
|
||||
|
@ -755,7 +745,7 @@ analyze_node(analyze_state *state, pic_value obj, bool tailpos)
|
|||
|
||||
proc = pic_list_ref(pic, obj, 0);
|
||||
if (pic_sym_p(proc)) {
|
||||
pic_sym sym = pic_sym(proc);
|
||||
pic_sym *sym = pic_sym_ptr(proc);
|
||||
|
||||
if (sym == pic->rDEFINE) {
|
||||
return analyze_define(state, obj);
|
||||
|
@ -791,13 +781,13 @@ analyze_node(analyze_state *state, pic_value obj, bool tailpos)
|
|||
ARGC_ASSERT(1);
|
||||
return CONSTRUCT_OP1(pic->sNILP);
|
||||
}
|
||||
else if (sym == state->rSYMBOL_P) {
|
||||
else if (sym == state->rSYMBOLP) {
|
||||
ARGC_ASSERT(1);
|
||||
return CONSTRUCT_OP1(pic->sSYMBOL_P);
|
||||
return CONSTRUCT_OP1(pic->sSYMBOLP);
|
||||
}
|
||||
else if (sym == state->rPAIR_P) {
|
||||
else if (sym == state->rPAIRP) {
|
||||
ARGC_ASSERT(1);
|
||||
return CONSTRUCT_OP1(pic->sPAIR_P);
|
||||
return CONSTRUCT_OP1(pic->sPAIRP);
|
||||
}
|
||||
else if (sym == state->rADD) {
|
||||
return analyze_add(state, obj, tailpos);
|
||||
|
@ -847,7 +837,7 @@ analyze_node(analyze_state *state, pic_value obj, bool tailpos)
|
|||
return analyze_call(state, obj, tailpos);
|
||||
}
|
||||
default:
|
||||
return pic_list2(pic, pic_symbol_value(pic->sQUOTE), obj);
|
||||
return pic_list2(pic, pic_obj_value(pic->sQUOTE), obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -871,7 +861,7 @@ pic_analyze(pic_state *pic, pic_value obj)
|
|||
*/
|
||||
|
||||
typedef struct codegen_context {
|
||||
pic_sym name;
|
||||
pic_sym *name;
|
||||
/* rest args variable is counted as a local */
|
||||
bool varg;
|
||||
xvect args, locals, captures;
|
||||
|
@ -884,6 +874,9 @@ typedef struct codegen_context {
|
|||
/* constant object pool */
|
||||
pic_value *pool;
|
||||
size_t plen, pcapa;
|
||||
/* symbol pool */
|
||||
pic_sym **syms;
|
||||
size_t slen, scapa;
|
||||
|
||||
struct codegen_context *up;
|
||||
} codegen_context;
|
||||
|
@ -895,9 +888,6 @@ typedef struct codegen_context {
|
|||
typedef struct codegen_state {
|
||||
pic_state *pic;
|
||||
codegen_context *cxt;
|
||||
pic_sym sGREF, sCREF, sLREF;
|
||||
pic_sym sCALL, sTAILCALL, sRETURN;
|
||||
pic_sym sCALL_WITH_VALUES, sTAILCALL_WITH_VALUES;
|
||||
} codegen_state;
|
||||
|
||||
static void push_codegen_context(codegen_state *, pic_value, pic_value, pic_value, bool, pic_value);
|
||||
|
@ -912,15 +902,6 @@ new_codegen_state(pic_state *pic)
|
|||
state->pic = pic;
|
||||
state->cxt = NULL;
|
||||
|
||||
register_symbol(pic, state, sCALL, "call");
|
||||
register_symbol(pic, state, sTAILCALL, "tail-call");
|
||||
register_symbol(pic, state, sGREF, "gref");
|
||||
register_symbol(pic, state, sLREF, "lref");
|
||||
register_symbol(pic, state, sCREF, "cref");
|
||||
register_symbol(pic, state, sRETURN, "return");
|
||||
register_symbol(pic, state, sCALL_WITH_VALUES, "call-with-values");
|
||||
register_symbol(pic, state, sTAILCALL_WITH_VALUES, "tailcall-with-values");
|
||||
|
||||
push_codegen_context(state, pic_false_value(), pic_nil_value(), pic_nil_value(), false, pic_nil_value());
|
||||
|
||||
return state;
|
||||
|
@ -943,27 +924,27 @@ create_activation(codegen_context *cxt)
|
|||
{
|
||||
size_t i, n;
|
||||
xhash regs;
|
||||
pic_sym *var;
|
||||
pic_sym **var;
|
||||
size_t offset;
|
||||
|
||||
xh_init_int(®s, sizeof(size_t));
|
||||
xh_init_ptr(®s, sizeof(size_t));
|
||||
|
||||
offset = 1;
|
||||
for (i = 0; i < xv_size(&cxt->args); ++i) {
|
||||
var = xv_get(&cxt->args, i);
|
||||
n = i + offset;
|
||||
xh_put_int(®s, *var, &n);
|
||||
xh_put_ptr(®s, *var, &n);
|
||||
}
|
||||
offset += i;
|
||||
for (i = 0; i < xv_size(&cxt->locals); ++i) {
|
||||
var = xv_get(&cxt->locals, i);
|
||||
n = i + offset;
|
||||
xh_put_int(®s, *var, &n);
|
||||
xh_put_ptr(®s, *var, &n);
|
||||
}
|
||||
|
||||
for (i = 0; i < xv_size(&cxt->captures); ++i) {
|
||||
var = xv_get(&cxt->captures, i);
|
||||
if ((n = xh_val(xh_get_int(®s, *var), size_t)) <= xv_size(&cxt->args) || (cxt->varg && n == xv_size(&cxt->args) + 1)) {
|
||||
if ((n = xh_val(xh_get_ptr(®s, *var), size_t)) <= xv_size(&cxt->args) || (cxt->varg && n == xv_size(&cxt->args) + 1)) {
|
||||
/* copy arguments to capture variable area */
|
||||
cxt->code[cxt->clen].insn = OP_LREF;
|
||||
cxt->code[cxt->clen].u.i = (int)n;
|
||||
|
@ -984,7 +965,7 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v
|
|||
pic_state *pic = state->pic;
|
||||
codegen_context *cxt;
|
||||
pic_value var;
|
||||
pic_sym sym;
|
||||
pic_sym *sym;
|
||||
|
||||
assert(pic_sym_p(name) || pic_false_p(name));
|
||||
|
||||
|
@ -992,23 +973,23 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v
|
|||
cxt->up = state->cxt;
|
||||
cxt->name = pic_false_p(name)
|
||||
? pic_intern_cstr(pic, "(anonymous lambda)")
|
||||
: pic_sym(name);
|
||||
: pic_sym_ptr(name);
|
||||
cxt->varg = varg;
|
||||
|
||||
xv_init(&cxt->args, sizeof(pic_sym));
|
||||
xv_init(&cxt->locals, sizeof(pic_sym));
|
||||
xv_init(&cxt->captures, sizeof(pic_sym));
|
||||
xv_init(&cxt->args, sizeof(pic_sym *));
|
||||
xv_init(&cxt->locals, sizeof(pic_sym *));
|
||||
xv_init(&cxt->captures, sizeof(pic_sym *));
|
||||
|
||||
pic_for_each (var, args) {
|
||||
sym = pic_sym(var);
|
||||
sym = pic_sym_ptr(var);
|
||||
xv_push(&cxt->args, &sym);
|
||||
}
|
||||
pic_for_each (var, locals) {
|
||||
sym = pic_sym(var);
|
||||
sym = pic_sym_ptr(var);
|
||||
xv_push(&cxt->locals, &sym);
|
||||
}
|
||||
pic_for_each (var, captures) {
|
||||
sym = pic_sym(var);
|
||||
sym = pic_sym_ptr(var);
|
||||
xv_push(&cxt->captures, &sym);
|
||||
}
|
||||
|
||||
|
@ -1024,6 +1005,10 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v
|
|||
cxt->plen = 0;
|
||||
cxt->pcapa = PIC_POOL_SIZE;
|
||||
|
||||
cxt->syms = pic_calloc(pic, PIC_POOL_SIZE, sizeof(pic_sym *));
|
||||
cxt->slen = 0;
|
||||
cxt->scapa = PIC_POOL_SIZE;
|
||||
|
||||
state->cxt = cxt;
|
||||
|
||||
create_activation(cxt);
|
||||
|
@ -1049,6 +1034,8 @@ pop_codegen_context(codegen_state *state)
|
|||
irep->ilen = state->cxt->ilen;
|
||||
irep->pool = pic_realloc(pic, state->cxt->pool, sizeof(pic_value) * state->cxt->plen);
|
||||
irep->plen = state->cxt->plen;
|
||||
irep->syms = pic_realloc(pic, state->cxt->syms, sizeof(pic_sym *) * state->cxt->slen);
|
||||
irep->slen = state->cxt->slen;
|
||||
|
||||
/* finalize */
|
||||
xv_destroy(&cxt->args);
|
||||
|
@ -1064,11 +1051,11 @@ pop_codegen_context(codegen_state *state)
|
|||
}
|
||||
|
||||
static int
|
||||
index_capture(codegen_state *state, pic_sym sym, int depth)
|
||||
index_capture(codegen_state *state, pic_sym *sym, int depth)
|
||||
{
|
||||
codegen_context *cxt = state->cxt;
|
||||
size_t i;
|
||||
pic_sym *var;
|
||||
pic_sym **var;
|
||||
|
||||
while (depth-- > 0) {
|
||||
cxt = cxt->up;
|
||||
|
@ -1083,11 +1070,11 @@ index_capture(codegen_state *state, pic_sym sym, int depth)
|
|||
}
|
||||
|
||||
static int
|
||||
index_local(codegen_state *state, pic_sym sym)
|
||||
index_local(codegen_state *state, pic_sym *sym)
|
||||
{
|
||||
codegen_context *cxt = state->cxt;
|
||||
size_t i, offset;
|
||||
pic_sym *var;
|
||||
pic_sym **var;
|
||||
|
||||
offset = 1;
|
||||
for (i = 0; i < xv_size(&cxt->args); ++i) {
|
||||
|
@ -1104,6 +1091,26 @@ index_local(codegen_state *state, pic_sym sym)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
index_symbol(codegen_state *state, pic_sym *sym)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
codegen_context *cxt = state->cxt;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < cxt->slen; ++i) {
|
||||
if (cxt->syms[i] == sym) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (cxt->slen >= cxt->scapa) {
|
||||
cxt->scapa *= 2;
|
||||
cxt->syms = pic_realloc(pic, cxt->syms, sizeof(pic_sym *) * cxt->scapa);
|
||||
}
|
||||
cxt->syms[cxt->slen++] = sym;
|
||||
return i;
|
||||
}
|
||||
|
||||
static struct pic_irep *codegen_lambda(codegen_state *, pic_value);
|
||||
|
||||
static void
|
||||
|
@ -1111,30 +1118,30 @@ codegen(codegen_state *state, pic_value obj)
|
|||
{
|
||||
pic_state *pic = state->pic;
|
||||
codegen_context *cxt = state->cxt;
|
||||
pic_sym sym;
|
||||
pic_sym *sym;
|
||||
|
||||
sym = pic_sym(pic_car(pic, obj));
|
||||
if (sym == state->sGREF) {
|
||||
sym = pic_sym_ptr(pic_car(pic, obj));
|
||||
if (sym == pic->sGREF) {
|
||||
cxt->code[cxt->clen].insn = OP_GREF;
|
||||
cxt->code[cxt->clen].u.i = pic_sym(pic_list_ref(pic, obj, 1));
|
||||
cxt->code[cxt->clen].u.i = index_symbol(state, pic_sym_ptr(pic_list_ref(pic, obj, 1)));
|
||||
cxt->clen++;
|
||||
return;
|
||||
} else if (sym == state->sCREF) {
|
||||
pic_sym name;
|
||||
} else if (sym == pic->sCREF) {
|
||||
pic_sym *name;
|
||||
int depth;
|
||||
|
||||
depth = pic_int(pic_list_ref(pic, obj, 1));
|
||||
name = pic_sym(pic_list_ref(pic, obj, 2));
|
||||
name = pic_sym_ptr(pic_list_ref(pic, obj, 2));
|
||||
cxt->code[cxt->clen].insn = OP_CREF;
|
||||
cxt->code[cxt->clen].u.r.depth = depth;
|
||||
cxt->code[cxt->clen].u.r.idx = index_capture(state, name, depth);
|
||||
cxt->clen++;
|
||||
return;
|
||||
} else if (sym == state->sLREF) {
|
||||
pic_sym name;
|
||||
} else if (sym == pic->sLREF) {
|
||||
pic_sym *name;
|
||||
int i;
|
||||
|
||||
name = pic_sym(pic_list_ref(pic, obj, 1));
|
||||
name = pic_sym_ptr(pic_list_ref(pic, obj, 1));
|
||||
if ((i = index_capture(state, name, 0)) != -1) {
|
||||
cxt->code[cxt->clen].insn = OP_LREF;
|
||||
cxt->code[cxt->clen].u.i = i + (int)xv_size(&cxt->args) + (int)xv_size(&cxt->locals) + 1;
|
||||
|
@ -1147,27 +1154,27 @@ codegen(codegen_state *state, pic_value obj)
|
|||
return;
|
||||
} else if (sym == pic->sSETBANG) {
|
||||
pic_value var, val;
|
||||
pic_sym type;
|
||||
pic_sym *type;
|
||||
|
||||
val = pic_list_ref(pic, obj, 2);
|
||||
codegen(state, val);
|
||||
|
||||
var = pic_list_ref(pic, obj, 1);
|
||||
type = pic_sym(pic_list_ref(pic, var, 0));
|
||||
if (type == state->sGREF) {
|
||||
type = pic_sym_ptr(pic_list_ref(pic, var, 0));
|
||||
if (type == pic->sGREF) {
|
||||
cxt->code[cxt->clen].insn = OP_GSET;
|
||||
cxt->code[cxt->clen].u.i = pic_int(pic_list_ref(pic, var, 1));
|
||||
cxt->code[cxt->clen].u.i = index_symbol(state, pic_sym_ptr(pic_list_ref(pic, var, 1)));
|
||||
cxt->clen++;
|
||||
cxt->code[cxt->clen].insn = OP_PUSHNONE;
|
||||
cxt->clen++;
|
||||
return;
|
||||
}
|
||||
else if (type == state->sCREF) {
|
||||
pic_sym name;
|
||||
else if (type == pic->sCREF) {
|
||||
pic_sym *name;
|
||||
int depth;
|
||||
|
||||
depth = pic_int(pic_list_ref(pic, var, 1));
|
||||
name = pic_sym(pic_list_ref(pic, var, 2));
|
||||
name = pic_sym_ptr(pic_list_ref(pic, var, 2));
|
||||
cxt->code[cxt->clen].insn = OP_CSET;
|
||||
cxt->code[cxt->clen].u.r.depth = depth;
|
||||
cxt->code[cxt->clen].u.r.idx = index_capture(state, name, depth);
|
||||
|
@ -1176,11 +1183,11 @@ codegen(codegen_state *state, pic_value obj)
|
|||
cxt->clen++;
|
||||
return;
|
||||
}
|
||||
else if (type == state->sLREF) {
|
||||
pic_sym name;
|
||||
else if (type == pic->sLREF) {
|
||||
pic_sym *name;
|
||||
int i;
|
||||
|
||||
name = pic_sym(pic_list_ref(pic, var, 1));
|
||||
name = pic_sym_ptr(pic_list_ref(pic, var, 1));
|
||||
if ((i = index_capture(state, name, 0)) != -1) {
|
||||
cxt->code[cxt->clen].insn = OP_LSET;
|
||||
cxt->code[cxt->clen].u.i = i + (int)xv_size(&cxt->args) + (int)xv_size(&cxt->locals) + 1;
|
||||
|
@ -1310,15 +1317,15 @@ codegen(codegen_state *state, pic_value obj)
|
|||
cxt->clen++;
|
||||
return;
|
||||
}
|
||||
else if (sym == pic->sSYMBOL_P) {
|
||||
else if (sym == pic->sSYMBOLP) {
|
||||
codegen(state, pic_list_ref(pic, obj, 1));
|
||||
cxt->code[cxt->clen].insn = OP_SYMBOL_P;
|
||||
cxt->code[cxt->clen].insn = OP_SYMBOLP;
|
||||
cxt->clen++;
|
||||
return;
|
||||
}
|
||||
else if (sym == pic->sPAIR_P) {
|
||||
else if (sym == pic->sPAIRP) {
|
||||
codegen(state, pic_list_ref(pic, obj, 1));
|
||||
cxt->code[cxt->clen].insn = OP_PAIR_P;
|
||||
cxt->code[cxt->clen].insn = OP_PAIRP;
|
||||
cxt->clen++;
|
||||
return;
|
||||
}
|
||||
|
@ -1397,19 +1404,19 @@ codegen(codegen_state *state, pic_value obj)
|
|||
cxt->clen++;
|
||||
return;
|
||||
}
|
||||
else if (sym == state->sCALL || sym == state->sTAILCALL) {
|
||||
else if (sym == pic->sCALL || sym == pic->sTAILCALL) {
|
||||
int len = (int)pic_length(pic, obj);
|
||||
pic_value elt;
|
||||
|
||||
pic_for_each (elt, pic_cdr(pic, obj)) {
|
||||
codegen(state, elt);
|
||||
}
|
||||
cxt->code[cxt->clen].insn = (sym == state->sCALL) ? OP_CALL : OP_TAILCALL;
|
||||
cxt->code[cxt->clen].insn = (sym == pic->sCALL) ? OP_CALL : OP_TAILCALL;
|
||||
cxt->code[cxt->clen].u.i = len - 1;
|
||||
cxt->clen++;
|
||||
return;
|
||||
}
|
||||
else if (sym == state->sCALL_WITH_VALUES || sym == state->sTAILCALL_WITH_VALUES) {
|
||||
else if (sym == pic->sCALL_WITH_VALUES || sym == pic->sTAILCALL_WITH_VALUES) {
|
||||
/* stack consumer at first */
|
||||
codegen(state, pic_list_ref(pic, obj, 2));
|
||||
codegen(state, pic_list_ref(pic, obj, 1));
|
||||
|
@ -1418,12 +1425,12 @@ codegen(codegen_state *state, pic_value obj)
|
|||
cxt->code[cxt->clen].u.i = 1;
|
||||
cxt->clen++;
|
||||
/* call consumer */
|
||||
cxt->code[cxt->clen].insn = (sym == state->sCALL_WITH_VALUES) ? OP_CALL : OP_TAILCALL;
|
||||
cxt->code[cxt->clen].insn = (sym == pic->sCALL_WITH_VALUES) ? OP_CALL : OP_TAILCALL;
|
||||
cxt->code[cxt->clen].u.i = -1;
|
||||
cxt->clen++;
|
||||
return;
|
||||
}
|
||||
else if (sym == state->sRETURN) {
|
||||
else if (sym == pic->sRETURN) {
|
||||
int len = (int)pic_length(pic, obj);
|
||||
pic_value elt;
|
||||
|
||||
|
@ -1435,7 +1442,7 @@ codegen(codegen_state *state, pic_value obj)
|
|||
cxt->clen++;
|
||||
return;
|
||||
}
|
||||
pic_errorf(pic, "codegen: unknown AST type");
|
||||
pic_errorf(pic, "codegen: unknown AST type ~s", obj);
|
||||
}
|
||||
|
||||
static struct pic_irep *
|
||||
|
|
4
cont.c
4
cont.c
|
@ -2,10 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/proc.h"
|
||||
#include "picrin/cont.h"
|
||||
|
|
2
debug.c
2
debug.c
|
@ -50,7 +50,7 @@ pic_print_backtrace(pic_state *pic)
|
|||
|
||||
e = pic_error_ptr(pic->err);
|
||||
if (e->type != pic_intern_cstr(pic, "")) {
|
||||
trace = pic_format(pic, "~s ", pic_sym_value(e->type));
|
||||
trace = pic_format(pic, "~s ", pic_obj_value(e->type));
|
||||
} else {
|
||||
trace = pic_make_str(pic, NULL, 0);
|
||||
}
|
||||
|
|
212
dict.c
212
dict.c
|
@ -6,69 +6,8 @@
|
|||
#include "picrin/dict.h"
|
||||
#include "picrin/cont.h"
|
||||
#include "picrin/pair.h"
|
||||
|
||||
static int
|
||||
xh_value_hash(const void *key, void *data)
|
||||
{
|
||||
union { double f; int i; } u;
|
||||
pic_value val = *(pic_value *)key;
|
||||
int hash, vtype;
|
||||
|
||||
PIC_UNUSED(data);
|
||||
|
||||
vtype = pic_vtype(val);
|
||||
|
||||
switch (vtype) {
|
||||
default:
|
||||
hash = 0;
|
||||
break;
|
||||
case PIC_VTYPE_SYMBOL:
|
||||
hash = pic_sym(val);
|
||||
break;
|
||||
case PIC_VTYPE_FLOAT:
|
||||
u.f = pic_float(val);
|
||||
hash = u.i;
|
||||
break;
|
||||
case PIC_VTYPE_INT:
|
||||
hash = pic_int(val);
|
||||
break;
|
||||
case PIC_VTYPE_HEAP:
|
||||
hash = (int)(intptr_t)pic_ptr(val);
|
||||
break;
|
||||
}
|
||||
|
||||
return hash + vtype;
|
||||
}
|
||||
|
||||
static int
|
||||
xh_value_equal(const void *key1, const void *key2, void *pic)
|
||||
{
|
||||
return pic_equal_p(pic, *(pic_value *)key1, *(pic_value *)key2);
|
||||
}
|
||||
|
||||
static void
|
||||
xh_init_value(pic_state *pic, xhash *x)
|
||||
{
|
||||
xh_init_(x, sizeof(pic_value), sizeof(pic_value), xh_value_hash, xh_value_equal, pic);
|
||||
}
|
||||
|
||||
static inline xh_entry *
|
||||
xh_get_value(xhash *x, pic_value key)
|
||||
{
|
||||
return xh_get_(x, &key);
|
||||
}
|
||||
|
||||
static inline xh_entry *
|
||||
xh_put_value(xhash *x, pic_value key, void *val)
|
||||
{
|
||||
return xh_put_(x, &key, val);
|
||||
}
|
||||
|
||||
static inline void
|
||||
xh_del_value(xhash *x, pic_value key)
|
||||
{
|
||||
xh_del_(x, &key);
|
||||
}
|
||||
#include "picrin/error.h"
|
||||
#include "picrin/symbol.h"
|
||||
|
||||
struct pic_dict *
|
||||
pic_make_dict(pic_state *pic)
|
||||
|
@ -76,29 +15,29 @@ pic_make_dict(pic_state *pic)
|
|||
struct pic_dict *dict;
|
||||
|
||||
dict = (struct pic_dict *)pic_obj_alloc(pic, sizeof(struct pic_dict), PIC_TT_DICT);
|
||||
xh_init_value(pic, &dict->hash);
|
||||
xh_init_ptr(&dict->hash, sizeof(pic_value));
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_dict_ref(pic_state *pic, struct pic_dict *dict, pic_value key)
|
||||
pic_dict_ref(pic_state *pic, struct pic_dict *dict, pic_sym *key)
|
||||
{
|
||||
xh_entry *e;
|
||||
|
||||
e = xh_get_value(&dict->hash, key);
|
||||
e = xh_get_ptr(&dict->hash, key);
|
||||
if (! e) {
|
||||
pic_errorf(pic, "element not found for a key: ~s", key);
|
||||
pic_errorf(pic, "element not found for a key: ~s", pic_obj_value(key));
|
||||
}
|
||||
return xh_val(e, pic_value);
|
||||
}
|
||||
|
||||
void
|
||||
pic_dict_set(pic_state *pic, struct pic_dict *dict, pic_value key, pic_value val)
|
||||
pic_dict_set(pic_state *pic, struct pic_dict *dict, pic_sym *key, pic_value val)
|
||||
{
|
||||
PIC_UNUSED(pic);
|
||||
|
||||
xh_put_value(&dict->hash, key, &val);
|
||||
xh_put_ptr(&dict->hash, key, &val);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -110,21 +49,21 @@ pic_dict_size(pic_state *pic, struct pic_dict *dict)
|
|||
}
|
||||
|
||||
bool
|
||||
pic_dict_has(pic_state *pic, struct pic_dict *dict, pic_value key)
|
||||
pic_dict_has(pic_state *pic, struct pic_dict *dict, pic_sym *key)
|
||||
{
|
||||
PIC_UNUSED(pic);
|
||||
|
||||
return xh_get_value(&dict->hash, key) != NULL;
|
||||
return xh_get_ptr(&dict->hash, key) != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
pic_dict_del(pic_state *pic, struct pic_dict *dict, pic_value key)
|
||||
pic_dict_del(pic_state *pic, struct pic_dict *dict, pic_sym *key)
|
||||
{
|
||||
if (xh_get_value(&dict->hash, key) == NULL) {
|
||||
pic_errorf(pic, "no slot named ~s found in dictionary", key);
|
||||
if (xh_get_ptr(&dict->hash, key) == NULL) {
|
||||
pic_errorf(pic, "no slot named ~s found in dictionary", pic_obj_value(key));
|
||||
}
|
||||
|
||||
xh_del_value(&dict->hash, key);
|
||||
xh_del_ptr(&dict->hash, key);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -151,7 +90,8 @@ pic_dict_dictionary(pic_state *pic)
|
|||
dict = pic_make_dict(pic);
|
||||
|
||||
for (i = 0; i < argc; i += 2) {
|
||||
pic_dict_set(pic, dict, argv[i], argv[i+1]);
|
||||
pic_assert_type(pic, argv[i], sym);
|
||||
pic_dict_set(pic, dict, pic_sym_ptr(argv[i]), argv[i+1]);
|
||||
}
|
||||
|
||||
return pic_obj_value(dict);
|
||||
|
@ -171,9 +111,9 @@ static pic_value
|
|||
pic_dict_dictionary_ref(pic_state *pic)
|
||||
{
|
||||
struct pic_dict *dict;
|
||||
pic_value key;
|
||||
pic_sym *key;
|
||||
|
||||
pic_get_args(pic, "do", &dict, &key);
|
||||
pic_get_args(pic, "dm", &dict, &key);
|
||||
|
||||
if (pic_dict_has(pic, dict, key)) {
|
||||
return pic_values2(pic, pic_dict_ref(pic, dict, key), pic_true_value());
|
||||
|
@ -186,9 +126,10 @@ static pic_value
|
|||
pic_dict_dictionary_set(pic_state *pic)
|
||||
{
|
||||
struct pic_dict *dict;
|
||||
pic_value key, val;
|
||||
pic_sym *key;
|
||||
pic_value val;
|
||||
|
||||
pic_get_args(pic, "doo", &dict, &key, &val);
|
||||
pic_get_args(pic, "dmo", &dict, &key, &val);
|
||||
|
||||
pic_dict_set(pic, dict, key, val);
|
||||
|
||||
|
@ -199,9 +140,9 @@ static pic_value
|
|||
pic_dict_dictionary_del(pic_state *pic)
|
||||
{
|
||||
struct pic_dict *dict;
|
||||
pic_value key;
|
||||
pic_sym *key;
|
||||
|
||||
pic_get_args(pic, "do", &dict, &key);
|
||||
pic_get_args(pic, "dm", &dict, &key);
|
||||
|
||||
pic_dict_del(pic, dict, key);
|
||||
|
||||
|
@ -215,7 +156,100 @@ pic_dict_dictionary_size(pic_state *pic)
|
|||
|
||||
pic_get_args(pic, "d", &dict);
|
||||
|
||||
return pic_size_value(pic_dict_size(pic, dict));
|
||||
return pic_int_value(pic_dict_size(pic, dict));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_dict_dictionary_map(pic_state *pic)
|
||||
{
|
||||
struct pic_proc *proc;
|
||||
size_t argc, i;
|
||||
pic_value *args;
|
||||
pic_value arg, ret;
|
||||
xh_entry **it;
|
||||
|
||||
pic_get_args(pic, "l*", &proc, &argc, &args);
|
||||
|
||||
it = pic_alloc(pic, argc * sizeof(xh_entry));
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (! pic_dict_p(args[i])) {
|
||||
pic_free(pic, it);
|
||||
pic_errorf(pic, "expected dict, but got %s", pic_type_repr(pic_type(args[i])));
|
||||
}
|
||||
it[i] = xh_begin(&pic_dict_ptr(args[i])->hash);
|
||||
}
|
||||
|
||||
pic_try {
|
||||
ret = pic_nil_value();
|
||||
do {
|
||||
arg = pic_nil_value();
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (it[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
pic_push(pic, pic_obj_value(xh_key(it[i], pic_sym *)), arg);
|
||||
it[i] = xh_next(it[i]);
|
||||
}
|
||||
if (i != argc) {
|
||||
break;
|
||||
}
|
||||
pic_push(pic, pic_apply(pic, proc, pic_reverse(pic, arg)), ret);
|
||||
} while (1);
|
||||
}
|
||||
pic_catch {
|
||||
pic_free(pic, it);
|
||||
pic_raise(pic, pic->err);
|
||||
}
|
||||
|
||||
pic_free(pic, it);
|
||||
|
||||
return pic_reverse(pic, ret);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_dict_dictionary_for_each(pic_state *pic)
|
||||
{
|
||||
struct pic_proc *proc;
|
||||
size_t argc, i;
|
||||
pic_value *args;
|
||||
pic_value arg;
|
||||
xh_entry **it;
|
||||
|
||||
pic_get_args(pic, "l*", &proc, &argc, &args);
|
||||
|
||||
it = pic_alloc(pic, argc * sizeof(xh_entry));
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (! pic_dict_p(args[i])) {
|
||||
pic_free(pic, it);
|
||||
pic_errorf(pic, "expected dict, but got %s", pic_type_repr(pic_type(args[i])));
|
||||
}
|
||||
it[i] = xh_begin(&pic_dict_ptr(args[i])->hash);
|
||||
}
|
||||
|
||||
pic_try {
|
||||
do {
|
||||
arg = pic_nil_value();
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (it[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
pic_push(pic, pic_obj_value(xh_key(it[i], pic_sym *)), arg);
|
||||
it[i] = xh_next(it[i]);
|
||||
}
|
||||
if (i != argc) {
|
||||
break;
|
||||
}
|
||||
pic_void(pic_apply(pic, proc, pic_reverse(pic, arg)));
|
||||
} while (1);
|
||||
}
|
||||
pic_catch {
|
||||
pic_free(pic, it);
|
||||
pic_raise(pic, pic->err);
|
||||
}
|
||||
|
||||
pic_free(pic, it);
|
||||
|
||||
return pic_none_value();
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -228,7 +262,7 @@ pic_dict_dictionary_to_alist(pic_state *pic)
|
|||
pic_get_args(pic, "d", &dict);
|
||||
|
||||
for (it = xh_begin(&dict->hash); it != NULL; it = xh_next(it)) {
|
||||
item = pic_cons(pic, xh_key(it, pic_value), xh_val(it, pic_value));
|
||||
item = pic_cons(pic, pic_obj_value(xh_key(it, pic_sym *)), xh_val(it, pic_value));
|
||||
pic_push(pic, item, alist);
|
||||
}
|
||||
|
||||
|
@ -246,7 +280,8 @@ pic_dict_alist_to_dictionary(pic_state *pic)
|
|||
dict = pic_make_dict(pic);
|
||||
|
||||
pic_for_each (e, pic_reverse(pic, alist)) {
|
||||
pic_dict_set(pic, dict, pic_car(pic, e), pic_cdr(pic, e));
|
||||
pic_assert_type(pic, pic_car(pic, e), sym);
|
||||
pic_dict_set(pic, dict, pic_sym_ptr(pic_car(pic, e)), pic_cdr(pic, e));
|
||||
}
|
||||
|
||||
return pic_obj_value(dict);
|
||||
|
@ -262,7 +297,7 @@ pic_dict_dictionary_to_plist(pic_state *pic)
|
|||
pic_get_args(pic, "d", &dict);
|
||||
|
||||
for (it = xh_begin(&dict->hash); it != NULL; it = xh_next(it)) {
|
||||
pic_push(pic, xh_key(it, pic_value), plist);
|
||||
pic_push(pic, pic_obj_value(xh_key(it, pic_sym *)), plist);
|
||||
pic_push(pic, xh_val(it, pic_value), plist);
|
||||
}
|
||||
|
||||
|
@ -280,7 +315,8 @@ pic_dict_plist_to_dictionary(pic_state *pic)
|
|||
dict = pic_make_dict(pic);
|
||||
|
||||
for (e = pic_reverse(pic, plist); ! pic_nil_p(e); e = pic_cddr(pic, e)) {
|
||||
pic_dict_set(pic, dict, pic_cadr(pic, e), pic_car(pic, e));
|
||||
pic_assert_type(pic, pic_cadr(pic, e), sym);
|
||||
pic_dict_set(pic, dict, pic_sym_ptr(pic_cadr(pic, e)), pic_car(pic, e));
|
||||
}
|
||||
|
||||
return pic_obj_value(dict);
|
||||
|
@ -296,6 +332,8 @@ pic_init_dict(pic_state *pic)
|
|||
pic_defun(pic, "dictionary-set!", pic_dict_dictionary_set);
|
||||
pic_defun(pic, "dictionary-delete!", pic_dict_dictionary_del);
|
||||
pic_defun(pic, "dictionary-size", pic_dict_dictionary_size);
|
||||
pic_defun(pic, "dictionary-map", pic_dict_dictionary_map);
|
||||
pic_defun(pic, "dictionary-for-each", pic_dict_dictionary_for_each);
|
||||
pic_defun(pic, "dictionary->alist", pic_dict_dictionary_to_alist);
|
||||
pic_defun(pic, "alist->dictionary", pic_dict_alist_to_dictionary);
|
||||
pic_defun(pic, "dictionary->plist", pic_dict_dictionary_to_plist);
|
||||
|
|
12
error.c
12
error.c
|
@ -2,10 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/pair.h"
|
||||
#include "picrin/proc.h"
|
||||
|
@ -129,7 +125,7 @@ pic_pop_try(pic_state *pic)
|
|||
}
|
||||
|
||||
struct pic_error *
|
||||
pic_make_error(pic_state *pic, pic_sym type, const char *msg, pic_value irrs)
|
||||
pic_make_error(pic_state *pic, pic_sym *type, const char *msg, pic_value irrs)
|
||||
{
|
||||
struct pic_error *e;
|
||||
pic_str *stack;
|
||||
|
@ -179,7 +175,7 @@ pic_raise(pic_state *pic, pic_value err)
|
|||
}
|
||||
|
||||
void
|
||||
pic_throw(pic_state *pic, pic_sym type, const char *msg, pic_value irrs)
|
||||
pic_throw(pic_state *pic, pic_sym *type, const char *msg, pic_value irrs)
|
||||
{
|
||||
struct pic_error *e;
|
||||
|
||||
|
@ -257,7 +253,7 @@ static pic_value
|
|||
pic_error_make_error_object(pic_state *pic)
|
||||
{
|
||||
struct pic_error *e;
|
||||
pic_sym type;
|
||||
pic_sym *type;
|
||||
pic_str *msg;
|
||||
size_t argc;
|
||||
pic_value *argv;
|
||||
|
@ -306,7 +302,7 @@ pic_error_error_object_type(pic_state *pic)
|
|||
|
||||
pic_get_args(pic, "e", &e);
|
||||
|
||||
return pic_sym_value(e->type);
|
||||
return pic_obj_value(e->type);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
117
file.c
117
file.c
|
@ -1,117 +0,0 @@
|
|||
/**
|
||||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/port.h"
|
||||
#include "picrin/error.h"
|
||||
|
||||
pic_noreturn static void
|
||||
file_error(pic_state *pic, const char *msg)
|
||||
{
|
||||
pic_throw(pic, pic->sFILE, msg, pic_nil_value());
|
||||
}
|
||||
|
||||
static pic_value
|
||||
generic_open_file(pic_state *pic, const char *fname, char *mode, short flags)
|
||||
{
|
||||
struct pic_port *port;
|
||||
xFILE *file;
|
||||
|
||||
file = xfopen(fname, mode);
|
||||
if (! file) {
|
||||
file_error(pic, "could not open file");
|
||||
}
|
||||
|
||||
port = (struct pic_port *)pic_obj_alloc(pic, sizeof(struct pic_port), PIC_TT_PORT);
|
||||
port->file = file;
|
||||
port->flags = flags;
|
||||
port->status = PIC_PORT_OPEN;
|
||||
|
||||
return pic_obj_value(port);
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_file_open_input_file(pic_state *pic)
|
||||
{
|
||||
static const short flags = PIC_PORT_IN | PIC_PORT_TEXT;
|
||||
char *fname;
|
||||
|
||||
pic_get_args(pic, "z", &fname);
|
||||
|
||||
return generic_open_file(pic, fname, "r", flags);
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_file_open_binary_input_file(pic_state *pic)
|
||||
{
|
||||
static const short flags = PIC_PORT_IN | PIC_PORT_BINARY;
|
||||
char *fname;
|
||||
|
||||
pic_get_args(pic, "z", &fname);
|
||||
|
||||
return generic_open_file(pic, fname, "rb", flags);
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_file_open_output_file(pic_state *pic)
|
||||
{
|
||||
static const short flags = PIC_PORT_OUT | PIC_PORT_TEXT;
|
||||
char *fname;
|
||||
|
||||
pic_get_args(pic, "z", &fname);
|
||||
|
||||
return generic_open_file(pic, fname, "w", flags);
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_file_open_binary_output_file(pic_state *pic)
|
||||
{
|
||||
static const short flags = PIC_PORT_OUT | PIC_PORT_BINARY;
|
||||
char *fname;
|
||||
|
||||
pic_get_args(pic, "z", &fname);
|
||||
|
||||
return generic_open_file(pic, fname, "wb", flags);
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_file_exists_p(pic_state *pic)
|
||||
{
|
||||
char *fname;
|
||||
FILE *fp;
|
||||
|
||||
pic_get_args(pic, "z", &fname);
|
||||
|
||||
fp = fopen(fname, "r");
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
return pic_true_value();
|
||||
} else {
|
||||
return pic_false_value();
|
||||
}
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_file_delete(pic_state *pic)
|
||||
{
|
||||
char *fname;
|
||||
|
||||
pic_get_args(pic, "z", &fname);
|
||||
|
||||
if (remove(fname) != 0) {
|
||||
file_error(pic, "file cannot be deleted");
|
||||
}
|
||||
return pic_none_value();
|
||||
}
|
||||
|
||||
void
|
||||
pic_init_file(pic_state *pic)
|
||||
{
|
||||
pic_defun(pic, "open-input-file", pic_file_open_input_file);
|
||||
pic_defun(pic, "open-binary-input-file", pic_file_open_binary_input_file);
|
||||
pic_defun(pic, "open-output-file", pic_file_open_output_file);
|
||||
pic_defun(pic, "open-binary-output-file", pic_file_open_binary_output_file);
|
||||
pic_defun(pic, "file-exists?", pic_file_exists_p);
|
||||
pic_defun(pic, "delete-file", pic_file_delete);
|
||||
}
|
85
gc.c
85
gc.c
|
@ -19,10 +19,7 @@
|
|||
#include "picrin/dict.h"
|
||||
#include "picrin/record.h"
|
||||
#include "picrin/read.h"
|
||||
|
||||
#if GC_DEBUG
|
||||
# include <string.h>
|
||||
#endif
|
||||
#include "picrin/symbol.h"
|
||||
|
||||
union header {
|
||||
struct {
|
||||
|
@ -393,6 +390,8 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
|||
}
|
||||
if (pic_proc_irep_p(proc)) {
|
||||
gc_mark_object(pic, (struct pic_object *)proc->u.irep);
|
||||
} else {
|
||||
gc_mark_object(pic, (struct pic_object *)proc->u.func.name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -401,7 +400,8 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
|||
}
|
||||
case PIC_TT_ERROR: {
|
||||
struct pic_error *err = (struct pic_error *)obj;
|
||||
gc_mark_object(pic,(struct pic_object *)err->msg);
|
||||
gc_mark_object(pic, (struct pic_object *)err->type);
|
||||
gc_mark_object(pic, (struct pic_object *)err->msg);
|
||||
gc_mark(pic, err->irrs);
|
||||
gc_mark_object(pic, (struct pic_object *)err->stack);
|
||||
break;
|
||||
|
@ -419,17 +419,6 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
|||
case PIC_TT_BLOB: {
|
||||
break;
|
||||
}
|
||||
case PIC_TT_MACRO: {
|
||||
struct pic_macro *mac = (struct pic_macro *)obj;
|
||||
|
||||
if (mac->proc) {
|
||||
gc_mark_object(pic, (struct pic_object *)mac->proc);
|
||||
}
|
||||
if (mac->senv) {
|
||||
gc_mark_object(pic, (struct pic_object *)mac->senv);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TT_SENV: {
|
||||
struct pic_senv *senv = (struct pic_senv *)obj;
|
||||
|
||||
|
@ -437,24 +426,31 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
|||
gc_mark_object(pic, (struct pic_object *)senv->up);
|
||||
}
|
||||
gc_mark(pic, senv->defer);
|
||||
gc_mark_object(pic, (struct pic_object *)senv->map);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_LIB: {
|
||||
struct pic_lib *lib = (struct pic_lib *)obj;
|
||||
gc_mark(pic, lib->name);
|
||||
gc_mark_object(pic, (struct pic_object *)lib->env);
|
||||
gc_mark_object(pic, (struct pic_object *)lib->exports);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_IREP: {
|
||||
struct pic_irep *irep = (struct pic_irep *)obj;
|
||||
size_t i;
|
||||
|
||||
gc_mark_object(pic, (struct pic_object *)irep->name);
|
||||
|
||||
for (i = 0; i < irep->ilen; ++i) {
|
||||
gc_mark_object(pic, (struct pic_object *)irep->irep[i]);
|
||||
}
|
||||
for (i = 0; i < irep->plen; ++i) {
|
||||
gc_mark(pic, irep->pool[i]);
|
||||
}
|
||||
for (i = 0; i < irep->slen; ++i) {
|
||||
gc_mark_object(pic, (struct pic_object *)irep->syms[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TT_DATA: {
|
||||
|
@ -474,25 +470,27 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
|||
xh_entry *it;
|
||||
|
||||
for (it = xh_begin(&dict->hash); it != NULL; it = xh_next(it)) {
|
||||
gc_mark(pic, xh_key(it, pic_value));
|
||||
gc_mark_object(pic, (struct pic_object *)xh_key(it, pic_sym *));
|
||||
gc_mark(pic, xh_val(it, pic_value));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TT_RECORD: {
|
||||
struct pic_record *rec = (struct pic_record *)obj;
|
||||
xh_entry *it;
|
||||
|
||||
for (it = xh_begin(&rec->hash); it != NULL; it = xh_next(it)) {
|
||||
gc_mark(pic, xh_val(it, pic_value));
|
||||
gc_mark_object(pic, (struct pic_object *)rec->data);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_SYMBOL: {
|
||||
struct pic_symbol *sym = (struct pic_symbol *)obj;
|
||||
|
||||
gc_mark_object(pic, (struct pic_object *)sym->str);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_NIL:
|
||||
case PIC_TT_BOOL:
|
||||
case PIC_TT_FLOAT:
|
||||
case PIC_TT_INT:
|
||||
case PIC_TT_SYMBOL:
|
||||
case PIC_TT_CHAR:
|
||||
case PIC_TT_EOF:
|
||||
case PIC_TT_UNDEF:
|
||||
|
@ -527,6 +525,17 @@ gc_mark_trie(pic_state *pic, struct pic_trie *trie)
|
|||
}
|
||||
}
|
||||
|
||||
#define M(x) gc_mark_object(pic, (struct pic_object *)pic->x)
|
||||
|
||||
static void
|
||||
gc_mark_global_symbols(pic_state *pic)
|
||||
{
|
||||
M(rDEFINE); M(rLAMBDA); M(rIF); M(rBEGIN); M(rQUOTE); M(rSETBANG);
|
||||
M(rDEFINE_SYNTAX); M(rIMPORT); M(rEXPORT);
|
||||
M(rDEFINE_LIBRARY); M(rIN_LIBRARY);
|
||||
M(rCOND_EXPAND);
|
||||
}
|
||||
|
||||
static void
|
||||
gc_mark_phase(pic_state *pic)
|
||||
{
|
||||
|
@ -564,14 +573,22 @@ gc_mark_phase(pic_state *pic)
|
|||
gc_mark_object(pic, pic->arena[j]);
|
||||
}
|
||||
|
||||
/* mark reserved uninterned symbols */
|
||||
gc_mark_global_symbols(pic);
|
||||
|
||||
/* mark all interned symbols */
|
||||
for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) {
|
||||
gc_mark_object(pic, (struct pic_object *)xh_val(it, pic_sym *));
|
||||
}
|
||||
|
||||
/* global variables */
|
||||
for (it = xh_begin(&pic->globals); it != NULL; it = xh_next(it)) {
|
||||
gc_mark(pic, xh_val(it, pic_value));
|
||||
if (pic->globals) {
|
||||
gc_mark_object(pic, (struct pic_object *)pic->globals);
|
||||
}
|
||||
|
||||
/* macro objects */
|
||||
for (it = xh_begin(&pic->macros); it != NULL; it = xh_next(it)) {
|
||||
gc_mark_object(pic, xh_val(it, struct pic_object *));
|
||||
if (pic->macros) {
|
||||
gc_mark_object(pic, (struct pic_object *)pic->macros);
|
||||
}
|
||||
|
||||
/* error object */
|
||||
|
@ -651,16 +668,9 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
|||
break;
|
||||
}
|
||||
case PIC_TT_SENV: {
|
||||
struct pic_senv *senv = (struct pic_senv *)obj;
|
||||
xh_destroy(&senv->map);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_MACRO: {
|
||||
break;
|
||||
}
|
||||
case PIC_TT_LIB: {
|
||||
struct pic_lib *lib = (struct pic_lib *)obj;
|
||||
xh_destroy(&lib->exports);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_IREP: {
|
||||
|
@ -668,6 +678,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
|||
pic_free(pic, irep->code);
|
||||
pic_free(pic, irep->irep);
|
||||
pic_free(pic, irep->pool);
|
||||
pic_free(pic, irep->syms);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_DATA: {
|
||||
|
@ -682,15 +693,15 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
|||
break;
|
||||
}
|
||||
case PIC_TT_RECORD: {
|
||||
struct pic_record *rec = (struct pic_record *)obj;
|
||||
xh_destroy(&rec->hash);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_SYMBOL: {
|
||||
break;
|
||||
}
|
||||
case PIC_TT_NIL:
|
||||
case PIC_TT_BOOL:
|
||||
case PIC_TT_FLOAT:
|
||||
case PIC_TT_INT:
|
||||
case PIC_TT_SYMBOL:
|
||||
case PIC_TT_CHAR:
|
||||
case PIC_TT_EOF:
|
||||
case PIC_TT_UNDEF:
|
||||
|
@ -777,6 +788,10 @@ pic_gc_run(pic_state *pic)
|
|||
struct heap_page *page;
|
||||
#endif
|
||||
|
||||
if (! pic->gc_enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
puts("gc run!");
|
||||
#endif
|
||||
|
|
|
@ -30,10 +30,17 @@ extern "C" {
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "picrin/xvect.h"
|
||||
#include "picrin/xhash.h"
|
||||
|
@ -82,22 +89,25 @@ typedef struct {
|
|||
|
||||
struct pic_lib *lib;
|
||||
|
||||
pic_sym sDEFINE, sLAMBDA, sIF, sBEGIN, sQUOTE, sSETBANG;
|
||||
pic_sym sQUASIQUOTE, sUNQUOTE, sUNQUOTE_SPLICING;
|
||||
pic_sym sDEFINE_SYNTAX, sIMPORT, sEXPORT;
|
||||
pic_sym sDEFINE_LIBRARY, sIN_LIBRARY;
|
||||
pic_sym sCOND_EXPAND, sAND, sOR, sELSE, sLIBRARY;
|
||||
pic_sym sONLY, sRENAME, sPREFIX, sEXCEPT;
|
||||
pic_sym sCONS, sCAR, sCDR, sNILP;
|
||||
pic_sym sSYMBOL_P, sPAIR_P;
|
||||
pic_sym sADD, sSUB, sMUL, sDIV, sMINUS;
|
||||
pic_sym sEQ, sLT, sLE, sGT, sGE, sNOT;
|
||||
pic_sym sREAD, sFILE;
|
||||
pic_sym *sDEFINE, *sLAMBDA, *sIF, *sBEGIN, *sQUOTE, *sSETBANG;
|
||||
pic_sym *sQUASIQUOTE, *sUNQUOTE, *sUNQUOTE_SPLICING;
|
||||
pic_sym *sDEFINE_SYNTAX, *sIMPORT, *sEXPORT;
|
||||
pic_sym *sDEFINE_LIBRARY, *sIN_LIBRARY;
|
||||
pic_sym *sCOND_EXPAND, *sAND, *sOR, *sELSE, *sLIBRARY;
|
||||
pic_sym *sONLY, *sRENAME, *sPREFIX, *sEXCEPT;
|
||||
pic_sym *sCONS, *sCAR, *sCDR, *sNILP;
|
||||
pic_sym *sSYMBOLP, *sPAIRP;
|
||||
pic_sym *sADD, *sSUB, *sMUL, *sDIV, *sMINUS;
|
||||
pic_sym *sEQ, *sLT, *sLE, *sGT, *sGE, *sNOT;
|
||||
pic_sym *sREAD, *sFILE;
|
||||
pic_sym *sGREF, *sCREF, *sLREF;
|
||||
pic_sym *sCALL, *sTAILCALL, *sRETURN;
|
||||
pic_sym *sCALL_WITH_VALUES, *sTAILCALL_WITH_VALUES;
|
||||
|
||||
pic_sym rDEFINE, rLAMBDA, rIF, rBEGIN, rQUOTE, rSETBANG;
|
||||
pic_sym rDEFINE_SYNTAX, rIMPORT, rEXPORT;
|
||||
pic_sym rDEFINE_LIBRARY, rIN_LIBRARY;
|
||||
pic_sym rCOND_EXPAND;
|
||||
pic_sym *rDEFINE, *rLAMBDA, *rIF, *rBEGIN, *rQUOTE, *rSETBANG;
|
||||
pic_sym *rDEFINE_SYNTAX, *rIMPORT, *rEXPORT;
|
||||
pic_sym *rDEFINE_LIBRARY, *rIN_LIBRARY;
|
||||
pic_sym *rCOND_EXPAND;
|
||||
|
||||
struct pic_lib *PICRIN_BASE;
|
||||
struct pic_lib *PICRIN_USER;
|
||||
|
@ -105,17 +115,14 @@ typedef struct {
|
|||
pic_value features;
|
||||
|
||||
xhash syms; /* name to symbol */
|
||||
xhash sym_names; /* symbol to name */
|
||||
int sym_cnt;
|
||||
int uniq_sym_cnt;
|
||||
|
||||
xhash globals;
|
||||
xhash macros;
|
||||
struct pic_dict *globals;
|
||||
struct pic_dict *macros;
|
||||
pic_value libs;
|
||||
xhash attrs;
|
||||
|
||||
struct pic_reader *reader;
|
||||
|
||||
bool gc_enable;
|
||||
struct pic_heap *heap;
|
||||
struct pic_object **arena;
|
||||
size_t arena_size, arena_idx;
|
||||
|
@ -168,18 +175,16 @@ bool pic_eq_p(pic_value, pic_value);
|
|||
bool pic_eqv_p(pic_value, pic_value);
|
||||
bool pic_equal_p(pic_state *, pic_value, pic_value);
|
||||
|
||||
pic_sym pic_intern(pic_state *, const char *, size_t);
|
||||
pic_sym pic_intern_str(pic_state *, pic_str *);
|
||||
pic_sym pic_intern_cstr(pic_state *, const char *);
|
||||
const char *pic_symbol_name(pic_state *, pic_sym);
|
||||
pic_sym pic_gensym(pic_state *, pic_sym);
|
||||
pic_sym pic_ungensym(pic_state *, pic_sym);
|
||||
bool pic_interned_p(pic_state *, pic_sym);
|
||||
pic_sym *pic_intern(pic_state *, pic_str *);
|
||||
pic_sym *pic_intern_cstr(pic_state *, const char *);
|
||||
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 *);
|
||||
|
||||
pic_value pic_read(pic_state *, struct pic_port *);
|
||||
pic_value pic_read_cstr(pic_state *, const char *);
|
||||
|
||||
void pic_load(pic_state *, const char *);
|
||||
void pic_load_port(pic_state *, struct pic_port *);
|
||||
void pic_load_cstr(pic_state *, const char *);
|
||||
|
||||
pic_value pic_funcall(pic_state *pic, struct pic_lib *, const char *, pic_list);
|
||||
|
@ -211,7 +216,7 @@ struct pic_lib *pic_find_library(pic_state *, pic_value);
|
|||
|
||||
void pic_import(pic_state *, pic_value);
|
||||
void pic_import_library(pic_state *, struct pic_lib *);
|
||||
void pic_export(pic_state *, pic_sym);
|
||||
void pic_export(pic_state *, pic_sym *);
|
||||
|
||||
pic_noreturn void pic_panic(pic_state *, const char *);
|
||||
pic_noreturn void pic_errorf(pic_state *, const char *, ...);
|
||||
|
|
|
@ -19,11 +19,18 @@ struct pic_dict {
|
|||
|
||||
struct pic_dict *pic_make_dict(pic_state *);
|
||||
|
||||
pic_value pic_dict_ref(pic_state *, struct pic_dict *, pic_value);
|
||||
void pic_dict_set(pic_state *, struct pic_dict *, pic_value, pic_value);
|
||||
void pic_dict_del(pic_state *, struct pic_dict *, pic_value);
|
||||
#define pic_dict_for_each(sym, dict) \
|
||||
pic_dict_for_each_helper_((sym), PIC_GENSYM(tmp), (dict))
|
||||
#define pic_dict_for_each_helper_(var, tmp, dict) \
|
||||
for (xh_entry *tmp = xh_begin(&dict->hash); \
|
||||
(tmp && ((var = xh_key(tmp, pic_sym *)), 1)); \
|
||||
tmp = xh_next(tmp))
|
||||
|
||||
pic_value pic_dict_ref(pic_state *, struct pic_dict *, pic_sym *);
|
||||
void pic_dict_set(pic_state *, struct pic_dict *, pic_sym *, pic_value);
|
||||
void pic_dict_del(pic_state *, struct pic_dict *, pic_sym *);
|
||||
size_t pic_dict_size(pic_state *, struct pic_dict *);
|
||||
bool pic_dict_has(pic_state *, struct pic_dict *, pic_value);
|
||||
bool pic_dict_has(pic_state *, struct pic_dict *, pic_sym *);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ extern "C" {
|
|||
|
||||
struct pic_error {
|
||||
PIC_OBJECT_HEADER
|
||||
pic_sym type;
|
||||
pic_sym *type;
|
||||
pic_str *msg;
|
||||
pic_value irrs;
|
||||
pic_str *stack;
|
||||
|
@ -22,7 +22,7 @@ struct pic_error {
|
|||
#define pic_error_p(v) (pic_type(v) == PIC_TT_ERROR)
|
||||
#define pic_error_ptr(v) ((struct pic_error *)pic_ptr(v))
|
||||
|
||||
struct pic_error *pic_make_error(pic_state *, pic_sym, const char *, pic_list);
|
||||
struct pic_error *pic_make_error(pic_state *, pic_sym *, const char *, pic_list);
|
||||
|
||||
/* do not return from try block! */
|
||||
|
||||
|
@ -44,7 +44,7 @@ void pic_pop_try(pic_state *);
|
|||
|
||||
pic_value pic_raise_continuable(pic_state *, pic_value);
|
||||
pic_noreturn void pic_raise(pic_state *, pic_value);
|
||||
pic_noreturn void pic_throw(pic_state *, pic_sym, const char *, pic_list);
|
||||
pic_noreturn void pic_throw(pic_state *, pic_sym *, const char *, pic_list);
|
||||
pic_noreturn void pic_error(pic_state *, const char *, pic_list);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -35,8 +35,8 @@ enum pic_opcode {
|
|||
OP_CAR,
|
||||
OP_CDR,
|
||||
OP_NILP,
|
||||
OP_SYMBOL_P,
|
||||
OP_PAIR_P,
|
||||
OP_SYMBOLP,
|
||||
OP_PAIRP,
|
||||
OP_ADD,
|
||||
OP_SUB,
|
||||
OP_MUL,
|
||||
|
@ -62,13 +62,14 @@ struct pic_code {
|
|||
|
||||
struct pic_irep {
|
||||
PIC_OBJECT_HEADER
|
||||
pic_sym name;
|
||||
pic_sym *name;
|
||||
pic_code *code;
|
||||
int argc, localc, capturec;
|
||||
bool varg;
|
||||
struct pic_irep **irep;
|
||||
pic_value *pool;
|
||||
size_t clen, ilen, plen;
|
||||
pic_sym **syms;
|
||||
size_t clen, ilen, plen, slen;
|
||||
};
|
||||
|
||||
pic_value pic_analyze(pic_state *, pic_value);
|
||||
|
@ -151,11 +152,11 @@ pic_dump_code(pic_code c)
|
|||
case OP_NILP:
|
||||
puts("OP_NILP");
|
||||
break;
|
||||
case OP_SYMBOL_P:
|
||||
puts("OP_SYMBOL_P");
|
||||
case OP_SYMBOLP:
|
||||
puts("OP_SYMBOLP");
|
||||
break;
|
||||
case OP_PAIR_P:
|
||||
puts("OP_PAIR_P");
|
||||
case OP_PAIRP:
|
||||
puts("OP_PAIRP");
|
||||
break;
|
||||
case OP_CDR:
|
||||
puts("OP_CDR");
|
||||
|
|
|
@ -13,7 +13,7 @@ struct pic_lib {
|
|||
PIC_OBJECT_HEADER
|
||||
pic_value name;
|
||||
struct pic_senv *env;
|
||||
xhash exports;
|
||||
struct pic_dict *exports;
|
||||
};
|
||||
|
||||
#define pic_lib_ptr(o) ((struct pic_lib *)pic_ptr(o))
|
||||
|
|
|
@ -11,35 +11,26 @@ extern "C" {
|
|||
|
||||
struct pic_senv {
|
||||
PIC_OBJECT_HEADER
|
||||
xhash map;
|
||||
struct pic_dict *map;
|
||||
pic_value defer;
|
||||
struct pic_senv *up;
|
||||
};
|
||||
|
||||
struct pic_macro {
|
||||
PIC_OBJECT_HEADER
|
||||
struct pic_proc *proc;
|
||||
struct pic_senv *senv;
|
||||
};
|
||||
|
||||
#define pic_macro_p(v) (pic_type(v) == PIC_TT_MACRO)
|
||||
#define pic_macro_ptr(v) ((struct pic_macro *)pic_ptr(v))
|
||||
|
||||
#define pic_senv_p(v) (pic_type(v) == PIC_TT_SENV)
|
||||
#define pic_senv_ptr(v) ((struct pic_senv *)pic_ptr(v))
|
||||
|
||||
struct pic_senv *pic_null_syntactic_environment(pic_state *);
|
||||
|
||||
bool pic_identifier_p(pic_state *pic, pic_value obj);
|
||||
bool pic_identifier_eq_p(pic_state *, struct pic_senv *, pic_sym, struct pic_senv *, pic_sym);
|
||||
bool pic_identifier_eq_p(pic_state *, struct pic_senv *, pic_sym *, struct pic_senv *, pic_sym *);
|
||||
|
||||
struct pic_senv *pic_make_senv(pic_state *, struct pic_senv *);
|
||||
|
||||
pic_sym pic_add_rename(pic_state *, struct pic_senv *, pic_sym);
|
||||
bool pic_find_rename(pic_state *, struct pic_senv *, pic_sym, pic_sym * /* = NULL */);
|
||||
void pic_put_rename(pic_state *, struct pic_senv *, pic_sym, pic_sym);
|
||||
pic_sym *pic_add_rename(pic_state *, struct pic_senv *, pic_sym *);
|
||||
bool pic_find_rename(pic_state *, struct pic_senv *, pic_sym *, pic_sym ** /* = NULL */);
|
||||
void pic_put_rename(pic_state *, struct pic_senv *, pic_sym *, pic_sym *);
|
||||
|
||||
void pic_define_syntactic_keyword(pic_state *, struct pic_senv *, pic_sym, pic_sym);
|
||||
void pic_define_syntactic_keyword(pic_state *, struct pic_senv *, pic_sym *, pic_sym *);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ extern "C" {
|
|||
/* native C function */
|
||||
struct pic_func {
|
||||
pic_func_t f;
|
||||
pic_sym name;
|
||||
pic_sym *name;
|
||||
};
|
||||
|
||||
struct pic_env {
|
||||
|
@ -48,7 +48,7 @@ struct pic_proc {
|
|||
struct pic_proc *pic_make_proc(pic_state *, pic_func_t, const char *);
|
||||
struct pic_proc *pic_make_proc_irep(pic_state *, struct pic_irep *, struct pic_env *);
|
||||
|
||||
pic_sym pic_proc_name(struct pic_proc *);
|
||||
pic_sym *pic_proc_name(struct pic_proc *);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ extern "C" {
|
|||
|
||||
struct pic_record {
|
||||
PIC_OBJECT_HEADER
|
||||
xhash hash;
|
||||
struct pic_dict *data;
|
||||
};
|
||||
|
||||
#define pic_record_p(v) (pic_type(v) == PIC_TT_RECORD)
|
||||
|
@ -20,8 +20,8 @@ struct pic_record {
|
|||
struct pic_record *pic_make_record(pic_state *, pic_value);
|
||||
|
||||
pic_value pic_record_type(pic_state *, struct pic_record *);
|
||||
pic_value pic_record_ref(pic_state *, struct pic_record *, pic_sym);
|
||||
void pic_record_set(pic_state *, struct pic_record *, pic_sym, pic_value);
|
||||
pic_value pic_record_ref(pic_state *, struct pic_record *, pic_sym *);
|
||||
void pic_record_set(pic_state *, struct pic_record *, pic_sym *, pic_value);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#ifndef PICRIN_SYMBOL_H
|
||||
#define PICRIN_SYMBOL_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct pic_symbol {
|
||||
PIC_OBJECT_HEADER
|
||||
pic_str *str;
|
||||
};
|
||||
|
||||
#define pic_sym_p(v) (pic_type(v) == PIC_TT_SYMBOL)
|
||||
#define pic_sym_ptr(v) ((struct pic_symbol *)pic_ptr(v))
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -32,7 +32,6 @@ extern "C" {
|
|||
#if GCC_VERSION >= 40500 || __clang__
|
||||
# define PIC_UNREACHABLE() (__builtin_unreachable())
|
||||
#else
|
||||
# include <assert.h>
|
||||
# define PIC_UNREACHABLE() (assert(false))
|
||||
#endif
|
||||
|
||||
|
|
|
@ -9,12 +9,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* pic_sym is just an alias of int.
|
||||
*/
|
||||
|
||||
typedef int pic_sym;
|
||||
|
||||
/**
|
||||
* `undef` values never seen from user-end: that is,
|
||||
* it's used only for repsenting internal special state
|
||||
|
@ -27,7 +21,6 @@ enum pic_vtype {
|
|||
PIC_VTYPE_UNDEF,
|
||||
PIC_VTYPE_FLOAT,
|
||||
PIC_VTYPE_INT,
|
||||
PIC_VTYPE_SYMBOL,
|
||||
PIC_VTYPE_CHAR,
|
||||
PIC_VTYPE_EOF,
|
||||
PIC_VTYPE_HEAP
|
||||
|
@ -40,7 +33,6 @@ enum pic_vtype {
|
|||
* float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
|
||||
* ptr : 111111111111TTTT PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP
|
||||
* int : 1111111111110110 0000000000000000 IIIIIIIIIIIIIIII IIIIIIIIIIIIIIII
|
||||
* sym : 1111111111110111 0000000000000000 SSSSSSSSSSSSSSSS SSSSSSSSSSSSSSSS
|
||||
* char : 1111111111111000 0000000000000000 CCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCC
|
||||
*/
|
||||
|
||||
|
@ -71,14 +63,6 @@ pic_int(pic_value v)
|
|||
return u.i;
|
||||
}
|
||||
|
||||
static inline int
|
||||
pic_sym(pic_value v)
|
||||
{
|
||||
union { int i; unsigned u; } u;
|
||||
u.u = v & 0xfffffffful;
|
||||
return u.i;
|
||||
}
|
||||
|
||||
#define pic_char(v) ((v) & 0xfffffffful)
|
||||
|
||||
#else
|
||||
|
@ -89,7 +73,6 @@ typedef struct {
|
|||
void *data;
|
||||
double f;
|
||||
int i;
|
||||
pic_sym sym;
|
||||
char c;
|
||||
} u;
|
||||
} pic_value;
|
||||
|
@ -100,7 +83,6 @@ typedef struct {
|
|||
|
||||
#define pic_float(v) ((v).u.f)
|
||||
#define pic_int(v) ((v).u.i)
|
||||
#define pic_sym(v) ((v).u.sym)
|
||||
#define pic_char(v) ((v).u.c)
|
||||
|
||||
#endif
|
||||
|
@ -111,11 +93,11 @@ enum pic_tt {
|
|||
PIC_TT_BOOL,
|
||||
PIC_TT_FLOAT,
|
||||
PIC_TT_INT,
|
||||
PIC_TT_SYMBOL,
|
||||
PIC_TT_CHAR,
|
||||
PIC_TT_EOF,
|
||||
PIC_TT_UNDEF,
|
||||
/* heap */
|
||||
PIC_TT_SYMBOL,
|
||||
PIC_TT_PAIR,
|
||||
PIC_TT_STRING,
|
||||
PIC_TT_VECTOR,
|
||||
|
@ -125,7 +107,6 @@ enum pic_tt {
|
|||
PIC_TT_ERROR,
|
||||
PIC_TT_ENV,
|
||||
PIC_TT_SENV,
|
||||
PIC_TT_MACRO,
|
||||
PIC_TT_LIB,
|
||||
PIC_TT_IREP,
|
||||
PIC_TT_DATA,
|
||||
|
@ -140,6 +121,7 @@ struct pic_object {
|
|||
PIC_OBJECT_HEADER
|
||||
};
|
||||
|
||||
struct pic_symbol;
|
||||
struct pic_pair;
|
||||
struct pic_string;
|
||||
struct pic_vector;
|
||||
|
@ -151,6 +133,7 @@ struct pic_error;
|
|||
|
||||
/* set aliases to basic types */
|
||||
typedef pic_value pic_list;
|
||||
typedef struct pic_symbol pic_sym;
|
||||
typedef struct pic_pair pic_pair;
|
||||
typedef struct pic_string pic_str;
|
||||
typedef struct pic_vector pic_vec;
|
||||
|
@ -165,7 +148,6 @@ typedef struct pic_blob pic_blob;
|
|||
#define pic_undef_p(v) (pic_vtype(v) == PIC_VTYPE_UNDEF)
|
||||
#define pic_float_p(v) (pic_vtype(v) == PIC_VTYPE_FLOAT)
|
||||
#define pic_int_p(v) (pic_vtype(v) == PIC_VTYPE_INT)
|
||||
#define pic_sym_p(v) (pic_vtype(v) == PIC_VTYPE_SYMBOL)
|
||||
#define pic_char_p(v) (pic_vtype(v) == PIC_VTYPE_CHAR)
|
||||
#define pic_eof_p(v) (pic_vtype(v) == PIC_VTYPE_EOF)
|
||||
|
||||
|
@ -190,12 +172,9 @@ static inline pic_value pic_obj_value(void *);
|
|||
static inline pic_value pic_float_value(double);
|
||||
static inline pic_value pic_int_value(int);
|
||||
static inline pic_value pic_size_value(size_t);
|
||||
static inline pic_value pic_sym_value(pic_sym);
|
||||
static inline pic_value pic_char_value(char c);
|
||||
static inline pic_value pic_none_value();
|
||||
|
||||
#define pic_symbol_value(sym) pic_sym_value(sym)
|
||||
|
||||
static inline bool pic_eq_p(pic_value, pic_value);
|
||||
static inline bool pic_eqv_p(pic_value, pic_value);
|
||||
|
||||
|
@ -215,8 +194,6 @@ pic_type(pic_value v)
|
|||
return PIC_TT_FLOAT;
|
||||
case PIC_VTYPE_INT:
|
||||
return PIC_TT_INT;
|
||||
case PIC_VTYPE_SYMBOL:
|
||||
return PIC_TT_SYMBOL;
|
||||
case PIC_VTYPE_CHAR:
|
||||
return PIC_TT_CHAR;
|
||||
case PIC_VTYPE_EOF:
|
||||
|
@ -266,8 +243,6 @@ pic_type_repr(enum pic_tt tt)
|
|||
return "proc";
|
||||
case PIC_TT_SENV:
|
||||
return "senv";
|
||||
case PIC_TT_MACRO:
|
||||
return "macro";
|
||||
case PIC_TT_LIB:
|
||||
return "lib";
|
||||
case PIC_TT_IREP:
|
||||
|
@ -373,19 +348,6 @@ pic_int_value(int i)
|
|||
return v;
|
||||
}
|
||||
|
||||
static inline pic_value
|
||||
pic_symbol_value(pic_sym sym)
|
||||
{
|
||||
union { int i; unsigned u; } u;
|
||||
pic_value v;
|
||||
|
||||
u.i = sym;
|
||||
|
||||
pic_init_value(v, PIC_VTYPE_SYMBOL);
|
||||
v |= u.u;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline pic_value
|
||||
pic_char_value(char c)
|
||||
{
|
||||
|
@ -428,16 +390,6 @@ pic_int_value(int i)
|
|||
return v;
|
||||
}
|
||||
|
||||
static inline pic_value
|
||||
pic_symbol_value(pic_sym sym)
|
||||
{
|
||||
pic_value v;
|
||||
|
||||
pic_init_value(v, PIC_VTYPE_SYMBOL);
|
||||
v.u.sym = sym;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline pic_value
|
||||
pic_char_value(char c)
|
||||
{
|
||||
|
@ -496,8 +448,6 @@ pic_eq_p(pic_value x, pic_value y)
|
|||
return true;
|
||||
case PIC_TT_BOOL:
|
||||
return pic_vtype(x) == pic_vtype(y);
|
||||
case PIC_TT_SYMBOL:
|
||||
return pic_sym(x) == pic_sym(y);
|
||||
default:
|
||||
return pic_ptr(x) == pic_ptr(y);
|
||||
}
|
||||
|
@ -514,8 +464,6 @@ pic_eqv_p(pic_value x, pic_value y)
|
|||
return true;
|
||||
case PIC_TT_BOOL:
|
||||
return pic_vtype(x) == pic_vtype(y);
|
||||
case PIC_TT_SYMBOL:
|
||||
return pic_sym(x) == pic_sym(y);
|
||||
case PIC_TT_FLOAT:
|
||||
return pic_float(x) == pic_float(y);
|
||||
case PIC_TT_INT:
|
||||
|
|
|
@ -5,12 +5,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
int ungot;
|
||||
int flags;
|
||||
|
|
|
@ -9,12 +9,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* simple object to object hash table */
|
||||
|
||||
#define XHASH_INIT_SIZE 11
|
||||
|
|
|
@ -5,11 +5,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* public APIs */
|
||||
|
||||
typedef struct xrope xrope;
|
||||
|
|
|
@ -9,11 +9,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
typedef struct xvect {
|
||||
char *data;
|
||||
size_t size, mask, head, tail, width;
|
||||
|
|
10
init.c
10
init.c
|
@ -11,16 +11,13 @@
|
|||
void
|
||||
pic_add_feature(pic_state *pic, const char *feature)
|
||||
{
|
||||
pic_push(pic, pic_sym_value(pic_intern_cstr(pic, feature)), pic->features);
|
||||
pic_push(pic, pic_obj_value(pic_intern_cstr(pic, feature)), pic->features);
|
||||
}
|
||||
|
||||
void pic_init_bool(pic_state *);
|
||||
void pic_init_pair(pic_state *);
|
||||
void pic_init_port(pic_state *);
|
||||
void pic_init_number(pic_state *);
|
||||
void pic_init_time(pic_state *);
|
||||
void pic_init_system(pic_state *);
|
||||
void pic_init_file(pic_state *);
|
||||
void pic_init_proc(pic_state *);
|
||||
void pic_init_symbol(pic_state *);
|
||||
void pic_init_vector(pic_state *);
|
||||
|
@ -31,7 +28,6 @@ void pic_init_error(pic_state *);
|
|||
void pic_init_str(pic_state *);
|
||||
void pic_init_macro(pic_state *);
|
||||
void pic_init_var(pic_state *);
|
||||
void pic_init_load(pic_state *);
|
||||
void pic_init_write(pic_state *);
|
||||
void pic_init_read(pic_state *);
|
||||
void pic_init_dict(pic_state *);
|
||||
|
@ -119,9 +115,6 @@ pic_init_core(pic_state *pic)
|
|||
pic_init_pair(pic); DONE;
|
||||
pic_init_port(pic); DONE;
|
||||
pic_init_number(pic); DONE;
|
||||
pic_init_time(pic); DONE;
|
||||
pic_init_system(pic); DONE;
|
||||
pic_init_file(pic); DONE;
|
||||
pic_init_proc(pic); DONE;
|
||||
pic_init_symbol(pic); DONE;
|
||||
pic_init_vector(pic); DONE;
|
||||
|
@ -132,7 +125,6 @@ pic_init_core(pic_state *pic)
|
|||
pic_init_str(pic); DONE;
|
||||
pic_init_macro(pic); DONE;
|
||||
pic_init_var(pic); DONE;
|
||||
pic_init_load(pic); DONE;
|
||||
pic_init_write(pic); DONE;
|
||||
pic_init_read(pic); DONE;
|
||||
pic_init_dict(pic); DONE;
|
||||
|
|
108
lib.c
108
lib.c
|
@ -9,12 +9,15 @@
|
|||
#include "picrin/error.h"
|
||||
#include "picrin/string.h"
|
||||
#include "picrin/proc.h"
|
||||
#include "picrin/dict.h"
|
||||
#include "picrin/symbol.h"
|
||||
|
||||
struct pic_lib *
|
||||
pic_open_library(pic_state *pic, pic_value name)
|
||||
{
|
||||
struct pic_lib *lib;
|
||||
struct pic_senv *senv;
|
||||
struct pic_dict *exports;
|
||||
|
||||
if ((lib = pic_find_library(pic, name)) != NULL) {
|
||||
|
||||
|
@ -28,11 +31,12 @@ pic_open_library(pic_state *pic, pic_value name)
|
|||
}
|
||||
|
||||
senv = pic_null_syntactic_environment(pic);
|
||||
exports = pic_make_dict(pic);
|
||||
|
||||
lib = (struct pic_lib *)pic_obj_alloc(pic, sizeof(struct pic_lib), PIC_TT_LIB);
|
||||
lib->env = senv;
|
||||
lib->name = name;
|
||||
xh_init_int(&lib->exports, sizeof(pic_sym));
|
||||
lib->env = senv;
|
||||
lib->exports = exports;
|
||||
|
||||
/* register! */
|
||||
pic->libs = pic_acons(pic, name, pic_obj_value(lib), pic->libs);
|
||||
|
@ -65,93 +69,85 @@ pic_find_library(pic_state *pic, pic_value spec)
|
|||
}
|
||||
|
||||
static void
|
||||
import_table(pic_state *pic, pic_value spec, xhash *imports)
|
||||
import_table(pic_state *pic, pic_value spec, struct pic_dict *imports)
|
||||
{
|
||||
struct pic_lib *lib;
|
||||
xhash table;
|
||||
pic_value val;
|
||||
pic_sym sym, id, tag;
|
||||
xh_entry *it;
|
||||
struct pic_dict *table;
|
||||
pic_value val, tmp, prefix;
|
||||
pic_sym *sym, *id, *tag;
|
||||
|
||||
xh_init_int(&table, sizeof(pic_sym));
|
||||
table = pic_make_dict(pic);
|
||||
|
||||
if (pic_pair_p(spec) && pic_sym_p(pic_car(pic, spec))) {
|
||||
|
||||
tag = pic_sym(pic_car(pic, spec));
|
||||
tag = pic_sym_ptr(pic_car(pic, spec));
|
||||
|
||||
if (tag == pic->sONLY) {
|
||||
import_table(pic, pic_cadr(pic, spec), &table);
|
||||
import_table(pic, pic_cadr(pic, spec), table);
|
||||
|
||||
pic_for_each (val, pic_cddr(pic, spec)) {
|
||||
xh_put_int(imports, pic_sym(val), &xh_val(xh_get_int(&table, pic_sym(val)), pic_sym));
|
||||
pic_dict_set(pic, imports, pic_sym_ptr(val), pic_dict_ref(pic, table, pic_sym_ptr(val)));
|
||||
}
|
||||
goto exit;
|
||||
return;
|
||||
}
|
||||
if (tag == pic->sRENAME) {
|
||||
import_table(pic, pic_cadr(pic, spec), imports);
|
||||
|
||||
pic_for_each (val, pic_cddr(pic, spec)) {
|
||||
id = xh_val(xh_get_int(imports, pic_sym(pic_car(pic, val))), pic_sym);
|
||||
xh_del_int(imports, pic_sym(pic_car(pic, val)));
|
||||
xh_put_int(imports, pic_sym(pic_cadr(pic, val)), &id);
|
||||
tmp = pic_dict_ref(pic, imports, pic_sym_ptr(pic_car(pic, val)));
|
||||
pic_dict_del(pic, imports, pic_sym_ptr(pic_car(pic, val)));
|
||||
pic_dict_set(pic, imports, pic_sym_ptr(pic_cadr(pic, val)), tmp);
|
||||
}
|
||||
goto exit;
|
||||
return;
|
||||
}
|
||||
if (tag == pic->sPREFIX) {
|
||||
import_table(pic, pic_cadr(pic, spec), &table);
|
||||
for (it = xh_begin(&table); it != NULL; it = xh_next(it)) {
|
||||
val = pic_list_ref(pic, spec, 2);
|
||||
sym = pic_intern_str(pic, pic_format(pic, "~s~s", val, pic_sym_value(xh_key(it, pic_sym))));
|
||||
xh_put_int(imports, sym, &xh_val(it, pic_sym));
|
||||
import_table(pic, pic_cadr(pic, spec), table);
|
||||
|
||||
prefix = pic_list_ref(pic, spec, 2);
|
||||
pic_dict_for_each (sym, table) {
|
||||
id = pic_intern(pic, pic_format(pic, "~s~s", prefix, pic_obj_value(sym)));
|
||||
pic_dict_set(pic, imports, id, pic_dict_ref(pic, table, sym));
|
||||
}
|
||||
goto exit;
|
||||
return;
|
||||
}
|
||||
if (tag == pic->sEXCEPT) {
|
||||
import_table(pic, pic_cadr(pic, spec), imports);
|
||||
pic_for_each (val, pic_cddr(pic, spec)) {
|
||||
xh_del_int(imports, pic_sym(val));
|
||||
pic_dict_del(pic, imports, pic_sym_ptr(val));
|
||||
}
|
||||
goto exit;
|
||||
return;
|
||||
}
|
||||
}
|
||||
lib = pic_find_library(pic, spec);
|
||||
if (! lib) {
|
||||
pic_errorf(pic, "library not found: ~a", spec);
|
||||
}
|
||||
for (it = xh_begin(&lib->exports); it != NULL; it = xh_next(it)) {
|
||||
xh_put_int(imports, xh_key(it, pic_sym), &xh_val(it, pic_sym));
|
||||
pic_dict_for_each (sym, lib->exports) {
|
||||
pic_dict_set(pic, imports, sym, pic_dict_ref(pic, lib->exports, sym));
|
||||
}
|
||||
|
||||
exit:
|
||||
xh_destroy(&table);
|
||||
}
|
||||
|
||||
static void
|
||||
import(pic_state *pic, pic_value spec)
|
||||
{
|
||||
xhash imports;
|
||||
xh_entry *it;
|
||||
struct pic_dict *imports;
|
||||
pic_sym *sym;
|
||||
|
||||
xh_init_int(&imports, sizeof(pic_sym)); /* pic_sym to pic_sym */
|
||||
imports = pic_make_dict(pic);
|
||||
|
||||
import_table(pic, spec, &imports);
|
||||
import_table(pic, spec, imports);
|
||||
|
||||
for (it = xh_begin(&imports); it != NULL; it = xh_next(it)) {
|
||||
|
||||
#if DEBUG
|
||||
printf("* importing %s as %s\n", pic_symbol_name(pic, xh_key(it, pic_sym)), pic_symbol_name(pic, xh_val(it, pic_sym)));
|
||||
#endif
|
||||
|
||||
pic_put_rename(pic, pic->lib->env, xh_key(it, pic_sym), xh_val(it, pic_sym));
|
||||
pic_dict_for_each (sym, imports) {
|
||||
pic_put_rename(pic, pic->lib->env, sym, pic_sym_ptr(pic_dict_ref(pic, imports, sym)));
|
||||
}
|
||||
|
||||
xh_destroy(&imports);
|
||||
}
|
||||
|
||||
static void
|
||||
export(pic_state *pic, pic_value spec)
|
||||
{
|
||||
const pic_sym sRENAME = pic_intern_cstr(pic, "rename");
|
||||
pic_sym *sRENAME = pic_intern_cstr(pic, "rename");
|
||||
pic_value a, b;
|
||||
pic_sym rename;
|
||||
pic_sym *rename;
|
||||
|
||||
if (pic_sym_p(spec)) { /* (export a) */
|
||||
a = b = spec;
|
||||
|
@ -160,7 +156,7 @@ export(pic_state *pic, pic_value spec)
|
|||
goto fail;
|
||||
if (! (pic_length(pic, spec) == 3))
|
||||
goto fail;
|
||||
if (! pic_eq_p(pic_car(pic, spec), pic_sym_value(sRENAME)))
|
||||
if (! pic_eq_p(pic_car(pic, spec), pic_obj_value(sRENAME)))
|
||||
goto fail;
|
||||
if (! pic_sym_p(a = pic_list_ref(pic, spec, 1)))
|
||||
goto fail;
|
||||
|
@ -168,15 +164,15 @@ export(pic_state *pic, pic_value spec)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (! pic_find_rename(pic, pic->lib->env, pic_sym(a), &rename)) {
|
||||
pic_errorf(pic, "export: symbol not defined %s", pic_symbol_name(pic, pic_sym(a)));
|
||||
if (! pic_find_rename(pic, pic->lib->env, pic_sym_ptr(a), &rename)) {
|
||||
pic_errorf(pic, "export: symbol not defined %s", pic_symbol_name(pic, pic_sym_ptr(a)));
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
printf("* exporting %s as %s\n", pic_symbol_name(pic, pic_sym(b)), pic_symbol_name(pic, rename));
|
||||
printf("* exporting %s as %s\n", pic_symbol_name(pic, pic_sym_ptr(b)), pic_symbol_name(pic, rename));
|
||||
#endif
|
||||
|
||||
xh_put_int(&pic->lib->exports, pic_sym(b), &rename);
|
||||
pic_dict_set(pic, pic->lib->exports, pic_sym_ptr(b), pic_obj_value(rename));
|
||||
|
||||
return;
|
||||
|
||||
|
@ -197,18 +193,18 @@ pic_import_library(pic_state *pic, struct pic_lib *lib)
|
|||
}
|
||||
|
||||
void
|
||||
pic_export(pic_state *pic, pic_sym sym)
|
||||
pic_export(pic_state *pic, pic_sym *sym)
|
||||
{
|
||||
export(pic, pic_sym_value(sym));
|
||||
export(pic, pic_obj_value(sym));
|
||||
}
|
||||
|
||||
static bool
|
||||
condexpand(pic_state *pic, pic_value clause)
|
||||
{
|
||||
pic_sym tag;
|
||||
pic_sym *tag;
|
||||
pic_value c, feature;
|
||||
|
||||
if (pic_eq_p(clause, pic_sym_value(pic->sELSE))) {
|
||||
if (pic_eq_p(clause, pic_obj_value(pic->sELSE))) {
|
||||
return true;
|
||||
}
|
||||
if (pic_sym_p(clause)) {
|
||||
|
@ -222,7 +218,7 @@ condexpand(pic_state *pic, pic_value clause)
|
|||
if (! (pic_pair_p(clause) && pic_sym_p(pic_car(pic, clause)))) {
|
||||
pic_errorf(pic, "invalid 'cond-expand' clause ~s", clause);
|
||||
} else {
|
||||
tag = pic_sym(pic_car(pic, clause));
|
||||
tag = pic_sym_ptr(pic_car(pic, clause));
|
||||
}
|
||||
|
||||
if (tag == pic->sLIBRARY) {
|
||||
|
@ -259,7 +255,7 @@ pic_lib_condexpand(pic_state *pic)
|
|||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (condexpand(pic, pic_car(pic, clauses[i]))) {
|
||||
return pic_cons(pic, pic_sym_value(pic->rBEGIN), pic_cdr(pic, clauses[i]));
|
||||
return pic_cons(pic, pic_obj_value(pic->rBEGIN), pic_cdr(pic, clauses[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,7 +335,7 @@ pic_lib_in_library(pic_state *pic)
|
|||
void
|
||||
pic_init_lib(pic_state *pic)
|
||||
{
|
||||
void pic_defmacro(pic_state *, pic_sym, pic_sym, pic_func_t);
|
||||
void pic_defmacro(pic_state *, pic_sym *, pic_sym *, pic_func_t);
|
||||
|
||||
pic_defmacro(pic, pic->sCOND_EXPAND, pic->rCOND_EXPAND, pic_lib_condexpand);
|
||||
pic_defmacro(pic, pic->sIMPORT, pic->rIMPORT, pic_lib_import);
|
||||
|
|
43
load.c
43
load.c
|
@ -3,11 +3,10 @@
|
|||
*/
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/pair.h"
|
||||
#include "picrin/port.h"
|
||||
#include "picrin/error.h"
|
||||
|
||||
static void
|
||||
void
|
||||
pic_load_port(pic_state *pic, struct pic_port *port)
|
||||
{
|
||||
pic_value form;
|
||||
|
@ -35,43 +34,3 @@ pic_load_cstr(pic_state *pic, const char *src)
|
|||
|
||||
pic_close_port(pic, port);
|
||||
}
|
||||
|
||||
void
|
||||
pic_load(pic_state *pic, const char *filename)
|
||||
{
|
||||
struct pic_port *port;
|
||||
xFILE *file;
|
||||
|
||||
file = xfopen(filename, "r");
|
||||
if (file == NULL) {
|
||||
pic_errorf(pic, "could not open file: %s", filename);
|
||||
}
|
||||
|
||||
port = (struct pic_port *)pic_obj_alloc(pic, sizeof(struct pic_port), PIC_TT_PORT);
|
||||
port->file = file;
|
||||
port->flags = PIC_PORT_IN | PIC_PORT_TEXT;
|
||||
port->status = PIC_PORT_OPEN;
|
||||
|
||||
pic_load_port(pic, port);
|
||||
|
||||
pic_close_port(pic, port);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_load_load(pic_state *pic)
|
||||
{
|
||||
pic_value envid;
|
||||
char *fn;
|
||||
|
||||
pic_get_args(pic, "z|o", &fn, &envid);
|
||||
|
||||
pic_load(pic, fn);
|
||||
|
||||
return pic_none_value();
|
||||
}
|
||||
|
||||
void
|
||||
pic_init_load(pic_state *pic)
|
||||
{
|
||||
pic_defun(pic, "load", pic_load_load);
|
||||
}
|
||||
|
|
146
macro.c
146
macro.c
|
@ -11,11 +11,12 @@
|
|||
#include "picrin/error.h"
|
||||
#include "picrin/dict.h"
|
||||
#include "picrin/cont.h"
|
||||
#include "picrin/symbol.h"
|
||||
|
||||
pic_sym
|
||||
pic_add_rename(pic_state *pic, struct pic_senv *senv, pic_sym sym)
|
||||
pic_sym *
|
||||
pic_add_rename(pic_state *pic, struct pic_senv *senv, pic_sym *sym)
|
||||
{
|
||||
pic_sym rename;
|
||||
pic_sym *rename;
|
||||
|
||||
rename = pic_gensym(pic, sym);
|
||||
pic_put_rename(pic, senv, sym, rename);
|
||||
|
@ -23,56 +24,42 @@ pic_add_rename(pic_state *pic, struct pic_senv *senv, pic_sym sym)
|
|||
}
|
||||
|
||||
void
|
||||
pic_put_rename(pic_state *pic, struct pic_senv *senv, pic_sym sym, pic_sym rename)
|
||||
pic_put_rename(pic_state *pic, struct pic_senv *senv, pic_sym *sym, pic_sym *rename)
|
||||
{
|
||||
PIC_UNUSED(pic);
|
||||
|
||||
xh_put_int(&senv->map, sym, &rename);
|
||||
pic_dict_set(pic, senv->map, sym, pic_obj_value(rename));
|
||||
}
|
||||
|
||||
bool
|
||||
pic_find_rename(pic_state *pic, struct pic_senv *senv, pic_sym sym, pic_sym *rename)
|
||||
pic_find_rename(pic_state *pic, struct pic_senv *senv, pic_sym *sym, pic_sym **rename)
|
||||
{
|
||||
xh_entry *e;
|
||||
|
||||
PIC_UNUSED(pic);
|
||||
|
||||
if ((e = xh_get_int(&senv->map, sym)) == NULL) {
|
||||
if (! pic_dict_has(pic, senv->map, sym)) {
|
||||
return false;
|
||||
}
|
||||
if (rename != NULL) {
|
||||
*rename = xh_val(e, pic_sym);
|
||||
*rename = pic_sym_ptr(pic_dict_ref(pic, senv->map, sym));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
define_macro(pic_state *pic, pic_sym rename, struct pic_proc *proc, struct pic_senv *senv)
|
||||
define_macro(pic_state *pic, pic_sym *rename, struct pic_proc *mac)
|
||||
{
|
||||
struct pic_macro *mac;
|
||||
|
||||
mac = (struct pic_macro *)pic_obj_alloc(pic, sizeof(struct pic_macro), PIC_TT_MACRO);
|
||||
mac->senv = senv;
|
||||
mac->proc = proc;
|
||||
|
||||
xh_put_int(&pic->macros, rename, &mac);
|
||||
pic_dict_set(pic, pic->macros, rename, pic_obj_value(mac));
|
||||
}
|
||||
|
||||
static struct pic_macro *
|
||||
find_macro(pic_state *pic, pic_sym rename)
|
||||
static struct pic_proc *
|
||||
find_macro(pic_state *pic, pic_sym *rename)
|
||||
{
|
||||
xh_entry *e;
|
||||
|
||||
if ((e = xh_get_int(&pic->macros, rename)) == NULL) {
|
||||
if (! pic_dict_has(pic, pic->macros, rename)) {
|
||||
return NULL;
|
||||
}
|
||||
return xh_val(e, struct pic_macro *);
|
||||
return pic_proc_ptr(pic_dict_ref(pic, pic->macros, rename));
|
||||
}
|
||||
|
||||
static pic_sym
|
||||
make_identifier(pic_state *pic, pic_sym sym, struct pic_senv *senv)
|
||||
static pic_sym *
|
||||
make_identifier(pic_state *pic, pic_sym *sym, struct pic_senv *senv)
|
||||
{
|
||||
pic_sym rename;
|
||||
pic_sym *rename;
|
||||
|
||||
while (true) {
|
||||
if (pic_find_rename(pic, senv, sym, &rename)) {
|
||||
|
@ -94,15 +81,15 @@ static pic_value macroexpand(pic_state *, pic_value, struct pic_senv *);
|
|||
static pic_value macroexpand_lambda(pic_state *, pic_value, struct pic_senv *);
|
||||
|
||||
static pic_value
|
||||
macroexpand_symbol(pic_state *pic, pic_sym sym, struct pic_senv *senv)
|
||||
macroexpand_symbol(pic_state *pic, pic_sym *sym, struct pic_senv *senv)
|
||||
{
|
||||
return pic_sym_value(make_identifier(pic, sym, senv));
|
||||
return pic_obj_value(make_identifier(pic, sym, senv));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
macroexpand_quote(pic_state *pic, pic_value expr)
|
||||
{
|
||||
return pic_cons(pic, pic_sym_value(pic->rQUOTE), pic_cdr(pic, expr));
|
||||
return pic_cons(pic, pic_obj_value(pic->rQUOTE), pic_cdr(pic, expr));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -172,10 +159,10 @@ macroexpand_lambda(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
|||
if (! pic_sym_p(v)) {
|
||||
pic_errorf(pic, "syntax error");
|
||||
}
|
||||
pic_add_rename(pic, in, pic_sym(v));
|
||||
pic_add_rename(pic, in, pic_sym_ptr(v));
|
||||
}
|
||||
if (pic_sym_p(a)) {
|
||||
pic_add_rename(pic, in, pic_sym(a));
|
||||
pic_add_rename(pic, in, pic_sym_ptr(a));
|
||||
}
|
||||
else if (! pic_nil_p(a)) {
|
||||
pic_errorf(pic, "syntax error");
|
||||
|
@ -186,20 +173,20 @@ macroexpand_lambda(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
|||
|
||||
macroexpand_deferred(pic, in);
|
||||
|
||||
return pic_cons(pic, pic_sym_value(pic->rLAMBDA), pic_cons(pic, formal, body));
|
||||
return pic_cons(pic, pic_obj_value(pic->rLAMBDA), pic_cons(pic, formal, body));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
macroexpand_define(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
||||
{
|
||||
pic_sym sym, rename;
|
||||
pic_sym *sym, *rename;
|
||||
pic_value var, val;
|
||||
|
||||
while (pic_length(pic, expr) >= 2 && pic_pair_p(pic_cadr(pic, expr))) {
|
||||
var = pic_car(pic, pic_cadr(pic, expr));
|
||||
val = pic_cdr(pic, pic_cadr(pic, expr));
|
||||
|
||||
expr = pic_list3(pic, pic_sym_value(pic->rDEFINE), var, pic_cons(pic, pic_sym_value(pic->rLAMBDA), pic_cons(pic, val, pic_cddr(pic, expr))));
|
||||
expr = pic_list3(pic, pic_obj_value(pic->rDEFINE), var, pic_cons(pic, pic_obj_value(pic->rLAMBDA), pic_cons(pic, val, pic_cddr(pic, expr))));
|
||||
}
|
||||
|
||||
if (pic_length(pic, expr) != 3) {
|
||||
|
@ -210,20 +197,20 @@ macroexpand_define(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
|||
if (! pic_sym_p(var)) {
|
||||
pic_errorf(pic, "binding to non-symbol object");
|
||||
}
|
||||
sym = pic_sym(var);
|
||||
sym = pic_sym_ptr(var);
|
||||
if (! pic_find_rename(pic, senv, sym, &rename)) {
|
||||
rename = pic_add_rename(pic, senv, sym);
|
||||
}
|
||||
val = macroexpand(pic, pic_list_ref(pic, expr, 2), senv);
|
||||
|
||||
return pic_list3(pic, pic_sym_value(pic->rDEFINE), pic_sym_value(rename), val);
|
||||
return pic_list3(pic, pic_obj_value(pic->rDEFINE), pic_obj_value(rename), val);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
macroexpand_defsyntax(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
||||
{
|
||||
pic_value var, val;
|
||||
pic_sym sym, rename;
|
||||
pic_sym *sym, *rename;
|
||||
|
||||
if (pic_length(pic, expr) != 3) {
|
||||
pic_errorf(pic, "syntax error");
|
||||
|
@ -233,11 +220,11 @@ macroexpand_defsyntax(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
|||
if (! pic_sym_p(var)) {
|
||||
pic_errorf(pic, "binding to non-symbol object");
|
||||
}
|
||||
sym = pic_sym(var);
|
||||
sym = pic_sym_ptr(var);
|
||||
if (! pic_find_rename(pic, senv, sym, &rename)) {
|
||||
rename = pic_add_rename(pic, senv, sym);
|
||||
} else {
|
||||
pic_warnf(pic, "redefining syntax variable: ~s", pic_sym_value(sym));
|
||||
pic_warnf(pic, "redefining syntax variable: ~s", pic_obj_value(sym));
|
||||
}
|
||||
|
||||
val = pic_cadr(pic, pic_cdr(pic, expr));
|
||||
|
@ -252,13 +239,19 @@ macroexpand_defsyntax(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
|||
pic_errorf(pic, "macro definition \"~s\" evaluates to non-procedure object", var);
|
||||
}
|
||||
|
||||
define_macro(pic, rename, pic_proc_ptr(val), senv);
|
||||
val = pic_apply1(pic, pic_proc_ptr(val), pic_obj_value(senv));
|
||||
|
||||
if (! pic_proc_p(val)) {
|
||||
pic_errorf(pic, "macro definition \"~s\" evaluates to non-procedure object", var);
|
||||
}
|
||||
|
||||
define_macro(pic, rename, pic_proc_ptr(val));
|
||||
|
||||
return pic_none_value();
|
||||
}
|
||||
|
||||
static pic_value
|
||||
macroexpand_macro(pic_state *pic, struct pic_macro *mac, pic_value expr, struct pic_senv *senv)
|
||||
macroexpand_macro(pic_state *pic, struct pic_proc *mac, pic_value expr, struct pic_senv *senv)
|
||||
{
|
||||
pic_value v, args;
|
||||
|
||||
|
@ -268,14 +261,10 @@ macroexpand_macro(pic_state *pic, struct pic_macro *mac, pic_value expr, struct
|
|||
puts("");
|
||||
#endif
|
||||
|
||||
if (mac->senv == NULL) { /* legacy macro */
|
||||
args = pic_cdr(pic, expr);
|
||||
} else {
|
||||
args = pic_list3(pic, expr, pic_obj_value(senv), pic_obj_value(mac->senv));
|
||||
}
|
||||
args = pic_list2(pic, expr, pic_obj_value(senv));
|
||||
|
||||
pic_try {
|
||||
v = pic_apply(pic, mac->proc, args);
|
||||
v = pic_apply(pic, mac, args);
|
||||
} pic_catch {
|
||||
pic_errorf(pic, "macroexpand error while application: %s", pic_errmsg(pic));
|
||||
}
|
||||
|
@ -294,11 +283,11 @@ macroexpand_node(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
|||
{
|
||||
switch (pic_type(expr)) {
|
||||
case PIC_TT_SYMBOL: {
|
||||
return macroexpand_symbol(pic, pic_sym(expr), senv);
|
||||
return macroexpand_symbol(pic, pic_sym_ptr(expr), senv);
|
||||
}
|
||||
case PIC_TT_PAIR: {
|
||||
pic_value car;
|
||||
struct pic_macro *mac;
|
||||
struct pic_proc *mac;
|
||||
|
||||
if (! pic_list_p(expr)) {
|
||||
pic_errorf(pic, "cannot macroexpand improper list: ~s", expr);
|
||||
|
@ -306,7 +295,7 @@ macroexpand_node(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
|||
|
||||
car = macroexpand(pic, pic_car(pic, expr), senv);
|
||||
if (pic_sym_p(car)) {
|
||||
pic_sym tag = pic_sym(car);
|
||||
pic_sym *tag = pic_sym_ptr(car);
|
||||
|
||||
if (tag == pic->rDEFINE_SYNTAX) {
|
||||
return macroexpand_defsyntax(pic, expr, senv);
|
||||
|
@ -389,11 +378,14 @@ struct pic_senv *
|
|||
pic_make_senv(pic_state *pic, struct pic_senv *up)
|
||||
{
|
||||
struct pic_senv *senv;
|
||||
struct pic_dict *map;
|
||||
|
||||
map = pic_make_dict(pic);
|
||||
|
||||
senv = (struct pic_senv *)pic_obj_alloc(pic, sizeof(struct pic_senv), PIC_TT_SENV);
|
||||
senv->up = up;
|
||||
senv->defer = pic_nil_value();
|
||||
xh_init_int(&senv->map, sizeof(pic_sym));
|
||||
senv->map = map;
|
||||
|
||||
return senv;
|
||||
}
|
||||
|
@ -415,7 +407,7 @@ pic_null_syntactic_environment(pic_state *pic)
|
|||
}
|
||||
|
||||
void
|
||||
pic_define_syntactic_keyword(pic_state *pic, struct pic_senv *senv, pic_sym sym, pic_sym rsym)
|
||||
pic_define_syntactic_keyword(pic_state *pic, struct pic_senv *senv, pic_sym *sym, pic_sym *rsym)
|
||||
{
|
||||
pic_put_rename(pic, senv, sym, rsym);
|
||||
|
||||
|
@ -424,13 +416,33 @@ pic_define_syntactic_keyword(pic_state *pic, struct pic_senv *senv, pic_sym sym,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
pic_defmacro(pic_state *pic, pic_sym name, pic_sym id, pic_func_t func)
|
||||
static pic_value
|
||||
defmacro_call(pic_state *pic)
|
||||
{
|
||||
struct pic_proc *self = pic_get_proc(pic);
|
||||
pic_value args, tmp, proc;
|
||||
|
||||
pic_get_args(pic, "oo", &args, &tmp);
|
||||
|
||||
proc = pic_attr_ref(pic, pic_obj_value(self), "@@transformer");
|
||||
|
||||
return pic_apply_trampoline(pic, pic_proc_ptr(proc), pic_cdr(pic, args));
|
||||
}
|
||||
|
||||
void
|
||||
pic_defmacro(pic_state *pic, pic_sym *name, pic_sym *id, pic_func_t func)
|
||||
{
|
||||
struct pic_proc *proc, *trans;
|
||||
|
||||
trans = pic_make_proc(pic, func, pic_symbol_name(pic, name));
|
||||
|
||||
pic_put_rename(pic, pic->lib->env, name, id);
|
||||
|
||||
proc = pic_make_proc(pic, defmacro_call, "defmacro_call");
|
||||
pic_attr_set(pic, pic_obj_value(proc), "@@transformer", pic_obj_value(trans));
|
||||
|
||||
/* symbol registration */
|
||||
define_macro(pic, id, pic_make_proc(pic, func, pic_symbol_name(pic, name)), NULL);
|
||||
define_macro(pic, id, proc);
|
||||
|
||||
/* auto export! */
|
||||
pic_export(pic, name);
|
||||
|
@ -439,13 +451,13 @@ pic_defmacro(pic_state *pic, pic_sym name, pic_sym id, pic_func_t func)
|
|||
bool
|
||||
pic_identifier_p(pic_state *pic, pic_value obj)
|
||||
{
|
||||
return pic_sym_p(obj) && ! pic_interned_p(pic, pic_sym(obj));
|
||||
return pic_sym_p(obj) && ! pic_interned_p(pic, pic_sym_ptr(obj));
|
||||
}
|
||||
|
||||
bool
|
||||
pic_identifier_eq_p(pic_state *pic, struct pic_senv *env1, pic_sym sym1, struct pic_senv *env2, pic_sym sym2)
|
||||
pic_identifier_eq_p(pic_state *pic, struct pic_senv *env1, pic_sym *sym1, struct pic_senv *env2, pic_sym *sym2)
|
||||
{
|
||||
pic_sym a, b;
|
||||
pic_sym *a, *b;
|
||||
|
||||
a = make_identifier(pic, sym1, env1);
|
||||
if (a != make_identifier(pic, sym1, env1)) {
|
||||
|
@ -457,7 +469,7 @@ pic_identifier_eq_p(pic_state *pic, struct pic_senv *env1, pic_sym sym1, struct
|
|||
b = sym2;
|
||||
}
|
||||
|
||||
return pic_eq_p(pic_sym_value(a), pic_sym_value(b));
|
||||
return pic_eq_p(pic_obj_value(a), pic_obj_value(b));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -474,19 +486,19 @@ static pic_value
|
|||
pic_macro_make_identifier(pic_state *pic)
|
||||
{
|
||||
pic_value obj;
|
||||
pic_sym sym;
|
||||
pic_sym *sym;
|
||||
|
||||
pic_get_args(pic, "mo", &sym, &obj);
|
||||
|
||||
pic_assert_type(pic, obj, senv);
|
||||
|
||||
return pic_sym_value(make_identifier(pic, sym, pic_senv_ptr(obj)));
|
||||
return pic_obj_value(make_identifier(pic, sym, pic_senv_ptr(obj)));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_macro_identifier_eq_p(pic_state *pic)
|
||||
{
|
||||
pic_sym sym1, sym2;
|
||||
pic_sym *sym1, *sym2;
|
||||
pic_value env1, env2;
|
||||
|
||||
pic_get_args(pic, "omom", &env1, &sym1, &env2, &sym2);
|
||||
|
|
4
number.c
4
number.c
|
@ -2,10 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/string.h"
|
||||
#include "picrin/cont.h"
|
||||
|
|
2
pair.c
2
pair.c
|
@ -2,8 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/pair.h"
|
||||
|
||||
|
|
4
port.c
4
port.c
|
@ -2,10 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/proc.h"
|
||||
#include "picrin/port.h"
|
||||
|
|
2
proc.c
2
proc.c
|
@ -34,7 +34,7 @@ pic_make_proc_irep(pic_state *pic, struct pic_irep *irep, struct pic_env *env)
|
|||
return proc;
|
||||
}
|
||||
|
||||
pic_sym
|
||||
pic_sym *
|
||||
pic_proc_name(struct pic_proc *proc)
|
||||
{
|
||||
switch (proc->kind) {
|
||||
|
|
31
read.c
31
read.c
|
@ -2,9 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "picrin.h"
|
||||
#include "picrin/read.h"
|
||||
#include "picrin/error.h"
|
||||
|
@ -14,6 +11,7 @@
|
|||
#include "picrin/blob.h"
|
||||
#include "picrin/port.h"
|
||||
#include "picrin/proc.h"
|
||||
#include "picrin/symbol.h"
|
||||
|
||||
static pic_value read(pic_state *pic, struct pic_port *port, int c);
|
||||
static pic_value read_nullable(pic_state *pic, struct pic_port *port, int c);
|
||||
|
@ -169,7 +167,7 @@ read_quote(pic_state *pic, struct pic_port *port, const char *str)
|
|||
{
|
||||
PIC_UNUSED(str);
|
||||
|
||||
return pic_list2(pic, pic_sym_value(pic->sQUOTE), read(pic, port, next(port)));
|
||||
return pic_list2(pic, pic_obj_value(pic->sQUOTE), read(pic, port, next(port)));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -177,7 +175,7 @@ read_quasiquote(pic_state *pic, struct pic_port *port, const char *str)
|
|||
{
|
||||
PIC_UNUSED(str);
|
||||
|
||||
return pic_list2(pic, pic_sym_value(pic->sQUASIQUOTE), read(pic, port, next(port)));
|
||||
return pic_list2(pic, pic_obj_value(pic->sQUASIQUOTE), read(pic, port, next(port)));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -185,7 +183,7 @@ read_unquote(pic_state *pic, struct pic_port *port, const char *str)
|
|||
{
|
||||
PIC_UNUSED(str);
|
||||
|
||||
return pic_list2(pic, pic_sym_value(pic->sUNQUOTE), read(pic, port, next(port)));
|
||||
return pic_list2(pic, pic_obj_value(pic->sUNQUOTE), read(pic, port, next(port)));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -193,7 +191,7 @@ read_unquote_splicing(pic_state *pic, struct pic_port *port, const char *str)
|
|||
{
|
||||
PIC_UNUSED(str);
|
||||
|
||||
return pic_list2(pic, pic_sym_value(pic->sUNQUOTE_SPLICING), read(pic, port, next(port)));
|
||||
return pic_list2(pic, pic_obj_value(pic->sUNQUOTE_SPLICING), read(pic, port, next(port)));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -201,7 +199,7 @@ read_symbol(pic_state *pic, struct pic_port *port, const char *str)
|
|||
{
|
||||
size_t len, i;
|
||||
char *buf;
|
||||
pic_sym sym;
|
||||
pic_sym *sym;
|
||||
int c;
|
||||
|
||||
len = strlen(str);
|
||||
|
@ -225,10 +223,11 @@ read_symbol(pic_state *pic, struct pic_port *port, const char *str)
|
|||
buf[len - 1] = (char)c;
|
||||
}
|
||||
|
||||
sym = pic_intern(pic, buf, len);
|
||||
buf[len] = 0;
|
||||
sym = pic_intern_cstr(pic, buf);
|
||||
pic_free(pic, buf);
|
||||
|
||||
return pic_sym_value(sym);
|
||||
return pic_obj_value(sym);
|
||||
}
|
||||
|
||||
static size_t
|
||||
|
@ -321,10 +320,10 @@ read_minus(pic_state *pic, struct pic_port *port, const char *str)
|
|||
}
|
||||
else {
|
||||
sym = read_symbol(pic, port, str);
|
||||
if (strcaseeq(pic_symbol_name(pic, pic_sym(sym)), "-inf.0")) {
|
||||
if (strcaseeq(pic_symbol_name(pic, pic_sym_ptr(sym)), "-inf.0")) {
|
||||
return pic_float_value(-INFINITY);
|
||||
}
|
||||
if (strcaseeq(pic_symbol_name(pic, pic_sym(sym)), "-nan.0")) {
|
||||
if (strcaseeq(pic_symbol_name(pic, pic_sym_ptr(sym)), "-nan.0")) {
|
||||
return pic_float_value(-NAN);
|
||||
}
|
||||
return sym;
|
||||
|
@ -341,10 +340,10 @@ read_plus(pic_state *pic, struct pic_port *port, const char *str)
|
|||
}
|
||||
else {
|
||||
sym = read_symbol(pic, port, str);
|
||||
if (strcaseeq(pic_symbol_name(pic, pic_sym(sym)), "+inf.0")) {
|
||||
if (strcaseeq(pic_symbol_name(pic, pic_sym_ptr(sym)), "+inf.0")) {
|
||||
return pic_float_value(INFINITY);
|
||||
}
|
||||
if (strcaseeq(pic_symbol_name(pic, pic_sym(sym)), "+nan.0")) {
|
||||
if (strcaseeq(pic_symbol_name(pic, pic_sym_ptr(sym)), "+nan.0")) {
|
||||
return pic_float_value(NAN);
|
||||
}
|
||||
return sym;
|
||||
|
@ -453,7 +452,7 @@ read_pipe(pic_state *pic, struct pic_port *port, const char *str)
|
|||
{
|
||||
char *buf;
|
||||
size_t size, cnt;
|
||||
pic_sym sym;
|
||||
pic_sym *sym;
|
||||
/* Currently supports only ascii chars */
|
||||
char HEX_BUF[3];
|
||||
size_t i = 0;
|
||||
|
@ -492,7 +491,7 @@ read_pipe(pic_state *pic, struct pic_port *port, const char *str)
|
|||
sym = pic_intern_cstr(pic, buf);
|
||||
pic_free(pic, buf);
|
||||
|
||||
return pic_sym_value(sym);
|
||||
return pic_obj_value(sym);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
|
27
record.c
27
record.c
|
@ -4,14 +4,18 @@
|
|||
|
||||
#include "picrin.h"
|
||||
#include "picrin/record.h"
|
||||
#include "picrin/dict.h"
|
||||
|
||||
struct pic_record *
|
||||
pic_make_record(pic_state *pic, pic_value rectype)
|
||||
{
|
||||
struct pic_record *rec;
|
||||
struct pic_dict *data;
|
||||
|
||||
data = pic_make_dict(pic);
|
||||
|
||||
rec = (struct pic_record *)pic_obj_alloc(pic, sizeof(struct pic_record), PIC_TT_RECORD);
|
||||
xh_init_int(&rec->hash, sizeof(pic_value));
|
||||
rec->data = data;
|
||||
|
||||
pic_record_set(pic, rec, pic_intern_cstr(pic, "@@type"), rectype);
|
||||
|
||||
|
@ -25,23 +29,18 @@ pic_record_type(pic_state *pic, struct pic_record *rec)
|
|||
}
|
||||
|
||||
pic_value
|
||||
pic_record_ref(pic_state *pic, struct pic_record *rec, pic_sym slot)
|
||||
pic_record_ref(pic_state *pic, struct pic_record *rec, pic_sym *slot)
|
||||
{
|
||||
xh_entry *e;
|
||||
|
||||
e = xh_get_int(&rec->hash, slot);
|
||||
if (! e) {
|
||||
pic_errorf(pic, "slot named ~s is not found for record: ~s", pic_sym_value(slot), rec);
|
||||
if (! pic_dict_has(pic, rec->data, slot)) {
|
||||
pic_errorf(pic, "slot named ~s is not found for record: ~s", pic_obj_value(slot), rec);
|
||||
}
|
||||
return xh_val(e, pic_value);
|
||||
return pic_dict_ref(pic, rec->data, slot);
|
||||
}
|
||||
|
||||
void
|
||||
pic_record_set(pic_state *pic, struct pic_record *rec, pic_sym slot, pic_value val)
|
||||
pic_record_set(pic_state *pic, struct pic_record *rec, pic_sym *slot, pic_value val)
|
||||
{
|
||||
PIC_UNUSED(pic);
|
||||
|
||||
xh_put_int(&rec->hash, slot, &val);
|
||||
pic_dict_set(pic, rec->data, slot, val);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -81,7 +80,7 @@ static pic_value
|
|||
pic_record_record_ref(pic_state *pic)
|
||||
{
|
||||
struct pic_record *rec;
|
||||
pic_sym slot;
|
||||
pic_sym *slot;
|
||||
|
||||
pic_get_args(pic, "rm", &rec, &slot);
|
||||
|
||||
|
@ -92,7 +91,7 @@ static pic_value
|
|||
pic_record_record_set(pic_state *pic)
|
||||
{
|
||||
struct pic_record *rec;
|
||||
pic_sym slot;
|
||||
pic_sym *slot;
|
||||
pic_value val;
|
||||
|
||||
pic_get_args(pic, "rmo", &rec, &slot, &val);
|
||||
|
|
79
state.c
79
state.c
|
@ -2,8 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/gc.h"
|
||||
#include "picrin/read.h"
|
||||
|
@ -12,6 +10,7 @@
|
|||
#include "picrin/cont.h"
|
||||
#include "picrin/port.h"
|
||||
#include "picrin/error.h"
|
||||
#include "picrin/dict.h"
|
||||
|
||||
void pic_init_core(pic_state *);
|
||||
|
||||
|
@ -26,6 +25,9 @@ pic_open(int argc, char *argv[], char **envp)
|
|||
|
||||
pic = malloc(sizeof(pic_state));
|
||||
|
||||
/* turn off GC */
|
||||
pic->gc_enable = false;
|
||||
|
||||
/* root block */
|
||||
pic->wind = NULL;
|
||||
|
||||
|
@ -50,16 +52,13 @@ pic_open(int argc, char *argv[], char **envp)
|
|||
pic->heap = pic_heap_open();
|
||||
|
||||
/* symbol table */
|
||||
xh_init_str(&pic->syms, sizeof(pic_sym));
|
||||
xh_init_int(&pic->sym_names, sizeof(const char *));
|
||||
pic->sym_cnt = 0;
|
||||
pic->uniq_sym_cnt = 0;
|
||||
xh_init_str(&pic->syms, sizeof(pic_sym *));
|
||||
|
||||
/* global variables */
|
||||
xh_init_int(&pic->globals, sizeof(pic_value));
|
||||
pic->globals = NULL;
|
||||
|
||||
/* macros */
|
||||
xh_init_int(&pic->macros, sizeof(struct pic_macro *));
|
||||
pic->macros = NULL;
|
||||
|
||||
/* attributes */
|
||||
xh_init_ptr(&pic->attrs, sizeof(struct pic_dict *));
|
||||
|
@ -71,11 +70,10 @@ pic_open(int argc, char *argv[], char **envp)
|
|||
pic->libs = pic_nil_value();
|
||||
pic->lib = NULL;
|
||||
|
||||
/* reader */
|
||||
pic->reader = malloc(sizeof(struct pic_reader));
|
||||
pic->reader->typecase = PIC_CASE_DEFAULT;
|
||||
pic->reader->trie = pic_make_trie(pic);
|
||||
xh_init_int(&pic->reader->labels, sizeof(pic_value));
|
||||
/* GC arena */
|
||||
pic->arena = calloc(PIC_ARENA_SIZE, sizeof(struct pic_object **));
|
||||
pic->arena_size = PIC_ARENA_SIZE;
|
||||
pic->arena_idx = 0;
|
||||
|
||||
/* raised error object */
|
||||
pic->err = pic_undef_value();
|
||||
|
@ -85,17 +83,13 @@ pic_open(int argc, char *argv[], char **envp)
|
|||
pic->xSTDOUT = NULL;
|
||||
pic->xSTDERR = NULL;
|
||||
|
||||
/* GC arena */
|
||||
pic->arena = calloc(PIC_ARENA_SIZE, sizeof(struct pic_object **));
|
||||
pic->arena_size = PIC_ARENA_SIZE;
|
||||
pic->arena_idx = 0;
|
||||
|
||||
/* native stack marker */
|
||||
pic->native_stack_start = &t;
|
||||
|
||||
ai = pic_gc_arena_preserve(pic);
|
||||
|
||||
#define S(slot,name) pic->slot = pic_intern_cstr(pic, name);
|
||||
|
||||
ai = pic_gc_arena_preserve(pic);
|
||||
S(sDEFINE, "define");
|
||||
S(sLAMBDA, "lambda");
|
||||
S(sIF, "if");
|
||||
|
@ -123,8 +117,8 @@ pic_open(int argc, char *argv[], char **envp)
|
|||
S(sCAR, "car");
|
||||
S(sCDR, "cdr");
|
||||
S(sNILP, "null?");
|
||||
S(sSYMBOL_P, "symbol?");
|
||||
S(sPAIR_P, "pair?");
|
||||
S(sSYMBOLP, "symbol?");
|
||||
S(sPAIRP, "pair?");
|
||||
S(sADD, "+");
|
||||
S(sSUB, "-");
|
||||
S(sMUL, "*");
|
||||
|
@ -138,11 +132,19 @@ pic_open(int argc, char *argv[], char **envp)
|
|||
S(sNOT, "not");
|
||||
S(sREAD, "read");
|
||||
S(sFILE, "file");
|
||||
S(sCALL, "call");
|
||||
S(sTAILCALL, "tail-call");
|
||||
S(sGREF, "gref");
|
||||
S(sLREF, "lref");
|
||||
S(sCREF, "cref");
|
||||
S(sRETURN, "return");
|
||||
S(sCALL_WITH_VALUES, "call-with-values");
|
||||
S(sTAILCALL_WITH_VALUES, "tailcall-with-values");
|
||||
|
||||
pic_gc_arena_restore(pic, ai);
|
||||
|
||||
#define R(slot,name) pic->slot = pic_gensym(pic, pic_intern_cstr(pic, name));
|
||||
|
||||
ai = pic_gc_arena_preserve(pic);
|
||||
R(rDEFINE, "define");
|
||||
R(rLAMBDA, "lambda");
|
||||
R(rIF, "if");
|
||||
|
@ -157,12 +159,22 @@ pic_open(int argc, char *argv[], char **envp)
|
|||
R(rCOND_EXPAND, "cond-expand");
|
||||
pic_gc_arena_restore(pic, ai);
|
||||
|
||||
/* root tables */
|
||||
pic->globals = pic_make_dict(pic);
|
||||
pic->macros = pic_make_dict(pic);
|
||||
|
||||
/* root block */
|
||||
pic->wind = pic_alloc(pic, sizeof(struct pic_winder));
|
||||
pic->wind->prev = NULL;
|
||||
pic->wind->depth = 0;
|
||||
pic->wind->in = pic->wind->out = NULL;
|
||||
|
||||
/* reader */
|
||||
pic->reader = malloc(sizeof(struct pic_reader));
|
||||
pic->reader->typecase = PIC_CASE_DEFAULT;
|
||||
pic->reader->trie = pic_make_trie(pic);
|
||||
xh_init_int(&pic->reader->labels, sizeof(pic_value));
|
||||
|
||||
/* init readers */
|
||||
pic_init_reader(pic);
|
||||
|
||||
|
@ -176,6 +188,11 @@ pic_open(int argc, char *argv[], char **envp)
|
|||
pic->xSTDOUT = pic_make_standard_port(pic, xstdout, PIC_PORT_OUT);
|
||||
pic->xSTDERR = pic_make_standard_port(pic, xstderr, PIC_PORT_OUT);
|
||||
|
||||
pic_gc_arena_restore(pic, ai);
|
||||
|
||||
/* turn on GC */
|
||||
pic->gc_enable = true;
|
||||
|
||||
pic_init_core(pic);
|
||||
|
||||
return pic;
|
||||
|
@ -194,14 +211,20 @@ pic_close(pic_state *pic)
|
|||
pic->wind = pic->wind->prev;
|
||||
}
|
||||
|
||||
/* free symbol names */
|
||||
for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) {
|
||||
free(xh_key(it, char *));
|
||||
}
|
||||
|
||||
/* clear out root objects */
|
||||
pic->sp = pic->stbase;
|
||||
pic->ci = pic->cibase;
|
||||
pic->xp = pic->xpbase;
|
||||
pic->arena_idx = 0;
|
||||
pic->err = pic_undef_value();
|
||||
xh_clear(&pic->globals);
|
||||
xh_clear(&pic->macros);
|
||||
pic->globals = NULL;
|
||||
pic->macros = NULL;
|
||||
xh_clear(&pic->syms);
|
||||
xh_clear(&pic->attrs);
|
||||
pic->features = pic_nil_value();
|
||||
pic->libs = pic_nil_value();
|
||||
|
@ -224,18 +247,10 @@ pic_close(pic_state *pic)
|
|||
|
||||
/* free global stacks */
|
||||
xh_destroy(&pic->syms);
|
||||
xh_destroy(&pic->globals);
|
||||
xh_destroy(&pic->macros);
|
||||
xh_destroy(&pic->attrs);
|
||||
|
||||
/* free GC arena */
|
||||
free(pic->arena);
|
||||
|
||||
/* free symbol names */
|
||||
for (it = xh_begin(&pic->sym_names); it != NULL; it = xh_next(it)) {
|
||||
free(xh_val(it, char *));
|
||||
}
|
||||
xh_destroy(&pic->sym_names);
|
||||
|
||||
free(pic);
|
||||
}
|
||||
|
|
2
string.c
2
string.c
|
@ -2,8 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/string.h"
|
||||
#include "picrin/pair.h"
|
||||
|
|
138
symbol.c
138
symbol.c
|
@ -2,97 +2,73 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/symbol.h"
|
||||
#include "picrin/string.h"
|
||||
|
||||
pic_sym
|
||||
pic_intern(pic_state *pic, const char *str, size_t len)
|
||||
pic_sym *
|
||||
pic_make_symbol(pic_state *pic, pic_str *str)
|
||||
{
|
||||
char *cstr;
|
||||
xh_entry *e;
|
||||
pic_sym id;
|
||||
pic_sym *sym;
|
||||
|
||||
cstr = (char *)pic_malloc(pic, len + 1);
|
||||
cstr[len] = '\0';
|
||||
memcpy(cstr, str, len);
|
||||
|
||||
e = xh_get_str(&pic->syms, cstr);
|
||||
if (e) {
|
||||
return xh_val(e, pic_sym);
|
||||
}
|
||||
|
||||
id = pic->sym_cnt++;
|
||||
xh_put_str(&pic->syms, cstr, &id);
|
||||
xh_put_int(&pic->sym_names, id, &cstr);
|
||||
return id;
|
||||
sym = (pic_sym *)pic_obj_alloc(pic, sizeof(struct pic_symbol), PIC_TT_SYMBOL);
|
||||
sym->str = str;
|
||||
return sym;
|
||||
}
|
||||
|
||||
pic_sym
|
||||
pic_sym *
|
||||
pic_intern(pic_state *pic, pic_str *str)
|
||||
{
|
||||
xh_entry *e;
|
||||
pic_sym *sym;
|
||||
char *cstr;
|
||||
|
||||
e = xh_get_str(&pic->syms, pic_str_cstr(str));
|
||||
if (e) {
|
||||
sym = xh_val(e, pic_sym *);
|
||||
pic_gc_protect(pic, pic_obj_value(sym));
|
||||
return sym;
|
||||
}
|
||||
|
||||
cstr = pic_malloc(pic, pic_strlen(str) + 1);
|
||||
strcpy(cstr, pic_str_cstr(str));
|
||||
|
||||
sym = pic_make_symbol(pic, str);
|
||||
xh_put_str(&pic->syms, cstr, &sym);
|
||||
return sym;
|
||||
}
|
||||
|
||||
pic_sym *
|
||||
pic_intern_cstr(pic_state *pic, const char *str)
|
||||
{
|
||||
return pic_intern(pic, str, strlen(str));
|
||||
return pic_intern(pic, pic_make_str(pic, str, strlen(str)));
|
||||
}
|
||||
|
||||
pic_sym
|
||||
pic_intern_str(pic_state *pic, pic_str *str)
|
||||
pic_sym *
|
||||
pic_gensym(pic_state *pic, pic_sym *base)
|
||||
{
|
||||
return pic_intern_cstr(pic, pic_str_cstr(str));
|
||||
}
|
||||
|
||||
pic_sym
|
||||
pic_gensym(pic_state *pic, pic_sym base)
|
||||
{
|
||||
int uid = pic->uniq_sym_cnt++, len;
|
||||
char *str, mark;
|
||||
pic_sym uniq;
|
||||
|
||||
if (pic_interned_p(pic, base)) {
|
||||
mark = '@';
|
||||
} else {
|
||||
mark = '.';
|
||||
}
|
||||
|
||||
len = snprintf(NULL, 0, "%s%c%d", pic_symbol_name(pic, base), mark, uid);
|
||||
str = pic_alloc(pic, (size_t)len + 1);
|
||||
sprintf(str, "%s%c%d", pic_symbol_name(pic, base), mark, uid);
|
||||
|
||||
/* don't put the symbol to pic->syms to keep it uninterned */
|
||||
uniq = pic->sym_cnt++;
|
||||
xh_put_int(&pic->sym_names, uniq, &str);
|
||||
|
||||
return uniq;
|
||||
}
|
||||
|
||||
pic_sym
|
||||
pic_ungensym(pic_state *pic, pic_sym base)
|
||||
{
|
||||
const char *name, *occr;
|
||||
|
||||
if (pic_interned_p(pic, base)) {
|
||||
return base;
|
||||
}
|
||||
|
||||
name = pic_symbol_name(pic, base);
|
||||
if ((occr = strrchr(name, '@')) == NULL) {
|
||||
pic_panic(pic, "logic flaw");
|
||||
}
|
||||
return pic_intern(pic, name, (size_t)(occr - name));
|
||||
return pic_make_symbol(pic, base->str);
|
||||
}
|
||||
|
||||
bool
|
||||
pic_interned_p(pic_state *pic, pic_sym sym)
|
||||
pic_interned_p(pic_state *pic, pic_sym *sym)
|
||||
{
|
||||
return sym == pic_intern_cstr(pic, pic_symbol_name(pic, sym));
|
||||
xh_entry *e;
|
||||
|
||||
e = xh_get_str(&pic->syms, pic_str_cstr(sym->str));
|
||||
if (e) {
|
||||
return sym == xh_val(e, pic_sym *);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
pic_symbol_name(pic_state *pic, pic_sym sym)
|
||||
pic_symbol_name(pic_state *pic, pic_sym *sym)
|
||||
{
|
||||
return xh_val(xh_get_int(&pic->sym_names, sym), const char *);
|
||||
PIC_UNUSED(pic);
|
||||
|
||||
return pic_str_cstr(sym->str);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -127,29 +103,21 @@ pic_symbol_symbol_eq_p(pic_state *pic)
|
|||
static pic_value
|
||||
pic_symbol_symbol_to_string(pic_state *pic)
|
||||
{
|
||||
pic_value v;
|
||||
pic_sym *sym;
|
||||
|
||||
pic_get_args(pic, "o", &v);
|
||||
pic_get_args(pic, "m", &sym);
|
||||
|
||||
if (! pic_sym_p(v)) {
|
||||
pic_errorf(pic, "symbol->string: expected symbol");
|
||||
}
|
||||
|
||||
return pic_obj_value(pic_make_str_cstr(pic, pic_symbol_name(pic, pic_sym(v))));
|
||||
return pic_obj_value(sym->str);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_symbol_string_to_symbol(pic_state *pic)
|
||||
{
|
||||
pic_value v;
|
||||
pic_str *str;
|
||||
|
||||
pic_get_args(pic, "o", &v);
|
||||
pic_get_args(pic, "s", &str);
|
||||
|
||||
if (! pic_str_p(v)) {
|
||||
pic_errorf(pic, "string->symbol: expected string");
|
||||
}
|
||||
|
||||
return pic_symbol_value(pic_intern_cstr(pic, pic_str_cstr(pic_str_ptr(v))));
|
||||
return pic_obj_value(pic_intern(pic, str));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
134
system.c
134
system.c
|
@ -1,134 +0,0 @@
|
|||
/**
|
||||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/string.h"
|
||||
#include "picrin/pair.h"
|
||||
#include "picrin/cont.h"
|
||||
|
||||
static pic_value
|
||||
pic_system_cmdline(pic_state *pic)
|
||||
{
|
||||
pic_value v = pic_nil_value();
|
||||
int i;
|
||||
|
||||
pic_get_args(pic, "");
|
||||
|
||||
for (i = 0; i < pic->argc; ++i) {
|
||||
size_t ai = pic_gc_arena_preserve(pic);
|
||||
|
||||
v = pic_cons(pic, pic_obj_value(pic_make_str_cstr(pic, pic->argv[i])), v);
|
||||
pic_gc_arena_restore(pic, ai);
|
||||
}
|
||||
|
||||
return pic_reverse(pic, v);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_system_exit(pic_state *pic)
|
||||
{
|
||||
pic_value v;
|
||||
int argc, status = EXIT_SUCCESS;
|
||||
|
||||
argc = pic_get_args(pic, "|o", &v);
|
||||
if (argc == 1) {
|
||||
switch (pic_type(v)) {
|
||||
case PIC_TT_FLOAT:
|
||||
status = (int)pic_float(v);
|
||||
break;
|
||||
case PIC_TT_INT:
|
||||
status = pic_int(v);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pic_close(pic);
|
||||
|
||||
exit(status);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_system_emergency_exit(pic_state *pic)
|
||||
{
|
||||
pic_value v;
|
||||
int argc, status = EXIT_FAILURE;
|
||||
|
||||
argc = pic_get_args(pic, "|o", &v);
|
||||
if (argc == 1) {
|
||||
switch (pic_type(v)) {
|
||||
case PIC_TT_FLOAT:
|
||||
status = (int)pic_float(v);
|
||||
break;
|
||||
case PIC_TT_INT:
|
||||
status = pic_int(v);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_Exit(status);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_system_getenv(pic_state *pic)
|
||||
{
|
||||
char *str, *val;
|
||||
|
||||
pic_get_args(pic, "z", &str);
|
||||
|
||||
val = getenv(str);
|
||||
|
||||
if (val == NULL)
|
||||
return pic_nil_value();
|
||||
else
|
||||
return pic_obj_value(pic_make_str_cstr(pic, val));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_system_getenvs(pic_state *pic)
|
||||
{
|
||||
char **envp;
|
||||
pic_value data = pic_nil_value();
|
||||
size_t ai = pic_gc_arena_preserve(pic);
|
||||
|
||||
pic_get_args(pic, "");
|
||||
|
||||
if (! pic->envp) {
|
||||
return pic_nil_value();
|
||||
}
|
||||
|
||||
for (envp = pic->envp; *envp; ++envp) {
|
||||
pic_str *key, *val;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; (*envp)[i] != '='; ++i)
|
||||
;
|
||||
|
||||
key = pic_make_str(pic, *envp, i);
|
||||
val = pic_make_str_cstr(pic, getenv(pic_str_cstr(key)));
|
||||
|
||||
/* push */
|
||||
data = pic_acons(pic, pic_obj_value(key), pic_obj_value(val), data);
|
||||
|
||||
pic_gc_arena_restore(pic, ai);
|
||||
pic_gc_protect(pic, data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
pic_init_system(pic_state *pic)
|
||||
{
|
||||
pic_defun(pic, "command-line", pic_system_cmdline);
|
||||
pic_defun(pic, "exit", pic_system_exit);
|
||||
pic_defun(pic, "emergency-exit", pic_system_emergency_exit);
|
||||
pic_defun(pic, "get-environment-variable", pic_system_getenv);
|
||||
pic_defun(pic, "get-environment-variables", pic_system_getenvs);
|
||||
}
|
47
time.c
47
time.c
|
@ -1,47 +0,0 @@
|
|||
/**
|
||||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "picrin.h"
|
||||
|
||||
#define UTC_TAI_DIFF 35
|
||||
|
||||
static pic_value
|
||||
pic_current_second(pic_state *pic)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
pic_get_args(pic, "");
|
||||
|
||||
time(&t);
|
||||
return pic_float_value((double)t + UTC_TAI_DIFF);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_current_jiffy(pic_state *pic)
|
||||
{
|
||||
clock_t c;
|
||||
|
||||
pic_get_args(pic, "");
|
||||
|
||||
c = clock();
|
||||
return pic_int_value((int)c); /* The year 2038 problem :-| */
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_jiffies_per_second(pic_state *pic)
|
||||
{
|
||||
pic_get_args(pic, "");
|
||||
|
||||
return pic_int_value(CLOCKS_PER_SEC);
|
||||
}
|
||||
|
||||
void
|
||||
pic_init_time(pic_state *pic)
|
||||
{
|
||||
pic_defun(pic, "current-second", pic_current_second);
|
||||
pic_defun(pic, "current-jiffy", pic_current_jiffy);
|
||||
pic_defun(pic, "jiffies-per-second", pic_jiffies_per_second);
|
||||
}
|
20
var.c
20
var.c
|
@ -5,13 +5,11 @@
|
|||
#include "picrin.h"
|
||||
#include "picrin/pair.h"
|
||||
#include "picrin/proc.h"
|
||||
#include "picrin/dict.h"
|
||||
|
||||
static pic_value
|
||||
var_lookup(pic_state *pic, pic_value var)
|
||||
{
|
||||
pic_value val, env;
|
||||
struct pic_dict *binding;
|
||||
pic_value val, env, binding;
|
||||
|
||||
val = pic_ref(pic, pic->PICRIN_BASE, "current-dynamic-environment");
|
||||
if (pic_eq_p(val, var)) {
|
||||
|
@ -20,11 +18,13 @@ var_lookup(pic_state *pic, pic_value var)
|
|||
|
||||
env = pic_apply0(pic, pic_proc_ptr(val));
|
||||
while (! pic_nil_p(env)) {
|
||||
pic_assert_type(pic, pic_car(pic, env), dict);
|
||||
binding = pic_car(pic, env);
|
||||
|
||||
binding = pic_dict_ptr(pic_car(pic, env));
|
||||
if (pic_dict_has(pic, binding, var)) {
|
||||
return pic_dict_ref(pic, binding, var);
|
||||
while (! pic_nil_p(binding)) {
|
||||
if (pic_eq_p(pic_caar(pic, binding), var)) {
|
||||
return pic_car(pic, binding);
|
||||
}
|
||||
binding = pic_cdr(pic, binding);
|
||||
}
|
||||
env = pic_cdr(pic, env);
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ var_call(pic_state *pic)
|
|||
|
||||
switch (n) {
|
||||
case 0:
|
||||
return pic_car(pic, box);
|
||||
return pic_cdr(pic, box);
|
||||
|
||||
case 1:
|
||||
conv = pic_attr_ref(pic, pic_obj_value(self), "@@converter");
|
||||
|
@ -57,7 +57,7 @@ var_call(pic_state *pic)
|
|||
|
||||
val = pic_apply1(pic, pic_proc_ptr(conv), val);
|
||||
}
|
||||
pic_set_car(pic, box, val);
|
||||
pic_set_cdr(pic, box, val);
|
||||
|
||||
return pic_none_value();
|
||||
|
||||
|
@ -82,7 +82,7 @@ pic_make_var(pic_state *pic, pic_value init, struct pic_proc *conv)
|
|||
struct pic_proc *var;
|
||||
|
||||
var = pic_make_proc(pic, var_call, "<var-call>");
|
||||
pic_attr_set(pic, pic_obj_value(var), "@@box", pic_list1(pic, init));
|
||||
pic_attr_set(pic, pic_obj_value(var), "@@box", pic_cons(pic, pic_false_value(), init));
|
||||
pic_attr_set(pic, pic_obj_value(var), "@@converter", conv ? pic_obj_value(conv) : pic_false_value());
|
||||
|
||||
return var;
|
||||
|
|
76
vm.c
76
vm.c
|
@ -2,11 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/pair.h"
|
||||
#include "picrin/string.h"
|
||||
|
@ -20,6 +15,7 @@
|
|||
#include "picrin/error.h"
|
||||
#include "picrin/dict.h"
|
||||
#include "picrin/record.h"
|
||||
#include "picrin/symbol.h"
|
||||
|
||||
#define GET_OPERAND(pic,n) ((pic)->ci->fp[(n)])
|
||||
|
||||
|
@ -45,7 +41,7 @@ pic_get_proc(pic_state *pic)
|
|||
* F double *, bool * float with exactness
|
||||
* s pic_str ** string object
|
||||
* z char ** c string
|
||||
* m pic_sym * symbol
|
||||
* m pic_sym ** symbol
|
||||
* v pic_vec ** vector object
|
||||
* b pic_blob ** bytevector object
|
||||
* c char * char
|
||||
|
@ -259,14 +255,14 @@ pic_get_args(pic_state *pic, const char *format, ...)
|
|||
break;
|
||||
}
|
||||
case 'm': {
|
||||
pic_sym *m;
|
||||
pic_sym **m;
|
||||
pic_value v;
|
||||
|
||||
m = va_arg(ap, pic_sym *);
|
||||
m = va_arg(ap, pic_sym **);
|
||||
if (i < argc) {
|
||||
v = GET_OPERAND(pic,i);
|
||||
if (pic_sym_p(v)) {
|
||||
*m = pic_sym(v);
|
||||
*m = pic_sym_ptr(v);
|
||||
}
|
||||
else {
|
||||
pic_errorf(pic, "pic_get_args: expected symbol, but got ~s", v);
|
||||
|
@ -437,7 +433,7 @@ pic_get_args(pic_state *pic, const char *format, ...)
|
|||
void
|
||||
pic_define_noexport(pic_state *pic, const char *name, pic_value val)
|
||||
{
|
||||
pic_sym sym, rename;
|
||||
pic_sym *sym, *rename;
|
||||
|
||||
sym = pic_intern_cstr(pic, name);
|
||||
|
||||
|
@ -447,7 +443,7 @@ pic_define_noexport(pic_state *pic, const char *name, pic_value val)
|
|||
pic_warn(pic, "redefining global");
|
||||
}
|
||||
|
||||
xh_put_int(&pic->globals, rename, &val);
|
||||
pic_dict_set(pic, pic->globals, rename, val);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -461,7 +457,7 @@ pic_define(pic_state *pic, const char *name, pic_value val)
|
|||
pic_value
|
||||
pic_ref(pic_state *pic, struct pic_lib *lib, const char *name)
|
||||
{
|
||||
pic_sym sym, rename;
|
||||
pic_sym *sym, *rename;
|
||||
|
||||
sym = pic_intern_cstr(pic, name);
|
||||
|
||||
|
@ -469,13 +465,13 @@ pic_ref(pic_state *pic, struct pic_lib *lib, const char *name)
|
|||
pic_errorf(pic, "symbol \"%s\" not defined in library ~s", name, lib->name);
|
||||
}
|
||||
|
||||
return xh_val(xh_get_int(&pic->globals, rename), pic_value);
|
||||
return pic_dict_ref(pic, pic->globals, rename);
|
||||
}
|
||||
|
||||
void
|
||||
pic_set(pic_state *pic, struct pic_lib *lib, const char *name, pic_value val)
|
||||
{
|
||||
pic_sym sym, rename;
|
||||
pic_sym *sym, *rename;
|
||||
|
||||
sym = pic_intern_cstr(pic, name);
|
||||
|
||||
|
@ -483,7 +479,7 @@ pic_set(pic_state *pic, struct pic_lib *lib, const char *name, pic_value val)
|
|||
pic_errorf(pic, "symbol \"%s\" not defined in library ~s", name, lib->name);
|
||||
}
|
||||
|
||||
xh_put_int(&pic->globals, rename, &val);
|
||||
pic_dict_set(pic, pic->globals, rename, val);
|
||||
}
|
||||
|
||||
pic_value
|
||||
|
@ -555,6 +551,23 @@ pic_vm_tear_off(pic_state *pic)
|
|||
}
|
||||
}
|
||||
|
||||
static struct pic_irep *
|
||||
vm_get_irep(pic_state *pic)
|
||||
{
|
||||
pic_value self;
|
||||
struct pic_irep *irep;
|
||||
|
||||
self = pic->ci->fp[0];
|
||||
if (! pic_proc_p(self)) {
|
||||
pic_errorf(pic, "logic flaw");
|
||||
}
|
||||
irep = pic_proc_ptr(self)->u.irep;
|
||||
if (! pic_proc_irep_p(pic_proc_ptr(self))) {
|
||||
pic_errorf(pic, "logic flaw");
|
||||
}
|
||||
return irep;
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_apply0(pic_state *pic, struct pic_proc *proc)
|
||||
{
|
||||
|
@ -693,7 +706,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
&&L_OP_GREF, &&L_OP_GSET, &&L_OP_LREF, &&L_OP_LSET, &&L_OP_CREF, &&L_OP_CSET,
|
||||
&&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_NOT, &&L_OP_CALL, &&L_OP_TAILCALL, &&L_OP_RET,
|
||||
&&L_OP_LAMBDA, &&L_OP_CONS, &&L_OP_CAR, &&L_OP_CDR, &&L_OP_NILP,
|
||||
&&L_OP_SYMBOL_P, &&L_OP_PAIR_P,
|
||||
&&L_OP_SYMBOLP, &&L_OP_PAIRP,
|
||||
&&L_OP_ADD, &&L_OP_SUB, &&L_OP_MUL, &&L_OP_DIV, &&L_OP_MINUS,
|
||||
&&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_STOP
|
||||
};
|
||||
|
@ -756,34 +769,31 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
NEXT;
|
||||
}
|
||||
CASE(OP_PUSHCONST) {
|
||||
pic_value self;
|
||||
struct pic_irep *irep;
|
||||
struct pic_irep *irep = vm_get_irep(pic);
|
||||
|
||||
self = pic->ci->fp[0];
|
||||
if (! pic_proc_p(self)) {
|
||||
pic_errorf(pic, "logic flaw");
|
||||
}
|
||||
irep = pic_proc_ptr(self)->u.irep;
|
||||
if (! pic_proc_irep_p(pic_proc_ptr(self))) {
|
||||
pic_errorf(pic, "logic flaw");
|
||||
}
|
||||
PUSH(irep->pool[c.u.i]);
|
||||
NEXT;
|
||||
}
|
||||
CASE(OP_GREF) {
|
||||
xh_entry *e;
|
||||
struct pic_irep *irep = vm_get_irep(pic);
|
||||
pic_sym *sym;
|
||||
|
||||
if ((e = xh_get_int(&pic->globals, c.u.i)) == NULL) {
|
||||
pic_errorf(pic, "logic flaw; reference to uninitialized global variable: %s", pic_symbol_name(pic, c.u.i));
|
||||
sym = irep->syms[c.u.i];
|
||||
if (! pic_dict_has(pic, pic->globals, sym)) {
|
||||
pic_errorf(pic, "logic flaw; reference to uninitialized global variable: %s", pic_symbol_name(pic, sym));
|
||||
}
|
||||
PUSH(xh_val(e, pic_value));
|
||||
PUSH(pic_dict_ref(pic, pic->globals, sym));
|
||||
NEXT;
|
||||
}
|
||||
CASE(OP_GSET) {
|
||||
struct pic_irep *irep = vm_get_irep(pic);
|
||||
pic_sym *sym;
|
||||
pic_value val;
|
||||
|
||||
sym = irep->syms[c.u.i];
|
||||
|
||||
val = POP();
|
||||
xh_put_int(&pic->globals, c.u.i, &val);
|
||||
pic_dict_set(pic, pic->globals, sym, val);
|
||||
NEXT;
|
||||
}
|
||||
CASE(OP_LREF) {
|
||||
|
@ -1036,14 +1046,14 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
NEXT;
|
||||
}
|
||||
|
||||
CASE(OP_SYMBOL_P) {
|
||||
CASE(OP_SYMBOLP) {
|
||||
pic_value p;
|
||||
p = POP();
|
||||
PUSH(pic_bool_value(pic_sym_p(p)));
|
||||
NEXT;
|
||||
}
|
||||
|
||||
CASE(OP_PAIR_P) {
|
||||
CASE(OP_PAIRP) {
|
||||
pic_value p;
|
||||
p = POP();
|
||||
PUSH(pic_bool_value(pic_pair_p(p)));
|
||||
|
|
15
write.c
15
write.c
|
@ -2,8 +2,6 @@
|
|||
* See Copyright Notice in picrin.h
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/port.h"
|
||||
#include "picrin/pair.h"
|
||||
|
@ -13,13 +11,14 @@
|
|||
#include "picrin/dict.h"
|
||||
#include "picrin/record.h"
|
||||
#include "picrin/proc.h"
|
||||
#include "picrin/symbol.h"
|
||||
|
||||
static bool
|
||||
is_tagged(pic_state *pic, pic_sym tag, pic_value pair)
|
||||
is_tagged(pic_state *pic, pic_sym *tag, pic_value pair)
|
||||
{
|
||||
return pic_pair_p(pic_cdr(pic, pair))
|
||||
&& pic_nil_p(pic_cddr(pic, pair))
|
||||
&& pic_eq_p(pic_car(pic, pair), pic_symbol_value(tag));
|
||||
&& pic_eq_p(pic_car(pic, pair), pic_obj_value(tag));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -177,7 +176,7 @@ write_str(pic_state *pic, struct pic_string *str, xFILE *file)
|
|||
static void
|
||||
write_record(pic_state *pic, struct pic_record *rec, xFILE *file)
|
||||
{
|
||||
const pic_sym sWRITER = pic_intern_cstr(pic, "writer");
|
||||
pic_sym *sWRITER = pic_intern_cstr(pic, "writer");
|
||||
pic_value type, writer, str;
|
||||
|
||||
#if DEBUG
|
||||
|
@ -267,7 +266,7 @@ write_core(struct writer_control *p, pic_value obj)
|
|||
xfprintf(file, ")");
|
||||
break;
|
||||
case PIC_TT_SYMBOL:
|
||||
xfprintf(file, "%s", pic_symbol_name(pic, pic_sym(obj)));
|
||||
xfprintf(file, "%s", pic_symbol_name(pic, pic_sym_ptr(obj)));
|
||||
break;
|
||||
case PIC_TT_CHAR:
|
||||
if (p->mode == DISPLAY_MODE) {
|
||||
|
@ -334,9 +333,7 @@ write_core(struct writer_control *p, pic_value obj)
|
|||
case PIC_TT_DICT:
|
||||
xfprintf(file, "#.(dictionary");
|
||||
for (it = xh_begin(&pic_dict_ptr(obj)->hash); it != NULL; it = xh_next(it)) {
|
||||
xfprintf(file, " '");
|
||||
write_core(p, xh_key(it, pic_value));
|
||||
xfprintf(file, " '");
|
||||
xfprintf(file, " '%s ", pic_symbol_name(pic, xh_key(it, pic_sym *)));
|
||||
write_core(p, xh_val(it, pic_value));
|
||||
}
|
||||
xfprintf(file, ")");
|
||||
|
|
Loading…
Reference in New Issue