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 #define _EXPRNPSR_SOURCE_
00033
00034 #include "setup.h"
00035
00036 #include <stdio.h>
00037 #define _STDIO_INCLUDED_
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include <ctype.h>
00041
00042 #include "constant.h"
00043 #include "envrnmnt.h"
00044 #include "router.h"
00045 #include "strngrtr.h"
00046 #include "scanner.h"
00047 #include "memalloc.h"
00048 #include "argacces.h"
00049 #include "prntutil.h"
00050 #include "cstrnchk.h"
00051 #include "extnfunc.h"
00052 #include "exprnpsr.h"
00053 #include "modulutl.h"
00054 #include "prcdrfun.h"
00055
00056 #if DEFRULE_CONSTRUCT
00057 #include "network.h"
00058 #endif
00059
00060 #if DEFGENERIC_CONSTRUCT
00061 #include "genrccom.h"
00062 #endif
00063
00064 #if DEFFUNCTION_CONSTRUCT
00065 #include "dffnxfun.h"
00066 #endif
00067
00068 #if (! RUN_TIME)
00069
00070
00071
00072
00073
00074 globle struct expr *Function0Parse(
00075 void *theEnv,
00076 char *logicalName)
00077 {
00078 struct token theToken;
00079 struct expr *top;
00080
00081
00082
00083
00084
00085 GetToken(theEnv,logicalName,&theToken);
00086 if (theToken.type != LPAREN)
00087 {
00088 SyntaxErrorMessage(theEnv,"function calls");
00089 return(NULL);
00090 }
00091
00092
00093
00094
00095
00096 top = Function1Parse(theEnv,logicalName);
00097 return(top);
00098 }
00099
00100
00101
00102
00103
00104 globle struct expr *Function1Parse(
00105 void *theEnv,
00106 char *logicalName)
00107 {
00108 struct token theToken;
00109 struct expr *top;
00110
00111
00112
00113
00114
00115 GetToken(theEnv,logicalName,&theToken);
00116 if (theToken.type != SYMBOL)
00117 {
00118 PrintErrorID(theEnv,"EXPRNPSR",1,TRUE);
00119 EnvPrintRouter(theEnv,WERROR,"A function name must be a symbol\n");
00120 return(NULL);
00121 }
00122
00123
00124
00125
00126
00127 top = Function2Parse(theEnv,logicalName,ValueToString(theToken.value));
00128 return(top);
00129 }
00130
00131
00132
00133
00134
00135
00136 globle struct expr *Function2Parse(
00137 void *theEnv,
00138 char *logicalName,
00139 char *name)
00140 {
00141 struct FunctionDefinition *theFunction;
00142 struct expr *top;
00143 int moduleSpecified = FALSE;
00144 unsigned position;
00145 struct symbolHashNode *moduleName = NULL, *constructName = NULL;
00146 #if DEFGENERIC_CONSTRUCT
00147 void *gfunc;
00148 #endif
00149 #if DEFFUNCTION_CONSTRUCT
00150 void *dptr;
00151 #endif
00152
00153
00154
00155
00156
00157 if ((position = FindModuleSeparator(name)) != FALSE)
00158 {
00159 moduleName = ExtractModuleName(theEnv,position,name);
00160 constructName = ExtractConstructName(theEnv,position,name);
00161 moduleSpecified = TRUE;
00162 }
00163
00164
00165
00166
00167
00168 theFunction = FindFunction(theEnv,name);
00169
00170 #if DEFGENERIC_CONSTRUCT
00171 if (moduleSpecified)
00172 {
00173 if (ConstructExported(theEnv,"defgeneric",moduleName,constructName) ||
00174 EnvGetCurrentModule(theEnv) == EnvFindDefmodule(theEnv,ValueToString(moduleName)))
00175 { gfunc = (void *) EnvFindDefgeneric(theEnv,name); }
00176 else
00177 { gfunc = NULL; }
00178 }
00179 else
00180 { gfunc = (void *) LookupDefgenericInScope(theEnv,name); }
00181 #endif
00182
00183 #if DEFFUNCTION_CONSTRUCT
00184 if ((theFunction == NULL)
00185 #if DEFGENERIC_CONSTRUCT
00186 && (gfunc == NULL)
00187 #endif
00188 )
00189 if (moduleSpecified)
00190 {
00191 if (ConstructExported(theEnv,"deffunction",moduleName,constructName) ||
00192 EnvGetCurrentModule(theEnv) == EnvFindDefmodule(theEnv,ValueToString(moduleName)))
00193 { dptr = (void *) EnvFindDeffunction(theEnv,name); }
00194 else
00195 { dptr = NULL; }
00196 }
00197 else
00198 { dptr = (void *) LookupDeffunctionInScope(theEnv,name); }
00199 else
00200 dptr = NULL;
00201 #endif
00202
00203
00204
00205
00206
00207 #if DEFFUNCTION_CONSTRUCT
00208 if (dptr != NULL)
00209 top = GenConstant(theEnv,PCALL,dptr);
00210 else
00211 #endif
00212 #if DEFGENERIC_CONSTRUCT
00213 if (gfunc != NULL)
00214 top = GenConstant(theEnv,GCALL,gfunc);
00215 else
00216 #endif
00217 if (theFunction != NULL)
00218 top = GenConstant(theEnv,FCALL,theFunction);
00219 else
00220 {
00221 PrintErrorID(theEnv,"EXPRNPSR",3,TRUE);
00222 EnvPrintRouter(theEnv,WERROR,"Missing function declaration for ");
00223 EnvPrintRouter(theEnv,WERROR,name);
00224 EnvPrintRouter(theEnv,WERROR,".\n");
00225 return(NULL);
00226 }
00227
00228
00229
00230
00231
00232 PushRtnBrkContexts(theEnv);
00233 ExpressionData(theEnv)->ReturnContext = FALSE;
00234 ExpressionData(theEnv)->BreakContext = FALSE;
00235
00236 #if DEFGENERIC_CONSTRUCT || DEFFUNCTION_CONSTRUCT
00237 if (top->type == FCALL)
00238 #endif
00239 {
00240 if (theFunction->parser != NULL)
00241 {
00242 top = (*theFunction->parser)(theEnv,top,logicalName);
00243 PopRtnBrkContexts(theEnv);
00244 if (top == NULL) return(NULL);
00245 if (ReplaceSequenceExpansionOps(theEnv,top->argList,top,FindFunction(theEnv,"(expansion-call)"),
00246 FindFunction(theEnv,"expand$")))
00247 {
00248 ReturnExpression(theEnv,top);
00249 return(NULL);
00250 }
00251 return(top);
00252 }
00253 }
00254
00255
00256
00257
00258
00259 top = CollectArguments(theEnv,top,logicalName);
00260 PopRtnBrkContexts(theEnv);
00261 if (top == NULL) return(NULL);
00262
00263 if (ReplaceSequenceExpansionOps(theEnv,top->argList,top,FindFunction(theEnv,"(expansion-call)"),
00264 FindFunction(theEnv,"expand$")))
00265 {
00266 ReturnExpression(theEnv,top);
00267 return(NULL);
00268 }
00269
00270
00271
00272
00273
00274
00275 if (top->value == (void *) FindFunction(theEnv,"(expansion-call)"))
00276 { return(top); }
00277
00278
00279
00280
00281
00282 if ((top->type == FCALL) && EnvGetStaticConstraintChecking(theEnv))
00283 {
00284 if (CheckExpressionAgainstRestrictions(theEnv,top,theFunction->restrictions,name))
00285 {
00286 ReturnExpression(theEnv,top);
00287 return(NULL);
00288 }
00289 }
00290
00291 #if DEFFUNCTION_CONSTRUCT
00292 else if (top->type == PCALL)
00293 {
00294 if (CheckDeffunctionCall(theEnv,top->value,CountArguments(top->argList)) == FALSE)
00295 {
00296 ReturnExpression(theEnv,top);
00297 return(NULL);
00298 }
00299 }
00300 #endif
00301
00302
00303
00304
00305
00306 return(top);
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 globle intBool ReplaceSequenceExpansionOps(
00330 void *theEnv,
00331 EXPRESSION *actions,
00332 EXPRESSION *fcallexp,
00333 void *expcall,
00334 void *expmult)
00335 {
00336 EXPRESSION *theExp;
00337
00338 while (actions != NULL)
00339 {
00340 if ((ExpressionData(theEnv)->SequenceOpMode == FALSE) && (actions->type == MF_VARIABLE))
00341 actions->type = SF_VARIABLE;
00342 if ((actions->type == MF_VARIABLE) || (actions->type == MF_GBL_VARIABLE) ||
00343 (actions->value == expmult))
00344 {
00345 if ((fcallexp->type != FCALL) ? FALSE :
00346 (((struct FunctionDefinition *) fcallexp->value)->sequenceuseok == FALSE))
00347 {
00348 PrintErrorID(theEnv,"EXPRNPSR",4,FALSE);
00349 EnvPrintRouter(theEnv,WERROR,"$ Sequence operator not a valid argument for ");
00350 EnvPrintRouter(theEnv,WERROR,ValueToString(((struct FunctionDefinition *)
00351 fcallexp->value)->callFunctionName));
00352 EnvPrintRouter(theEnv,WERROR,".\n");
00353 return(TRUE);
00354 }
00355 if (fcallexp->value != expcall)
00356 {
00357 theExp = GenConstant(theEnv,fcallexp->type,fcallexp->value);
00358 theExp->argList = fcallexp->argList;
00359 theExp->nextArg = NULL;
00360 fcallexp->type = FCALL;
00361 fcallexp->value = expcall;
00362 fcallexp->argList = theExp;
00363 }
00364 if (actions->value != expmult)
00365 {
00366 theExp = GenConstant(theEnv,SF_VARIABLE,actions->value);
00367 if (actions->type == MF_GBL_VARIABLE)
00368 theExp->type = GBL_VARIABLE;
00369 actions->argList = theExp;
00370 actions->type = FCALL;
00371 actions->value = expmult;
00372 }
00373 }
00374 if (actions->argList != NULL)
00375 {
00376 if ((actions->type == GCALL) ||
00377 (actions->type == PCALL) ||
00378 (actions->type == FCALL))
00379 theExp = actions;
00380 else
00381 theExp = fcallexp;
00382 if (ReplaceSequenceExpansionOps(theEnv,actions->argList,theExp,expcall,expmult))
00383 return(TRUE);
00384 }
00385 actions = actions->nextArg;
00386 }
00387 return(FALSE);
00388 }
00389
00390
00391
00392
00393
00394 globle void PushRtnBrkContexts(
00395 void *theEnv)
00396 {
00397 SAVED_CONTEXTS *svtmp;
00398
00399 svtmp = get_struct(theEnv,saved_contexts);
00400 svtmp->rtn = ExpressionData(theEnv)->ReturnContext;
00401 svtmp->brk = ExpressionData(theEnv)->BreakContext;
00402 svtmp->nxt = ExpressionData(theEnv)->svContexts;
00403 ExpressionData(theEnv)->svContexts = svtmp;
00404 }
00405
00406
00407
00408
00409
00410 globle void PopRtnBrkContexts(
00411 void *theEnv)
00412 {
00413 SAVED_CONTEXTS *svtmp;
00414
00415 ExpressionData(theEnv)->ReturnContext = ExpressionData(theEnv)->svContexts->rtn;
00416 ExpressionData(theEnv)->BreakContext = ExpressionData(theEnv)->svContexts->brk;
00417 svtmp = ExpressionData(theEnv)->svContexts;
00418 ExpressionData(theEnv)->svContexts = ExpressionData(theEnv)->svContexts->nxt;
00419 rtn_struct(theEnv,saved_contexts,svtmp);
00420 }
00421
00422
00423
00424
00425
00426
00427
00428 globle int CheckExpressionAgainstRestrictions(
00429 void *theEnv,
00430 struct expr *theExpression,
00431 char *restrictions,
00432 char *functionName)
00433 {
00434 char theChar[2];
00435 int i = 0, j = 1;
00436 int number1, number2;
00437 int argCount;
00438 char defaultRestriction, argRestriction;
00439 struct expr *argPtr;
00440 int theRestriction;
00441
00442 theChar[0] = '0';
00443 theChar[1] = '\0';
00444
00445
00446
00447
00448
00449
00450 if (restrictions == NULL) return(FALSE);
00451
00452
00453
00454
00455
00456 argCount = CountArguments(theExpression->argList);
00457
00458
00459
00460
00461
00462 theChar[0] = restrictions[i++];
00463
00464 if (isdigit(theChar[0]))
00465 { number1 = atoi(theChar); }
00466 else if (theChar[0] == '*')
00467 { number1 = -1; }
00468 else
00469 { return(FALSE); }
00470
00471
00472
00473
00474
00475 theChar[0] = restrictions[i++];
00476 if (isdigit(theChar[0]))
00477 { number2 = atoi(theChar); }
00478 else if (theChar[0] == '*')
00479 { number2 = 10000; }
00480 else
00481 { return(FALSE); }
00482
00483
00484
00485
00486
00487 if (number1 == number2)
00488 {
00489 if (argCount != number1)
00490 {
00491 ExpectedCountError(theEnv,functionName,EXACTLY,number1);
00492 return(TRUE);
00493 }
00494 }
00495 else if (argCount < number1)
00496 {
00497 ExpectedCountError(theEnv,functionName,AT_LEAST,number1);
00498 return(TRUE);
00499 }
00500 else if (argCount > number2)
00501 {
00502 ExpectedCountError(theEnv,functionName,NO_MORE_THAN,number2);
00503 return(TRUE);
00504 }
00505
00506
00507
00508
00509
00510 defaultRestriction = restrictions[i];
00511 if (defaultRestriction == '\0')
00512 { defaultRestriction = 'u'; }
00513 else if (defaultRestriction == '*')
00514 {
00515 defaultRestriction = 'u';
00516 i++;
00517 }
00518 else
00519 { i++; }
00520
00521
00522
00523
00524
00525 for (argPtr = theExpression->argList;
00526 argPtr != NULL;
00527 argPtr = argPtr->nextArg)
00528 {
00529 argRestriction = restrictions[i];
00530 if (argRestriction == '\0')
00531 { argRestriction = defaultRestriction; }
00532 else
00533 { i++; }
00534
00535 if (argRestriction != '*')
00536 { theRestriction = (int) argRestriction; }
00537 else
00538 { theRestriction = (int) defaultRestriction; }
00539
00540 if (CheckArgumentAgainstRestriction(theEnv,argPtr,theRestriction))
00541 {
00542 ExpectedTypeError1(theEnv,functionName,j,GetArgumentTypeName(theRestriction));
00543 return(TRUE);
00544 }
00545
00546 j++;
00547 }
00548
00549 return(FALSE);
00550 }
00551
00552
00553
00554
00555
00556 globle struct expr *CollectArguments(
00557 void *theEnv,
00558 struct expr *top,
00559 char *logicalName)
00560 {
00561 int errorFlag;
00562 struct expr *lastOne, *nextOne;
00563
00564
00565
00566
00567
00568 lastOne = NULL;
00569
00570 while (TRUE)
00571 {
00572 SavePPBuffer(theEnv," ");
00573
00574 errorFlag = FALSE;
00575 nextOne = ArgumentParse(theEnv,logicalName,&errorFlag);
00576
00577 if (errorFlag == TRUE)
00578 {
00579 ReturnExpression(theEnv,top);
00580 return(NULL);
00581 }
00582
00583 if (nextOne == NULL)
00584 {
00585 PPBackup(theEnv);
00586 PPBackup(theEnv);
00587 SavePPBuffer(theEnv,")");
00588 return(top);
00589 }
00590
00591 if (lastOne == NULL)
00592 { top->argList = nextOne; }
00593 else
00594 { lastOne->nextArg = nextOne; }
00595
00596 lastOne = nextOne;
00597 }
00598 }
00599
00600
00601
00602
00603
00604 globle struct expr *ArgumentParse(
00605 void *theEnv,
00606 char *logicalName,
00607 int *errorFlag)
00608 {
00609 struct expr *top;
00610 struct token theToken;
00611
00612
00613
00614
00615
00616 GetToken(theEnv,logicalName,&theToken);
00617
00618
00619
00620
00621
00622 if (theToken.type == RPAREN)
00623 { return(NULL); }
00624
00625
00626
00627
00628
00629 if ((theToken.type == SF_VARIABLE) || (theToken.type == MF_VARIABLE) ||
00630 (theToken.type == SYMBOL) || (theToken.type == STRING) ||
00631 #if DEFGLOBAL_CONSTRUCT
00632 (theToken.type == GBL_VARIABLE) ||
00633 (theToken.type == MF_GBL_VARIABLE) ||
00634 #endif
00635 #if OBJECT_SYSTEM
00636 (theToken.type == INSTANCE_NAME) ||
00637 #endif
00638 (theToken.type == FLOAT) || (theToken.type == INTEGER))
00639 { return(GenConstant(theEnv,theToken.type,theToken.value)); }
00640
00641
00642
00643
00644
00645 if (theToken.type != LPAREN)
00646 {
00647 PrintErrorID(theEnv,"EXPRNPSR",2,TRUE);
00648 EnvPrintRouter(theEnv,WERROR,"Expected a constant, variable, or expression.\n");
00649 *errorFlag = TRUE;
00650 return(NULL);
00651 }
00652
00653 top = Function1Parse(theEnv,logicalName);
00654 if (top == NULL) *errorFlag = TRUE;
00655 return(top);
00656 }
00657
00658
00659
00660
00661
00662
00663 globle struct expr *ParseAtomOrExpression(
00664 void *theEnv,
00665 char *logicalName,
00666 struct token *useToken)
00667 {
00668 struct token theToken, *thisToken;
00669 struct expr *rv;
00670
00671 if (useToken == NULL)
00672 {
00673 thisToken = &theToken;
00674 GetToken(theEnv,logicalName,thisToken);
00675 }
00676 else thisToken = useToken;
00677
00678 if ((thisToken->type == SYMBOL) || (thisToken->type == STRING) ||
00679 (thisToken->type == INTEGER) || (thisToken->type == FLOAT) ||
00680 #if OBJECT_SYSTEM
00681 (thisToken->type == INSTANCE_NAME) ||
00682 #endif
00683 #if DEFGLOBAL_CONSTRUCT
00684 (thisToken->type == GBL_VARIABLE) ||
00685 (thisToken->type == MF_GBL_VARIABLE) ||
00686 #endif
00687 (thisToken->type == SF_VARIABLE) || (thisToken->type == MF_VARIABLE))
00688 { rv = GenConstant(theEnv,thisToken->type,thisToken->value); }
00689 else if (thisToken->type == LPAREN)
00690 {
00691 rv = Function1Parse(theEnv,logicalName);
00692 if (rv == NULL) return(NULL);
00693 }
00694 else
00695 {
00696 PrintErrorID(theEnv,"EXPRNPSR",2,TRUE);
00697 EnvPrintRouter(theEnv,WERROR,"Expected a constant, variable, or expression.\n");
00698 return(NULL);
00699 }
00700
00701 return(rv);
00702 }
00703
00704
00705
00706
00707
00708
00709 globle struct expr *GroupActions(
00710 void *theEnv,
00711 char *logicalName,
00712 struct token *theToken,
00713 int readFirstToken,
00714 char *endWord,
00715 int functionNameParsed)
00716 {
00717 struct expr *top, *nextOne, *lastOne = NULL;
00718
00719
00720
00721
00722
00723 top = GenConstant(theEnv,FCALL,FindFunction(theEnv,"progn"));
00724
00725
00726
00727
00728
00729 while (TRUE)
00730 {
00731
00732
00733
00734
00735
00736
00737 if (readFirstToken)
00738 { GetToken(theEnv,logicalName,theToken); }
00739 else
00740 { readFirstToken = TRUE; }
00741
00742
00743
00744
00745
00746
00747 if ((theToken->type == SYMBOL) &&
00748 (endWord != NULL) &&
00749 (! functionNameParsed))
00750 {
00751 if (strcmp(ValueToString(theToken->value),endWord) == 0)
00752 { return(top); }
00753 }
00754
00755
00756
00757
00758
00759
00760 if (functionNameParsed)
00761 {
00762 nextOne = Function2Parse(theEnv,logicalName,ValueToString(theToken->value));
00763 functionNameParsed = FALSE;
00764 }
00765
00766
00767
00768
00769
00770 else if ((theToken->type == SYMBOL) || (theToken->type == STRING) ||
00771 (theToken->type == INTEGER) || (theToken->type == FLOAT) ||
00772 #if DEFGLOBAL_CONSTRUCT
00773 (theToken->type == GBL_VARIABLE) ||
00774 (theToken->type == MF_GBL_VARIABLE) ||
00775 #endif
00776 #if OBJECT_SYSTEM
00777 (theToken->type == INSTANCE_NAME) ||
00778 #endif
00779 (theToken->type == SF_VARIABLE) || (theToken->type == MF_VARIABLE))
00780 { nextOne = GenConstant(theEnv,theToken->type,theToken->value); }
00781
00782
00783
00784
00785
00786 else if (theToken->type == LPAREN)
00787 { nextOne = Function1Parse(theEnv,logicalName); }
00788
00789
00790
00791
00792
00793
00794 else
00795 {
00796 if (ReplaceSequenceExpansionOps(theEnv,top,NULL,
00797 FindFunction(theEnv,"(expansion-call)"),
00798 FindFunction(theEnv,"expand$")))
00799 {
00800 ReturnExpression(theEnv,top);
00801 return(NULL);
00802 }
00803
00804 return(top);
00805 }
00806
00807
00808
00809
00810
00811
00812 if (nextOne == NULL)
00813 {
00814 theToken->type = UNKNOWN_VALUE;
00815 ReturnExpression(theEnv,top);
00816 return(NULL);
00817 }
00818
00819 if (lastOne == NULL)
00820 { top->argList = nextOne; }
00821 else
00822 { lastOne->nextArg = nextOne; }
00823
00824 lastOne = nextOne;
00825
00826 PPCRAndIndent(theEnv);
00827 }
00828 }
00829
00830 #endif
00831
00832
00833
00834
00835
00836 globle intBool EnvSetSequenceOperatorRecognition(
00837 void *theEnv,
00838 int value)
00839 {
00840 int ov;
00841
00842 ov = ExpressionData(theEnv)->SequenceOpMode;
00843 ExpressionData(theEnv)->SequenceOpMode = value;
00844 return(ov);
00845 }
00846
00847
00848
00849
00850
00851 globle intBool EnvGetSequenceOperatorRecognition(
00852 void *theEnv)
00853 {
00854 return(ExpressionData(theEnv)->SequenceOpMode);
00855 }
00856
00857
00858
00859
00860
00861 globle EXPRESSION *ParseConstantArguments(
00862 void *theEnv,
00863 char *argstr,
00864 int *error)
00865 {
00866 EXPRESSION *top = NULL,*bot = NULL,*tmp;
00867 char *router = "***FNXARGS***";
00868 struct token tkn;
00869
00870 *error = FALSE;
00871
00872 if (argstr == NULL) return(NULL);
00873
00874
00875
00876
00877
00878 if (OpenStringSource(theEnv,router,argstr,0) == 0)
00879 {
00880 PrintErrorID(theEnv,"EXPRNPSR",6,FALSE);
00881 EnvPrintRouter(theEnv,WERROR,"Cannot read arguments for external call.\n");
00882 *error = TRUE;
00883 return(NULL);
00884 }
00885
00886
00887
00888
00889
00890 GetToken(theEnv,router,&tkn);
00891 while (tkn.type != STOP)
00892 {
00893 if ((tkn.type != SYMBOL) && (tkn.type != STRING) &&
00894 (tkn.type != FLOAT) && (tkn.type != INTEGER) &&
00895 (tkn.type != INSTANCE_NAME))
00896 {
00897 PrintErrorID(theEnv,"EXPRNPSR",7,FALSE);
00898 EnvPrintRouter(theEnv,WERROR,"Only constant arguments allowed for external function call.\n");
00899 ReturnExpression(theEnv,top);
00900 *error = TRUE;
00901 CloseStringSource(theEnv,router);
00902 return(NULL);
00903 }
00904 tmp = GenConstant(theEnv,tkn.type,tkn.value);
00905 if (top == NULL)
00906 top = tmp;
00907 else
00908 bot->nextArg = tmp;
00909 bot = tmp;
00910 GetToken(theEnv,router,&tkn);
00911 }
00912
00913
00914
00915
00916
00917 CloseStringSource(theEnv,router);
00918
00919
00920
00921
00922
00923 return(top);
00924 }
00925
00926
00927
00928
00929 globle struct expr *RemoveUnneededProgn(
00930 void *theEnv,
00931 struct expr *theExpression)
00932 {
00933 struct FunctionDefinition *fptr;
00934 struct expr *temp;
00935
00936 if (theExpression == NULL) return(theExpression);
00937
00938 if (theExpression->type != FCALL) return(theExpression);
00939
00940 fptr = (struct FunctionDefinition *) theExpression->value;
00941
00942 if (fptr->functionPointer != PTIF PrognFunction)
00943 { return(theExpression); }
00944
00945 if ((theExpression->argList != NULL) &&
00946 (theExpression->argList->nextArg == NULL))
00947 {
00948 temp = theExpression;
00949 theExpression = theExpression->argList;
00950 temp->argList = NULL;
00951 temp->nextArg = NULL;
00952 ReturnExpression(theEnv,temp);
00953 }
00954
00955 return(theExpression);
00956 }