root/NEWT0/trunk/src/newt_core/NewtParser.c

Revision 113, 21.5 kB (checked in by gnue, 17 months ago)

'#pragma mark' is invalidated by '#if 0'

Line 
1//--------------------------------------------------------------------------
2/**
3 * @file    NewtParser.c
4 * @brief   構文木の生成
5 *
6 * @author  M.Nukui
7 * @date    2003-11-07
8 *
9 * Copyright (C) 2003-2004 M.Nukui All rights reserved.
10 */
11
12
13/* ヘッダファイル */
14#include <stdlib.h>
15#include <string.h>
16
17#include "NewtParser.h"
18#include "NewtErrs.h"
19#include "NewtMem.h"
20#include "NewtObj.h"
21#include "NewtEnv.h"
22#include "NewtFns.h"
23#include "NewtVM.h"
24#include "NewtIO.h"
25#include "NewtPrint.h"
26
27#include "yacc.h"
28
29
30/* 型宣言 */
31
32/// 入力データ
33typedef struct {
34    const char *    data;       ///< 入力データ
35    const char *    currp;      ///< 現在の入力位置
36    const char *    limit;      ///< 入力データの最後
37} nps_inputdata_t;
38
39
40/* グローバル変数 */
41nps_env_t               nps_env;        ///< パーサ環境
42
43
44/* ローカル変数 */
45static newtStack        nps_stree;      ///< 構文木スタック情報
46static nps_inputdata_t  nps_inputdata;  ///< 入力データ
47
48
49/* マクロ */
50#define STREESTACK      ((nps_syntax_node_t *)nps_stree.stackp)     ///< 構文木スタック
51#define CX              (nps_stree.sp)                              ///< 構文木スタックポインタ
52
53
54/* 関数プロトタイプ */
55static void     NPSBindParserInput(const char * s);
56static int      nps_yyinput_str(char * buff, int max_size);
57
58static void     NPSInit(newtPool pool);
59
60static void     NPSPrintNode(FILE * f, nps_node_t r);
61static void     NPSPrintSyntaxCode(FILE * f, uint32_t code);
62
63
64#if 0
65#pragma mark -
66#endif
67/*------------------------------------------------------------------------*/
68/** 構文解析する文字列をセットする
69 *
70 * @param s         [in] 文字列
71 *
72 * @return          なし
73 */
74
75void NPSBindParserInput(const char * s)
76{
77    nps_inputdata.data = nps_inputdata.currp = s;
78
79    if (s != NULL)
80        nps_inputdata.limit = s + strlen(s);
81    else
82        nps_inputdata.limit = NULL;
83}
84
85
86/*------------------------------------------------------------------------*/
87/** 構文解析するデータを文字列から取出す
88 *
89 * @param buff      [out]バッファ
90 * @param max_size  [in] 最大長
91 *
92 * @return          取出したデータサイズ
93 */
94
95int nps_yyinput_str(char * buff, int max_size)
96{
97    int n;
98
99    n = nps_inputdata.limit - nps_inputdata.currp;
100    if (max_size < n) n = max_size;
101
102    if (0 < n)
103    {
104        memcpy(buff, nps_inputdata.currp, n);
105        nps_inputdata.currp += n;
106    }
107
108    return n;
109}
110
111
112/*------------------------------------------------------------------------*/
113/** 構文解析するデータを取出す
114 *
115 * @param yyin      [in] 入力ファイル
116 * @param buff      [out]バッファ
117 * @param max_size  [in] 最大長
118 *
119 * @return          取出したデータサイズ
120 */
121
122int nps_yyinput(FILE * yyin, char * buff, int max_size)
123{
124    if (nps_inputdata.data != NULL)
125        return nps_yyinput_str(buff, max_size);
126    else
127        return fread(buff, 1, max_size, yyin);
128}
129
130
131#if 0
132#pragma mark -
133#endif
134/*------------------------------------------------------------------------*/
135/** 構文解析のための初期化
136 *
137 * @param pool      [in] メモリプール
138 *
139 * @return          なし
140 */
141
142void NPSInit(newtPool pool)
143{
144    nps_yyinit();
145
146    nps_env.numwarns = 0;
147    nps_env.numerrs = 0;
148    nps_env.fname = NULL;
149    nps_env.lineno = 1;
150    nps_env.tokenpos = 0;
151    nps_env.first_time = true;
152    nps_env.linebuf[sizeof(nps_env.linebuf) - 1] = '\0';
153
154    NewtStackSetup(&nps_stree, NEWT_POOL, sizeof(nps_syntax_node_t), NEWT_NUM_STREESTACK);
155}
156
157
158/*------------------------------------------------------------------------*/
159/** 構文解析する
160 *
161 * @param path      [in] 入力ファイルのパス
162 * @param streeP    [out]構文木
163 * @param sizeP     [out]構文木のサイズ
164 * @param is_file   [in] ファイルかどうか(#! 処理をおこなうかどうか)
165 *
166 * @return          エラーコード
167 */
168
169newtErr NPSParse(const char * path, nps_syntax_node_t ** streeP, uint32_t * sizeP, bool is_file)
170{
171    newtErr err = kNErrNone;
172
173    NPSInit(NULL);
174    nps_env.fname = path;
175    nps_env.first_time = is_file;
176
177    if (yyparse() != 0 || 0 < nps_env.numerrs)
178        err = kNErrSyntaxError;
179
180    nps_yycleanup();
181
182    if (NEWT_DUMPSYNTAX)
183    {
184        NewtFprintf(stderr, "*** syntax tree ***\n");
185        NPSDumpSyntaxTree(stderr, STREESTACK, CX);
186        NewtFprintf(stderr, "\n");
187    }
188
189    if (err == kNErrNone && 0 < CX)
190        NewtStackSlim(&nps_stree, CX);
191    else
192        NPSCleanup();
193
194    *streeP = STREESTACK;
195    *sizeP = CX;
196
197    return err;
198}
199
200
201/*------------------------------------------------------------------------*/
202/** 指定されたファイルをソースに構文解析する
203 *
204 * @param path      [in] 入力ファイルのパス
205 * @param streeP    [out]構文木
206 * @param sizeP     [out]構文木のサイズ
207 *
208 * @return          エラーコード
209 */
210
211newtErr NPSParseFile(const char * path,
212        nps_syntax_node_t ** streeP, uint32_t * sizeP)
213{
214    newtErr err;
215
216    if (path != NULL)
217    {
218        yyin = fopen(path, "r");
219
220        if (yyin == NULL)
221        {
222            NewtFprintf(stderr, "not open file.\n");
223            return kNErrFileNotOpen;
224        }
225
226        err = NPSParse(path, streeP, sizeP, true);
227        fclose(yyin);
228    }
229    else
230    {
231        err = NPSParse(path, streeP, sizeP, true);
232    }
233
234    return err;
235}
236
237
238/*------------------------------------------------------------------------*/
239/** 文字列をソースに構文解析する
240 *
241 * @param s         [in] 入力データ
242 * @param streeP    [out]構文木
243 * @param sizeP     [out]構文木のサイズ
244 *
245 * @return          エラーコード
246 */
247
248newtErr NPSParseStr(const char * s,
249        nps_syntax_node_t ** streeP, uint32_t * sizeP)
250{
251    newtErr err;
252
253    NPSBindParserInput(s);
254    err = NPSParse(NULL, streeP, sizeP, false);
255    NPSBindParserInput(NULL);
256
257    return err;
258}
259
260
261/*------------------------------------------------------------------------*/
262/** 構文解析の後始末
263 *
264 * @return          なし
265 */
266
267void NPSCleanup(void)
268{
269    NewtStackFree(&nps_stree);
270}
271
272
273#if 0
274#pragma mark -
275#endif
276/*------------------------------------------------------------------------*/
277/** 構文木のノードを印字する
278 *
279 * @param f         [in] 出力ファイル
280 * @param r         [in] ノード
281 *
282 * @return          なし
283 */
284
285void NPSPrintNode(FILE * f, nps_node_t r)
286{
287    if (NPSRefIsSyntaxNode(r))
288        NewtFprintf(f, "*%d", (int)NPSRefToSyntaxNode(r));
289    else
290        NewtPrintObj(f, (newtRef)r);
291}
292
293
294/*------------------------------------------------------------------------*/
295/** 構文コードを印字する
296 *
297 * @param f         [in] 出力ファイル
298 * @param code      [in] 構文コード
299 *
300 * @return          なし
301 */
302
303void NPSPrintSyntaxCode(FILE * f, uint32_t code)
304{
305    char *  s = "Unknown";
306
307    switch (code)
308    {
309        case kNPSConstituentList:
310            s = ";";
311            break;
312
313        case kNPSCommaList:
314            s = ",";
315            break;
316
317        case kNPSConstant:
318            s = "constant";
319            break;
320
321        case kNPSGlobal:
322            s = "global";
323            break;
324
325        case kNPSLocal:
326            s = "local";
327            break;
328
329        case kNPSGlobalFn:
330            s = "global func";
331            break;
332
333        case kNPSFunc:
334            s = "func";
335            break;
336
337        case kNPSArg:
338            s = "arg";
339            break;
340
341        case kNPSMessage:
342            s = "message";
343            break;
344
345        case kNPSLvalue:
346            s = "lvalue";
347            break;
348
349        case kNPSAsign:
350            s = ":=";
351            break;
352
353        case kNPSExists:
354            s = "exists";
355            break;
356
357        case kNPSMethodExists:
358            s = "method exists";
359            break;
360
361        case kNPSTry:
362            s = "try";
363            break;
364
365        case kNPSOnexception:
366            s = "onexception";
367            break;
368
369        case kNPSOnexceptionList:
370            s = "onexception list";
371            break;
372
373        case kNPSIf:
374            s = "if";
375            break;
376
377        case kNPSLoop:
378            s = "loop";
379            break;
380
381        case kNPSFor:
382            s = "for";
383            break;
384
385        case kNPSForeach:
386            s = "foreach";
387            break;
388
389        case kNPSWhile:
390            s = "while";
391            break;
392
393        case kNPSRepeat:
394            s = "repeat";
395            break;
396
397        case kNPSBreak:
398            s = "break";
399            break;
400
401        case kNPSSlot:
402            s = "slot";
403            break;
404    }
405
406    NewtFprintf(f, "%24s\t", s);
407}
408
409
410/*------------------------------------------------------------------------*/
411/** 構文木をダンプする
412 *
413 * @param f         [in] 出力ファイル
414 * @param stree     [in] 構文木
415 * @param size      [in] 構文木のサイズ
416 *
417 * @return          なし
418 */
419
420void NPSDumpSyntaxTree(FILE * f, nps_syntax_node_t * stree, uint32_t size)
421{
422    nps_syntax_node_t * node;
423    uint32_t    i;
424
425    for (i = 0, node = stree; i < size; i++, node++)
426    {
427        NewtFprintf(f, "%d\t", (int)i);
428
429        if (kNPSConstituentList <= node->code)
430        {
431            NPSPrintSyntaxCode(f, node->code);
432        }
433        else
434        {
435            if (node->code <= kNPSPopHandlers)
436                NVMDumpInstName(f, 0, node->code);
437            else if (kNPSAdd <= node->code)
438                NVMDumpInstName(f, kNPSFreqFunc >> 3, node->code - kNPSAdd);
439            else
440                NVMDumpInstName(f, node->code >> 3, 0);
441        }
442
443        NewtFprintf(f, "\t");
444        NPSPrintNode(f, node->op1);
445        NewtFprintf(f, "\t");
446        NPSPrintNode(f, node->op2);
447        NewtFprintf(f, "\n");
448    }
449}
450
451
452#if 0
453#pragma mark -
454#endif
455/*------------------------------------------------------------------------*/
456/** 引数0のノードを作成
457 *
458 * @param code      [in] 構文コード
459 *
460 * @return          ノード
461 */
462
463nps_node_t NPSGenNode0(uint32_t code)
464{
465    return NPSGenNode2(code, kNewtRefUnbind, kNewtRefUnbind);
466}
467
468
469/*------------------------------------------------------------------------*/
470/** 引数1のノードを作成
471 *
472 * @param code      [in] 構文コード
473 * @param op1       [in] 引数1
474 *
475 * @return          ノード
476 */
477
478nps_node_t NPSGenNode1(uint32_t code, nps_node_t op1)
479{
480    return NPSGenNode2(code, op1, kNewtRefUnbind);
481}
482
483
484/*------------------------------------------------------------------------*/
485/** 引数2のノードを作成
486 *
487 * @param code      [in] 構文コード
488 * @param op1       [in] 引数1
489 * @param op2       [in] 引数2
490 *
491 * @return          ノード
492 */
493
494nps_node_t NPSGenNode2(uint32_t code, nps_node_t op1, nps_node_t op2)
495{
496    nps_syntax_node_t * node;
497
498    if (! NewtStackExpand(&nps_stree, CX + 1))
499    {
500        yyerror("Syntax tree overflow");
501        return -1;
502    }
503
504    node = &STREESTACK[CX];
505
506    node->code = code;
507    node->op1 = op1;
508    node->op2 = op2;
509
510    CX++;
511
512    return NPSMakeSyntaxNode(CX - 1);
513}
514
515
516/*------------------------------------------------------------------------*/
517/** 引数1のオペレータノードを作成
518 *
519 * @param op        [in] オペコード
520 * @param op1       [in] 引数1
521 *
522 * @return          ノード
523 */
524
525nps_node_t NPSGenOP1(uint32_t op, nps_node_t op1)
526{
527    uint32_t    b = KNPSUnknownCode;
528
529    switch (op)
530    {
531        case kNPS_NOT:
532            b = kNPSNot;
533            break;
534
535        default:
536            NPSError(kNErrSyntaxError);
537            return kNewtRefUnbind;
538    }
539
540    return NPSGenNode1(b, op1);
541}
542
543
544/*------------------------------------------------------------------------*/
545/** 引数2のオペレータノードを作成
546 *
547 * @param op        [in] オペコード
548 * @param op1       [in] 引数1
549 * @param op2       [in] 引数2
550 *
551 * @return          ノード
552 */
553
554nps_node_t NPSGenOP2(uint32_t op, nps_node_t op1, nps_node_t op2)
555{
556    uint32_t    b = KNPSUnknownCode;
557
558    switch (op)
559    {
560        case '+':
561            b = kNPSAdd;
562            break;
563
564        case '-':
565            b = kNPSSubtract;
566            break;
567
568        case '=':
569            b = kNPSEquals;
570            break;
571
572        case kNPS_NOT_EQUAL:
573            b = kNPSNotEqual;
574            break;
575
576        case kNPS_OBJECT_EQUAL:
577            b = kNPSObjectEqual;
578            break;
579
580        case '<':
581            b = kNPSLessThan;
582            break;
583
584        case '>':
585            b = kNPSGreaterThan;
586            break;
587
588        case kNPS_GREATER_EQUAL:
589            b = kNPSGreaterOrEqual;
590            break;
591
592        case kNPS_LESS_EQUAL:
593            b = kNPSLessOrEqual;
594            break;
595
596        case '*':
597            b = kNPSMultiply;
598            break;
599
600        case '/':
601            b = kNPSDivide;
602            break;
603
604        case kNPS_DIV:
605            b = kNPSDiv;
606            break;
607
608        case kNPS_MOD:
609            b = kNPSMod;
610            break;
611
612        case kNPS_SHIFT_LEFT:
613            b = kNPSShiftLeft;
614            break;
615
616        case kNPS_SHIFT_RIGHT:
617            b = kNPSShiftRight;
618            break;
619
620        case '&':
621            b = kNPSConcat;
622            break;
623
624        case kNPS_CONCAT2:
625            b = kNPSConcat2;
626            break;
627
628        default:
629            NPSError(kNErrSyntaxError);
630            return kNewtRefUnbind;
631    }
632
633    return NPSGenNode2(b, op1, op2);
634}
635
636
637/*------------------------------------------------------------------------*/
638/** メッセージ送信のオペノードを作成
639 *
640 * @param receiver  [in] レシーバ
641 * @param op        [in] オペコード
642 * @param msg       [in] メッセージ
643 * @param args      [in] メッセージの引数
644 *
645 * @return          ノード
646 */
647
648nps_node_t NPSGenSend(nps_node_t receiver,
649                uint32_t op, nps_node_t msg, nps_node_t args)
650{
651    nps_node_t  node;
652
653    op = (op == ':')?kNPSSend:kNPSSendIfDefined;
654
655    node = NPSGenNode2(kNPSMessage, msg, args);
656    return NPSGenNode2(op, receiver, node);
657}
658
659
660/*------------------------------------------------------------------------*/
661/** メッセージ再送信のオペノードを作成
662 *
663 * @param op        [in] オペコード
664 * @param msg       [in] メッセージ
665 * @param args      [in] メッセージの引数
666 *
667 * @return          ノード
668 */
669
670nps_node_t NPSGenResend(uint32_t op, nps_node_t msg, nps_node_t args)
671{
672    op = (op == ':')?kNPSResend:kNPSResendIfDefined;
673
674    return NPSGenNode2(op, msg, args);
675}
676
677
678//--------------------------------------------------------------------------
679/** 条件文のオペノードを作成
680 *
681 * @param cond      [in] 条件式
682 * @param ifthen    [in] THEN 式
683 * @param ifelse    [in] ELSE 式
684 *
685 * @return          ノード
686 */
687
688nps_node_t NPSGenIfThenElse(nps_node_t cond, nps_node_t ifthen, nps_node_t ifelse)
689{
690    nps_node_t  node;
691
692    if (ifelse == kNewtRefUnbind)
693    {
694        node = ifthen;
695    }
696    else
697    {
698        node = NewtMakeArray(kNewtRefUnbind, 2);
699        NewtSetArraySlot(node, 0, ifthen);
700        NewtSetArraySlot(node, 1, ifelse);
701    }
702
703    return NPSGenNode2(kNPSIf, cond, node);
704}
705
706
707//--------------------------------------------------------------------------
708/** FOR 文のオペノードを作成
709 *
710 * @param index     [in] インデックス変数
711 * @param v         [in] 初期値
712 * @param to        [in] 終了値
713 * @param by        [in] ステップ値
714 * @param expr      [in] 繰り返し式
715 *
716 * @return          ノード
717 */
718
719nps_node_t NPSGenForLoop(nps_node_t index, nps_node_t v,
720                nps_node_t to, nps_node_t by, nps_node_t expr)
721{
722    newtRefVar  r;
723
724    r = NewtMakeArray(kNewtRefUnbind, 4);
725    NewtSetArraySlot(r, 0, index);
726    NewtSetArraySlot(r, 1, v);
727    NewtSetArraySlot(r, 2, to);
728    NewtSetArraySlot(r, 3, by);
729
730    return NPSGenNode2(kNPSFor, r, expr);
731}
732
733
734//--------------------------------------------------------------------------
735/** FOREACH 文のオペノードを作成
736 *
737 * @param index     [in] インデックス変数
738 * @param val       [in] 値を格納する変数
739 * @param obj       [in] ループの対象となるオブジェクト
740 * @param deeply    [in] deeply フラグ
741 * @param op        [in] オペレーション種別(DO or COLLECT)
742 * @param expr      [in] 繰り返し式
743 *
744 * @return          ノード
745 */
746
747nps_node_t NPSGenForeach(nps_node_t index, nps_node_t val, nps_node_t obj,
748                nps_node_t deeply, nps_node_t op, nps_node_t expr)
749{
750    newtRefVar  r;
751
752    r = NewtMakeArray(kNewtRefUnbind, 5);
753    NewtSetArraySlot(r, 0, index);
754    NewtSetArraySlot(r, 1, val);
755    NewtSetArraySlot(r, 2, obj);
756    NewtSetArraySlot(r, 3, deeply);
757    NewtSetArraySlot(r, 4, op);
758
759    return NPSGenNode2(kNPSForeach, r, expr);
760}
761
762
763//--------------------------------------------------------------------------
764/** グローバル関数のオペノードを作成
765 *
766 * @param name      [in] 関数名
767 * @param args      [in] 関数の引数
768 * @param expr      [in] 実行式
769 *
770 * @return          ノード
771 */
772
773nps_node_t NPSGenGlobalFn(nps_node_t name, nps_node_t args, nps_node_t expr)
774{
775    nps_node_t  node;
776
777    node = NPSGenNode2(kNPSFunc, args, expr);
778    return NPSGenNode2(kNPSGlobalFn, name, node);
779}
780
781
782#if 0
783#pragma mark -
784#endif
785//--------------------------------------------------------------------------
786/** 参照パスオブジェクトの作成
787 *
788 * @param sym1      [in] シンボル1
789 * @param sym2      [in] シンボル2
790 *
791 * @return          参照パスオブジェクト
792 */
793
794newtRef NPSMakePathExpr(newtRefArg sym1, newtRefArg sym2)
795{
796    newtRefVar  r;
797
798    r = NewtMakeArray(NSSYM0(pathExpr), 2);
799    NewtSetArraySlot(r, 0, sym1);
800    NewtSetArraySlot(r, 1, sym2);
801
802    return r;
803}
804
805
806//--------------------------------------------------------------------------
807/** 配列オブジェクトの作成
808 *
809 * @param v         [in] 初期値
810 *
811 * @return          配列オブジェクト
812 */
813
814newtRef NPSMakeArray(newtRefArg v)
815{
816    newtRefVar  r;
817
818    if (v == kNewtRefUnbind)
819    {
820        r = NewtMakeArray(kNewtRefUnbind, 0);
821    }
822    else
823    {
824        r = NewtMakeArray(kNewtRefUnbind, 1);
825        NewtSetArraySlot(r, 0, v);
826    }
827
828    return r;
829}
830
831
832//--------------------------------------------------------------------------
833/** 配列オブジェクトの最後にオブジェクトを追加する
834 *
835 * @param r         [in] 配列オブジェクト
836 * @param v         [in] 追加するオブジェクト
837 *
838 * @return          配列オブジェクト
839 */
840
841newtRef NPSAddArraySlot(newtRefArg r, newtRefArg v)
842{
843    NcAddArraySlot(r, v);
844    return r;
845}
846
847
848//--------------------------------------------------------------------------
849/** 配列オブジェクトのオブジェクトを挿入する
850 *
851 * @param r         [in] 配列オブジェクト
852 * @param p         [in] 挿入する位置
853 * @param v         [in] 挿入るオブジェクト
854 *
855 * @return          配列オブジェクト
856 */
857
858newtRef NPSInsertArraySlot(newtRefArg r, uint32_t p, newtRefArg v)
859{
860    NewtInsertArraySlot(r, p, v);
861
862    return (newtRef)r;
863}
864
865
866//--------------------------------------------------------------------------
867/** フレームマップオブジェクトの作成
868 *
869 * @param v         [in] 初期値
870 *
871 * @return          フレームマップオブジェクト
872 */
873
874newtRef NPSMakeMap(newtRefArg v)
875{
876    newtRefVar  r;
877
878    if (v == kNewtRefUnbind)
879    {
880        r = NewtMakeMap(kNewtRefNIL, 0, NULL);
881    }
882    else
883    {
884        r = NewtMakeMap(kNewtRefNIL, 1, NULL);
885        NewtSetArraySlot(r, 1, v);
886    }
887
888    return r;
889}
890
891
892//--------------------------------------------------------------------------
893/** フレームオブジェクトの作成
894 *
895 * @param slot      [in] スロットシンボル
896 * @param v         [in] 初期値
897 *
898 * @return          フレームオブジェクト
899 */
900
901newtRef NPSMakeFrame(newtRefArg slot, newtRefArg v)
902{
903    newtRefVar  r;
904
905    if (NewtRefIsNIL(slot))
906    {
907        r = NcMakeFrame();
908    }
909    else
910    {
911        newtRefVar  def[] = {slot, v};
912
913        r = NewtMakeFrame2(1, def);
914    }
915
916    return r;
917}
918
919
920//--------------------------------------------------------------------------
921/** フレームのスロットにオブジェクトをセットする
922 *
923 * @param r         [in] フレームオブジェクト
924 * @param slot      [in] スロットシンボル
925 * @param v         [in] オブジェクト
926 *
927 * @return          フレームオブジェクト
928 */
929
930newtRef NPSSetSlot(newtRefArg r, newtRefArg slot, newtRefArg v)
931{
932    NcSetSlot(r, slot, v);
933    return r;
934}
935
936
937//--------------------------------------------------------------------------
938/** バイナリオブジェクトの作成
939 *
940 * @param v         [in] 初期値
941 *
942 * @return          バイナリオブジェクト
943 */
944
945newtRef NPSMakeBinary(newtRefArg v)
946{
947    newtRefVar  r;
948
949    if (v == kNewtRefUnbind)
950    {
951        r = NewtMakeBinary(kNewtRefUnbind, NULL, 0, false);
952    }
953    else if (NewtRefIsString(v))
954    {
955        r = NcClone(v);
956        NcSetClass(r, kNewtRefUnbind);
957        NewtBinarySetLength(r, NewtStringLength(v));
958    }
959    else
960    {
961        r = NewtMakeBinary(kNewtRefUnbind, NULL, 1, false);
962        NewtSetARef(r, 0, v);
963    }
964
965    return r;
966}
967
968
969//--------------------------------------------------------------------------
970/** バイナリオブジェクトの最後にデータを追加
971 *
972 * @param r         [in] バイナリオブジェクト
973 * @param v         [in] 追加するデータ
974 *
975 * @return          バイナリオブジェクト
976 */
977
978newtRef NPSAddARef(newtRefArg r, newtRefArg v)
979{
980    int32_t len;
981
982    len = NewtBinaryLength(r);
983    NewtBinarySetLength(r, len + 1);
984    NewtSetARef(r, len, v);
985
986    return r;
987}
988
989
990#if 0
991#pragma mark -
992#endif
993//--------------------------------------------------------------------------
994/** エラーメッセージの表示
995 *
996 * @param c         [in] エラー種別
997 * @param s         [in] エラーメッセージ
998 *
999 * @return          なし
1000 */
1001
1002void NPSErrorStr(char c, char * s)
1003{
1004    NewtFprintf(stderr, "%c:", c);
1005
1006    switch (c)
1007    {
1008        case 'W':
1009            nps_env.numwarns++;
1010            break;
1011
1012        case 'E':
1013        default:
1014            nps_env.numerrs++;
1015            break;
1016    }
1017
1018    if (nps_env.fname != NULL)
1019        NewtFprintf(stderr, "\"%s\" ", nps_env.fname);
1020
1021    NewtFprintf(stderr, "lines %d: %s:\n%s\n", nps_env.lineno, s, nps_env.linebuf);
1022    NewtFprintf(stderr, "%*s\n", nps_env.tokenpos - nps_env.yyleng + 1, "^");
1023}
1024
1025
1026//--------------------------------------------------------------------------
1027/** 構文エラー
1028 *
1029 * @param err       [in] エラーコード
1030 *
1031 * @return          なし
1032 */
1033
1034void NPSError(int32_t err)
1035{
1036    yyerror("E:Syntax error");
1037}
Note: See TracBrowser for help on using the browser.