TypePtr doType (void) { switch (curToken) { case TKN_IDENTIFIER: { SymTableNodePtr idPtr; searchAllSymTables(idPtr); if (!idPtr) { syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER); return(NULL); } else if (idPtr->defn.key == DFN_TYPE) { //---------------------------------------------------------- // NOTE: Array types should be parsed in this case if a left // bracket follows the type identifier. TypePtr elementType = setType(identifierType(idPtr)); if (curToken == TKN_LBRACKET) { //-------------- // Array type... TypePtr typePtr = createType(); if (!typePtr) ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc array type "); TypePtr elementTypePtr = typePtr; do { getToken(); if (tokenIn(indexTypeStartList)) { elementTypePtr->form = FRM_ARRAY; elementTypePtr->size = 0; elementTypePtr->typeIdPtr = NULL; //---------------------------------------------- // All array indices must be integer, for now... elementTypePtr->info.array.indexTypePtr = setType(IntegerTypePtr); //------------------------ // Read the index count... switch (curToken) { case TKN_NUMBER: if (curLiteral.type == LIT_INTEGER) elementTypePtr->info.array.elementCount = curLiteral.value.integer; else { elementTypePtr->form = FRM_NONE; elementTypePtr->size = 0; elementTypePtr->typeIdPtr = NULL; elementTypePtr->info.array.indexTypePtr = NULL; syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE); } getToken(); break; case TKN_IDENTIFIER: { SymTableNodePtr idPtr; searchAllSymTables(idPtr); if (idPtr == NULL) syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER); else if (idPtr->defn.key == DFN_CONST) { if (idPtr->typePtr == IntegerTypePtr) elementTypePtr->info.array.elementCount = idPtr->defn.info.constant.value.integer; else { elementTypePtr->form = FRM_NONE; elementTypePtr->size = 0; elementTypePtr->typeIdPtr = NULL; elementTypePtr->info.array.indexTypePtr = NULL; syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE); } } else { elementTypePtr->form = FRM_NONE; elementTypePtr->size = 0; elementTypePtr->typeIdPtr = NULL; elementTypePtr->info.array.indexTypePtr = NULL; syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE); } getToken(); } break; default: elementTypePtr->form = FRM_NONE; elementTypePtr->size = 0; elementTypePtr->typeIdPtr = NULL; elementTypePtr->info.array.indexTypePtr = NULL; syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE); getToken(); } } else { elementTypePtr->form = FRM_NONE; elementTypePtr->size = 0; elementTypePtr->typeIdPtr = NULL; elementTypePtr->info.array.indexTypePtr = NULL; syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE); getToken(); } synchronize(followDimensionList, NULL, NULL); //-------------------------------- // Create an array element type... if (curToken == TKN_COMMA) { elementTypePtr = elementTypePtr->info.array.elementTypePtr = createType(); if (!elementTypePtr) ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc array element Type "); } } while (curToken == TKN_COMMA); ifTokenGetElseError(TKN_RBRACKET, ABL_ERR_SYNTAX_MISSING_RBRACKET); elementTypePtr->info.array.elementTypePtr = elementType; typePtr->size = arraySize(typePtr); elementType = typePtr; } return(elementType); } else { syntaxError(ABL_ERR_SYNTAX_NOT_A_TYPE_IDENTIFIER); return(NULL); } } break; case TKN_LPAREN: return(enumerationType()); default: syntaxError(ABL_ERR_SYNTAX_INVALID_TYPE); return(NULL); } }
TypePtr caseLabel (CaseItemPtr& caseItemHead, CaseItemPtr& caseItemTail, long& caseLabelCount) { CaseItemPtr newCaseItem = (CaseItemPtr)ABLStackMallocCallback(sizeof(CaseItem)); if (!newCaseItem) ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc case item "); if (caseItemHead) { caseItemTail->next = newCaseItem; caseItemTail = newCaseItem; } else caseItemHead = caseItemTail = newCaseItem; newCaseItem->next = NULL; caseLabelCount++; TokenCodeType sign = TKN_PLUS; bool sawSign = false; if ((curToken == TKN_PLUS) || (curToken == TKN_MINUS)) { sign = curToken; sawSign = true; getToken(); } if (curToken == TKN_NUMBER) { SymTableNodePtr thisNode = searchSymTable(tokenString, SymTableDisplay[1]); if (!thisNode) thisNode = enterSymTable(tokenString, &SymTableDisplay[1]); crunchSymTableNodePtr(thisNode); if (curLiteral.type == LIT_INTEGER) newCaseItem->labelValue = (sign == TKN_PLUS) ? curLiteral.value.integer : -curLiteral.value.integer; else syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT); return(IntegerTypePtr); } else if (curToken == TKN_IDENTIFIER) { SymTableNodePtr idPtr; searchAllSymTables(idPtr); crunchSymTableNodePtr(idPtr); if (!idPtr) { syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER); return(&DummyType); } else if (idPtr->defn.key != DFN_CONST) { syntaxError(ABL_ERR_SYNTAX_NOT_A_CONSTANT_IDENTIFIER); return(&DummyType); } else if (idPtr->typePtr == IntegerTypePtr) { newCaseItem->labelValue = (sign == TKN_PLUS ? idPtr->defn.info.constant.value.integer : -idPtr->defn.info.constant.value.integer); return(IntegerTypePtr); } else if (idPtr->typePtr == CharTypePtr) { if (sawSign) syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT); newCaseItem->labelValue = idPtr->defn.info.constant.value.character; return(CharTypePtr); } else if (idPtr->typePtr->form == FRM_ENUM) { if (sawSign) syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT); newCaseItem->labelValue = idPtr->defn.info.constant.value.integer; return(idPtr->typePtr); } else return(&DummyType); } else if (curToken == TKN_STRING) { // STRING/CHAR TYPE... } else { syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT); return(&DummyType); } return(&DummyType); }
void doConst (SymTableNodePtr constantIdPtr) { TokenCodeType sign = TKN_PLUS; bool sawSign = false; if ((curToken == TKN_PLUS) || (curToken == TKN_MINUS)) { sign = curToken; sawSign = true; getToken(); } //---------------------------------- // Numeric constant: real or integer if (curToken == TKN_NUMBER) { if (curLiteral.type == LIT_INTEGER) { if (sign == TKN_PLUS) constantIdPtr->defn.info.constant.value.integer = curLiteral.value.integer; else constantIdPtr->defn.info.constant.value.integer = -(curLiteral.value.integer); constantIdPtr->typePtr = setType(IntegerTypePtr); } else { if (sign == TKN_PLUS) constantIdPtr->defn.info.constant.value.real = curLiteral.value.real; else constantIdPtr->defn.info.constant.value.real = -(curLiteral.value.real); constantIdPtr->typePtr = setType(RealTypePtr); } } else if (curToken == TKN_IDENTIFIER) { SymTableNodePtr idPtr = NULL; searchAllSymTables(idPtr); if (!idPtr) syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER); else if (idPtr->defn.key != DFN_CONST) syntaxError(ABL_ERR_SYNTAX_NOT_A_CONSTANT_IDENTIFIER); else if (idPtr->typePtr == IntegerTypePtr) { if (sign == TKN_PLUS) constantIdPtr->defn.info.constant.value.integer = idPtr->defn.info.constant.value.integer; else constantIdPtr->defn.info.constant.value.integer = -(idPtr->defn.info.constant.value.integer); constantIdPtr->typePtr = setType(IntegerTypePtr); } else if (idPtr->typePtr == CharTypePtr) { if (sawSign) syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT); constantIdPtr->defn.info.constant.value.character = idPtr->defn.info.constant.value.character; constantIdPtr->typePtr = setType(CharTypePtr); } else if (idPtr->typePtr == RealTypePtr) { if (sign == TKN_PLUS) constantIdPtr->defn.info.constant.value.real = idPtr->defn.info.constant.value.real; else constantIdPtr->defn.info.constant.value.real = -(idPtr->defn.info.constant.value.real); constantIdPtr->typePtr = setType(RealTypePtr); } else if (((Type*)(idPtr->typePtr))->form == FRM_ENUM) { if (sawSign) syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT); constantIdPtr->defn.info.constant.value.integer = idPtr->defn.info.constant.value.integer; constantIdPtr->typePtr = setType(idPtr->typePtr); } else if (((TypePtr)(idPtr->typePtr))->form == FRM_ARRAY) { if (sawSign) syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT); constantIdPtr->defn.info.constant.value.stringPtr = idPtr->defn.info.constant.value.stringPtr; constantIdPtr->typePtr = setType(idPtr->typePtr); } } else if (curToken == TKN_STRING) { if (sawSign) syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT); if (strlen(curLiteral.value.string) == 1) { constantIdPtr->defn.info.constant.value.character = curLiteral.value.string[0]; constantIdPtr->typePtr = setType(CharTypePtr); } else { long length = strlen(curLiteral.value.string); constantIdPtr->defn.info.constant.value.stringPtr = (char*)ABLSymbolMallocCallback(length + 1); if (!constantIdPtr->defn.info.constant.value.stringPtr) ABL_Fatal(0, " ABL: Unable to AblSymbolHeap->malloc array string constant "); strcpy(constantIdPtr->defn.info.constant.value.stringPtr, curLiteral.value.string); constantIdPtr->typePtr = makeStringType(length); } } else { constantIdPtr->typePtr = NULL; syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT); } getToken(); }