globle int CheckSyntax( char *theString, DATA_OBJECT_PTR returnValue) { char *name; struct token theToken; struct expr *top; short rv; /*==============================*/ /* Set the default return value */ /* (TRUE for problems found). */ /*==============================*/ SetpType(returnValue,SYMBOL); SetpValue(returnValue,TrueSymbol); /*===========================================*/ /* Create a string source router so that the */ /* string can be used as an input source. */ /*===========================================*/ if (OpenStringSource("check-syntax",theString,0) == 0) { return(TRUE); } /*=================================*/ /* Only expressions and constructs */ /* can have their syntax checked. */ /*=================================*/ GetToken("check-syntax",&theToken); if (theToken.type != LPAREN) { CloseStringSource("check-syntax"); SetpValue(returnValue,AddSymbol("MISSING-LEFT-PARENTHESIS")); return(TRUE); } /*========================================*/ /* The next token should be the construct */ /* type or function name. */ /*========================================*/ GetToken("check-syntax",&theToken); if (theToken.type != SYMBOL) { CloseStringSource("check-syntax"); SetpValue(returnValue,AddSymbol("EXPECTED-SYMBOL-AFTER-LEFT-PARENTHESIS")); return(TRUE); } name = ValueToString(theToken.value); /*==============================================*/ /* Set up a router to capture the error output. */ /*==============================================*/ AddRouter("error-capture",40, FindErrorCapture, PrintErrorCapture, NULL, NULL, NULL); /*================================*/ /* Determine if it's a construct. */ /*================================*/ if (FindConstruct(name)) { CheckSyntaxMode = TRUE; rv = (short) ParseConstruct(name,"check-syntax"); GetToken("check-syntax",&theToken); CheckSyntaxMode = FALSE; if (rv) { PrintRouter(WERROR,"\nERROR:\n"); PrintInChunks(WERROR,GetPPBuffer()); PrintRouter(WERROR,"\n"); } DestroyPPBuffer(); CloseStringSource("check-syntax"); if ((rv != FALSE) || (WarningString != NULL)) { SetErrorCaptureValues(returnValue); DeactivateErrorCapture(); return(TRUE); } if (theToken.type != STOP) { SetpValue(returnValue,AddSymbol("EXTRANEOUS-INPUT-AFTER-LAST-PARENTHESIS")); DeactivateErrorCapture(); return(TRUE); } SetpType(returnValue,SYMBOL); SetpValue(returnValue,FalseSymbol); DeactivateErrorCapture(); return(FALSE); } /*=======================*/ /* Parse the expression. */ /*=======================*/ top = Function2Parse("check-syntax",name); GetToken("check-syntax",&theToken); ClearParsedBindNames(); CloseStringSource("check-syntax"); if (top == NULL) { SetErrorCaptureValues(returnValue); DeactivateErrorCapture(); return(TRUE); } if (theToken.type != STOP) { SetpValue(returnValue,AddSymbol("EXTRANEOUS-INPUT-AFTER-LAST-PARENTHESIS")); DeactivateErrorCapture(); ReturnExpression(top); return(TRUE); } DeactivateErrorCapture(); ReturnExpression(top); SetpType(returnValue,SYMBOL); SetpValue(returnValue,FalseSymbol); return(FALSE); }
globle int EnvBuild( void *theEnv, char *theString) { char *constructType; struct token theToken; int errorFlag; /*====================================================*/ /* No additions during defrule join network activity. */ /*====================================================*/ #if DEFRULE_CONSTRUCT if (EngineData(theEnv)->JoinOperationInProgress) return(FALSE); #endif /*===========================================*/ /* Create a string source router so that the */ /* string can be used as an input source. */ /*===========================================*/ if (OpenStringSource(theEnv,"build",theString,0) == 0) { return(FALSE); } /*================================*/ /* The first token of a construct */ /* must be a left parenthesis. */ /*================================*/ GetToken(theEnv,"build",&theToken); if (theToken.type != LPAREN) { CloseStringSource(theEnv,"build"); return(FALSE); } /*==============================================*/ /* The next token should be the construct type. */ /*==============================================*/ GetToken(theEnv,"build",&theToken); if (theToken.type != SYMBOL) { CloseStringSource(theEnv,"build"); return(FALSE); } constructType = ValueToString(theToken.value); /*======================*/ /* Parse the construct. */ /*======================*/ errorFlag = ParseConstruct(theEnv,constructType,"build"); /*=================================*/ /* Close the string source router. */ /*=================================*/ CloseStringSource(theEnv,"build"); /*=========================================*/ /* If an error occured while parsing the */ /* construct, then print an error message. */ /*=========================================*/ if (errorFlag == 1) { EnvPrintRouter(theEnv,WERROR,"\nERROR:\n"); PrintInChunks(theEnv,WERROR,GetPPBuffer(theEnv)); EnvPrintRouter(theEnv,WERROR,"\n"); } DestroyPPBuffer(theEnv); /*===============================================*/ /* Return TRUE if the construct was successfully */ /* parsed, otherwise return FALSE. */ /*===============================================*/ if (errorFlag == 0) return(TRUE); return(FALSE); }
bool RouteCommand( void *theEnv, const char *command, bool printResult) { DATA_OBJECT result; struct expr *top; const char *commandName; struct token theToken; int danglingConstructs; if (command == NULL) { return(0); } /*========================================*/ /* Open a string input source and get the */ /* first token from that source. */ /*========================================*/ OpenStringSource(theEnv,"command",command,0); GetToken(theEnv,"command",&theToken); /*=====================*/ /* Evaluate constants. */ /*=====================*/ if ((theToken.type == SYMBOL) || (theToken.type == STRING) || (theToken.type == FLOAT) || (theToken.type == INTEGER) || (theToken.type == INSTANCE_NAME)) { CloseStringSource(theEnv,"command"); if (printResult) { PrintAtom(theEnv,STDOUT,theToken.type,theToken.value); EnvPrintRouter(theEnv,STDOUT,"\n"); } return(1); } /*=====================*/ /* Evaluate variables. */ /*=====================*/ if ((theToken.type == GBL_VARIABLE) || (theToken.type == SF_VARIABLE) || (theToken.type == MF_VARIABLE)) { CloseStringSource(theEnv,"command"); top = GenConstant(theEnv,theToken.type,theToken.value); EvaluateExpression(theEnv,top,&result); rtn_struct(theEnv,expr,top); if (printResult) { PrintDataObject(theEnv,STDOUT,&result); EnvPrintRouter(theEnv,STDOUT,"\n"); } return(1); } /*========================================================*/ /* If the next token isn't the beginning left parenthesis */ /* of a command or construct, then whatever was entered */ /* cannot be evaluated at the command prompt. */ /*========================================================*/ if (theToken.type != LPAREN) { PrintErrorID(theEnv,"COMMLINE",1,false); EnvPrintRouter(theEnv,WERROR,"Expected a '(', constant, or variable\n"); CloseStringSource(theEnv,"command"); return(0); } /*===========================================================*/ /* The next token must be a function name or construct type. */ /*===========================================================*/ GetToken(theEnv,"command",&theToken); if (theToken.type != SYMBOL) { PrintErrorID(theEnv,"COMMLINE",2,false); EnvPrintRouter(theEnv,WERROR,"Expected a command.\n"); CloseStringSource(theEnv,"command"); return(0); } commandName = ValueToString(theToken.value); /*======================*/ /* Evaluate constructs. */ /*======================*/ #if (! RUN_TIME) && (! BLOAD_ONLY) { int errorFlag; errorFlag = ParseConstruct(theEnv,commandName,"command"); if (errorFlag != -1) { CloseStringSource(theEnv,"command"); if (errorFlag == 1) { EnvPrintRouter(theEnv,WERROR,"\nERROR:\n"); PrintInChunks(theEnv,WERROR,GetPPBuffer(theEnv)); EnvPrintRouter(theEnv,WERROR,"\n"); } DestroyPPBuffer(theEnv); if (errorFlag) return 0; else return 1; } } #endif /*========================*/ /* Parse a function call. */ /*========================*/ danglingConstructs = ConstructData(theEnv)->DanglingConstructs; CommandLineData(theEnv)->ParsingTopLevelCommand = true; top = Function2Parse(theEnv,"command",commandName); CommandLineData(theEnv)->ParsingTopLevelCommand = false; ClearParsedBindNames(theEnv); /*================================*/ /* Close the string input source. */ /*================================*/ CloseStringSource(theEnv,"command"); /*=========================*/ /* Evaluate function call. */ /*=========================*/ if (top == NULL) { ConstructData(theEnv)->DanglingConstructs = danglingConstructs; return false; } ExpressionInstall(theEnv,top); CommandLineData(theEnv)->EvaluatingTopLevelCommand = true; CommandLineData(theEnv)->CurrentCommand = top; EvaluateExpression(theEnv,top,&result); CommandLineData(theEnv)->CurrentCommand = NULL; CommandLineData(theEnv)->EvaluatingTopLevelCommand = false; ExpressionDeinstall(theEnv,top); ReturnExpression(theEnv,top); ConstructData(theEnv)->DanglingConstructs = danglingConstructs; /*=================================================*/ /* Print the return value of the function/command. */ /*=================================================*/ if ((result.type != RVOID) && printResult) { PrintDataObject(theEnv,STDOUT,&result); EnvPrintRouter(theEnv,STDOUT,"\n"); } return true; }
globle int LoadConstructsFromLogicalName( void *theEnv, char *readSource) { int constructFlag; struct token theToken; int noErrors = TRUE; int foundConstruct; /*=========================================*/ /* Reset the halt execution and evaluation */ /* error flags in preparation for parsing. */ /*=========================================*/ if (EvaluationData(theEnv)->CurrentEvaluationDepth == 0) SetHaltExecution(theEnv,FALSE); SetEvaluationError(theEnv,FALSE); /*========================================================*/ /* Find the beginning of the first construct in the file. */ /*========================================================*/ EvaluationData(theEnv)->CurrentEvaluationDepth++; GetToken(theEnv,readSource,&theToken); foundConstruct = FindConstructBeginning(theEnv,readSource,&theToken,FALSE,&noErrors); /*==================================================*/ /* Parse the file until the end of file is reached. */ /*==================================================*/ while ((foundConstruct == TRUE) && (GetHaltExecution(theEnv) == FALSE)) { /*===========================================================*/ /* Clear the pretty print buffer in preparation for parsing. */ /*===========================================================*/ FlushPPBuffer(theEnv); /*======================*/ /* Parse the construct. */ /*======================*/ constructFlag = ParseConstruct(theEnv,ValueToString(theToken.value),readSource); /*==============================================================*/ /* If an error occurred while parsing, then find the beginning */ /* of the next construct (but don't generate any more error */ /* messages--in effect, skip everything until another construct */ /* is found). */ /*==============================================================*/ if (constructFlag == 1) { EnvPrintRouter(theEnv,WERROR,"\nERROR:\n"); PrintInChunks(theEnv,WERROR,GetPPBuffer(theEnv)); EnvPrintRouter(theEnv,WERROR,"\n"); noErrors = FALSE; GetToken(theEnv,readSource,&theToken); foundConstruct = FindConstructBeginning(theEnv,readSource,&theToken,TRUE,&noErrors); } /*======================================================*/ /* Otherwise, find the beginning of the next construct. */ /*======================================================*/ else { GetToken(theEnv,readSource,&theToken); foundConstruct = FindConstructBeginning(theEnv,readSource,&theToken,FALSE,&noErrors); } /*=====================================================*/ /* Yield time if necessary to foreground applications. */ /*=====================================================*/ if (foundConstruct) { IncrementSymbolCount(theToken.value); } EvaluationData(theEnv)->CurrentEvaluationDepth--; PeriodicCleanup(theEnv,FALSE,TRUE); YieldTime(theEnv); EvaluationData(theEnv)->CurrentEvaluationDepth++; if (foundConstruct) { DecrementSymbolCount(theEnv,(SYMBOL_HN *) theToken.value); } } EvaluationData(theEnv)->CurrentEvaluationDepth--; /*========================================================*/ /* Print a carriage return if a single character is being */ /* printed to indicate constructs are being processed. */ /*========================================================*/ #if DEBUGGING_FUNCTIONS if ((EnvGetWatchItem(theEnv,"compilations") != TRUE) && GetPrintWhileLoading(theEnv)) #else if (GetPrintWhileLoading(theEnv)) #endif { EnvPrintRouter(theEnv,WDIALOG,"\n"); } /*=============================================================*/ /* Once the load is complete, destroy the pretty print buffer. */ /* This frees up any memory that was used to create the pretty */ /* print forms for constructs during parsing. Thus calls to */ /* the mem-used function will accurately reflect the amount of */ /* memory being used after a load command. */ /*=============================================================*/ DestroyPPBuffer(theEnv); /*==========================================================*/ /* Return a boolean flag which indicates whether any errors */ /* were encountered while loading the constructs. */ /*==========================================================*/ return(noErrors); }