• R/O
  • SSH
  • HTTPS

npl: コミット


コミットメタ情報

リビジョン67 (tree)
日時2017-09-13 02:10:13
作者tamiya25

ログメッセージ

stack変更

変更サマリ

差分

--- trunk/npl/stack.c (revision 66)
+++ trunk/npl/stack.c (revision 67)
@@ -4,7 +4,10 @@
44
55 struct _StackFrameInfo {
66 size_t count;
7- void (*_cleaner)(npl_stack_t *s);
7+ union {
8+ size_t stack_count;
9+ npl_stack_frame_info_t *sfi;
10+ };
811 };
912
1013 static npl_sblock_t* _get_prev(npl_sblock_t *s)
@@ -34,104 +37,210 @@
3437 }
3538 }
3639
37-static int _enter(npl_stack_t *s, void (*_cleaner_fn)(npl_stack_t *s))
40+static void* _push(npl_stack_t *s, size_t bytes)
3841 {
39- struct _StackFrameInfo sfi;
42+ void *p;
4043
41- assert(s);
44+ // まだ、リストがない
45+ if (s->stack == NULL) {
46+ if (s->unused != NULL) {
47+ npl_sblock_clear(s->unused);
48+ s->stack = s->unused;
49+ s->unused = NULL;
50+ } else {
51+ s->stack = npl_sblock_new(s->block_size);
52+ if (s->stack == NULL)
53+ return NULL; // error
54+ }
55+ }
4256
43- sfi.count = s->count;
44- sfi._cleaner = s->_cleaner;
45- if (npl_stack_push(s, sizeof(sfi), &sfi))
46- return 1;
57+ p = npl_sblock_push(s->stack, bytes);
4758
48- s->count = 0;
49- s->_cleaner = _cleaner_fn;
59+ // リストが一杯の場合
60+ if (p == NULL) {
61+ if (s->unused != NULL) {
62+ npl_sblock_clear(s->unused);
63+ npl_sblock_set_prev(s->unused, s->stack);
64+ npl_object_unref(NPL_OBJECT(s->stack));
65+ s->stack = s->unused;
66+ s->unused = NULL;
67+ } else {
68+ npl_sblock_t *sb = npl_sblock_new(s->block_size);
69+ if (sb == NULL)
70+ return NULL; // error
71+ npl_sblock_set_prev(sb, s->stack);
72+ npl_object_unref(NPL_OBJECT(s->stack));
73+ s->stack = sb;
74+ }
75+ p = npl_sblock_push(s->stack, bytes);
76+ }
5077
51- return 0;
78+ return p;
5279 }
5380
5481 // 要素を取り出す
55-static int _pop(npl_stack_t *s, size_t bytes, void *p)
82+static void* _get(npl_stack_t *s, size_t bytes)
5683 {
5784 if (s->stack == NULL)
85+ return NULL; // 要素なし
86+ return npl_sblock_get(s->stack, bytes);
87+}
88+
89+// 要素を削除する
90+static int _remove(npl_stack_t *s, size_t bytes)
91+{
92+ if (s->stack == NULL)
5893 return 1; // 要素なし
59- if (npl_sblock_pop(s->stack, bytes, p))
94+ if (npl_sblock_remove(s->stack, bytes))
6095 return 1; // 要素なし
6196 _delete_sblock(s);
6297 return 0;
6398 }
6499
65-// 通常の cleaner
66-static void _cleaner(npl_stack_t *s)
100+static int _pop(npl_stack_t *s, size_t bytes, void *r)
67101 {
68- npl_sblock_t *sb;
102+ void *p;
69103
70- // clean
71- sb = s->stack;
72- while (sb != NULL && s->count > 0) {
73- if (sb->sp > s->count) {
74- sb->sp -= s->count;
75- s->count = 0;
76- } else {
77- s->count -= sb->sp;
78- sb->sp = 0;
79- sb = _get_prev(sb);
80- }
104+ if (s->stack == NULL)
105+ return 1; // 要素なし
106+ if ((p = _get(s, bytes)) == NULL)
107+ return 1; // 要素なし
108+ if (r != NULL)
109+ memcpy(r, p, bytes);
110+ _remove(s, bytes);
111+
112+ return 0;
113+}
114+
115+static int _enter(npl_stack_t *s, npl_stack_frame_info_t *sfi_)
116+{
117+ void *p;
118+ struct _StackFrameInfo sfi;
119+
120+ s->stack_count += s->count;
121+ sfi.count = s->count;
122+ sfi.sfi = s->sfi;
123+ if ((p = _push(s, sizeof(sfi))) == NULL)
124+ return 1; // error
125+ memcpy(p, &sfi, sizeof(sfi));
126+ s->count = 0;
127+ s->sfi = sfi_;
128+
129+ return 0;
130+}
131+
132+static int _enter_stack(npl_stack_t *s)
133+{
134+ void *p;
135+ struct _StackFrameInfo sfi;
136+
137+ sfi.count = s->count;
138+ sfi.stack_count = s->stack_count;
139+ if ((p = _push(s, sizeof(sfi))) == NULL)
140+ return 1; // error
141+ memcpy(p, &sfi, sizeof(sfi));
142+ s->count = 0;
143+ s->stack_count = 0;
144+
145+ return 0;
146+}
147+
148+static void _leave(npl_stack_t *s)
149+{
150+ struct _StackFrameInfo sfi;
151+
152+ if (s->stack_count == 0)
153+ return;
154+ while (s->count == 0) {
155+ if (_pop(s, sizeof(sfi), &sfi))
156+ break;
157+ s->count = sfi.count;
158+ s->sfi = sfi.sfi;
159+ s->stack_count -= s->count;
81160 }
82161 }
83162
84-// object スタックの場合の cleaner
85-static void _cleaner_obj(npl_stack_t *s)
163+static int _leave_stack(npl_stack_t *s)
86164 {
87- npl_object_t *obj;
165+ struct _StackFrameInfo sfi;
88166
89- assert(s);
167+ if (s->count != 0 || s->stack_count != 0)
168+ return 1; // 要素なし
169+ if (_pop(s, sizeof(sfi), &sfi))
170+ return 1; // 要素なし
171+ s->count = sfi.count;
172+ s->stack_count = sfi.stack_count;
90173
91- while (npl_stack_pop_obj(s, &obj) == 0)
92- if (obj != NULL)
93- npl_object_unref(obj);
174+ return 0;
94175 }
95176
177+// object スタックの場合の cleaner
178+static void _object_cleaner(void *p)
179+{
180+ npl_object_t *obj = p;
181+
182+ if (obj != NULL)
183+ npl_object_unref(obj);
184+}
185+
96186 // val スタックの場合の cleaner
97-static void _cleaner_val(npl_stack_t *s)
187+static void _val_cleaner(void *p)
98188 {
99- int res = 0;
100- npl_val_t val;
189+ npl_val_t *val = p;
101190
102- assert(s);
103-
104- while (res == 0) {
105- npl_val_begin(&val);
106- res = npl_stack_pop_val(s, &val);
107- npl_val_end(&val);
108- }
191+ if (val != NULL)
192+ npl_val_end(val);
109193 }
110194
111-int npl_stack_init(npl_stack_t *s)
195+static npl_stack_frame_info_t _object_sfi = {
196+ .data_size = sizeof(npl_object_t*),
197+ .cleaner = _object_cleaner,
198+};
199+
200+static npl_stack_frame_info_t _val_sfi = {
201+ .data_size = sizeof(npl_val_t),
202+ .cleaner = _val_cleaner,
203+};
204+
205+int npl_stack_init(npl_stack_t *s, npl_stack_type_t type, size_t block_size)
112206 {
113207 assert(s);
114208
115- if (s->block_size == 0)
209+ if (block_size == 0)
116210 s->block_size = _STACK_BLOCK_SIZE;
211+ else
212+ s->block_size = block_size;
213+
117214 s->stack = npl_sblock_new(s->block_size);
118215 if (s->stack == NULL)
119216 return 1; // error
120- s->_cleaner = _cleaner;
121217
218+ switch (type) {
219+ case NPL_ST_OBJECT:
220+ s->sfi = &_object_sfi;
221+ break;
222+ case NPL_ST_VALUE:
223+ s->sfi = &_val_sfi;
224+ break;
225+ default:
226+ s->sfi = NULL;
227+ break;
228+ }
229+
122230 return 0;
123231 }
124232
125-npl_stack_t* npl_stack_new_with_block_size(size_t block_size)
233+npl_stack_t* npl_stack_new(npl_stack_type_t type, size_t block_size)
126234 {
235+ npl_object_t *obj;
127236 npl_stack_t *s;
128237
129- s = NPL_STACK(npl_object_alloc(npl_stack_type));
130- if (s == NULL)
238+ obj = npl_object_alloc(npl_stack_type);
239+ if (obj == NULL)
131240 return NULL;
132241
133- s->block_size = block_size;
134- if (npl_stack_init(s)) {
242+ s = NPL_STACK(obj);
243+ if (npl_stack_init(s, type, block_size)) {
135244 npl_object_unref(NPL_OBJECT(s));
136245 return NULL;
137246 }
@@ -139,35 +248,59 @@
139248 return s;
140249 }
141250
142-npl_stack_t* npl_stack_new(void)
251+size_t npl_stack_count(npl_stack_t *s)
143252 {
144- return npl_stack_new_with_block_size(0);
253+ assert(s);
254+ return s->count + s->stack_count;
145255 }
146256
147-size_t npl_stack_count(npl_stack_t *s)
257+int npl_stack_enter(npl_stack_t *s)
148258 {
149259 assert(s);
150- return s->count;
260+ return _enter_stack(s);
151261 }
152262
153263 int npl_stack_leave(npl_stack_t *s)
154264 {
155- struct _StackFrameInfo sfi;
156-
157265 assert(s);
158-
159266 npl_stack_empty(s);
267+ return _leave_stack(s);
268+}
160269
161- // sfi を取り出す
162- if (s->stack == NULL)
163- return 1; // 要素なし
164- if (_pop(s, sizeof(sfi), &sfi))
165- return 1; // 要素なし
270+// スタックフレームがプリミティブ・データの場合、
271+// count をゼロまで戻す(すべて取り除く)。
272+// それ以外 (object や val) の場合、要素を1つ取り除く。
273+void npl_stack_remove(npl_stack_t *s)
274+{
275+ void *p;
166276
167- s->count = sfi.count;
168- s->_cleaner = sfi._cleaner;
277+ assert(s);
169278
170- return 0;
279+ if (s->sfi == NULL) { // プリミティブ・データ
280+ npl_sblock_t *sb;
281+
282+ sb = s->stack;
283+ while (sb != NULL && s->count > 0) {
284+ if (sb->sp > s->count) {
285+ sb->sp -= s->count;
286+ s->count = 0;
287+ } else {
288+ s->count -= sb->sp;
289+ sb->sp = 0;
290+ sb = _get_prev(sb);
291+ }
292+ }
293+ _delete_sblock(s);
294+ } else { // プリミティブ・データ以外
295+ if (s->count >= s->sfi->data_size) {
296+ p = _get(s, s->sfi->data_size);
297+ if (s->sfi->cleaner != NULL)
298+ s->sfi->cleaner(p);
299+ _remove(s, s->sfi->data_size);
300+ s->count -= s->sfi->data_size;
301+ }
302+ }
303+ _leave(s);
171304 }
172305
173306 int npl_stack_is_empty(npl_stack_t *s)
@@ -174,10 +307,10 @@
174307 {
175308 assert(s);
176309
177- if (s->count > 0)
178- return 1; // 空ではない
310+ if (s->count == 0 && s->stack_count == 0)
311+ return 0;
179312
180- return 0;
313+ return 1; // 空ではない
181314 }
182315
183316 void npl_stack_empty(npl_stack_t *s)
@@ -184,63 +317,27 @@
184317 {
185318 assert(s);
186319
187- if (s->_cleaner != NULL)
188- s->_cleaner(s);
189- _delete_sblock(s);
320+ while (npl_stack_is_empty(s))
321+ npl_stack_remove(s);
190322 }
191323
192-int npl_stack_enter(npl_stack_t *s)
193-{
194- return _enter(s, _cleaner);
195-}
196-
197324 int npl_stack_push(npl_stack_t *s, size_t bytes, void *p)
198325 {
326+ void *d;
199327 size_t new_count;
200- int res;
201328
202329 assert(s);
203330 assert(bytes > 0);
204331 assert(p);
205332
333+ if (s->sfi != NULL)
334+ if (_enter(s, NULL))
335+ return 1; // error
206336 if (npl_add(s->count, bytes, &new_count))
207337 return 1; // error
208-
209- // まだ、リストがない
210- if (s->stack == NULL) {
211- if (s->unused != NULL) {
212- npl_sblock_clear(s->unused);
213- s->stack = s->unused;
214- s->unused = NULL;
215- } else {
216- s->stack = npl_sblock_new(s->block_size);
217- if (s->stack == NULL)
218- return 1; // error
219- }
220- }
221-
222- res = npl_sblock_push(s->stack, bytes, p);
223-
224- // リストが一杯の場合
225- if (res) {
226- if (s->unused != NULL) {
227- npl_sblock_clear(s->unused);
228- npl_sblock_set_prev(s->unused, s->stack);
229- npl_object_unref(NPL_OBJECT(s->stack));
230- s->stack = s->unused;
231- s->unused = NULL;
232- } else {
233- npl_sblock_t *sb = npl_sblock_new(s->block_size);
234- if (sb == NULL)
235- return 1; // error
236- npl_sblock_set_prev(sb, s->stack);
237- npl_object_unref(NPL_OBJECT(s->stack));
238- s->stack = sb;
239- }
240- if (npl_sblock_push(s->stack, bytes, p))
241- return 1; // error
242- }
243-
338+ if ((d = _push(s, bytes)) == NULL)
339+ return 1; // error
340+ memcpy(d, p, bytes);
244341 s->count = new_count;
245342
246343 return 0;
@@ -248,7 +345,6 @@
248345
249346 int npl_stack_pop(npl_stack_t *s, size_t bytes, void *p)
250347 {
251- npl_sblock_t *sb;
252348 size_t new_count;
253349
254350 assert(s);
@@ -259,49 +355,46 @@
259355 if (_pop(s, bytes, p))
260356 return 1; // 要素なし
261357 s->count = new_count;
358+ _leave(s);
262359
263360 return 0;
264361 }
265362
266-int npl_stack_remove(npl_stack_t *s, size_t bytes)
363+int npl_stack_get(npl_stack_t *s, size_t bytes, void *r)
267364 {
268- return npl_stack_pop(s, bytes, NULL);
269-}
365+ void *p;
366+ size_t new_count;
270367
271-int npl_stack_get(npl_stack_t *s, size_t offset, size_t bytes, void *p)
272-{
273- npl_sblock_t *sb;
274- size_t count;
275-
276368 assert(s);
369+ assert(bytes > 0);
277370
278- sb = s->stack;
279- if (npl_add(offset, bytes, &count))
371+ if (npl_sub(s->count, bytes, &new_count))
280372 return 1; // 要素なし
281- if (count > s->count)
373+ if ((p = _get(s, bytes)) == NULL)
282374 return 1; // 要素なし
375+ if (r != NULL)
376+ memcpy(r, p, bytes);
283377
284- while (offset >= sb->sp) {
285- offset -= sb->sp;
286- if (NPL_BLOCK(sb)->link == NULL)
287- return 1; // 要素なし
288- sb = NPL_SBLOCK(NPL_BLOCK(sb)->link);
289- }
290-
291- return npl_sblock_get(sb, offset, bytes, p);
378+ return 0;
292379 }
293380
294-int npl_stack_enter_obj(npl_stack_t *s)
381+int npl_stack_push_obj(npl_stack_t *s, npl_object_t *obj)
295382 {
296- return _enter(s, _cleaner_obj);
297-}
383+ void *d;
384+ size_t new_count, bytes;
298385
299-int npl_stack_push_obj(npl_stack_t *s, npl_object_t *obj)
300-{
301386 assert(s);
302387
303- if (npl_stack_push(s, sizeof(npl_object_t*), &obj))
388+ bytes = sizeof(npl_object_t*);
389+ if (s->sfi != &_object_sfi)
390+ if (_enter(s, &_object_sfi))
391+ return 1; // error
392+ if (npl_add(s->count, bytes, &new_count))
304393 return 1; // error
394+ if ((d = _push(s, bytes)) == NULL)
395+ return 1; // error
396+ memcpy(d, &obj, bytes);
397+ s->count = new_count;
305398 if (obj != NULL)
306399 npl_object_ref(obj);
307400
@@ -308,52 +401,101 @@
308401 return 0;
309402 }
310403
311-int npl_stack_pop_obj(npl_stack_t *s, void *obj_r)
404+npl_object_t* npl_stack_get_obj(npl_stack_t *s)
312405 {
406+ void *p;
407+ npl_object_t *obj;
408+ size_t new_count;
409+ size_t bytes = sizeof(npl_object_t*);
410+
313411 assert(s);
314- assert(obj_r);
315412
316- if (npl_stack_pop(s, sizeof(npl_object_t*), obj_r))
317- return 1; // error
413+ if (npl_sub(s->count, bytes, &new_count))
414+ return NULL; // 要素なし
415+ if ((p = _get(s, bytes)) == NULL)
416+ return NULL; // 要素なし
417+ memcpy(&obj, p, bytes);
418+ if (obj != NULL)
419+ npl_object_ref(NPL_OBJECT(obj));
318420
319- return 0;
421+ return obj;
320422 }
321423
322-int npl_stack_enter_val(npl_stack_t *s)
424+npl_object_t* npl_stack_pop_obj(npl_stack_t *s)
323425 {
324- return _enter(s, _cleaner_val);
426+ void *p;
427+ npl_object_t *obj;
428+ size_t new_count;
429+ size_t bytes = sizeof(npl_object_t*);
430+
431+ assert(s);
432+
433+ if (npl_sub(s->count, bytes, &new_count))
434+ return NULL; // 要素なし
435+ if ((p = _get(s, bytes)) == NULL)
436+ return NULL; // 要素なし
437+ memcpy(&obj, p, bytes);
438+ _remove(s, bytes);
439+ s->count = new_count;
440+ _leave(s);
441+
442+ return obj;
325443 }
326444
327445 int npl_stack_push_val(npl_stack_t *s, npl_val_t *val)
328446 {
329- npl_val_t v;
447+ npl_val_t *v;
448+ size_t new_count, bytes;
330449
331450 assert(s);
332451 assert(val);
333452
334- npl_val_begin(&v);
335- npl_val_copy(&v, val);
336- if (npl_stack_push(s, sizeof(npl_val_t), &v)) {
337- npl_val_end(&v);
453+ bytes = sizeof(npl_val_t);
454+ if (s->sfi != &_val_sfi)
455+ if (_enter(s, &_val_sfi))
456+ return 1; // error
457+ if (npl_add(s->count, bytes, &new_count))
338458 return 1; // error
339- }
459+ if ((v = _push(s, bytes)) == NULL)
460+ return 1; // error
461+ npl_val_begin(v);
462+ npl_val_copy(v, val);
463+ s->count = new_count;
340464
341465 return 0;
342466 }
343467
344-int npl_stack_pop_val(npl_stack_t *s, npl_val_t *val_r)
468+void npl_stack_get_val(npl_stack_t *s, npl_val_t *val_r)
345469 {
346- npl_val_t v;
470+ npl_val_t *v;
471+ size_t new_count;
472+ size_t bytes = sizeof(npl_val_t);
347473
348474 assert(s);
349- assert(val_r);
350475
351- if (npl_stack_pop(s, sizeof(npl_val_t), &v))
352- return 1; // error
353- npl_val_copy(val_r, &v);
354- npl_val_end(&v);
476+ if (npl_sub(s->count, bytes, &new_count))
477+ return; // 要素なし
478+ if ((v = _get(s, bytes)) == NULL)
479+ return; // 要素なし
480+ npl_val_copy(val_r, v);
481+}
355482
356- return 0;
483+void npl_stack_pop_val(npl_stack_t *s, npl_val_t *val_r)
484+{
485+ npl_val_t *v;
486+ size_t new_count;
487+ size_t bytes = sizeof(npl_val_t);
488+
489+ assert(s);
490+
491+ if (npl_sub(s->count, bytes, &new_count))
492+ return; // 要素なし
493+ if ((v = _get(s, bytes)) == NULL)
494+ return; // 要素なし
495+ npl_val_copy(val_r, v);
496+ npl_val_end(v);
497+ s->count = new_count;
498+ _remove(s, bytes);
357499 }
358500
359501 // デストラクタ
--- trunk/npl/sblock.c (revision 66)
+++ trunk/npl/sblock.c (revision 67)
@@ -35,7 +35,7 @@
3535 npl_block_set_link(NPL_BLOCK(sb), NULL);
3636 }
3737
38-int npl_sblock_push(npl_sblock_t *sb, size_t bytes, void *p)
38+void* npl_sblock_push(npl_sblock_t *sb, size_t bytes)
3939 {
4040 size_t new_sp;
4141 unsigned char *d;
@@ -42,62 +42,47 @@
4242
4343 assert(sb);
4444 assert(bytes > 0);
45- assert(p);
4645
4746 if (npl_add(sb->sp, bytes, &new_sp))
48- return 1; // プッシュできない
47+ return NULL; // プッシュできない
4948 if (new_sp > NPL_CHUNK(sb)->bytes)
50- return 1; // プッシュできない
49+ return NULL; // プッシュできない
5150
5251 d = NPL_CHUNK(sb)->chunk;
5352 d = d + sb->sp;
54- memcpy(d, p, bytes);
5553 sb->sp = new_sp;
5654
57- return 0;
55+ return d;
5856 }
5957
60-int npl_sblock_pop(npl_sblock_t *sb, size_t bytes, void *p)
58+void* npl_sblock_get(npl_sblock_t *sb, size_t bytes)
6159 {
62- size_t new_sp;
60+ size_t sp;
6361 unsigned char *s;
6462
6563 assert(sb);
6664 assert(bytes > 0);
6765
68- if (npl_sub(sb->sp, bytes, &new_sp))
69- return 1; // ポップできない
66+ sp = sb->sp;
67+ if (npl_sub(sp, bytes, &sp))
68+ return NULL; // 要素なし
7069
71- sb->sp = new_sp;
72- if (p != NULL) {
73- s = NPL_CHUNK(sb)->chunk;
74- s = s + sb->sp;
75- memcpy(p, s, bytes);
76- }
77-
78- return 0;
70+ s = NPL_CHUNK(sb)->chunk;
71+ s = s + sp;
72+ return s;
7973 }
8074
81-int npl_sblock_get(npl_sblock_t *sb, size_t offset, size_t bytes, void *p)
75+int npl_sblock_remove(npl_sblock_t *sb, size_t bytes)
8276 {
83- size_t sp;
84- unsigned char *s;
77+ size_t new_sp;
8578
8679 assert(sb);
8780 assert(bytes > 0);
8881
89- sp = sb->sp;
90- if (npl_sub(sp, offset, &sp))
91- return 1; // 要素なし
92- if (npl_sub(sp, bytes, &sp))
93- return 1; // 要素なし
82+ if (npl_sub(sb->sp, bytes, &new_sp))
83+ return 1; // ポップできない
9484
95- if (p != NULL) {
96- s = NPL_CHUNK(sb)->chunk;
97- s = s + sp;
98- memcpy(p, s, bytes);
99- }
100-
85+ sb->sp = new_sp;
10186 return 0;
10287 }
10388
--- trunk/npl/stream.c (revision 66)
+++ trunk/npl/stream.c (revision 67)
@@ -28,27 +28,27 @@
2828
2929 static void c_write_str(void *stream, wchar_t *str)
3030 {
31- fprintf(stream, "%S", str);
31+ fprintf((FILE*)stream, "%S", str);
3232 }
3333
3434 static wchar_t* c_fgetws(wchar_t *ws, int n, void *stream)
3535 {
36- return fgetws(ws, n, stream);
36+ return fgetws(ws, n, (FILE*)stream);
3737 }
3838
3939 static int c_ferror(void *stream)
4040 {
41- return ferror(stream);
41+ return ferror((FILE*)stream);
4242 }
4343
4444 static int c_feof(void *stream)
4545 {
46- return feof(stream);
46+ return feof((FILE*)stream);
4747 }
4848
4949 static void c_fclose(void *stream)
5050 {
51- fclose(stream);
51+ fclose((FILE*)stream);
5252 }
5353
5454 // ストリーム初期化
--- trunk/npl/test/stack/test1.c (revision 66)
+++ trunk/npl/test/stack/test1.c (revision 67)
@@ -34,7 +34,7 @@
3434 }
3535
3636 // 新しいスタック・オブジェクトを作成する
37- if ((s = npl_stack_new()) == NULL) {
37+ if ((s = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
3838 fprintf(stderr, "npl_stack_new() failed.\n");
3939 exit(1);
4040 }
--- trunk/npl/test/stack/test2.c (revision 66)
+++ trunk/npl/test/stack/test2.c (revision 67)
@@ -42,7 +42,7 @@
4242 }
4343
4444 // 新しいスタック・オブジェクトを作成する
45- if ((s = npl_stack_new()) == NULL) {
45+ if ((s = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
4646 fprintf(stderr, "npl_stack_new() failed.\n");
4747 exit(1);
4848 }
--- trunk/npl/test/stack/calc.c (revision 66)
+++ trunk/npl/test/stack/calc.c (revision 67)
@@ -110,12 +110,12 @@
110110
111111 int get_code(npl_stack_t *s, Code *c)
112112 {
113- return npl_stack_get(s, 0, sizeof(Code), c);
113+ return npl_stack_get(s, sizeof(Code), c);
114114 }
115115
116116 void remove_code(npl_stack_t *s)
117117 {
118- npl_stack_remove(s, sizeof(Code));
118+ npl_stack_pop(s, sizeof(Code), NULL);
119119 }
120120
121121 // a のすべての内容をポップして、
@@ -132,7 +132,7 @@
132132 {
133133 npl_stack_t *s;
134134
135- if ((s = npl_stack_new()) == NULL) {
135+ if ((s = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
136136 fprintf(stderr, "my_stack_new() failed.\n");
137137 exit(1);
138138 }
@@ -187,7 +187,7 @@
187187 npl_stack_t *t; // 計算用
188188 Code c;
189189
190- if ((t = npl_stack_new()) == NULL) {
190+ if ((t = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
191191 fprintf(stderr, "calc() failed.\n");
192192 exit(1);
193193 }
@@ -274,9 +274,9 @@
274274 int first; // 単項演算子を判別するため
275275
276276 // セットアップ
277- t = my_stack_new();
278- u = my_stack_new();
279- v = my_stack_new();
277+ t = my_stack_new(NPL_ST_PRIMITIVE, 0);
278+ u = my_stack_new(NPL_ST_PRIMITIVE, 0);
279+ v = my_stack_new(NPL_ST_PRIMITIVE, 0);
280280 pop_code_all(s, t);
281281
282282 // 変換処理
@@ -444,7 +444,7 @@
444444 }
445445
446446 // 新しいスタック・オブジェクトを作成する
447- if ((s = npl_stack_new()) == NULL) {
447+ if ((s = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
448448 fprintf(stderr, "npl_stack_new() failed.\n");
449449 exit(1);
450450 }
--- trunk/npl/test/stack/test3.c (revision 66)
+++ trunk/npl/test/stack/test3.c (revision 67)
@@ -84,7 +84,7 @@
8484 npl_stack_t *t; // 計算用
8585 Code c;
8686
87- if ((t = npl_stack_new()) == NULL) {
87+ if ((t = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
8888 fprintf(stderr, "calc() failed.\n");
8989 exit(1);
9090 }
@@ -137,7 +137,7 @@
137137 }
138138
139139 // 新しいスタック・オブジェクトを作成する
140- if ((s = npl_stack_new()) == NULL) {
140+ if ((s = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
141141 fprintf(stderr, "npl_stack_new() failed.\n");
142142 exit(1);
143143 }
--- trunk/npl/npl.h (revision 66)
+++ trunk/npl/npl.h (revision 67)
@@ -54,6 +54,8 @@
5454 typedef struct npl_stream_t npl_stream_t;
5555
5656 typedef void (*npl_cfunc_t)(npl_func_t *fn, npl_state_t *state);
57+typedef struct npl_stack_frame_info_t npl_stack_frame_info_t;
58+typedef enum npl_stack_type_t npl_stack_type_t;
5759
5860 // グローバルな関数
5961 int npl_init(void);
@@ -454,12 +456,23 @@
454456
455457 npl_sblock_t* npl_sblock_new(size_t block_size);
456458 void npl_sblock_set_prev(npl_sblock_t *sb, npl_sblock_t *prev);
457-int npl_sblock_push(npl_sblock_t *sb, size_t bytes, void *p);
458-int npl_sblock_pop(npl_sblock_t *sb, size_t bytes, void *p);
459-int npl_sblock_get(npl_sblock_t *sb, size_t offset, size_t bytes, void *p);
459+void* npl_sblock_push(npl_sblock_t *sb, size_t bytes);
460+void* npl_sblock_get(npl_sblock_t *sb, size_t bytes);
461+int npl_sblock_remove(npl_sblock_t *sb, size_t bytes);
460462 void npl_sblock_clear(npl_sblock_t *sb);
461463
462464 // stack class
465+struct npl_stack_frame_info_t {
466+ size_t data_size;
467+ void (*cleaner)(void *p);
468+};
469+
470+enum npl_stack_type_t {
471+ NPL_ST_PRIMITIVE = 0,
472+ NPL_ST_OBJECT,
473+ NPL_ST_VALUE,
474+};
475+
463476 struct npl_stack_t {
464477 npl_object_t object;
465478 npl_sblock_t *stack;
@@ -466,30 +479,30 @@
466479 npl_sblock_t *unused;
467480 size_t block_size;
468481 size_t count;
469- void (*_cleaner)(npl_stack_t *s);
482+ size_t stack_count;
483+ npl_stack_frame_info_t *sfi;
470484 };
471485
472-int npl_stack_init(npl_stack_t *s);
473-npl_stack_t* npl_stack_new_with_block_size(size_t block_size);
474-npl_stack_t* npl_stack_new(void);
486+int npl_stack_init(npl_stack_t *s, npl_stack_type_t type, size_t block_size);
487+npl_stack_t* npl_stack_new(npl_stack_type_t type, size_t block_size);
475488 size_t npl_stack_count(npl_stack_t *s);
489+int npl_stack_enter(npl_stack_t *s);
476490 int npl_stack_leave(npl_stack_t *s);
491+void npl_stack_remove(npl_stack_t *s);
477492 int npl_stack_is_empty(npl_stack_t *s);
478493 void npl_stack_empty(npl_stack_t *s);
479494
480-int npl_stack_enter(npl_stack_t *s);
481495 int npl_stack_push(npl_stack_t *s, size_t bytes, void *p);
482-int npl_stack_pop(npl_stack_t *s, size_t bytes, void *p);
483-int npl_stack_remove(npl_stack_t *s, size_t bytes);
484-int npl_stack_get(npl_stack_t *s, size_t offset, size_t bytes, void *p);
496+int npl_stack_pop(npl_stack_t *s, size_t bytes, void *r);
497+int npl_stack_get(npl_stack_t *s, size_t bytes, void *r);
485498
486-int npl_stack_enter_obj(npl_stack_t *s);
487499 int npl_stack_push_obj(npl_stack_t *s, npl_object_t *obj);
488-int npl_stack_pop_obj(npl_stack_t *s, void *obj_r);
500+npl_object_t* npl_stack_get_obj(npl_stack_t *s);
501+npl_object_t* npl_stack_pop_obj(npl_stack_t *s);
489502
490-int npl_stack_enter_val(npl_stack_t *s);
491503 int npl_stack_push_val(npl_stack_t *s, npl_val_t *val);
492-int npl_stack_pop_val(npl_stack_t *s, npl_val_t *val_r);
504+void npl_stack_get_val(npl_stack_t *s, npl_val_t *val_r);
505+void npl_stack_pop_val(npl_stack_t *s, npl_val_t *val_r);
493506
494507 // stream class
495508 struct npl_stream_t {
--- trunk/npl/lang/calcf.c (revision 66)
+++ trunk/npl/lang/calcf.c (revision 67)
@@ -52,31 +52,30 @@
5252 };
5353 };
5454
55-// 変数スタック
56-npl_stack_t *var_stack;
55+// 変数リスト
56+npl_array_t *vlist;
5757
5858 npl_var_t* get_var(wchar_t *name)
5959 {
6060 npl_var_t *var = NULL;
61- size_t i, len, offset;
61+ npl_val_t val;
62+ size_t i, len;
6263
63- // スタックを探す
64- len = npl_stack_count(var_stack) / sizeof(npl_var_t*);
64+ // リストから探す
65+ npl_val_begin(&val);
66+ len = npl_array_len(vlist);
6567 for (i=0; i<len; i++) {
66- offset = i * sizeof(npl_var_t*);
67- if (npl_stack_get(var_stack, offset, sizeof(npl_var_t*), &var)) {
68- fprintf(stderr, "npl_stack_get() failed.\n");
69- exit(1);
70- }
71- if (wcscmp(npl_var_name(var), name) == 0) {
72- npl_object_ref(NPL_OBJECT(var));
68+ npl_array_get(vlist, i, &val);
69+ if (npl_val_check_object(&val, npl_var_type))
70+ continue;
71+ var = NPL_VAR(val.object);
72+ if (wcscmp(npl_var_name(var), name) == 0)
7373 break;
74- }
7574 var = NULL;
7675 }
7776
7877 if (var == NULL) {
79- npl_val_t val;
78+ npl_val_t val2;
8079
8180 if ((var = npl_var_new(name)) == NULL) {
8281 fprintf(stderr, "npl_var_new() failed.\n");
@@ -83,16 +82,26 @@
8382 exit(1);
8483 }
8584
86- npl_val_begin(&val);
87- npl_val_set_int(&val, 0);
88- npl_var_set(var, &val);
89- npl_val_end(&val);
90- if (npl_stack_push_obj(var_stack, NPL_OBJECT(var))) {
91- fprintf(stderr, "npl_stack_push_obj() failed.\n");
92- exit(1);
85+ npl_val_begin(&val2);
86+ npl_val_set_int(&val2, 0);
87+ npl_var_set(var, &val2);
88+ npl_val_end(&val2);
89+
90+ npl_val_begin(&val2);
91+ npl_val_set_object(&val2, NPL_OBJECT(var));
92+ len = npl_array_len(vlist);
93+ for (i=0; i<len; i++) {
94+ npl_array_get(vlist, i, &val);
95+ if (npl_val_check_null(&val))
96+ continue;
97+ npl_array_set(vlist, i, &val2);
98+ break;
9399 }
100+ npl_val_end(&val2);
94101 }
102+ npl_val_end(&val);
95103
104+ npl_object_ref(NPL_OBJECT(var));
96105 return var;
97106 }
98107
@@ -234,7 +243,7 @@
234243
235244 int get_code(npl_stack_t *s, Code *c)
236245 {
237- return npl_stack_get(s, 0, sizeof(Code), c);
246+ return npl_stack_get(s, sizeof(Code), c);
238247 }
239248
240249 void remove_code(npl_stack_t *s)
@@ -247,7 +256,7 @@
247256 npl_object_unref(NPL_OBJECT(c.var));
248257 c.var = NULL;
249258 }
250- npl_stack_remove(s, sizeof(Code));
259+ npl_stack_pop(s, sizeof(Code), NULL);
251260 }
252261
253262 // a のすべての内容をポップして、
@@ -264,7 +273,7 @@
264273 {
265274 npl_stack_t *s;
266275
267- if ((s = npl_stack_new()) == NULL) {
276+ if ((s = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
268277 fprintf(stderr, "my_stack_new() failed.\n");
269278 exit(1);
270279 }
@@ -341,7 +350,7 @@
341350 npl_stack_t *t; // 計算用
342351 Code c;
343352
344- if ((t = npl_stack_new()) == NULL) {
353+ if ((t = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
345354 fprintf(stderr, "calc() failed.\n");
346355 exit(1);
347356 }
@@ -804,20 +813,16 @@
804813 }
805814
806815 // 新しいスタック・オブジェクトを作成する
807- if ((s = npl_stack_new()) == NULL) {
816+ if ((s = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
808817 fprintf(stderr, "npl_stack_new() failed.\n");
809818 exit(1);
810819 }
811820
812- // 変数スタック
813- if ((var_stack = npl_stack_new()) == NULL) {
821+ // 変数リスト
822+ if ((vlist = npl_array_new(64)) == NULL) {
814823 fprintf(stderr, "npl_stack_new() failed.\n");
815824 exit(1);
816825 }
817- if (npl_stack_enter_obj(var_stack)) {
818- fprintf(stderr, "npl_stack_enter_obj() failed.\n");
819- exit(1);
820- }
821826
822827 // 数式インタプリタ
823828 while (1) {
@@ -848,7 +853,7 @@
848853 }
849854
850855 // オブジェクトは、もう参照しない
851- npl_object_unref(NPL_OBJECT(var_stack));
856+ npl_object_unref(NPL_OBJECT(vlist));
852857 npl_object_unref(NPL_OBJECT(s));
853858 npl_object_unref(NPL_OBJECT(sbuf));
854859 npl_object_unref(NPL_OBJECT(in));
--- trunk/npl/lang/calci.c (revision 66)
+++ trunk/npl/lang/calci.c (revision 67)
@@ -52,31 +52,30 @@
5252 };
5353 };
5454
55-// 変数スタック
56-npl_stack_t *var_stack;
55+// 変数リスト
56+npl_array_t *vlist;
5757
5858 npl_var_t* get_var(wchar_t *name)
5959 {
6060 npl_var_t *var = NULL;
61- size_t i, len, offset;
61+ npl_val_t val;
62+ size_t i, len;
6263
63- // スタックを探す
64- len = npl_stack_count(var_stack) / sizeof(npl_var_t*);
64+ // リストから探す
65+ npl_val_begin(&val);
66+ len = npl_array_len(vlist);
6567 for (i=0; i<len; i++) {
66- offset = i * sizeof(npl_var_t*);
67- if (npl_stack_get(var_stack, offset, sizeof(npl_var_t*), &var)) {
68- fprintf(stderr, "npl_stack_get() failed.\n");
69- exit(1);
70- }
71- if (wcscmp(npl_var_name(var), name) == 0) {
72- npl_object_ref(NPL_OBJECT(var));
68+ npl_array_get(vlist, i, &val);
69+ if (npl_val_check_object(&val, npl_var_type))
70+ continue;
71+ var = NPL_VAR(val.object);
72+ if (wcscmp(npl_var_name(var), name) == 0)
7373 break;
74- }
7574 var = NULL;
7675 }
7776
7877 if (var == NULL) {
79- npl_val_t val;
78+ npl_val_t val2;
8079
8180 if ((var = npl_var_new(name)) == NULL) {
8281 fprintf(stderr, "npl_var_new() failed.\n");
@@ -83,16 +82,26 @@
8382 exit(1);
8483 }
8584
86- npl_val_begin(&val);
87- npl_val_set_int(&val, 0);
88- npl_var_set(var, &val);
89- npl_val_end(&val);
90- if (npl_stack_push_obj(var_stack, NPL_OBJECT(var))) {
91- fprintf(stderr, "npl_stack_push_obj() failed.\n");
92- exit(1);
85+ npl_val_begin(&val2);
86+ npl_val_set_int(&val2, 0);
87+ npl_var_set(var, &val2);
88+ npl_val_end(&val2);
89+
90+ npl_val_begin(&val2);
91+ npl_val_set_object(&val2, NPL_OBJECT(var));
92+ len = npl_array_len(vlist);
93+ for (i=0; i<len; i++) {
94+ npl_array_get(vlist, i, &val);
95+ if (npl_val_check_null(&val))
96+ continue;
97+ npl_array_set(vlist, i, &val2);
98+ break;
9399 }
100+ npl_val_end(&val2);
94101 }
102+ npl_val_end(&val);
95103
104+ npl_object_ref(NPL_OBJECT(var));
96105 return var;
97106 }
98107
@@ -234,7 +243,7 @@
234243
235244 int get_code(npl_stack_t *s, Code *c)
236245 {
237- return npl_stack_get(s, 0, sizeof(Code), c);
246+ return npl_stack_get(s, sizeof(Code), c);
238247 }
239248
240249 void remove_code(npl_stack_t *s)
@@ -247,7 +256,7 @@
247256 npl_object_unref(NPL_OBJECT(c.var));
248257 c.var = NULL;
249258 }
250- npl_stack_remove(s, sizeof(Code));
259+ npl_stack_pop(s, sizeof(Code), NULL);
251260 }
252261
253262 // a のすべての内容をポップして、
@@ -264,7 +273,7 @@
264273 {
265274 npl_stack_t *s;
266275
267- if ((s = npl_stack_new()) == NULL) {
276+ if ((s = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
268277 fprintf(stderr, "my_stack_new() failed.\n");
269278 exit(1);
270279 }
@@ -403,7 +412,7 @@
403412 npl_stack_t *t; // 計算用
404413 Code c;
405414
406- if ((t = npl_stack_new()) == NULL) {
415+ if ((t = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
407416 fprintf(stderr, "calc() failed.\n");
408417 exit(1);
409418 }
@@ -671,9 +680,9 @@
671680 int first; // 単項演算子を判別するため
672681
673682 // セットアップ
674- t = my_stack_new();
675- u = my_stack_new();
676- v = my_stack_new();
683+ t = my_stack_new(NPL_ST_PRIMITIVE, 0);
684+ u = my_stack_new(NPL_ST_PRIMITIVE, 0);
685+ v = my_stack_new(NPL_ST_PRIMITIVE, 0);
677686 pop_code_all(s, t);
678687
679688 // 変換処理
@@ -869,20 +878,16 @@
869878 }
870879
871880 // 新しいスタック・オブジェクトを作成する
872- if ((s = npl_stack_new()) == NULL) {
881+ if ((s = npl_stack_new(NPL_ST_PRIMITIVE, 0)) == NULL) {
873882 fprintf(stderr, "npl_stack_new() failed.\n");
874883 exit(1);
875884 }
876885
877- // 変数スタック
878- if ((var_stack = npl_stack_new()) == NULL) {
886+ // 変数リスト
887+ if ((vlist = npl_array_new(64)) == NULL) {
879888 fprintf(stderr, "npl_stack_new() failed.\n");
880889 exit(1);
881890 }
882- if (npl_stack_enter_obj(var_stack)) {
883- fprintf(stderr, "npl_stack_enter_obj() failed.\n");
884- exit(1);
885- }
886891
887892 // 数式インタプリタ
888893 while (1) {
@@ -913,7 +918,7 @@
913918 }
914919
915920 // オブジェクトは、もう参照しない
916- npl_object_unref(NPL_OBJECT(var_stack));
921+ npl_object_unref(NPL_OBJECT(vlist));
917922 npl_object_unref(NPL_OBJECT(s));
918923 npl_object_unref(NPL_OBJECT(sbuf));
919924 npl_object_unref(NPL_OBJECT(in));
旧リポジトリブラウザで表示