00001
00013
00014 #include <stdlib.h>
00015 #include <string.h>
00016
00017 #include "NewtParser.h"
00018 #include "NewtErrs.h"
00019 #include "NewtMem.h"
00020 #include "NewtObj.h"
00021 #include "NewtEnv.h"
00022 #include "NewtFns.h"
00023 #include "NewtVM.h"
00024 #include "NewtIO.h"
00025 #include "NewtPrint.h"
00026
00027 #include "yacc.h"
00028
00029
00030
00031
00033 typedef struct {
00034 const char * data;
00035 const char * currp;
00036 const char * limit;
00037 } nps_inputdata_t;
00038
00039
00040
00041 nps_env_t nps_env;
00042
00043
00044
00045 static newtStack nps_stree;
00046 static nps_inputdata_t nps_inputdata;
00047
00048
00049
00050 #define STREESTACK ((nps_syntax_node_t *)nps_stree.stackp)
00051 #define CX (nps_stree.sp)
00052
00053
00054
00055 static void NPSBindParserInput(const char * s);
00056 static int nps_yyinput_str(char * buff, int max_size);
00057
00058 static void NPSInit(newtPool pool);
00059
00060 static void NPSPrintNode(FILE * f, nps_node_t r);
00061 static void NPSPrintSyntaxCode(FILE * f, uint32_t code);
00062
00063
00064 #pragma mark -
00065
00073 void NPSBindParserInput(const char * s)
00074 {
00075 nps_inputdata.data = nps_inputdata.currp = s;
00076
00077 if (s != NULL)
00078 nps_inputdata.limit = s + strlen(s);
00079 else
00080 nps_inputdata.limit = NULL;
00081 }
00082
00083
00084
00093 int nps_yyinput_str(char * buff, int max_size)
00094 {
00095 int n;
00096
00097 n = nps_inputdata.limit - nps_inputdata.currp;
00098 if (max_size < n) n = max_size;
00099
00100 if (0 < n)
00101 {
00102 memcpy(buff, nps_inputdata.currp, n);
00103 nps_inputdata.currp += n;
00104 }
00105
00106 return n;
00107 }
00108
00109
00110
00120 int nps_yyinput(FILE * yyin, char * buff, int max_size)
00121 {
00122 if (nps_inputdata.data != NULL)
00123 return nps_yyinput_str(buff, max_size);
00124 else
00125 return fread(buff, 1, max_size, yyin);
00126 }
00127
00128
00129 #pragma mark -
00130
00138 void NPSInit(newtPool pool)
00139 {
00140 nps_yyinit();
00141
00142 nps_env.numwarns = 0;
00143 nps_env.numerrs = 0;
00144 nps_env.fname = NULL;
00145 nps_env.lineno = 1;
00146 nps_env.tokenpos = 0;
00147 nps_env.first_time = true;
00148 nps_env.linebuf[sizeof(nps_env.linebuf) - 1] = '0';
00149
00150 NewtStackSetup(&nps_stree, NEWT_POOL, sizeof(nps_syntax_node_t), NEWT_NUM_STREESTACK);
00151 }
00152
00153
00154
00165 newtErr NPSParse(const char * path, nps_syntax_node_t ** streeP, uint32_t * sizeP, bool is_file)
00166 {
00167 newtErr err = kNErrNone;
00168
00169 NPSInit(NULL);
00170 nps_env.fname = path;
00171 nps_env.first_time = is_file;
00172
00173 if (yyparse() != 0 || 0 < nps_env.numerrs)
00174 err = kNErrSyntaxError;
00175
00176 nps_yycleanup();
00177
00178 if (NEWT_DUMPSYNTAX)
00179 {
00180 NewtFprintf(stderr, "*** syntax tree ***n");
00181 NPSDumpSyntaxTree(stderr, STREESTACK, CX);
00182 NewtFprintf(stderr, "n");
00183 }
00184
00185 if (err == kNErrNone && 0 < CX)
00186 NewtStackSlim(&nps_stree, CX);
00187 else
00188 NPSCleanup();
00189
00190 *streeP = STREESTACK;
00191 *sizeP = CX;
00192
00193 return err;
00194 }
00195
00196
00197
00207 newtErr NPSParseFile(const char * path,
00208 nps_syntax_node_t ** streeP, uint32_t * sizeP)
00209 {
00210 newtErr err;
00211
00212 if (path != NULL)
00213 {
00214 yyin = fopen(path, "r");
00215
00216 if (yyin == NULL)
00217 {
00218 NewtFprintf(stderr, "not open file.n");
00219 return kNErrFileNotOpen;
00220 }
00221
00222 err = NPSParse(path, streeP, sizeP, true);
00223 fclose(yyin);
00224 }
00225 else
00226 {
00227 err = NPSParse(path, streeP, sizeP, true);
00228 }
00229
00230 return err;
00231 }
00232
00233
00234
00244 newtErr NPSParseStr(const char * s,
00245 nps_syntax_node_t ** streeP, uint32_t * sizeP)
00246 {
00247 newtErr err;
00248
00249 NPSBindParserInput(s);
00250 err = NPSParse(NULL, streeP, sizeP, false);
00251 NPSBindParserInput(NULL);
00252
00253 return err;
00254 }
00255
00256
00257
00263 void NPSCleanup(void)
00264 {
00265 NewtStackFree(&nps_stree);
00266 }
00267
00268
00269 #pragma mark -
00270
00279 void NPSPrintNode(FILE * f, nps_node_t r)
00280 {
00281 if (NPSRefIsSyntaxNode(r))
00282 NewtFprintf(f, "*%d", (int)NPSRefToSyntaxNode(r));
00283 else
00284 NewtPrintObj(f, (newtRef)r);
00285 }
00286
00287
00288
00297 void NPSPrintSyntaxCode(FILE * f, uint32_t code)
00298 {
00299 char * s = "Unknown";
00300
00301 switch (code)
00302 {
00303 case kNPSConstituentList:
00304 s = ";";
00305 break;
00306
00307 case kNPSCommaList:
00308 s = ",";
00309 break;
00310
00311 case kNPSConstant:
00312 s = "constant";
00313 break;
00314
00315 case kNPSGlobal:
00316 s = "global";
00317 break;
00318
00319 case kNPSLocal:
00320 s = "local";
00321 break;
00322
00323 case kNPSGlobalFn:
00324 s = "global func";
00325 break;
00326
00327 case kNPSFunc:
00328 s = "func";
00329 break;
00330
00331 case kNPSArg:
00332 s = "arg";
00333 break;
00334
00335 case kNPSMessage:
00336 s = "message";
00337 break;
00338
00339 case kNPSLvalue:
00340 s = "lvalue";
00341 break;
00342
00343 case kNPSAsign:
00344 s = ":=";
00345 break;
00346
00347 case kNPSExists:
00348 s = "exists";
00349 break;
00350
00351 case kNPSMethodExists:
00352 s = "method exists";
00353 break;
00354
00355 case kNPSTry:
00356 s = "try";
00357 break;
00358
00359 case kNPSOnexception:
00360 s = "onexception";
00361 break;
00362
00363 case kNPSOnexceptionList:
00364 s = "onexception list";
00365 break;
00366
00367 case kNPSIf:
00368 s = "if";
00369 break;
00370
00371 case kNPSLoop:
00372 s = "loop";
00373 break;
00374
00375 case kNPSFor:
00376 s = "for";
00377 break;
00378
00379 case kNPSForeach:
00380 s = "foreach";
00381 break;
00382
00383 case kNPSWhile:
00384 s = "while";
00385 break;
00386
00387 case kNPSRepeat:
00388 s = "repeat";
00389 break;
00390
00391 case kNPSBreak:
00392 s = "break";
00393 break;
00394
00395 case kNPSSlot:
00396 s = "slot";
00397 break;
00398 }
00399
00400 NewtFprintf(f, "%24st", s);
00401 }
00402
00403
00404
00414 void NPSDumpSyntaxTree(FILE * f, nps_syntax_node_t * stree, uint32_t size)
00415 {
00416 nps_syntax_node_t * node;
00417 uint32_t i;
00418
00419 for (i = 0, node = stree; i < size; i++, node++)
00420 {
00421 NewtFprintf(f, "%dt", (int)i);
00422
00423 if (kNPSConstituentList <= node->code)
00424 {
00425 NPSPrintSyntaxCode(f, node->code);
00426 }
00427 else
00428 {
00429 if (node->code <= kNPSPopHandlers)
00430 NVMDumpInstName(f, 0, node->code);
00431 else if (kNPSAdd <= node->code)
00432 NVMDumpInstName(f, kNPSFreqFunc >> 3, node->code - kNPSAdd);
00433 else
00434 NVMDumpInstName(f, node->code >> 3, 0);
00435 }
00436
00437 NewtFprintf(f, "t");
00438 NPSPrintNode(f, node->op1);
00439 NewtFprintf(f, "t");
00440 NPSPrintNode(f, node->op2);
00441 NewtFprintf(f, "n");
00442 }
00443 }
00444
00445
00446 #pragma mark -
00447
00455 nps_node_t NPSGenNode0(uint32_t code)
00456 {
00457 return NPSGenNode2(code, kNewtRefUnbind, kNewtRefUnbind);
00458 }
00459
00460
00461
00470 nps_node_t NPSGenNode1(uint32_t code, nps_node_t op1)
00471 {
00472 return NPSGenNode2(code, op1, kNewtRefUnbind);
00473 }
00474
00475
00476
00486 nps_node_t NPSGenNode2(uint32_t code, nps_node_t op1, nps_node_t op2)
00487 {
00488 nps_syntax_node_t * node;
00489
00490 if (! NewtStackExpand(&nps_stree, CX + 1))
00491 {
00492 yyerror("Syntax tree overflow");
00493 return -1;
00494 }
00495
00496 node = &STREESTACK[CX];
00497
00498 node->code = code;
00499 node->op1 = op1;
00500 node->op2 = op2;
00501
00502 CX++;
00503
00504 return NPSMakeSyntaxNode(CX - 1);
00505 }
00506
00507
00508
00517 nps_node_t NPSGenOP1(uint32_t op, nps_node_t op1)
00518 {
00519 uint32_t b = KNPSUnknownCode;
00520
00521 switch (op)
00522 {
00523 case kNPS_NOT:
00524 b = kNPSNot;
00525 break;
00526
00527 default:
00528 NPSError(kNErrSyntaxError);
00529 return kNewtRefUnbind;
00530 }
00531
00532 return NPSGenNode1(b, op1);
00533 }
00534
00535
00536
00546 nps_node_t NPSGenOP2(uint32_t op, nps_node_t op1, nps_node_t op2)
00547 {
00548 uint32_t b = KNPSUnknownCode;
00549
00550 switch (op)
00551 {
00552 case '+':
00553 b = kNPSAdd;
00554 break;
00555
00556 case '-':
00557 b = kNPSSubtract;
00558 break;
00559
00560 case '=':
00561 b = kNPSEquals;
00562 break;
00563
00564 case kNPS_NOT_EQUAL:
00565 b = kNPSNotEqual;
00566 break;
00567
00568 case kNPS_OBJECT_EQUAL:
00569 b = kNPSObjectEqual;
00570 break;
00571
00572 case '<':
00573 b = kNPSLessThan;
00574 break;
00575
00576 case '>':
00577 b = kNPSGreaterThan;
00578 break;
00579
00580 case kNPS_GREATER_EQUAL:
00581 b = kNPSGreaterOrEqual;
00582 break;
00583
00584 case kNPS_LESS_EQUAL:
00585 b = kNPSLessOrEqual;
00586 break;
00587
00588 case '*':
00589 b = kNPSMultiply;
00590 break;
00591
00592 case '/':
00593 b = kNPSDivide;
00594 break;
00595
00596 case kNPS_DIV:
00597 b = kNPSDiv;
00598 break;
00599
00600 case kNPS_MOD:
00601 b = kNPSMod;
00602 break;
00603
00604 case kNPS_SHIFT_LEFT:
00605 b = kNPSShiftLeft;
00606 break;
00607
00608 case kNPS_SHIFT_RIGHT:
00609 b = kNPSShiftRight;
00610 break;
00611
00612 case '&':
00613 b = kNPSConcat;
00614 break;
00615
00616 case kNPS_CONCAT2:
00617 b = kNPSConcat2;
00618 break;
00619
00620 default:
00621 NPSError(kNErrSyntaxError);
00622 return kNewtRefUnbind;
00623 }
00624
00625 return NPSGenNode2(b, op1, op2);
00626 }
00627
00628
00629
00640 nps_node_t NPSGenSend(nps_node_t receiver,
00641 uint32_t op, nps_node_t msg, nps_node_t args)
00642 {
00643 nps_node_t node;
00644
00645 op = (op == ':')?kNPSSend:kNPSSendIfDefined;
00646
00647 node = NPSGenNode2(kNPSMessage, msg, args);
00648 return NPSGenNode2(op, receiver, node);
00649 }
00650
00651
00652
00662 nps_node_t NPSGenResend(uint32_t op, nps_node_t msg, nps_node_t args)
00663 {
00664 op = (op == ':')?kNPSResend:kNPSResendIfDefined;
00665
00666 return NPSGenNode2(op, msg, args);
00667 }
00668
00669
00670
00680 nps_node_t NPSGenIfThenElse(nps_node_t cond, nps_node_t ifthen, nps_node_t ifelse)
00681 {
00682 nps_node_t node;
00683
00684 if (ifelse == kNewtRefUnbind)
00685 {
00686 node = ifthen;
00687 }
00688 else
00689 {
00690 node = NewtMakeArray(kNewtRefUnbind, 2);
00691 NewtSetArraySlot(node, 0, ifthen);
00692 NewtSetArraySlot(node, 1, ifelse);
00693 }
00694
00695 return NPSGenNode2(kNPSIf, cond, node);
00696 }
00697
00698
00699
00711 nps_node_t NPSGenForLoop(nps_node_t index, nps_node_t v,
00712 nps_node_t to, nps_node_t by, nps_node_t expr)
00713 {
00714 newtRefVar r;
00715
00716 r = NewtMakeArray(kNewtRefUnbind, 4);
00717 NewtSetArraySlot(r, 0, index);
00718 NewtSetArraySlot(r, 1, v);
00719 NewtSetArraySlot(r, 2, to);
00720 NewtSetArraySlot(r, 3, by);
00721
00722 return NPSGenNode2(kNPSFor, r, expr);
00723 }
00724
00725
00726
00739 nps_node_t NPSGenForeach(nps_node_t index, nps_node_t val, nps_node_t obj,
00740 nps_node_t deeply, nps_node_t op, nps_node_t expr)
00741 {
00742 newtRefVar r;
00743
00744 r = NewtMakeArray(kNewtRefUnbind, 5);
00745 NewtSetArraySlot(r, 0, index);
00746 NewtSetArraySlot(r, 1, val);
00747 NewtSetArraySlot(r, 2, obj);
00748 NewtSetArraySlot(r, 3, deeply);
00749 NewtSetArraySlot(r, 4, op);
00750
00751 return NPSGenNode2(kNPSForeach, r, expr);
00752 }
00753
00754
00755
00765 nps_node_t NPSGenGlobalFn(nps_node_t name, nps_node_t args, nps_node_t expr)
00766 {
00767 nps_node_t node;
00768
00769 node = NPSGenNode2(kNPSFunc, args, expr);
00770 return NPSGenNode2(kNPSGlobalFn, name, node);
00771 }
00772
00773
00774 #pragma mark -
00775
00784 newtRef NPSMakePathExpr(newtRefArg sym1, newtRefArg sym2)
00785 {
00786 newtRefVar r;
00787
00788 r = NewtMakeArray(NSSYM0(pathExpr), 2);
00789 NewtSetArraySlot(r, 0, sym1);
00790 NewtSetArraySlot(r, 1, sym2);
00791
00792 return r;
00793 }
00794
00795
00796
00804 newtRef NPSMakeArray(newtRefArg v)
00805 {
00806 newtRefVar r;
00807
00808 if (v == kNewtRefUnbind)
00809 {
00810 r = NewtMakeArray(kNewtRefUnbind, 0);
00811 }
00812 else
00813 {
00814 r = NewtMakeArray(kNewtRefUnbind, 1);
00815 NewtSetArraySlot(r, 0, v);
00816 }
00817
00818 return r;
00819 }
00820
00821
00822
00831 newtRef NPSAddArraySlot(newtRefArg r, newtRefArg v)
00832 {
00833 NcAddArraySlot(r, v);
00834 return r;
00835 }
00836
00837
00838
00848 newtRef NPSInsertArraySlot(newtRefArg r, uint32_t p, newtRefArg v)
00849 {
00850 NewtInsertArraySlot(r, p, v);
00851
00852 return (newtRef)r;
00853 }
00854
00855
00856
00864 newtRef NPSMakeMap(newtRefArg v)
00865 {
00866 newtRefVar r;
00867
00868 if (v == kNewtRefUnbind)
00869 {
00870 r = NewtMakeMap(kNewtRefNIL, 0, NULL);
00871 }
00872 else
00873 {
00874 r = NewtMakeMap(kNewtRefNIL, 1, NULL);
00875 NewtSetArraySlot(r, 1, v);
00876 }
00877
00878 return r;
00879 }
00880
00881
00882
00891 newtRef NPSMakeFrame(newtRefArg slot, newtRefArg v)
00892 {
00893 newtRefVar r;
00894
00895 if (NewtRefIsNIL(slot))
00896 {
00897 r = NcMakeFrame();
00898 }
00899 else
00900 {
00901 newtRefVar def[] = {slot, v};
00902
00903 r = NewtMakeFrame2(1, def);
00904 }
00905
00906 return r;
00907 }
00908
00909
00910
00920 newtRef NPSSetSlot(newtRefArg r, newtRefArg slot, newtRefArg v)
00921 {
00922 NcSetSlot(r, slot, v);
00923 return r;
00924 }
00925
00926
00927
00935 newtRef NPSMakeBinary(newtRefArg v)
00936 {
00937 newtRefVar r;
00938
00939 if (v == kNewtRefUnbind)
00940 {
00941 r = NewtMakeBinary(kNewtRefUnbind, NULL, 0, false);
00942 }
00943 else if (NewtRefIsString(v))
00944 {
00945 r = NcClone(v);
00946 NcSetClass(r, kNewtRefUnbind);
00947 NewtBinarySetLength(r, NewtStringLength(v));
00948 }
00949 else
00950 {
00951 r = NewtMakeBinary(kNewtRefUnbind, NULL, 1, false);
00952 NewtSetARef(r, 0, v);
00953 }
00954
00955 return r;
00956 }
00957
00958
00959
00968 newtRef NPSAddARef(newtRefArg r, newtRefArg v)
00969 {
00970 int32_t len;
00971
00972 len = NewtBinaryLength(r);
00973 NewtBinarySetLength(r, len + 1);
00974 NewtSetARef(r, len, v);
00975
00976 return r;
00977 }
00978
00979
00980 #pragma mark -
00981
00990 void NPSErrorStr(char c, char * s)
00991 {
00992 NewtFprintf(stderr, "%c:", c);
00993
00994 switch (c)
00995 {
00996 case 'W':
00997 nps_env.numwarns++;
00998 break;
00999
01000 case 'E':
01001 default:
01002 nps_env.numerrs++;
01003 break;
01004 }
01005
01006 if (nps_env.fname != NULL)
01007 NewtFprintf(stderr, ""%s" ", nps_env.fname);
01008
01009 NewtFprintf(stderr, "lines %d: %s:n%sn", nps_env.lineno, s, nps_env.linebuf);
01010 NewtFprintf(stderr, "%*sn", nps_env.tokenpos - nps_env.yyleng + 1, "^");
01011 }
01012
01013
01014
01022 void NPSError(int32_t err)
01023 {
01024 yyerror("E:Syntax error");
01025 }
01026