00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 #include <stdlib.h>
00379 #include <string.h>
00380 #include <stdio.h>
00381
00382
00383 #include "errcodes.h"
00384 #include "report.h"
00385 #include "lexer.h"
00386 #include "sym.h"
00387 #include "expression.h"
00388 #include "myalloc.h"
00389
00390
00391 #include "syntax.h"
00392 #include "ipreproc.h"
00393
00394 #define new_eNODE() _new_eNODE(pEx)
00395 #define new_eNODE_l() _new_eNODE_l(pEx,NULL,0L)
00396 #define new_eNODE_lL() _new_eNODE_l(pEx,pszFileName,lLineNumber)
00397 #define new_SymbolUF() _new_SymbolUF(pEx)
00398 #define new_SymbolVAR(y) _new_SymbolVAR(pEx,y)
00399 #define new_SymbolLABEL() _new_SymbolLABEL(pEx)
00400 #define ex_PopLabel(y) _ex_PopLabel(pEx,y)
00401 #define ex_CleanLabelStack() _ex_CleanLabelStack(pEx)
00402 #define LOCAL_VAR 1
00403 #define GLOBAL_VAR 0
00404
00405 #define LexemeLineNumber lex_LineNumber(pEx->pLex)
00406 #define LexemeFileName lex_FileName(pEx->pLex)
00407 #define NextLexeme lex_NextLexeme(pEx->pLex);
00408 #define LexemeType (lex_EOF(pEx->pLex) ? 0 : lex_Type(pEx->pLex))
00409 #define LexemeCode lex_Code(pEx->pLex)
00410 #define LexemeChar lex_Char(pEx->pLex)
00411 #define LexemeStrLen lex_StrLen(pEx->pLex)
00412 #define LexemeString lex_String(pEx->pLex)
00413 #define LexemeDouble lex_Double(pEx->pLex)
00414 #define LexemeLong lex_Long(pEx->pLex)
00415 #define LexemeInt lex_Int(pEx->pLex)
00416 #define LexemeSymbol lex_Symbol(pEx->pLex)
00417 #define WeAreLocal (pEx->iWeAreLocal)
00418 #define WeAreNotLocal (!pEx->iWeAreLocal)
00419 #define DeclareVars (pEx->iDeclareVars)
00420 #define DefaultLocal (pEx->iDefaultLocal)
00421
00422 #define COUNT_STRING_LEN (pEx->cbStringTable += sizeof(long));
00423
00424 #define CALL_PREPROCESSOR(X,Y) if( pEx->pPREP && pEx->pPREP->n )ipreproc_Process(pEx->pPREP,X,Y)
00425
00426 #define REPORT(x1,x2,x3,x4) do{if( pEx->report )pEx->report(pEx->reportptr,x1,x2,x3,REPORT_ERROR,&(pEx->iErrorCounter),x4,&(pEx->fErrorFlags));}while(0)
00427
00428 static isinset(int ch,char *string){
00429 while( ch != *string && *++string );
00430 return *string;
00431 }
00432
00433 static void _ex_printVAR(char *name, void *value, void *f){
00434 FILE *fp = (FILE *)f;
00435 pSymbolVAR p = (pSymbolVAR)value;
00436
00437 fprintf(f,"%s=%d\n",name,p->Serial);
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 void ex_DumpVariables(SymbolTable q,
00448 FILE *fp
00449 ){
00450
00451
00452
00453
00454 sym_TraverseSymbolTable(q,_ex_printVAR,(void*)fp);
00455 }
00456
00457 static void _ex_pprint(FILE *f, peNODE p, peXobject pEx,int tab);
00458 void _ex_pprint_l(FILE *f, peNODE_l p, peXobject pEx,int tab){
00459 fprintf(f,"%*sexpression list\n",tab,"");
00460 while( p ){
00461 fprintf(f,"%*sNode id=%d\n",tab,"",p->NodeId);
00462 _ex_pprint(f,p->actualm,pEx,tab+1);
00463 p = p->rest ;
00464 }
00465 }
00466
00467 static void _ex_pprint(FILE *f, peNODE p, peXobject pEx,int tab){
00468 unsigned long *q;
00469 pLineSyntax pCommand;
00470 peNODE_l z;
00471 int i,j;
00472
00473 #define OPCODE (p->OpCode)
00474
00475 if( tab )fprintf(f,"%*s",tab,"");
00476 fprintf(f," %d ",p->NodeId);
00477 tab++;
00478 if( p == NULL )return;
00479 switch(OPCODE){
00480
00481 case eNTYPE_ARR:
00482 fprintf(f,"Array access\n");
00483 _ex_pprint_l(f, p->Parameter.Arguments.Argument ,pEx,tab+1);
00484 break;
00485 case eNTYPE_SAR:
00486 fprintf(f,"Associative array access\n");
00487 _ex_pprint_l(f, p->Parameter.Arguments.Argument ,pEx,tab+1);
00488 break;
00489 case eNTYPE_FUN:
00490 fprintf(f,"User function call starting at node %d\n",p->Parameter.UserFunction.pFunction->node);
00491 _ex_pprint_l(f, p->Parameter.UserFunction.Argument ,pEx,tab+1);
00492 break;
00493 case eNTYPE_LVR:
00494 fprintf(f,"Local variable %d\n",p->Parameter.Variable.Serial);
00495 return;
00496 case eNTYPE_GVR:
00497 fprintf(f,"Global variable %d\n",p->Parameter.Variable.Serial);
00498 return;
00499 case eNTYPE_DBL:
00500 fprintf(f,"Double: %f\n",p->Parameter.Constant.Value.dValue);
00501 return;
00502 case eNTYPE_LNG:
00503 fprintf(f,"Long: %d\n",p->Parameter.Constant.Value.lValue);
00504 return;
00505 case eNTYPE_STR:
00506 fprintf(f,"String %s\n",p->Parameter.Constant.Value.sValue);
00507 return;
00508 default:
00509 q = pEx->Binaries;
00510
00511 while( *q && *q != (unsigned)OPCODE )q+=2;
00512 if( *q ){
00513 fprintf(f,"Opcode: %d %s",OPCODE,lex_SymbolicName(pEx->pLex,OPCODE));
00514 fprintf(f,"bin\n");
00515 _ex_pprint(f,p->Parameter.Arguments.Argument->actualm,pEx,tab);
00516 fprintf(f,"rest %d\n",p->Parameter.Arguments.Argument->rest->NodeId);
00517 _ex_pprint(f,p->Parameter.Arguments.Argument->rest->actualm,pEx,tab);
00518 return;
00519 }
00520 q = pEx->Unaries;
00521 while( *q && *q != (unsigned)OPCODE )q++;
00522 if( *q ){
00523 fprintf(f,"Opcode: %d %s",OPCODE,lex_SymbolicName(pEx->pLex,OPCODE));
00524 fprintf(f,"una\n");
00525 _ex_pprint(f,p->Parameter.Arguments.Argument->actualm,pEx,tab);
00526 return;
00527 }
00528 pCommand = pEx->Command;
00529 while( pCommand && pCommand->CommandOpCode != 0 && pCommand->CommandOpCode != OPCODE )pCommand++;
00530 if( pCommand && pCommand->CommandOpCode ){
00531 fprintf(f,"Command %d %s\n",OPCODE,lex_SymbolicName(pEx->pLex,OPCODE));
00532 for( i=0,j=0 ; j < MAX_LEXES_PER_LINE && pCommand->lexes[j].type && p ; j++ ){
00533 switch( pCommand->lexes[j].type ){
00534 case EX_LEX_CHARACTER:
00535 break;
00536 case EX_LEX_NSYMBOL:
00537 break;
00538 case EX_LEX_EXP:
00539 fprintf(f,"%*sexpression %d\n",tab,"",p->Parameter.CommandArgument.Argument.pNode->NodeId);
00540 _ex_pprint(f,p->Parameter.CommandArgument.Argument.pNode,pEx,tab);
00541 p=p->Parameter.CommandArgument.next;
00542 break;
00543 case EX_LEX_EXPL:
00544 fprintf(f,"%*sexpression list\n",tab,"");
00545 z = p->Parameter.CommandArgument.Argument.pNodeList;
00546 while( z ){
00547 _ex_pprint(f,z->actualm,pEx,tab);
00548 z = z->rest;
00549 }
00550 p=p->Parameter.CommandArgument.next;
00551 break;
00552 case EX_LEX_LVAL:
00553 fprintf(f,"%*slval %d\n",tab,"",p->Parameter.CommandArgument.Argument.pNode->NodeId);
00554 _ex_pprint(f,p->Parameter.CommandArgument.Argument.pNode,pEx,tab);
00555 p=p->Parameter.CommandArgument.next;
00556 break;
00557 case EX_LEX_SYMBOL:
00558 fprintf(f,"%*ssymbol=%s\n",tab,"",p->Parameter.CommandArgument.Argument.szStringValue);
00559 p=p->Parameter.CommandArgument.next;
00560 break;
00561 case EX_LEX_LONG:
00562 fprintf(f,"%*slong=%d\n",tab,"",p->Parameter.CommandArgument.Argument.lLongValue);
00563 p=p->Parameter.CommandArgument.next;
00564 break;
00565 case EX_LEX_DOUBLE:
00566 fprintf(f,"%*sdouble=%f\n",tab,"",p->Parameter.CommandArgument.Argument.dDoubleValue);
00567 p=p->Parameter.CommandArgument.next;
00568 break;
00569 case EX_LEX_ASYMBOL:
00570 fprintf(f,"%*ssymbol=\"%s\"\n",tab,"",p->Parameter.CommandArgument.Argument.szStringValue);
00571 p=p->Parameter.CommandArgument.next;
00572 break;
00573 case EX_LEX_STRING:
00574 fprintf(f,"%*sstring=\"%s\"\n",tab,"",p->Parameter.CommandArgument.Argument.szStringValue);
00575 p=p->Parameter.CommandArgument.next;
00576 break;
00577 }
00578 }
00579 return;
00580 }
00581
00582 fprintf(f,"Opcode: %d ",OPCODE);
00583 fprintf(f,"bif\n");
00584 z = p->Parameter.Arguments.Argument;
00585 while( z ){
00586 _ex_pprint(f,z->actualm,pEx,tab);
00587 z = z->rest;
00588 }
00589 return;
00590 }
00591 #undef OPCODE
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 int expression_PushNameSpace(peXobject pEx
00608 ){
00609
00610
00611 pNameSpaceStack p;
00612
00613 p = (pNameSpaceStack)alloc_Alloc(sizeof(NameSpaceStack),pEx->pMemorySegment);
00614 if( p == NULL )return EX_ERROR_MEMORY_LOW;
00615
00616 p->ThisNameSpace = (char *)alloc_Alloc(strlen(pEx->CurrentNameSpace)+1,pEx->pMemorySegment);
00617 if( p->ThisNameSpace == NULL ){
00618 alloc_Free(p,pEx->pMemorySegment);
00619 return EX_ERROR_MEMORY_LOW;
00620 }
00621 strcpy(p->ThisNameSpace,pEx->CurrentNameSpace);
00622
00623 p->next = pEx->pOldNameSpace;
00624 pEx->pOldNameSpace = p;
00625 return EX_ERROR_SUCCESS;
00626 }
00627
00628
00629
00630
00631 static void CUL_callback(char *LabelName, void *pL, void *f){
00632 peXobject pEx = (peXobject)f;
00633 pSymbolLABEL pLabel = (pSymbolLABEL)pL;
00634
00635 if( pLabel->node == 0 ){
00636 if( pEx->report )
00637 REPORT("",0,EX_ERROR_LABEL_NOT_DEFINED,LabelName);
00638 else
00639 pEx->iErrorCounter++;
00640 }
00641 }
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 void ex_CheckUndefinedLabels(peXobject pEx
00653 ){
00654
00655
00656 sym_TraverseSymbolTable(pEx->GlobalLabels,CUL_callback,pEx);
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 void ex_CleanNameSpaceStack(peXobject pEx
00671 ){
00672
00673
00674 pNameSpaceStack p;
00675
00676 if( pEx->pOldNameSpace )
00677 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNFINISHED_MODULE,NULL);
00678 while( pEx->pOldNameSpace ){
00679 p = pEx->pOldNameSpace;
00680 pEx->pOldNameSpace = pEx->pOldNameSpace->next;
00681 alloc_Free(p->ThisNameSpace,pEx->pMemorySegment);
00682 alloc_Free(p,pEx->pMemorySegment);
00683 }
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 int expression_PopNameSpace(peXobject pEx
00700 ){
00701
00702
00703 pNameSpaceStack p;
00704
00705 if( (p=pEx->pOldNameSpace) == NULL )return EX_ERROR_NO_OLD_NAMESPACE;
00706
00707 pEx->pOldNameSpace = pEx->pOldNameSpace->next;
00708 strcpy(pEx->CurrentNameSpace,p->ThisNameSpace);
00709
00710 alloc_Free(p->ThisNameSpace,pEx->pMemorySegment);
00711 alloc_Free(p,pEx->pMemorySegment);
00712 return EX_ERROR_SUCCESS;
00713 }
00714
00715
00716
00717
00718
00719
00720
00721 int ex_PushWaitingLabel(peXobject pEx,
00722 pSymbolLABEL pLbl
00723 ){
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 if( pEx->cLabelsWaiting < MAX_SAME_LABELS ){
00756 pEx->LabelsWaiting[pEx->cLabelsWaiting++] = pLbl;
00757 return EX_ERROR_SUCCESS;
00758 }
00759 return EX_ERROR_TOO_MANY_WAITING_LABEL;
00760 }
00761
00762
00763
00764
00765
00766
00767
00768 pSymbolLABEL ex_PopWaitingLabel(peXobject pEx
00769 ){
00770
00771
00772
00773
00774
00775 if( pEx->cLabelsWaiting == 0 )return NULL;
00776 return pEx->LabelsWaiting[ -- (pEx->cLabelsWaiting) ];
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 int _ex_PushLabel(peXobject pEx,
00788 pSymbolLABEL pLbl,
00789 long Type,
00790 void *pMemorySegment
00791 ){
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 pLabelStack p;
00806
00807 if( pEx->pFreeComeAndGoStack == NULL ){
00808 pEx->pFreeComeAndGoStack = alloc_Alloc(sizeof(LabelStack),pMemorySegment);
00809 if( pEx->pFreeComeAndGoStack == NULL )return EX_ERROR_MEMORY_LOW;
00810 pEx->pFreeComeAndGoStack->Flink = NULL;
00811 }
00812 p = pEx->pFreeComeAndGoStack;
00813 pEx->pFreeComeAndGoStack = pEx->pFreeComeAndGoStack->Flink;
00814 p->Flink = pEx->pComeAndGoStack;
00815 p->Type = Type;
00816 pEx->pComeAndGoStack = p;
00817 p->pLabel = pLbl;
00818 return 0;
00819 }
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 pSymbolLABEL _ex_PopLabel(peXobject pEx,
00840 long *pAcceptedType
00841 ){
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 pLabelStack q;
00853 pSymbolLABEL p;
00854 int i = MAX_GO_CONSTANTS;
00855 long lTypeOnStack;
00856
00857 if( pEx->pComeAndGoStack == NULL )return NULL;
00858 p = pEx->pComeAndGoStack->pLabel;
00859 lTypeOnStack = pEx->pComeAndGoStack->Type;
00860 pEx->pComeAndGoStack->pLabel = NULL;
00861 q = pEx->pComeAndGoStack->Flink;
00862 pEx->pComeAndGoStack->Flink = pEx->pFreeComeAndGoStack;
00863 pEx->pFreeComeAndGoStack = pEx->pComeAndGoStack;
00864 pEx->pComeAndGoStack = q;
00865
00866 if( pAcceptedType ){
00867 while( i-- )
00868 if( *pAcceptedType++ == lTypeOnStack )return p;
00869 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_BAD_NESTING,NULL);
00870 }
00871
00872 return p;
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882 void _ex_CleanLabelStack(peXobject pEx
00883 ){
00884
00885
00886
00887 if( ex_PopLabel(NULL) )
00888 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNFINISHED_NESTING,NULL);
00889 while( ex_PopLabel(NULL) );
00890 }
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 pSymbolLABEL _new_SymbolLABEL(peXobject pEx
00937 ){
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 pSymbolLABEL p;
00948
00949 p = (pSymbolLABEL)alloc_Alloc(sizeof(SymbolLABEL),pEx->pMemorySegment);
00950 if( p == NULL )return NULL;
00951 pEx->cGlobalLabels ++;
00952 p->Serial = pEx->cGlobalLabels;
00953 p->node = 0;
00954 return p;
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 pSymbolVAR _new_SymbolVAR(peXobject pEx,
00966 int iLocal
00967 ){
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977 pSymbolVAR p;
00978
00979 if( iLocal ){
00980 p = (pSymbolVAR)alloc_Alloc(sizeof(SymbolVAR),pEx->pLocalVarMemorySegment);
00981 if( p == NULL )return NULL;
00982 pEx->cLocalVariables++;
00983 p->Serial = pEx->cLocalVariables;
00984 }else{
00985 p = (pSymbolVAR)alloc_Alloc(sizeof(SymbolVAR),pEx->pMemorySegment);
00986 if( p == NULL )return NULL;
00987 pEx->cGlobalVariables++;
00988 p->Serial = pEx->cGlobalVariables;
00989 }
00990
00991 return p;
00992 }
00993
00994
00995
00996
00997
00998
00999 pSymbolUF _new_SymbolUF(peXobject pEx
01000 ){
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 pSymbolUF p;
01011
01012 p = (pSymbolUF)alloc_Alloc(sizeof(SymbolUF),pEx->pMemorySegment);
01013 if( p == NULL )return NULL;
01014
01015 pEx->cUserFunctions ++;
01016 p->FunId = pEx->cUserFunctions;
01017 p->next = pEx->FirstUF;
01018 pEx->FirstUF = p;
01019 p->node = 0L;
01020
01021 return p;
01022 }
01023
01024
01025
01026
01027
01028
01029
01030 peNODE _new_eNODE(peXobject pEx
01031 ){
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044 peNODE p;
01045
01046 p = (peNODE)alloc_Alloc(sizeof(eNODE),pEx->pMemorySegment);
01047 if( p == NULL )return NULL;
01048 pEx->NodeCounter ++;
01049 p->NodeId = pEx->NodeCounter;
01050 if( pEx->pLex->pLexCurrentLexeme ){
01051 p->szFileName = pEx->pLex->pLexCurrentLexeme->szFileName;
01052 p->lLineNumber = pEx->pLex->pLexCurrentLexeme->lLineNumber;
01053 }else{
01054 p->szFileName = NULL;
01055 p->lLineNumber = 0;
01056 }
01057
01058 return p;
01059 }
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069 peNODE_l _new_eNODE_l(peXobject pEx,
01070 char *pszFileName,
01071 long lLineNumber
01072 ){
01073
01074
01075
01076
01077
01078 peNODE_l p;
01079
01080 p = ((peNODE_l)alloc_Alloc(sizeof(eNODE_l),pEx->pMemorySegment));
01081 if( p == NULL )return NULL;
01082 pEx->NodeCounter ++;
01083 p->NodeId = pEx->NodeCounter;
01084 p->szFileName = NULL;
01085 p->lLineNumber = 0;
01086 if( pszFileName ){
01087 p->szFileName = pszFileName;
01088 p->lLineNumber = lLineNumber;
01089 }else
01090 if( pEx->pLex && pEx->pLex->pLexCurrentLexeme ){
01091 p->szFileName = pEx->pLex->pLexCurrentLexeme->szFileName;
01092 p->lLineNumber = pEx->pLex->pLexCurrentLexeme->lLineNumber;
01093 }
01094
01095 p->rest = NULL;
01096 p->actualm = NULL;
01097
01098 return p;
01099 }
01100
01101
01102
01103
01104
01105
01106
01107 void ex_free(peXobject pEx
01108 ){
01109
01110
01111
01112 alloc_FinishSegment(pEx->pMemorySegment);
01113 alloc_FinishSegment(pEx->pLocalVarMemorySegment);
01114 alloc_FinishSegment(pEx->pSymbolTableMemorySegment);
01115 pEx->pMemorySegment = NULL;
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132 int ex_init(peXobject pEx
01133 ){
01134
01135
01136 long i;
01137
01138
01139 lex_StartIteration(pEx->pLex);
01140
01141 pEx->pMemorySegment
01142 = alloc_InitSegment(pEx->memory_allocating_function,
01143 pEx->memory_releasing_function);
01144 if( pEx->pMemorySegment == NULL )return EX_ERROR_MEMORY_LOW;
01145
01146 pEx->pSymbolTableMemorySegment
01147 = alloc_InitSegment(pEx->memory_allocating_function,
01148 pEx->memory_releasing_function);
01149 if( pEx->pSymbolTableMemorySegment == NULL )return EX_ERROR_MEMORY_LOW;
01150
01151 pEx->pLocalVarMemorySegment = alloc_InitSegment(pEx->memory_allocating_function,
01152 pEx->memory_releasing_function);
01153 if( pEx->pLocalVarMemorySegment == NULL )return EX_ERROR_MEMORY_LOW;
01154
01155
01156 pEx->GlobalVariables = sym_NewSymbolTable(alloc_Alloc,pEx->pSymbolTableMemorySegment);
01157 pEx->GlobalLabels = sym_NewSymbolTable(alloc_Alloc,pEx->pSymbolTableMemorySegment);
01158 pEx->GlobalConstants = sym_NewSymbolTable(alloc_Alloc,pEx->pSymbolTableMemorySegment);
01159
01160 if( pEx->GlobalVariables == NULL ||
01161 pEx->GlobalLabels == NULL ||
01162 pEx->GlobalConstants == NULL )return EX_ERROR_MEMORY_LOW;
01163
01164 pEx->LocalVariables = NULL;
01165 pEx->LocallyDeclaredGlobalVariables = NULL;
01166 pEx->UserFunctions = sym_NewSymbolTable(alloc_Alloc,pEx->pSymbolTableMemorySegment);
01167 if( pEx->UserFunctions == NULL )return EX_ERROR_MEMORY_LOW;
01168
01169 pEx->ThisFunction = NULL;
01170
01171 pEx->NodeCounter = 0;
01172
01173
01174 pEx->pFunctionWaiting = NULL;
01175
01176
01177 pEx->FirstUF = NULL;
01178
01179
01180 pEx->pComeAndGoStack = NULL;
01181 pEx->pFreeComeAndGoStack = NULL;
01182
01183
01184 pEx->iWeAreLocal = 0;
01185
01186 pEx->iDeclareVars = 0;
01187
01188 pEx->iDefaultLocal = 0;
01189
01190 pEx->Buffer = alloc_Alloc(pEx->cbBuffer*sizeof(char),pEx->pMemorySegment);
01191 pEx->CurrentNameSpace = alloc_Alloc(pEx->cbCurrentNameSpace*sizeof(char),pEx->pMemorySegment);
01192
01193 if( !pEx->GlobalVariables ||
01194 !pEx->UserFunctions ||
01195 !pEx->BuiltInFunctions ||
01196 !pEx->GlobalLabels ||
01197 !pEx->GlobalConstants ||
01198 !pEx->Binaries ||
01199 !pEx->CurrentNameSpace ||
01200 0
01201 ){
01202 ex_free(pEx);
01203 return EX_ERROR_MEMORY_LOW;
01204 }
01205
01206 pEx->cGlobalLabels = 0;
01207 pEx->cGlobalVariables = 0;
01208
01209 pEx->cUserFunctions = 0;
01210
01211 if( pEx->cbCurrentNameSpace < 7 ){
01212 ex_free(pEx);
01213 return EX_ERROR_TOO_LONG_NAME_SPACE;
01214 }
01215 strcpy(pEx->CurrentNameSpace,"main::");
01216 pEx->pOldNameSpace = NULL;
01217 pEx->cbStringTable = 0L;
01218
01219 for( i=0 ; pEx->PredeclaredLongConstants[i].name ; i++ )
01220 ex_PredeclareGlobalLongConst(pEx,
01221 pEx->PredeclaredLongConstants[i].name,
01222 pEx->PredeclaredLongConstants[i].value);
01223
01224 return EX_ERROR_SUCCESS;
01225 }
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258 void ex_CleanNamePath(char *s
01259 ){
01260
01261
01262 int i,j;
01263 int f;
01264
01265 while(1){
01266 j = 0; f = 0;
01267 for( i=0 ; s[i] ; i++ ){
01268 if( s[i] == ':' && s[i+1] == ':' && s[i+2] == '_' && s[i+3] == ':' && s[i+4] == ':' ){
01269 f = 1;
01270 i += 5;
01271 break;
01272 }
01273 if( s[i] == ':' && s[i+1] == ':' ){
01274 j = i+2;
01275 i ++;
01276 continue;
01277 }
01278 }
01279 if( !f )return;
01280 while( s[j]=s[i] )i++,j++;
01281
01282 }
01283 }
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299 int ex_ConvertName(char *s,
01300 char *Buffer,
01301 size_t cbBuffer,
01302 peXobject pEx
01303 ){
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314 int i;
01315
01316
01317
01318
01319 if( !s[0] || !s[1] ){
01320 if( cbBuffer < strlen(pEx->CurrentNameSpace) + strlen(s) + 1 )
01321 return EX_ERROR_TOO_LONG_VARIABLE;
01322 strcpy(Buffer,pEx->CurrentNameSpace);
01323 strcat(Buffer,s);
01324 return EX_ERROR_SUCCESS;
01325 }
01326
01327
01328
01329 if( s[0] == ':' && s[1] == ':' ){
01330 if( cbBuffer < strlen(pEx->CurrentNameSpace) + strlen(s) - 1 )
01331 return EX_ERROR_TOO_LONG_VARIABLE;
01332 strcpy(Buffer,pEx->CurrentNameSpace);
01333 strcat(Buffer,s+2);
01334
01335 ex_CleanNamePath(Buffer);
01336 return EX_ERROR_SUCCESS;
01337 }
01338
01339
01340
01341 if( s[0] == '_' && s[1] == ':' && s[2] == ':' ){
01342 if( cbBuffer < strlen(pEx->CurrentNameSpace) + strlen(s) + 1 )
01343 return EX_ERROR_TOO_LONG_VARIABLE;
01344 strcpy(Buffer,pEx->CurrentNameSpace);
01345 strcat(Buffer,s);
01346 ex_CleanNamePath(Buffer);
01347 return EX_ERROR_SUCCESS;
01348 }
01349
01350
01351 for( i=1 ; s[i] ; i++ ){
01352
01353
01354 if( s[i] == ':' && s[i+1] == ':' ){
01355 if( cbBuffer < strlen(pEx->CurrentNameSpace) + 1 )
01356 return EX_ERROR_TOO_LONG_VARIABLE;
01357 strcpy(Buffer,s);
01358 ex_CleanNamePath(Buffer);
01359 return EX_ERROR_SUCCESS;
01360 }
01361 }
01362
01363
01364
01365 if( cbBuffer < strlen(pEx->CurrentNameSpace) + strlen(s) + 1 )
01366 return EX_ERROR_TOO_LONG_VARIABLE;
01367 strcpy(Buffer,pEx->CurrentNameSpace);
01368 strcat(Buffer,s);
01369 return EX_ERROR_SUCCESS;
01370 }
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380 pBFun ex_IsBFun(peXobject pEx
01381 ){
01382
01383
01384 pBFun p;
01385
01386 if( LexemeType != LEX_T_NSYMBOL )return NULL;
01387 p = pEx->BuiltInFunctions;
01388
01389 while( p->OpCode && (long)p->OpCode != LexemeCode )p++;
01390 if( p->OpCode )return p;
01391 return NULL;
01392 }
01393
01394
01395
01396
01397
01398
01399
01400
01401 unsigned long ex_IsUnop(peXobject pEx
01402 ){
01403
01404
01405 unsigned long *p;
01406
01407 if( LexemeType != LEX_T_NSYMBOL && LexemeType != LEX_T_ASYMBOL )return 0;
01408 p = pEx->Unaries;
01409
01410 while( *p && (long)*p != LexemeCode )p++;
01411 return *p;
01412 }
01413
01414
01415
01416
01417
01418
01419
01420
01421 unsigned long ex_IsBinop(peXobject pEx,
01422 unsigned long precedence
01423 ){
01424
01425
01426 unsigned long *p;
01427
01428 if( LexemeType != LEX_T_NSYMBOL && LexemeType != LEX_T_ASYMBOL )return 0;
01429 p = pEx->Binaries;
01430
01431 while( *p && *p != (unsigned)LexemeCode )p += 2;
01432 if( *p && p[1] == precedence )return *p;
01433 return 0;
01434 }
01435
01436
01437
01438
01439
01440
01441
01442
01443 peNODE_l ex_LeftValueList(peXobject pEx
01444 ){
01445
01446
01447 peNODE_l r;
01448 peNODE q;
01449
01450 q = ex_LeftValue(pEx);
01451 if( ! q )return NULL;
01452 r = new_eNODE_l();
01453 r->actualm = q;
01454 r->rest = NULL;
01455 if( LexemeType == LEX_T_CHARACTER && LexemeChar == ',' ){
01456 NextLexeme;
01457 r->rest = ex_LeftValueList(pEx);
01458 }
01459 return r;
01460 }
01461
01462
01463
01464
01465
01466
01467
01468 peNODE_l ex_ExpressionList(peXobject pEx
01469 ){
01470
01471
01472 peNODE_l r;
01473 peNODE q;
01474
01475 q = ex_Expression_i(pEx,pEx->MAXPREC);
01476 if( ! q )return NULL;
01477 r = new_eNODE_l();
01478 r->actualm = q;
01479 r->rest = NULL;
01480 if( LexemeType == LEX_T_CHARACTER && LexemeChar == ',' ){
01481 NextLexeme;
01482 r->rest = ex_ExpressionList(pEx);
01483 if( r->rest == NULL )return NULL;
01484 }
01485 return r;
01486 }
01487
01488
01489
01490
01491
01492
01493
01494 int ex_Local(peXobject pEx
01495 ){
01496
01497
01498
01499
01500
01501
01502
01503 void **pSymbol;
01504
01505 if( LexemeType != LEX_T_ASYMBOL )return 1;
01506 ex_ConvertName(LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx);
01507 if( WeAreNotLocal )return 2;
01508 pSymbol = sym_LookupSymbol(pEx->Buffer,
01509 pEx->LocallyDeclaredGlobalVariables,
01510 0,
01511 alloc_Alloc,
01512 alloc_Free,
01513 pEx->pLocalVarMemorySegment);
01514 if( pSymbol )REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_GLODEF,pEx->Buffer);
01515 pSymbol = sym_LookupSymbol(pEx->Buffer,
01516 pEx->LocalVariables,
01517 1,
01518 alloc_Alloc,
01519 alloc_Free,
01520 pEx->pLocalVarMemorySegment);
01521
01522
01523 if( *pSymbol == NULL )
01524 *pSymbol = (void *)new_SymbolVAR(LOCAL_VAR);
01525 NextLexeme;
01526 return 0;
01527 }
01528
01529
01530
01531
01532
01533
01534
01535 int ex_LocalList(peXobject pEx
01536 ){
01537
01538
01539
01540
01541
01542
01543
01544 int iErr;
01545
01546 iErr = ex_Local(pEx);
01547 if( iErr )return iErr;
01548 while( LexemeType == LEX_T_CHARACTER && LexemeChar == ',' ){
01549 NextLexeme;
01550 iErr = ex_Local(pEx);
01551 if( iErr )return iErr;
01552 }
01553 return 0;
01554 }
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565 int ex_Global(peXobject pEx
01566 ){
01567
01568
01569
01570
01571
01572
01573
01574 void **pSymbol;
01575 void **plSymbol;
01576
01577 if( LexemeType != LEX_T_ASYMBOL )return 1;
01578 ex_ConvertName(LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx);
01579
01580
01581
01582
01583
01584 if( WeAreLocal ){
01585 pSymbol = sym_LookupSymbol(pEx->Buffer,
01586 pEx->GlobalVariables,
01587 0,
01588 alloc_Alloc,
01589 alloc_Free,
01590 pEx->pMemorySegment);
01591 if( pSymbol == NULL ){
01592 if( DeclareVars )REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNDEF_GLOBAL,NULL);
01593
01594 pSymbol = sym_LookupSymbol(pEx->Buffer,
01595 pEx->GlobalVariables,
01596 1,
01597 alloc_Alloc,
01598 alloc_Free,
01599 pEx->pMemorySegment);
01600 }
01601 plSymbol = sym_LookupSymbol(pEx->Buffer,
01602 pEx->LocalVariables,
01603 0,
01604 alloc_Alloc,
01605 alloc_Free,
01606 pEx->pLocalVarMemorySegment);
01607 if( plSymbol ){
01608 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_GLODEF,pEx->Buffer);
01609 NextLexeme;
01610 return 0;
01611 }
01612
01613 sym_LookupSymbol(pEx->Buffer,
01614 pEx->LocallyDeclaredGlobalVariables,
01615 1,
01616 alloc_Alloc,
01617 alloc_Free,
01618 pEx->pLocalVarMemorySegment);
01619 }else{
01620 pSymbol = sym_LookupSymbol(pEx->Buffer,
01621 pEx->GlobalVariables,
01622 1,
01623 alloc_Alloc,
01624 alloc_Free,
01625 pEx->pMemorySegment);
01626 if( *pSymbol ){
01627 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_GREDEF,pEx->Buffer);
01628 NextLexeme;
01629 return 0;
01630 }
01631 }
01632 *pSymbol = (void *)new_SymbolVAR(GLOBAL_VAR);
01633 NextLexeme;
01634 return 0;
01635 }
01636
01637
01638
01639
01640
01641
01642
01643 int ex_GlobalList(peXobject pEx
01644 ){
01645
01646
01647
01648
01649
01650
01651
01652 int iErr;
01653
01654 iErr = ex_Global(pEx);
01655 if( iErr )return iErr;
01656 while( LexemeType == LEX_T_CHARACTER && LexemeChar == ',' ){
01657 NextLexeme;
01658 iErr = ex_Global(pEx);
01659 if( iErr )return iErr;
01660 }
01661 return 0;
01662 }
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674 void **ex_LookupUserFunction(peXobject pEx,
01675 int iInsert
01676 ){
01677
01678
01679 void **pSymbol;
01680
01681 pSymbol = sym_LookupSymbol(pEx->Buffer,
01682 pEx->UserFunctions,
01683 iInsert,
01684 alloc_Alloc,
01685 alloc_Free,
01686 pEx->pSymbolTableMemorySegment);
01687
01688 return pSymbol;
01689 }
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700 void **ex_LookupGlobalVariable(peXobject pEx,
01701 int iInsert
01702 ){
01703
01704
01705
01706
01707 void **pSymbol;
01708
01709 pSymbol = sym_LookupSymbol(pEx->Buffer,
01710 pEx->GlobalVariables,
01711 iInsert,
01712 alloc_Alloc,
01713 alloc_Free,
01714 pEx->pSymbolTableMemorySegment);
01715 return pSymbol;
01716 }
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733 void **ex_LookupLocallyDeclaredGlobalVariable(peXobject pEx
01734 ){
01735
01736
01737
01738
01739 void **pSymbol;
01740
01741 pSymbol = sym_LookupSymbol(pEx->Buffer,
01742 pEx->LocallyDeclaredGlobalVariables,
01743 0,
01744 alloc_Alloc,
01745 alloc_Free,
01746 pEx->pLocalVarMemorySegment);
01747 return pSymbol;
01748 }
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760 void **ex_LookupLocalVariable(peXobject pEx,
01761 int iInsert
01762 ){
01763
01764
01765
01766
01767 void **pSymbol;
01768
01769 pSymbol = sym_LookupSymbol(pEx->Buffer,
01770 pEx->LocalVariables,
01771 iInsert,
01772 alloc_Alloc,
01773 alloc_Free,
01774 pEx->pLocalVarMemorySegment);
01775 return pSymbol;
01776 }
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798 peNODE ex_Tag(peXobject pEx
01799 ){
01800
01801
01802
01803
01804
01805
01806
01807
01808 peNODE q,r;
01809 peNODE_l z;
01810 long OpCode;
01811 char *s,*pszFN;
01812 int is_local;
01813 int is_assoc;
01814 long arg_count;
01815 void **pSymbol;
01816 pBFun pFunction;
01817 pLexeme pConstantLexeme;
01818
01819
01820 if( pFunction = ex_IsBFun(pEx) ){
01821 q = new_eNODE();
01822 if( q == NULL )return NULL;
01823 q->OpCode = LexemeCode;
01824 NextLexeme;
01825 if( LexemeType == LEX_T_CHARACTER && LexemeChar == '(' ){
01826 NextLexeme;
01827 if( LexemeType == LEX_T_CHARACTER && LexemeChar == ')' ){
01828 NextLexeme;
01829 goto no_arguments;
01830 }
01831 q->Parameter.Arguments.Argument = ex_ExpressionList(pEx);
01832 if( LexemeType != LEX_T_CHARACTER || LexemeChar != ')' ){
01833 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_PAREN,NULL);
01834 }else{ NextLexeme; }
01835
01836 z = q->Parameter.Arguments.Argument;
01837 arg_count = 0;
01838 while( z ){
01839 z = z->rest;
01840 arg_count++;
01841 }
01842 if( arg_count < pFunction->MinArgs )REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_TOO_FEW_ARGUMENTS,NULL);
01843 if( arg_count > pFunction->MaxArgs )REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_TOO_MANY_ARGUMENTS,NULL);
01844 return q;
01845 }else{
01846 no_arguments:
01847 q->Parameter.Arguments.Argument = NULL;
01848
01849 if( pFunction->MinArgs == 0 )return q;
01850 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_FUNCTION_NEEDS_ARGUMENTS,NULL);
01851 return q;
01852 }
01853 }
01854
01855
01856 if( OpCode = ex_IsUnop(pEx) ){
01857 q = new_eNODE();
01858 if( q == NULL )return NULL;
01859 q->OpCode = OpCode;
01860 NextLexeme;
01861 q->Parameter.Arguments.Argument = new_eNODE_l();
01862 if( q->Parameter.Arguments.Argument == NULL ){
01863 alloc_Free(q,pEx->pMemorySegment);
01864 return NULL;
01865 }
01866 q->Parameter.Arguments.Argument->actualm = ex_Tag(pEx);
01867 q->Parameter.Arguments.Argument->rest = NULL;
01868 return q;
01869 }
01870
01871
01872 if( LexemeType == LEX_T_CHARACTER && LexemeChar == '(' ){
01873 NextLexeme;
01874 q = ex_Expression_i(pEx,pEx->MAXPREC);
01875 if( LexemeType != LEX_T_CHARACTER || LexemeChar != ')' ){
01876 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_PAREN,NULL);
01877 }else{
01878 NextLexeme;
01879 }
01880 return q;
01881 }
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898 pConstantLexeme = NULL ;
01899 if( LexemeType == LEX_T_ASYMBOL ){
01900 if( ex_ConvertName(LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx) )goto ConstFinish;
01901 strcat(pEx->Buffer,"'");
01902 if( pEx->ThisFunction ){
01903 if( strlen(pEx->Buffer) + strlen(pEx->ThisFunction->FunctionName) >= pEx->cbBuffer )
01904 goto ConstFinish;
01905 strcat(pEx->Buffer,pEx->ThisFunction->FunctionName );
01906 pSymbol = sym_LookupSymbol(pEx->Buffer,
01907 pEx->GlobalConstants,
01908 0,
01909 alloc_Alloc,
01910 alloc_Free,
01911 pEx->pSymbolTableMemorySegment);
01912 if( pSymbol ){
01913 pConstantLexeme = (pLexeme)*pSymbol;
01914 goto ConstFinish;
01915 }
01916 }
01917
01918 for( s=pEx->Buffer ; *s && *s != '\'' ; s++ );
01919 if( *s )s++;
01920 if( *s )*s = (char)0;
01921 pSymbol = sym_LookupSymbol(pEx->Buffer,
01922 pEx->GlobalConstants,
01923 0,
01924 alloc_Alloc,
01925 alloc_Free,
01926 pEx->pSymbolTableMemorySegment);
01927 if( pSymbol ){
01928 pConstantLexeme = (pLexeme)*pSymbol;
01929 goto ConstFinish;
01930 }
01931
01932 pSymbol = sym_LookupSymbol(LexemeSymbol,
01933 pEx->GlobalConstants,
01934 0,
01935 alloc_Alloc,
01936 alloc_Free,
01937 pEx->pSymbolTableMemorySegment);
01938 if( pSymbol ){
01939 pConstantLexeme = (pLexeme)*pSymbol;
01940 goto ConstFinish;
01941 }
01942 }
01943 ConstFinish:
01944
01945
01946 if( LexemeType == LEX_T_DOUBLE ||
01947 LexemeType == LEX_T_LONG ||
01948 LexemeType == LEX_T_STRING ||
01949 pConstantLexeme
01950 ){
01951
01952 if( pConstantLexeme == NULL )
01953 pConstantLexeme = pEx->pLex->pLexCurrentLexeme;
01954
01955 q = new_eNODE();
01956 if( q == NULL )return NULL;
01957 switch( pConstantLexeme->type ){
01958 case LEX_T_DOUBLE:
01959 q->OpCode = eNTYPE_DBL;
01960 q->Parameter.Constant.Value.dValue = pConstantLexeme->value.dValue;
01961 break;
01962 case LEX_T_LONG:
01963 q->OpCode = eNTYPE_LNG;
01964 q->Parameter.Constant.Value.lValue = pConstantLexeme->value.lValue;
01965 break;
01966 case LEX_T_STRING:
01967 q->OpCode = eNTYPE_STR;
01968 s = (char *)alloc_Alloc((pConstantLexeme->sLen+1)*sizeof(char),pEx->pMemorySegment);
01969 if( s == NULL ){
01970 alloc_Free(q,pEx->pMemorySegment);
01971 return NULL;
01972 }
01973 memcpy(s,pConstantLexeme->value.sValue,pConstantLexeme->sLen+1);
01974 pEx->cbStringTable += pConstantLexeme->sLen+1;
01975 COUNT_STRING_LEN
01976 q->Parameter.Constant.Value.sValue = s;
01977 q->Parameter.Constant.sLen = pConstantLexeme->sLen;
01978 break;
01979 default:
01980 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_INTERNAL,NULL);
01981 break;
01982 }
01983 NextLexeme;
01984 return q;
01985 }
01986
01987
01988 if( LexemeType == LEX_T_ASYMBOL ){
01989 q = new_eNODE();
01990 if( q == NULL )return NULL;
01991 ex_ConvertName(pszFN=LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx);
01992
01993 NextLexeme;
01994 if( LexemeType == LEX_T_CHARACTER && LexemeChar == '(' ){
01995 pSymbol = ex_LookupUserFunction(pEx,1);
01996 if( *pSymbol == NULL ){
01997
01998 *pSymbol = (void *)new_SymbolUF();
01999 if( *pSymbol == NULL )return NULL;
02000 ((pSymbolUF)*pSymbol)->FunctionName = pszFN;
02001 }
02002 q->OpCode = eNTYPE_FUN;
02003 q->Parameter.UserFunction.pFunction = (pSymbolUF)(*pSymbol);
02004 NextLexeme;
02005 if( LexemeType == LEX_T_CHARACTER && LexemeChar == ')' ){
02006
02007 q->Parameter.UserFunction.Argument = NULL;
02008 NextLexeme;
02009 }else{
02010 q->Parameter.UserFunction.Argument = ex_ExpressionList(pEx);
02011 if( LexemeType != LEX_T_CHARACTER || LexemeChar != ')' ){
02012 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_PAREN,NULL);
02013 }else{ NextLexeme; }
02014 }
02015 return q;
02016 }
02017 if( LexemeType == LEX_T_CHARACTER && (LexemeChar == '[' || LexemeChar == '{') ){
02018 if( LexemeChar == '[' )is_assoc = 0; else is_assoc = 1;
02019 NextLexeme;
02020 q->OpCode = is_assoc ? eNTYPE_SAR : eNTYPE_ARR;
02021 if( WeAreNotLocal || (pSymbol = ex_LookupLocalVariable(pEx,0)) == NULL ){
02022 if( WeAreLocal && DefaultLocal && ex_LookupLocallyDeclaredGlobalVariable(pEx) == NULL ){
02023 pSymbol = ex_LookupLocalVariable(pEx,1);
02024 is_local = 1;
02025 }else{
02026 pSymbol = ex_LookupGlobalVariable(pEx,1);
02027 is_local = 0;
02028 }
02029 }else is_local = 1;
02030
02031 if( *pSymbol == NULL ){
02032 if( DeclareVars )REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNDEF_GLOBAL,NULL);
02033 if( DefaultLocal && is_local )
02034 *pSymbol = (void *)new_SymbolVAR(LOCAL_VAR);
02035 else
02036 *pSymbol = (void *)new_SymbolVAR(GLOBAL_VAR);
02037 if( *pSymbol == NULL )return NULL;
02038 }else{
02039 if( DeclareVars && DefaultLocal && is_local && ex_LookupLocallyDeclaredGlobalVariable(pEx) == NULL && ex_LookupLocalVariable(pEx,0) == NULL)
02040 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNDEF_GLOBAL,NULL);
02041 }
02042
02043 q->Parameter.Arguments.Argument = new_eNODE_l();
02044 if( q->Parameter.Arguments.Argument == NULL )return NULL;
02045 q->Parameter.Arguments.Argument->actualm = new_eNODE();
02046 if( q->Parameter.Arguments.Argument->actualm == NULL )return NULL;
02047 q->Parameter.Arguments.Argument->actualm->Parameter.Variable.Serial = ((pSymbolVAR)(*pSymbol))->Serial;
02048 q->Parameter.Arguments.Argument->actualm->OpCode = is_local ? eNTYPE_LVR : eNTYPE_GVR;
02049
02050 q->Parameter.Arguments.Argument->rest = ex_ExpressionList(pEx);
02051 if( is_assoc )
02052 if( LexemeType != LEX_T_CHARACTER || LexemeChar != '}' ){
02053 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_SAPAREN,NULL);
02054 }else{ NextLexeme; }
02055 else
02056 if( LexemeType != LEX_T_CHARACTER || LexemeChar != ']' ){
02057 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_APAREN,NULL);
02058 }else{ NextLexeme; }
02059
02060 while( LexemeType == LEX_T_CHARACTER && (LexemeChar == '[' || LexemeChar == '{') ){
02061 if( LexemeChar == '[' )is_assoc = 0; else is_assoc = 1;
02062 NextLexeme;
02063 r = q;
02064 q = new_eNODE();
02065 if( q == NULL )return NULL;
02066 q->OpCode = is_assoc ? eNTYPE_SAR : eNTYPE_ARR;
02067 q->Parameter.Arguments.Argument = new_eNODE_l();
02068 if( q->Parameter.Arguments.Argument == NULL )return NULL;
02069
02070 q->Parameter.Arguments.Argument->actualm = r;
02071
02072 q->Parameter.Arguments.Argument->rest = ex_ExpressionList(pEx);
02073 if( is_assoc )
02074 if( LexemeType != LEX_T_CHARACTER || LexemeChar != '}' ){
02075 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_SAPAREN,NULL);
02076 }else{ NextLexeme; }
02077 else
02078 if( LexemeType != LEX_T_CHARACTER || LexemeChar != ']' ){
02079 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_APAREN,NULL);
02080 }else{ NextLexeme; }
02081 }
02082 return q;
02083 }
02084
02085
02086 if( WeAreNotLocal || (pSymbol = ex_LookupLocalVariable(pEx,0)) == NULL ){
02087 if( WeAreLocal && DefaultLocal && ex_LookupLocallyDeclaredGlobalVariable(pEx) == NULL ){
02088
02089
02090 pSymbol = ex_LookupLocalVariable(pEx,1);
02091 is_local = 1;
02092 }else{
02093
02094 pSymbol = ex_LookupGlobalVariable(pEx,1);
02095 is_local = 0;
02096 }
02097 }else is_local = 1;
02098 if( *pSymbol == NULL ){
02099 if( DeclareVars )REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNDEF_GLOBAL,NULL);
02100 if( DefaultLocal && is_local )
02101 *pSymbol = (void *)new_SymbolVAR(LOCAL_VAR);
02102 else
02103 *pSymbol = (void *)new_SymbolVAR(GLOBAL_VAR);
02104 if( *pSymbol == NULL )return NULL;
02105 }else{
02106 if( DeclareVars && DefaultLocal && is_local && ex_LookupLocallyDeclaredGlobalVariable(pEx) == NULL && ex_LookupLocalVariable(pEx,0) == NULL)
02107 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNDEF_GLOBAL,NULL);
02108 }
02109 q->OpCode = is_local ? eNTYPE_LVR : eNTYPE_GVR;
02110 q->Parameter.Variable.Serial = ((pSymbolVAR)(*pSymbol))->Serial;
02111 return q;
02112 }
02113 return NULL;
02114 }
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127 peNODE ex_Expression_i(peXobject pEx,
02128 int i
02129 ){
02130
02131
02132
02133 peNODE fo;
02134 peNODE q;
02135 int iOperation;
02136
02137 if( i == 1 )return ex_Tag(pEx);
02138
02139 fo = ex_Expression_i(pEx,i-1);
02140 if( fo == NULL )return NULL;
02141 while( iOperation = ex_IsBinop(pEx,i-1) ){
02142 q = new_eNODE();
02143 if( q == NULL )return NULL;
02144 q->OpCode = iOperation;
02145 q->Parameter.Arguments.Argument = new_eNODE_l();
02146 if( q->Parameter.Arguments.Argument == NULL )return NULL;
02147 q->Parameter.Arguments.Argument->actualm = fo;
02148 q->Parameter.Arguments.Argument->rest = new_eNODE_l();
02149 if( q->Parameter.Arguments.Argument->rest == NULL )return NULL;
02150 NextLexeme;
02151 q->Parameter.Arguments.Argument->rest->actualm = ex_Expression_i(pEx,i-1);
02152
02153
02154
02155 if( q->Parameter.Arguments.Argument->rest->actualm == NULL )return NULL;
02156 fo = q;
02157 }
02158 return fo;
02159 }
02160
02161
02162
02163
02164
02165
02166
02167 void ex_Expression_r(peXobject pEx,
02168 peNODE *Result
02169 ){
02170
02171
02172 *Result = ex_Expression_i(pEx,pEx->MAXPREC);
02173 }
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192 int ex_IsSymbolValidLval(peXobject pEx
02193 ){
02194
02195
02196
02197 void **pSymbol;
02198 char *s;
02199 char *fs;
02200 int isLocalVar;
02201
02202 fs = pEx->Buffer + strlen(pEx->Buffer);
02203 if( pEx->iWeAreLocal && pEx->ThisFunction ){
02204 pSymbol = sym_LookupSymbol(pEx->Buffer,
02205 pEx->LocalVariables,
02206 0,
02207 alloc_Alloc,
02208 alloc_Free,
02209 pEx->pLocalVarMemorySegment);
02210 isLocalVar = NULL != pSymbol;
02211
02212 }else isLocalVar = 0;
02213
02214 strcpy(fs,"'");
02215 if( pEx->iWeAreLocal && pEx->ThisFunction ){
02216 if( strlen(pEx->Buffer) + strlen(pEx->ThisFunction->FunctionName) >= pEx->cbBuffer )
02217 return 0;
02218 strcat(pEx->Buffer,pEx->ThisFunction->FunctionName );
02219 pSymbol = sym_LookupSymbol(pEx->Buffer,
02220 pEx->GlobalConstants,
02221 0,
02222 alloc_Alloc,
02223 alloc_Free,
02224 pEx->pSymbolTableMemorySegment);
02225 if( pSymbol && *pSymbol )return 1;
02226 }
02227
02228
02229 if( isLocalVar ){
02230
02231 *fs = (char)0;
02232 return 0;
02233 }
02234
02235
02236 s = fs + 1 ;
02237 if( *s )*s = (char)0;
02238 pSymbol = sym_LookupSymbol(pEx->Buffer,
02239 pEx->GlobalConstants,
02240 0,
02241 alloc_Alloc,
02242 alloc_Free,
02243 pEx->pSymbolTableMemorySegment);
02244 if( pSymbol && *pSymbol )return 1;
02245
02246
02247 pSymbol = sym_LookupSymbol(LexemeSymbol,
02248 pEx->GlobalConstants,
02249 0,
02250 alloc_Alloc,
02251 alloc_Free,
02252 pEx->pSymbolTableMemorySegment);
02253 if( pSymbol && *pSymbol )return 1;
02254
02255
02256 *fs = (char)0;
02257
02258 return 0;
02259 }
02260
02261
02262
02263
02264
02265
02266
02267 peNODE ex_LeftValue(peXobject pEx
02268 ){
02269
02270
02271
02272 peNODE q,r;
02273 int is_local;
02274 int is_assoc;
02275 void **pSymbol;
02276
02277 if( LexemeType != LEX_T_ASYMBOL )return NULL;
02278 ex_ConvertName(LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx);
02279 if( ex_IsSymbolValidLval(pEx) )REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_CONST_LVAL,NULL);
02280
02281 NextLexeme;
02282 if( LexemeType == LEX_T_CHARACTER && (LexemeChar == '[' || LexemeChar == '{') ){
02283 if( LexemeChar == '{' )is_assoc = 1; else is_assoc = 0;
02284 NextLexeme;
02285 q = new_eNODE();
02286 if( q == NULL )return NULL;
02287 q->OpCode = is_assoc ? eNTYPE_SAR : eNTYPE_ARR;
02288 if( WeAreNotLocal || (pSymbol = ex_LookupLocalVariable(pEx,0)) == NULL ){
02289 if( WeAreLocal && DefaultLocal && ex_LookupLocallyDeclaredGlobalVariable(pEx) == NULL ){
02290 pSymbol = ex_LookupLocalVariable(pEx,1);
02291 is_local = 1;
02292 }else{
02293 pSymbol = ex_LookupGlobalVariable(pEx,1);
02294 is_local = 0;
02295 }
02296 }else is_local = 1;
02297
02298 if( *pSymbol == NULL ){
02299 if( DeclareVars )REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNDEF_GLOBAL,NULL);
02300 if( DefaultLocal && is_local )
02301 *pSymbol = (void *)new_SymbolVAR(LOCAL_VAR);
02302 else
02303 *pSymbol = (void *)new_SymbolVAR(GLOBAL_VAR);
02304 if( *pSymbol == NULL )return NULL;
02305 }else{
02306 if( DeclareVars && DefaultLocal && is_local && ex_LookupLocallyDeclaredGlobalVariable(pEx) == NULL && ex_LookupLocalVariable(pEx,0) == NULL)
02307 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNDEF_GLOBAL,NULL);
02308 }
02309
02310 q->Parameter.Arguments.Argument = new_eNODE_l();
02311 if( q->Parameter.Arguments.Argument == NULL )return NULL;
02312 q->Parameter.Arguments.Argument->actualm = new_eNODE();
02313 if( q->Parameter.Arguments.Argument->actualm == NULL )return NULL;
02314 q->Parameter.Arguments.Argument->actualm->Parameter.Variable.Serial = ((pSymbolVAR)(*pSymbol))->Serial;
02315 q->Parameter.Arguments.Argument->actualm->OpCode = is_local ? eNTYPE_LVR : eNTYPE_GVR;
02316
02317 q->Parameter.Arguments.Argument->rest = ex_ExpressionList(pEx);
02318 if( is_assoc )
02319 if( LexemeType != LEX_T_CHARACTER || LexemeChar != '}' ){
02320 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_SAPAREN,NULL);
02321 }else{ NextLexeme; }
02322 else
02323 if( LexemeType != LEX_T_CHARACTER || LexemeChar != ']' ){
02324 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_APAREN,NULL);
02325 }else{ NextLexeme; }
02326
02327 while( LexemeType == LEX_T_CHARACTER && (LexemeChar == '[' || LexemeChar == '{') ){
02328 if( LexemeChar == '[' )is_assoc = 0; else is_assoc = 1;
02329 NextLexeme;
02330 r = q;
02331 q = new_eNODE();
02332 if( q == NULL )return NULL;
02333 q->OpCode = is_assoc ? eNTYPE_SAR : eNTYPE_ARR;
02334 q->Parameter.Arguments.Argument = new_eNODE_l();
02335 if( q->Parameter.Arguments.Argument == NULL )return NULL;
02336
02337 q->Parameter.Arguments.Argument->actualm = r;
02338
02339 q->Parameter.Arguments.Argument->rest = ex_ExpressionList(pEx);
02340 if( is_assoc )
02341 if( LexemeType != LEX_T_CHARACTER || LexemeChar != '}' ){
02342 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_SAPAREN,NULL);
02343 }else{ NextLexeme; }
02344 else
02345 if( LexemeType != LEX_T_CHARACTER || LexemeChar != ']' ){
02346 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_APAREN,NULL);
02347 }else{ NextLexeme; }
02348 }
02349 return q;
02350 }
02351
02352 q = new_eNODE();
02353 if( q == NULL )return NULL;
02354
02355 if( WeAreNotLocal || (pSymbol = ex_LookupLocalVariable(pEx,0)) == NULL ){
02356 if( WeAreLocal && DefaultLocal && ex_LookupLocallyDeclaredGlobalVariable(pEx) == NULL ){
02357 pSymbol = ex_LookupLocalVariable(pEx,1);
02358 is_local = 1;
02359 }else{
02360 pSymbol = ex_LookupGlobalVariable(pEx,1);
02361 is_local = 0;
02362 }
02363 }else is_local = 1;
02364 if( *pSymbol == NULL ){
02365 if( DeclareVars )REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNDEF_GLOBAL,NULL);
02366 if( DefaultLocal && is_local )
02367 *pSymbol = (void *)new_SymbolVAR(LOCAL_VAR);
02368 else
02369 *pSymbol = (void *)new_SymbolVAR(GLOBAL_VAR);
02370 }else{
02371 if( DeclareVars && DefaultLocal && is_local && ex_LookupLocallyDeclaredGlobalVariable(pEx) == NULL && ex_LookupLocalVariable(pEx,0) == NULL)
02372 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNDEF_GLOBAL,NULL);
02373 }
02374 q->OpCode = is_local ? eNTYPE_LVR : eNTYPE_GVR;
02375 q->Parameter.Variable.Serial = ((pSymbolVAR)(*pSymbol))->Serial;
02376 return q;
02377 }
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387 int ex_PredeclareGlobalLongConst(peXobject pEx,
02388 char *pszConstName,
02389 long lConstValue
02390 ){
02391
02392
02393 void **pSymbol;
02394 pLexeme pConstValue;
02395 void *prepar[2];
02396
02397 prepar[0] = (void *)pszConstName;
02398 prepar[1] = (void *)lConstValue;
02399 pConstValue = alloc_Alloc(sizeof(Lexeme),pEx->pSymbolTableMemorySegment);
02400 if( pConstValue == NULL )return EX_ERROR_MEMORY_LOW;
02401 pSymbol = sym_LookupSymbol(pszConstName,
02402 pEx->GlobalConstants,
02403 1,
02404 alloc_Alloc,
02405 alloc_Free,
02406 pEx->pSymbolTableMemorySegment);
02407 if( pSymbol == NULL )return 1;
02408 *pSymbol = (void *)pConstValue;
02409 pConstValue->type = LEX_T_LONG;
02410 pConstValue->value.lValue = lConstValue;
02411 return 0;
02412 }
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446 peNODE ex_IsCommandThis(peXobject pEx,
02447 pLineSyntax p,
02448 int *piFailure
02449 ){
02450
02451
02452
02453
02454
02455 #define ABORT goto SYNTAX_FAILURE_DO_CLEANUP
02456 #define ARGUMENT pArgument->Parameter.CommandArgument.Argument
02457 #define ASSERT_NON_NULL(x) if( (x) == NULL ){ *piFailure = EX_ERROR_MEMORY_LOW; ABORT; }
02458
02459 #define NewArgument if( (*ppArgument = new_eNODE()) == NULL ){\
02460 *piFailure = EX_ERROR_MEMORY_LOW;\
02461 ABORT;\
02462 }else{\
02463 pArgument = *ppArgument;\
02464 ppArgument = &(pArgument->Parameter.CommandArgument.next);\
02465 *ppArgument = NULL;\
02466 }
02467
02468
02469
02470
02471 #define ex_PushLabel(y,z) _ex_PushLabel(pEx,y,z,pMyMemorySegment)
02472
02473 void *pMyMemorySegment,*pSwapMemorySegment;
02474 #define ex_SwapMemorySegment() do{ pSwapMemorySegment = pEx->pMemorySegment; \
02475 pEx->pMemorySegment = pMyMemorySegment; \
02476 pMyMemorySegment = pSwapMemorySegment; }while(0)
02477 int iCurrentLex;
02478 int iSaveWeAreLocal;
02479 peNODE pCommandNode;
02480 peNODE *ppArgument,pArgument;
02481 pSymbolUF pFunction;
02482 pSymbolLABEL pLabel;
02483 void **pSymbol;
02484 void **pFailedFunctionSymbol;
02485 char *pszNewNameSpace;
02486 char *pszLabelDefined;
02487 char *pszConstDefined;
02488 int iConstGlobal;
02489 pLexeme pConstValue;
02490 char szNumericLabelName[80];
02491 int iSideEffectWas;
02492 int iCommandNeedsCode;
02493 int fResetNameSpace;
02494 int StackCleanc;
02495 int isig;
02496 long sLen;
02497
02498 iCommandNeedsCode = 1;
02499 fResetNameSpace = 0;
02500 *piFailure = EX_ERROR_SUCCESS;
02501 iSaveWeAreLocal = pEx->iWeAreLocal;
02502 pszNewNameSpace = NULL;
02503 pszLabelDefined = NULL;
02504 pszConstDefined = NULL;
02505 pConstValue = NULL;
02506 iSideEffectWas = 0;
02507 StackCleanc = 0;
02508 pFailedFunctionSymbol = NULL;
02509 pMyMemorySegment = pEx->pMemorySegment;
02510
02511 pEx->pMemorySegment = alloc_InitSegment(pEx->memory_allocating_function,
02512 pEx->memory_releasing_function);
02513
02514 if( pEx->pMemorySegment == NULL ){
02515 pEx->pMemorySegment = pMyMemorySegment;
02516 return NULL;
02517 }
02518 ppArgument = &pCommandNode;
02519 pCommandNode = NULL;
02520
02521 for( iCurrentLex = 0; p->lexes[iCurrentLex].type ; iCurrentLex ++ ){
02522 switch( p->lexes[iCurrentLex].type ){
02523
02524 case EX_LEX_LOCAL_START:
02525 if( pEx->iWeAreLocal )ABORT;
02526 pEx->iWeAreLocal = 1;
02527 pEx->cLocalVariables = 0;
02528 NewArgument;
02529 pEx->plNrLocalVariables = &(ARGUMENT.lLongValue);
02530 pEx->LocalVariables = sym_NewSymbolTable(alloc_Alloc,pEx->pLocalVarMemorySegment);
02531 pEx->LocallyDeclaredGlobalVariables = sym_NewSymbolTable(alloc_Alloc,pEx->pLocalVarMemorySegment);
02532 CALL_PREPROCESSOR(PreprocessorExStartLocal,pEx);
02533 break;
02534
02535 case EX_LEX_ARG_NUM:
02536 NewArgument;
02537 ARGUMENT.lLongValue = pEx->cLocalVariables;
02538 break;
02539
02540 case EX_LEX_LOCAL_END:
02541 if( pEx->plNrLocalVariables )
02542 *(pEx->plNrLocalVariables) = pEx->cLocalVariables;
02543 pEx->plNrLocalVariables = NULL;
02544 pEx->iWeAreLocal = 0;
02545 CALL_PREPROCESSOR(PreprocessorExEndLocal,pEx);
02546
02547 break;
02548
02549 case EX_LEX_STAR:
02550 iSideEffectWas = 1;
02551 break;
02552
02553 case EX_LEX_NOEXEC:
02554 iCommandNeedsCode = 0;
02555 break;
02556
02557
02558
02559
02560
02561
02562 case EX_LEX_LOCAL:
02563 iSideEffectWas = 1;
02564 if( ex_Local(pEx) )ABORT;
02565 break;
02566
02567 case EX_LEX_LOCALL:
02568 iSideEffectWas = 1;
02569 if( ex_LocalList(pEx) )ABORT;
02570 break;
02571
02572 case EX_LEX_GLOBAL:
02573 iSideEffectWas = 1;
02574 if( ex_Global(pEx) )ABORT;
02575 break;
02576
02577 case EX_LEX_GLOBALL:
02578 iSideEffectWas = 1;
02579 if( ex_GlobalList(pEx) )ABORT;
02580 break;
02581
02582
02583
02584
02585
02586
02587 case EX_LEX_EXP:
02588 iSideEffectWas = 1;
02589 NewArgument;
02590 ex_Expression_r(pEx,&(ARGUMENT.pNode));
02591 if( ARGUMENT.pNode == NULL )ABORT;
02592 break;
02593
02594 case EX_LEX_EXPL:
02595 iSideEffectWas = 1;
02596 NewArgument;
02597 if( (ARGUMENT.pNodeList = ex_ExpressionList(pEx)) != NULL ){
02598 break;
02599 }else{
02600 ABORT;
02601 }
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616 case EX_LEX_LVAL:
02617 if( LexemeType != LEX_T_ASYMBOL )ABORT;
02618
02619 iSideEffectWas = 1;
02620 NewArgument;
02621 if( (ARGUMENT.pNode = ex_LeftValue(pEx)) != NULL ){
02622 break;
02623 }else{
02624 ABORT;
02625 }
02626
02627 case EX_LEX_LVALL:
02628 if( LexemeType != LEX_T_ASYMBOL )ABORT;
02629
02630 iSideEffectWas = 1;
02631 NewArgument;
02632 if( (ARGUMENT.pNodeList = ex_LeftValueList(pEx)) != NULL ){
02633 break;
02634 }else{
02635 ABORT;
02636 }
02637
02638
02639
02640
02641
02642 case EX_LEX_GO_FORWARD:
02643 iSideEffectWas = 1;
02644 NewArgument;
02645 pLabel = (ARGUMENT.pLabel = new_SymbolLABEL());
02646 ex_PushLabel(pLabel,p->lexes[iCurrentLex].GoConstant[0]);
02647 StackCleanc++;
02648 break;
02649
02650 case EX_LEX_GO_BACK:
02651 iSideEffectWas = 1;
02652 NewArgument;
02653 pLabel = (ARGUMENT.pLabel = ex_PopLabel(p->lexes[iCurrentLex].GoConstant));
02654 break;
02655
02656 case EX_LEX_COME_FORWARD:
02657 iSideEffectWas = 1;
02658 pLabel = ex_PopLabel(p->lexes[iCurrentLex].GoConstant);
02659
02660 if( NULL == pLabel ){
02661 *piFailure = EX_ERROR_BAD_NESTING;
02662 ABORT;
02663 }
02664 ex_PushWaitingLabel(pEx,pLabel);
02665 break;
02666
02667 case EX_LEX_COME_BACK:
02668 iSideEffectWas = 1;
02669 pLabel = new_SymbolLABEL();
02670 ex_PushWaitingLabel(pEx,pLabel);
02671 ex_PushLabel(pLabel,p->lexes[iCurrentLex].GoConstant[0]);
02672 StackCleanc++;
02673 break;
02674
02675 case EX_LEX_NSYMBOL:
02676 if( LexemeType != LEX_T_NSYMBOL )ABORT;
02677
02678 if( LexemeCode != p->lexes[iCurrentLex].OpCode )ABORT;
02679 NextLexeme;
02680 break;
02681
02682 case EX_LEX_FUNCTION:
02683
02684 if( LexemeType != LEX_T_ASYMBOL )ABORT;
02685 *piFailure = ex_ConvertName(LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx);
02686 if( *piFailure )ABORT;
02687 pSymbol = ex_LookupUserFunction(pEx,1);
02688 ASSERT_NON_NULL(pSymbol);
02689 if( *pSymbol == NULL ){
02690 pFailedFunctionSymbol = pSymbol;
02691 *pSymbol = (void *)(pFunction=new_SymbolUF());
02692 pFunction->node = 0;
02693 }
02694 else{
02695 pFunction = (pSymbolUF)*pSymbol;
02696 pFailedFunctionSymbol = NULL;
02697 }
02698 ASSERT_NON_NULL(pFunction)
02699 pEx->pFunctionWaiting = pFunction;
02700 pEx->ThisFunction = pFunction;
02701 pEx->ThisFunction->Argc = -1;
02702 pEx->ThisFunction->FunctionName = LexemeSymbol;
02703 if( pFunction->node ){
02704 *piFailure = EX_ERROR_FUNCTION_DOUBLE_DEFINED;
02705 ABORT;
02706 }
02707 NextLexeme;
02708 break;
02709
02710 case EX_LEX_THIS_FUNCTION:
02711 if( LexemeType != LEX_T_ASYMBOL )ABORT;
02712 ex_ConvertName(LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx);
02713 pSymbol = ex_LookupUserFunction(pEx,0);
02714 if( pSymbol == NULL )ABORT;
02715 pFunction = (pSymbolUF)*pSymbol;
02716 if( pEx->ThisFunction == NULL ||
02717 pFunction->FunId != pEx->ThisFunction->FunId )ABORT;
02718 NextLexeme;
02719 break;
02720
02721 case EX_LEX_CONST_NAME:
02722 if( LexemeType != LEX_T_ASYMBOL && LexemeType != LEX_T_LONG )ABORT;
02723 pszConstDefined = LexemeSymbol;
02724
02725 NextLexeme;
02726 iConstGlobal = 0;
02727 break;
02728
02729 case EX_LEX_GCONST_NAME:
02730 if( LexemeType != LEX_T_ASYMBOL && LexemeType != LEX_T_LONG )ABORT;
02731 pszConstDefined = LexemeSymbol;
02732
02733 NextLexeme;
02734 iConstGlobal = 1;
02735 break;
02736
02737 case EX_LEX_CONST_VALUE:
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747 if( LexemeType == LEX_T_NSYMBOL && ( LexemeCode == CMD_MINUS || LexemeCode == CMD_PLUS ) ){
02748 pConstValue = pEx->pLex->pLexCurrentLexeme;
02749 if( LexemeCode == CMD_MINUS )isig = -1; else isig = 1;
02750 NextLexeme;
02751 if( LexemeType != LEX_T_DOUBLE && LexemeType != LEX_T_LONG )ABORT;
02752 pConstValue = pEx->pLex->pLexCurrentLexeme;
02753 NextLexeme;
02754 if( LexemeType != LEX_T_DOUBLE ){
02755 pConstValue->value.lValue *= isig;
02756 }else{
02757 pConstValue->value.dValue *= isig;
02758 }
02759 break;
02760 }
02761 if( LexemeType != LEX_T_DOUBLE && LexemeType != LEX_T_LONG && LexemeType != LEX_T_STRING )ABORT;
02762 pConstValue = pEx->pLex->pLexCurrentLexeme;
02763 NextLexeme;
02764 break;
02765
02766 case EX_LEX_LABEL_DEFINITION:
02767 if( LexemeType != LEX_T_ASYMBOL && LexemeType != LEX_T_LONG )ABORT;
02768 if( LexemeType == LEX_T_ASYMBOL ){
02769 pszLabelDefined = LexemeSymbol;
02770
02771 }else{
02772 sprintf(szNumericLabelName,"%ld",LexemeLong);
02773 pszLabelDefined = szNumericLabelName;
02774 }
02775 NextLexeme;
02776 break;
02777
02778 case EX_LEX_LABEL:
02779 if( LexemeType != LEX_T_ASYMBOL && LexemeType != LEX_T_LONG)ABORT;
02780 if( LexemeType == LEX_T_ASYMBOL ){
02781 *piFailure = ex_ConvertName(LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx);
02782 }else{
02783 sprintf(szNumericLabelName,"%ld",LexemeLong);
02784 *piFailure = ex_ConvertName(szNumericLabelName, pEx->Buffer,pEx->cbBuffer,pEx);
02785 }
02786
02787 if( *piFailure )ABORT;
02788 iSideEffectWas = 1;
02789 if( strlen(pEx->Buffer) >= pEx->cbBuffer-1 ){
02790 *piFailure = EX_ERROR_TOO_LONG_VARIABLE;
02791 ABORT;
02792 }
02793 strcat(pEx->Buffer,"'");
02794 if( pEx->ThisFunction ){
02795 if( strlen(pEx->Buffer) + strlen(pEx->ThisFunction->FunctionName) >= pEx->cbBuffer ){
02796 *piFailure = EX_ERROR_TOO_LONG_VARIABLE;
02797 ABORT;
02798 }
02799 strcat(pEx->Buffer,pEx->ThisFunction->FunctionName );
02800 }
02801
02802 pSymbol = sym_LookupSymbol(pEx->Buffer,
02803 pEx->GlobalLabels,
02804 1,
02805 alloc_Alloc,
02806 alloc_Free,
02807 pEx->pSymbolTableMemorySegment);
02808 ASSERT_NON_NULL(pSymbol)
02809 if( *pSymbol == NULL ){
02810 *pSymbol = (void *)new_SymbolLABEL();
02811 pLabel = (pSymbolLABEL)*pSymbol;
02812 pLabel->node = 0;
02813 }else
02814 pLabel = (pSymbolLABEL)*pSymbol;
02815 ASSERT_NON_NULL(pLabel)
02816 NewArgument;
02817 ARGUMENT.pLabel = pLabel;
02818 NextLexeme;
02819 break;
02820
02821 case EX_LEX_SET_NAME_SPACE:
02822 if( LexemeType != LEX_T_ASYMBOL )ABORT;
02823 if( LexemeSymbol[0] == ':' && LexemeSymbol[1] == ':' ){
02824
02825 *piFailure = ex_ConvertName(LexemeSymbol+2, pEx->Buffer,pEx->cbBuffer,pEx);
02826 if( *piFailure )ABORT;
02827 pszNewNameSpace = pEx->Buffer;
02828 }else{
02829 pszNewNameSpace = LexemeSymbol;
02830 }
02831 NextLexeme;
02832 break;
02833
02834 case EX_LEX_RESET_NAME_SPACE:
02835 fResetNameSpace = 1;
02836 break;
02837
02838 case EX_LEX_PRAGMA:
02839 if( LexemeType != LEX_T_ASYMBOL && LexemeType != LEX_T_NSYMBOL )ABORT;
02840 if( LexemeType == LEX_T_ASYMBOL ){
02841 ex_Pragma(pEx,LexemeSymbol);
02842 }else{
02843 ex_Pragma(pEx,lex_SymbolicName(pEx->pLex,LexemeCode));
02844 }
02845 NextLexeme;
02846 break;
02847
02848
02849 case EX_LEX_ASYMBOL:
02850 if( LexemeType != LEX_T_ASYMBOL && LexemeType != LEX_T_NSYMBOL )ABORT;
02851 if( LexemeType == LEX_T_ASYMBOL ){
02852 NewArgument;
02853 if( (ARGUMENT.szStringValue = alloc_Alloc(sLen=strlen(LexemeSymbol)+1,pEx->pMemorySegment)) == NULL )ABORT;
02854 strcpy(ARGUMENT.szStringValue,LexemeSymbol);
02855 pArgument->Parameter.CommandArgument.sLen = sLen;
02856 pEx->cbStringTable += sLen+1;
02857 COUNT_STRING_LEN
02858 }else{
02859 NewArgument;
02860 if( (ARGUMENT.szStringValue = alloc_Alloc(sLen=strlen(lex_SymbolicName(pEx->pLex,LexemeCode))+1,pEx->pMemorySegment)) == NULL )ABORT;
02861 strcpy(ARGUMENT.szStringValue,lex_SymbolicName(pEx->pLex,LexemeCode));
02862 pArgument->Parameter.CommandArgument.sLen = sLen;
02863 pEx->cbStringTable += sLen+1;
02864 COUNT_STRING_LEN
02865 }
02866 NextLexeme;
02867 break;
02868
02869 case EX_LEX_SYMBOL:
02870 if( LexemeType != LEX_T_ASYMBOL )ABORT;
02871 *piFailure = ex_ConvertName(LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx);
02872 if( *piFailure )ABORT;
02873 NewArgument;
02874 if( (ARGUMENT.szStringValue = alloc_Alloc((sLen=strlen(pEx->Buffer))+1,pEx->pMemorySegment)) == NULL )ABORT;
02875 strcpy(ARGUMENT.szStringValue,pEx->Buffer);
02876 pArgument->Parameter.CommandArgument.sLen = sLen;
02877 pEx->cbStringTable += sLen+1;
02878 COUNT_STRING_LEN
02879 NextLexeme;
02880 break;
02881
02882 case EX_LEX_CHARACTER:
02883 if( LexemeType == LEX_T_CHARACTER && p->lexes[iCurrentLex].OpCode == LexemeChar ){
02884 NextLexeme;
02885 break;
02886 }
02887 ABORT;
02888
02889 case EX_LEX_LONG:
02890 if( LexemeType != LEX_T_LONG )ABORT;
02891 NewArgument;
02892 ARGUMENT.lLongValue = LexemeLong;
02893 NextLexeme;
02894 break;
02895
02896 case EX_LEX_DOUBLE:
02897 if( LexemeType != LEX_T_DOUBLE && LexemeType != LEX_T_LONG )ABORT;
02898 NewArgument;
02899 if( LexemeType == LEX_T_LONG )
02900 ARGUMENT.dDoubleValue = (double)LexemeLong;
02901 else
02902 ARGUMENT.dDoubleValue = LexemeDouble;
02903 NextLexeme;
02904 break;
02905
02906 case EX_LEX_STRING:
02907 if( LexemeType != LEX_T_STRING )ABORT;
02908 NewArgument;
02909 ASSERT_NON_NULL( (ARGUMENT.szStringValue = alloc_Alloc(LexemeStrLen+1,pEx->pMemorySegment)) )
02910 memcpy(ARGUMENT.szStringValue,LexemeSymbol,LexemeStrLen+1);
02911 pArgument->Parameter.CommandArgument.sLen = LexemeStrLen;
02912 pEx->cbStringTable += LexemeStrLen+1;
02913 COUNT_STRING_LEN
02914 NextLexeme;
02915 break;
02916 }
02917 }
02918
02919
02920 if( pszConstDefined ){
02921 if( iConstGlobal ){
02922 if( strlen(pszConstDefined) >= pEx->cbBuffer ){
02923 *piFailure = EX_ERROR_TOO_LONG_VARIABLE;
02924 ABORT;
02925 }
02926 strcpy(pEx->Buffer,pszConstDefined);
02927 }else{
02928 ex_ConvertName(pszConstDefined, pEx->Buffer,pEx->cbBuffer,pEx);
02929 if( strlen(pEx->Buffer) >= pEx->cbBuffer-1 ){
02930 *piFailure = EX_ERROR_TOO_LONG_VARIABLE;
02931 ABORT;
02932 }
02933 strcat(pEx->Buffer,"'");
02934 if( pEx->ThisFunction ){
02935 if( strlen(pEx->Buffer) + strlen(pEx->ThisFunction->FunctionName) >= pEx->cbBuffer ){
02936 *piFailure = EX_ERROR_TOO_LONG_VARIABLE;
02937 ABORT;
02938 }
02939 strcat(pEx->Buffer,pEx->ThisFunction->FunctionName );
02940 }
02941 }
02942
02943 pSymbol = sym_LookupSymbol(pEx->Buffer,
02944 pEx->GlobalConstants,
02945 1,
02946 alloc_Alloc,
02947 alloc_Free,
02948 pEx->pSymbolTableMemorySegment);
02949 ASSERT_NON_NULL(pSymbol)
02950 *pSymbol = (void *)pConstValue;
02951
02952 }
02953
02954
02955 if( pszLabelDefined ){
02956 ex_ConvertName(pszLabelDefined, pEx->Buffer,pEx->cbBuffer,pEx);
02957 if( strlen(pEx->Buffer) >= pEx->cbBuffer-1 ){
02958 *piFailure = EX_ERROR_TOO_LONG_VARIABLE;
02959 ABORT;
02960 }
02961 strcat(pEx->Buffer,"'");
02962 if( pEx->ThisFunction ){
02963 if( strlen(pEx->Buffer) + strlen(pEx->ThisFunction->FunctionName) >= pEx->cbBuffer ){
02964 *piFailure = EX_ERROR_TOO_LONG_VARIABLE;
02965 ABORT;
02966 }
02967 strcat(pEx->Buffer,pEx->ThisFunction->FunctionName );
02968 }
02969
02970 pSymbol = sym_LookupSymbol(pEx->Buffer,
02971 pEx->GlobalLabels,
02972 1,
02973 alloc_Alloc,
02974 alloc_Free,
02975 pEx->pSymbolTableMemorySegment);
02976 ASSERT_NON_NULL(pSymbol)
02977 if( *pSymbol == NULL ){
02978 *pSymbol = (void *)new_SymbolLABEL();
02979 pLabel = (pSymbolLABEL)*pSymbol;
02980 pLabel->node = 0;
02981 }else{
02982 pLabel = (pSymbolLABEL)*pSymbol;
02983 }
02984 if( pLabel == NULL )ABORT;
02985 if( pLabel->node != 0 )*piFailure = EX_ERROR_LABEL_DOUBLE_DEFINED;
02986 ex_PushWaitingLabel(pEx,pLabel);
02987 }
02988
02989
02990 if( (!pEx->iWeAreLocal) && iSaveWeAreLocal ){
02991
02992 alloc_FreeSegment(pEx->pLocalVarMemorySegment);
02993 pEx->LocalVariables = NULL;
02994 pEx->LocallyDeclaredGlobalVariables = NULL;
02995 pEx->ThisFunction = NULL;
02996 ex_CleanLabelStack();
02997 }
02998
02999
03000
03001
03002
03003 if( pEx->ThisFunction && pEx->ThisFunction->Argc == -1 )pEx->ThisFunction->Argc = pEx->cLocalVariables;
03004
03005
03006
03007
03008
03009 if( !pEx->iWeAreLocal )pEx->ThisFunction = NULL;
03010
03011 if( fResetNameSpace ){
03012
03013
03014
03015 ex_SwapMemorySegment();
03016 if( *piFailure = expression_PopNameSpace(pEx) ){
03017 ex_SwapMemorySegment();
03018 ABORT;
03019 }
03020 ex_SwapMemorySegment();
03021 }
03022 if( pszNewNameSpace ){
03023 if( pEx->cbCurrentNameSpace < (long)strlen(pszNewNameSpace)+3 ){
03024 *piFailure = EX_ERROR_TOO_LONG_NAME_SPACE;
03025 ABORT;
03026 }
03027 if( *piFailure = expression_PushNameSpace(pEx) )ABORT;
03028 strcpy(pEx->CurrentNameSpace,pszNewNameSpace);
03029 strcat(pEx->CurrentNameSpace,"::");
03030 }
03031
03032 if( pCommandNode == NULL && iCommandNeedsCode ){
03033 NewArgument;
03034 pCommandNode->Parameter.CommandArgument.Argument.pNode = NULL;
03035 }
03036
03037 if( pCommandNode )
03038 pCommandNode->OpCode = p->CommandOpCode;
03039
03040 alloc_MergeAndFinish(pEx->pMemorySegment,pMyMemorySegment);
03041
03042 return pCommandNode;
03043
03044 #undef ABORT
03045 #undef NextArgument
03046 #undef NewArgument
03047 #undef ARGUMENT
03048
03049 SYNTAX_FAILURE_DO_CLEANUP:
03050 if( ! *piFailure )
03051 *piFailure = iSideEffectWas ? EX_ERROR_SYNTAX_FATAL : EX_ERROR_SYNTAX;
03052
03053
03054 if( pEx->ThisFunction && pEx->ThisFunction->Argc == -1 ){
03055 pEx->ThisFunction = NULL;
03056
03057
03058
03059
03060
03061 if( pFailedFunctionSymbol )*pFailedFunctionSymbol = NULL;
03062 }
03063 pEx->iWeAreLocal = iSaveWeAreLocal;
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074 while( StackCleanc ){
03075 ex_PopLabel(NULL);
03076 StackCleanc--;
03077 }
03078
03079 alloc_FinishSegment(pEx->pMemorySegment);
03080
03081 pEx->pMemorySegment = pMyMemorySegment;
03082 return NULL;
03083 }
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093 void ex_Command_r(peXobject pEx,
03094 peNODE *Result,
03095 int *piFailure
03096 ){
03097
03098
03099
03100
03101
03102
03103
03104
03105 pLineSyntax p;
03106 pLexeme pPosition;
03107 int i;
03108 p = pEx->Command;
03109 lex_SavePosition(pEx->pLex,&pPosition);
03110 i = 0;
03111 while(1){
03112 i++;
03113 *Result = p->pfAnalyzeFunction(pEx,p,piFailure);
03114 if( *piFailure != EX_ERROR_SYNTAX )
03115 break;
03116 p++;
03117 if( p->CommandOpCode == 0 )break;
03118 lex_RestorePosition(pEx->pLex,&pPosition);
03119 }
03120 }
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131 int ex_Command_l(peXobject pEx,
03132 peNODE_l *Result
03133 ){
03134
03135
03136
03137
03138
03139
03140 int iFailure;
03141 peNODE pCommand;
03142 pSymbolLABEL pLabel;
03143 char *pszFileName;
03144 long lLineNumber;
03145
03146 CALL_PREPROCESSOR(PreprocessorExStart,pEx);
03147 pEx->cLabelsWaiting = 0;
03148 *Result = NULL;
03149 while( LexemeType ){
03150 pszFileName = LexemeFileName;
03151 lLineNumber = LexemeLineNumber;
03152 CALL_PREPROCESSOR(PreprocessorExStartLine,pEx);
03153 ex_Command_r(pEx,&pCommand,&iFailure);
03154 if( iFailure ){
03155 REPORT(LexemeFileName,LexemeLineNumber,iFailure,NULL);
03156 while( LexemeType && (LexemeType != LEX_T_CHARACTER || LexemeChar != '\n') ) NextLexeme;
03157 continue;
03158 }
03159
03160 if( pCommand ){
03161 *Result = new_eNODE_lL();
03162 CALL_PREPROCESSOR(PreprocessorExLineNode,pEx);
03163 if( *Result == NULL )return EX_ERROR_MEMORY_LOW;
03164 (*Result)->actualm = pCommand;
03165
03166
03167
03168 while( pLabel = ex_PopWaitingLabel(pEx) )pLabel->node = (*Result)->NodeId;
03169 if( pEx->pFunctionWaiting ){
03170 pEx->pFunctionWaiting->node = (*Result)->NodeId;
03171 pEx->pFunctionWaiting = NULL;
03172 }
03173 Result = &((*Result)->rest);
03174 *Result = NULL;
03175
03176 }
03177 }
03178
03179
03180
03181 if( pLabel = ex_PopWaitingLabel(pEx) ){
03182 *Result = new_eNODE_lL();
03183 if( *Result == NULL )return EX_ERROR_MEMORY_LOW;
03184 (*Result)->actualm = NULL;
03185 (*Result)->rest = NULL;
03186 while( pLabel ){
03187 pLabel->node = (*Result)->NodeId;
03188 pLabel = ex_PopWaitingLabel(pEx);
03189 }
03190 }
03191
03192
03193
03194
03195
03196
03197 ex_CleanNameSpaceStack(pEx);
03198
03199
03200
03201
03202 ex_CleanLabelStack();
03203
03204
03205
03206
03207 ex_CheckUndefinedLabels(pEx);
03208
03209
03210
03211
03212
03213 if( pEx->cGlobalVariables == 0 )pEx->cGlobalVariables++;
03214 CALL_PREPROCESSOR(PreprocessorExEnd,pEx);
03215 return 0;
03216 }
03217
03218
03219 void ex_pprint(FILE *f,
03220 peXobject pEx
03221 ){
03222 peNODE_l q;
03223
03224 for( q = pEx->pCommandList ; q ; q = q->rest )
03225 _ex_pprint(f,q->actualm,pEx,0);
03226 }
03227
03228
03229 #define ABORT do{ *piFailure = EX_ERROR_SYNTAX;return NULL; }while(0)
03230 #define FABORT do{ *piFailure = EX_ERROR_SYNTAX_FATAL;return NULL; }while(0)
03231 #define ARGUMENT pArgument->Parameter.CommandArgument.Argument
03232 #define ASSERT_NON_NULL(x) if( (x) == NULL ){ *piFailure = EX_ERROR_MEMORY_LOW; ABORT; }
03233
03234 #define NewArgument if( (*ppArgument = new_eNODE()) == NULL ){\
03235 *piFailure = EX_ERROR_MEMORY_LOW;\
03236 return NULL;\
03237 }else{\
03238 pArgument = *ppArgument;\
03239 ppArgument = &(pArgument->Parameter.CommandArgument.next);\
03240 *ppArgument = NULL;\
03241 }
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260 int ex_Pragma(peXobject pEx,
03261 char *pszPragma
03262 ){
03263
03264
03265
03266
03267
03268
03269 if( ! strcmp(pszPragma,"DeclareVars") ){
03270 DeclareVars = 1;
03271 return 0;
03272 }
03273
03274 if( ! strcmp(pszPragma,"AutoVars") ){
03275 DeclareVars = 0;
03276 return 0;
03277 }
03278
03279 if( ! strcmp(pszPragma,"DefaultLocal") ){
03280 DefaultLocal = 1;
03281 return 0;
03282 }
03283
03284 if( ! strcmp(pszPragma,"DefaultGlobal") ){
03285 DefaultLocal = 0;
03286 return 0;
03287 }
03288
03289 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_UNDEF_PRAGMA,pszPragma);
03290 return 1;
03291 }
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307 peNODE ex_IsCommandCALL(peXobject pEx,
03308 pLineSyntax p,
03309 int *piFailure
03310 ){
03311
03312
03313
03314
03315
03316
03317 peNODE pCommandNode,q;
03318 peNODE *ppArgument,pArgument;
03319 char *pszFN;
03320 int iOpened;
03321 int PCbeforeNL;
03322 void **pSymbol;
03323 pLexeme pPosition;
03324
03325 *piFailure = EX_ERROR_SUCCESS;
03326
03327 ppArgument = &pCommandNode;
03328 pCommandNode = NULL;
03329
03330 pSymbol = NULL;
03331 if( LexemeType == LEX_T_NSYMBOL && LexemeCode == p->lexes[0].OpCode ){
03332 NextLexeme;
03333 }else{
03334 if( LexemeType == LEX_T_ASYMBOL ){
03335 ex_ConvertName(pszFN=LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx);
03336 pSymbol = ex_LookupUserFunction(pEx,0);
03337 if( pSymbol == NULL )ABORT;
03338 }else ABORT;
03339
03340 }
03341
03342
03343 if( LexemeType != LEX_T_ASYMBOL )ABORT;
03344
03345
03346 if( pSymbol == NULL ){
03347
03348
03349 ex_ConvertName(pszFN=LexemeSymbol, pEx->Buffer,pEx->cbBuffer,pEx);
03350 pSymbol = ex_LookupUserFunction(pEx,1);
03351 }
03352 if( *pSymbol == NULL ){
03353
03354 *pSymbol = (void *)new_SymbolUF();
03355 if( *pSymbol == NULL )return NULL;
03356 ((pSymbolUF)*pSymbol)->FunctionName = pszFN;
03357 }
03358
03359 NextLexeme;
03360 if( LexemeType == LEX_T_NSYMBOL && LexemeCode == CMD_EQ )ABORT;
03361 if( LexemeType == LEX_T_CHARACTER && LexemeChar == '[' )ABORT;
03362
03363
03364 NewArgument;
03365 q = new_eNODE();
03366 if( q == NULL ){
03367 *piFailure = EX_ERROR_MEMORY_LOW;
03368 return NULL;
03369 }
03370 ARGUMENT.pNode = q;
03371 q->OpCode = eNTYPE_FUN;
03372 q->Parameter.UserFunction.pFunction = (pSymbolUF)(*pSymbol);
03373
03374 if( LexemeType == LEX_T_CHARACTER && LexemeChar == '(' ){
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392 lex_SavePosition(pEx->pLex,&pPosition);
03393 iOpened = 0;
03394 while( ! lex_EOF(pEx->pLex) && !(LexemeType == LEX_T_CHARACTER && LexemeChar == '\n') ){
03395 PCbeforeNL = 0;
03396 if( LexemeType == LEX_T_CHARACTER && LexemeChar == '(' )iOpened++;
03397 else
03398 if( LexemeType == LEX_T_CHARACTER && LexemeChar == ')' ){
03399 iOpened--;
03400 PCbeforeNL = 1;
03401 }
03402 else
03403 if( LexemeType == LEX_T_CHARACTER && LexemeChar == ',' && iOpened == 1 ){
03404 goto CommaFound;
03405 }
03406 NextLexeme;
03407 }
03408
03409 iOpened = PCbeforeNL;
03410 CommaFound:
03411 lex_RestorePosition(pEx->pLex,&pPosition);
03412 if( iOpened )
03413 NextLexeme;
03414 }else iOpened = 0;
03415
03416 if( iOpened && LexemeType == LEX_T_CHARACTER && LexemeChar == ')' ){
03417
03418 q->Parameter.UserFunction.Argument = NULL;
03419 NextLexeme;
03420 if( LexemeType == LEX_T_CHARACTER && LexemeChar == '\n' ){
03421 NextLexeme;
03422 pCommandNode->OpCode = p->CommandOpCode;
03423 return pCommandNode;
03424 }else FABORT;
03425 }
03426
03427 if( (! iOpened) && LexemeType == LEX_T_CHARACTER && LexemeChar == '\n' ){
03428 q->Parameter.UserFunction.Argument = NULL;
03429 NextLexeme;
03430 pCommandNode->OpCode = p->CommandOpCode;
03431 return pCommandNode;
03432 }
03433
03434 q->Parameter.UserFunction.Argument = ex_ExpressionList(pEx);
03435 if( q->Parameter.UserFunction.Argument == NULL )FABORT;
03436 if( iOpened ){
03437 if( LexemeType != LEX_T_CHARACTER || LexemeChar != ')' ){
03438
03439 REPORT(LexemeFileName,LexemeLineNumber,EX_ERROR_MISSING_PAREN,NULL);
03440 FABORT;
03441 }else{ NextLexeme; }
03442 }
03443
03444
03445 if( LexemeType != LEX_T_CHARACTER || LexemeChar != '\n' )FABORT;
03446
03447 pCommandNode->OpCode = p->CommandOpCode;
03448 return pCommandNode;
03449 }
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459 peNODE ex_IsCommandOPEN(peXobject pEx,
03460 pLineSyntax p,
03461 int *piFailure
03462 ){
03463
03464
03465
03466
03467
03468 peNODE pCommandNode,q;
03469 peNODE *ppArgument,pArgument;
03470 long sLen;
03471
03472 *piFailure = EX_ERROR_SUCCESS;
03473
03474 ppArgument = &pCommandNode;
03475 pCommandNode = NULL;
03476
03477
03478 if( LexemeType != EX_LEX_NSYMBOL || LexemeCode != p->lexes[0].OpCode )ABORT;
03479 NextLexeme;
03480
03481
03482 NewArgument;
03483 ex_Expression_r(pEx,&(ARGUMENT.pNode));
03484 if( ARGUMENT.pNode == NULL )FABORT;
03485
03486
03487 if( LexemeType != EX_LEX_NSYMBOL || LexemeCode != p->lexes[2].OpCode )FABORT;
03488 NextLexeme;
03489
03490
03491 if( LexemeType != LEX_T_ASYMBOL && LexemeType != LEX_T_NSYMBOL )FABORT;
03492 if( LexemeType == LEX_T_ASYMBOL ){
03493 NewArgument;
03494 if( (ARGUMENT.szStringValue = alloc_Alloc((sLen=strlen(LexemeSymbol))+1,pEx->pMemorySegment)) == NULL )ABORT;
03495 strcpy(ARGUMENT.szStringValue,LexemeSymbol);
03496 pArgument->Parameter.CommandArgument.sLen = sLen;
03497 pEx->cbStringTable += sLen+1;
03498 COUNT_STRING_LEN
03499 }else{
03500 NewArgument;
03501 if( (ARGUMENT.szStringValue = alloc_Alloc((sLen=strlen(lex_SymbolicName(pEx->pLex,LexemeCode)))+1,pEx->pMemorySegment)) == NULL )ABORT;
03502 strcpy(ARGUMENT.szStringValue,lex_SymbolicName(pEx->pLex,LexemeCode));
03503 pArgument->Parameter.CommandArgument.sLen = sLen;
03504 pEx->cbStringTable += strlen(ARGUMENT.szStringValue)+1;
03505 COUNT_STRING_LEN
03506 }
03507 NextLexeme;
03508
03509
03510 if( LexemeType != EX_LEX_NSYMBOL || LexemeCode != p->lexes[4].OpCode )FABORT;
03511 NextLexeme;
03512
03513 if( LexemeType == LEX_T_CHARACTER && LexemeCode == '#' )
03514 NextLexeme;
03515
03516
03517 NewArgument;
03518 ex_Expression_r(pEx,&(ARGUMENT.pNode));
03519 if( ARGUMENT.pNode == NULL )FABORT;
03520
03521
03522 if( LexemeType == LEX_T_NSYMBOL && LexemeCode == p->lexes[6].OpCode ){
03523 NextLexeme;
03524 if( LexemeType != LEX_T_NSYMBOL || LexemeCode != p->lexes[7].OpCode )FABORT;
03525 NextLexeme;
03526
03527
03528 NewArgument;
03529 ex_Expression_r(pEx,&(ARGUMENT.pNode));
03530 if( ARGUMENT.pNode == NULL )FABORT;
03531 }else{
03532
03533 NewArgument;
03534 q = new_eNODE();
03535 if( q == NULL ){
03536 *piFailure = EX_ERROR_MEMORY_LOW;
03537 return NULL;
03538 }
03539 ARGUMENT.pNode = q;
03540 q->OpCode = eNTYPE_LNG;
03541 q->Parameter.Constant.Value.lValue = 1;
03542 }
03543
03544
03545 if( LexemeType != LEX_T_CHARACTER || LexemeCode != p->lexes[9].OpCode )FABORT;
03546 NextLexeme;
03547
03548 pCommandNode->OpCode = p->CommandOpCode;
03549 return pCommandNode;
03550 }
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566 peNODE ex_IsCommandSLIF(peXobject pEx,
03567 pLineSyntax p,
03568 int *piFailure
03569 ){
03570
03571
03572 ABORT;
03573 }
03574
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584
03585
03586 peNODE ex_IsCommandIF(peXobject pEx,
03587 pLineSyntax p,
03588 int *piFailure
03589 ){
03590
03591
03592
03593
03594
03595
03596
03597 peNODE pCommandNode;
03598 peNODE *ppArgument,pArgument;
03599 pSymbolLABEL pLabel;
03600
03601 *piFailure = EX_ERROR_SUCCESS;
03602
03603 ppArgument = &pCommandNode;
03604 pCommandNode = NULL;
03605
03606
03607 if( LexemeType != EX_LEX_NSYMBOL || LexemeCode != p->lexes[0].OpCode )ABORT;
03608 NextLexeme;
03609
03610
03611 NewArgument;
03612 ex_Expression_r(pEx,&(ARGUMENT.pNode));
03613 if( ARGUMENT.pNode == NULL )FABORT;
03614
03615
03616 if( LexemeType != EX_LEX_NSYMBOL || LexemeCode != p->lexes[3].OpCode )FABORT;
03617 NextLexeme;
03618
03619
03620 if( LexemeType == LEX_T_CHARACTER && LexemeCode == p->lexes[5].OpCode ){
03621
03622 pCommandNode->OpCode = p->CommandOpCode;
03623 NextLexeme;
03624 NewArgument;
03625 pLabel = (ARGUMENT.pLabel = new_SymbolLABEL());
03626 _ex_PushLabel(pEx,pLabel,CMD_IF,pEx->pMemorySegment);
03627 }else{
03628
03629
03630
03631 if( LexemeType == EX_LEX_NSYMBOL &&
03632 ( LexemeCode == KEYWORDCODE_IF ||
03633 LexemeCode == KEYWORDCODE_DECLARE ||
03634 LexemeCode == KEYWORDCODE_MODULE ||
03635 LexemeCode == KEYWORDCODE_ELSEIF ||
03636 LexemeCode == KEYWORDCODE_ELSIF ||
03637 LexemeCode == KEYWORDCODE_ELIF ||
03638 LexemeCode == KEYWORDCODE_ELSE ||
03639 LexemeCode == KEYWORDCODE_ENDIF ||
03640
03641 LexemeCode == KEYWORDCODE_GLOBAL ||
03642 LexemeCode == KEYWORDCODE_CONST ||
03643 LexemeCode == KEYWORDCODE_LOCAL ||
03644 LexemeCode == KEYWORDCODE_VAR ||
03645
03646 LexemeCode == KEYWORDCODE_REPEAT ||
03647 LexemeCode == KEYWORDCODE_UNTIL ||
03648 LexemeCode == KEYWORDCODE_FOR ||
03649 LexemeCode == KEYWORDCODE_WHILE ||
03650 LexemeCode == KEYWORDCODE_NEXT ||
03651 LexemeCode == KEYWORDCODE_WEND ||
03652
03653 LexemeCode == KEYWORDCODE_SUB ||
03654 LexemeCode == KEYWORDCODE_FUNCTION||
03655 LexemeCode == KEYWORDCODE_END ||
03656 0
03657 ) )FABORT;
03658 pCommandNode->OpCode = CMD_SLIF;
03659 }
03660
03661 return pCommandNode;
03662 }
03663
03664
03665
03666
03667
03668 peNODE ex_IsCommandLET(peXobject pEx,
03669 pLineSyntax p,
03670 int *piFailure
03671 ){
03672
03673
03674
03675 peNODE pCommandNode;
03676 peNODE *ppArgument,pArgument;
03677
03678 *piFailure = EX_ERROR_SUCCESS;
03679
03680 ppArgument = &pCommandNode;
03681 pCommandNode = NULL;
03682
03683 if( LexemeType == EX_LEX_NSYMBOL && LexemeCode == KEYWORDCODE_LET )NextLexeme;
03684
03685 if( LexemeType != LEX_T_ASYMBOL )ABORT;
03686
03687 NewArgument;
03688 if( (ARGUMENT.pNode = ex_LeftValue(pEx)) == NULL )FABORT;
03689
03690 if( LexemeType != EX_LEX_NSYMBOL )FABORT;
03691 switch( LexemeCode ){
03692 case CMD_EQ:
03693 pCommandNode->OpCode = CMD_LET;
03694 break;
03695 case CMD_EXTOPAG:
03696 pCommandNode->OpCode = CMD_LETP;
03697 break;
03698 case CMD_EXTOPMG:
03699 pCommandNode->OpCode = CMD_LETC;
03700 break;
03701 case CMD_EXTOPHG:
03702 pCommandNode->OpCode = CMD_LETS;
03703 break;
03704 case CMD_EXTOPIG:
03705 pCommandNode->OpCode = CMD_LETD;
03706 break;
03707 case CMD_EXTOPBG:
03708 pCommandNode->OpCode = CMD_LETM;
03709 break;
03710 case CMD_EXTOPNG:
03711 pCommandNode->OpCode = CMD_LETI;
03712 break;
03713 default: FABORT;
03714 }
03715 NextLexeme;
03716
03717
03718 NewArgument;
03719 ex_Expression_r(pEx,&(ARGUMENT.pNode));
03720 if( ARGUMENT.pNode == NULL )FABORT;
03721
03722
03723 if( LexemeType == LEX_T_CHARACTER && LexemeCode == '\n' )
03724 return pCommandNode;
03725 FABORT;
03726 }