/* * Returns a Type* given an AstNode*. */ Type * buildType(AstNode * n) { NameId *ident; Type *retval = NULL; /* * n can either be an INT_NODE, an ARRAY_NODE, or a NAMEID_NODE. */ if (n->type == INT_NODE) { retval = makeIntType(); } else if (n->type == ARRAY_NODE) { retval = (Type *) makeArrayType(buildType(((Array *) n)->child)); } else { assert(n->type == NAMEID_NODE); ident = (NameId *) n; retval = (Type *) getClass(ident->name); if (retval == NULL) { error("class name expected", &ident->super); retval = makeErrorType(); } } return retval; }
/* * Returns a list of arrays given a declarator. */ Type * getDims(AstNode * n) { if (n == NULL) return NULL; switch (n->type) { case ARRAY_NODE: return (Type *) makeArrayType(getDims(((Array *) n)->child)); default: return NULL; } }
Type* compileType(void) { Type* type; Type* elementType; int arraySize; Object* obj; switch (lookAhead->tokenType) { case KW_INTEGER: eat(KW_INTEGER); type = makeIntType(); break; case KW_CHAR: eat(KW_CHAR); type = makeCharType(); break; case KW_STRING: eat(KW_STRING); type=makeStringType(); break; case KW_FLOAT: eat(KW_FLOAT); type=makeFloatType(); break; case KW_ARRAY: eat(KW_ARRAY); eat(SB_LSEL); eat(TK_NUMBER); arraySize = currentToken->value; eat(SB_RSEL); eat(KW_OF); elementType = compileType(); type = makeArrayType(arraySize, elementType); break; case TK_IDENT: eat(TK_IDENT); obj = checkDeclaredType(currentToken->string); type = duplicateType(obj->typeAttrs->actualType); break; default: error(ERR_INVALID_TYPE, lookAhead->lineNo, lookAhead->colNo); break; } return type; }
Type* compileType(void) { Type* type; Type* elementType; int arraySize; Object* obj; switch (lookAhead->tokenType) { case KW_INTEGER: eat(KW_INTEGER); type = makeIntType(); break; case KW_CHAR: eat(KW_CHAR); type = makeCharType(); break; case KW_ARRAY: eat(KW_ARRAY); eat(SB_LSEL); eat(TK_NUMBER); arraySize = currentToken->value; eat(SB_RSEL); eat(KW_OF); elementType = compileType(); type = makeArrayType(arraySize, elementType); break; case TK_IDENT: eat(TK_IDENT); // check if the type identifier is declared and get its actual type obj = checkDeclaredType(currentToken->string); if (obj != NULL) type = duplicateType(obj->typeAttrs->actualType); else error(ERR_UNDECLARED_TYPE, currentToken->colNo, currentToken->lineNo); break; default: error(ERR_INVALID_TYPE, lookAhead->lineNo, lookAhead->colNo); break; } return type; }
Type* compileType(void) { Type* type; Type* elementType; int arraySize; Object* obj; switch (lookAhead->tokenType) { case KW_INTEGER: eat(KW_INTEGER); type = makeIntType(); break; case KW_CHAR: eat(KW_CHAR); type = makeCharType(); break; case KW_ARRAY: eat(KW_ARRAY); eat(SB_LSEL); eat(TK_NUMBER); arraySize = currentToken->value; eat(SB_RSEL); eat(KW_OF); elementType = compileType(); type = makeArrayType(arraySize, elementType); break; case TK_IDENT: eat(TK_IDENT); // TODO: check if the type idntifier is declared and get its actual type break; default: error(ERR_INVALID_TYPE, lookAhead->lineNo, lookAhead->colNo); break; } return type; }
int main() { Object* obj; initSymTab(); obj = createProgramObject("PRG"); enterBlock(obj->progAttrs->scope); obj = createConstantObject("c1"); obj->constAttrs->value = makeIntConstant(10); declareObject(obj); obj = createConstantObject("c2"); obj->constAttrs->value = makeCharConstant('a'); declareObject(obj); obj = createTypeObject("t1"); obj->typeAttrs->actualType = makeArrayType(10, makeIntType()); declareObject(obj); obj = createVariableObject("v1"); obj->varAttrs->type = makeIntType(); declareObject(obj); obj = createVariableObject("v2"); obj->varAttrs->type = makeArrayType(10, makeArrayType(10, makeIntType())); declareObject(obj); obj = createFunctionObject("f"); obj->funcAttrs->returnType = makeIntType(); declareObject(obj); enterBlock(obj->funcAttrs->scope); obj = createParameterObject("p1", PARAM_VALUE, symtab->currentScope->owner); obj->paramAttrs->type = makeIntType(); declareObject(obj); obj = createParameterObject("p2", PARAM_REFERENCE, symtab->currentScope->owner); obj->paramAttrs->type = makeCharType(); declareObject(obj); exitBlock(); obj = createProcedureObject("p"); declareObject(obj); enterBlock(obj->procAttrs->scope); obj = createParameterObject("v1", PARAM_VALUE, symtab->currentScope->owner); obj->paramAttrs->type = makeIntType(); declareObject(obj); obj = createConstantObject("c1"); obj->constAttrs->value = makeCharConstant('a'); declareObject(obj); obj = createConstantObject("c3"); obj->constAttrs->value = makeIntConstant(10); declareObject(obj); obj = createTypeObject("t1"); obj->typeAttrs->actualType = makeIntType(); declareObject(obj); obj = createTypeObject("t2"); obj->typeAttrs->actualType = makeArrayType(10, makeIntType()); declareObject(obj); obj = createVariableObject("v2"); obj->varAttrs->type = makeArrayType(10, makeIntType()); declareObject(obj); obj = createVariableObject("v3"); obj->varAttrs->type = makeCharType(); declareObject(obj); exitBlock(); exitBlock(); printObject(symtab->program, 0); cleanSymTab(); return 0; }
IHqlExpression * HqlCppCaseInfo::buildIndexedMap(BuildCtx & ctx, const CHqlBoundExpr & test) { ITypeInfo * compareType = test.queryType()->queryPromotedType(); type_t compareTypeCode = compareType->getTypeCode(); HqlExprArray values; IHqlExpression * dft = queryActiveTableSelector(); // value doesn't matter as long as it will not occur __int64 lower = getIntValue(lowerTableBound, 0); unsigned num = (getIntValue(upperTableBound, 0)-lower)+1; CHqlBoundExpr indexExpr; switch (compareTypeCode) { case type_int: indexExpr.set(test); break; case type_string: indexExpr.expr.setown(createValue(no_index, makeCharType(), LINK(test.expr), getZero())); indexExpr.expr.setown(createValue(no_cast, makeIntType(1, false), LINK(indexExpr.expr))); break; default: throwUnexpectedType(compareType); } if (useRangeIndex && (num != 1)) translator.ensureSimpleExpr(ctx, indexExpr); OwnedHqlExpr mapped; ITypeInfo * retType = resultType; //if num == pairs.ordinality() and all results are identical, avoid the table lookup. if (allResultsMatch && (num == pairs.ordinality())) { mapped.set(pairs.item(0).queryChild(1)); } else { values.ensure(num); unsigned idx; for (idx = 0; idx < num; idx++) values.append(*LINK(dft)); ForEachItemIn(idx2, pairs) { IHqlExpression & cur = pairs.item(idx2); IValue * value = cur.queryChild(0)->queryValue(); unsigned replaceIndex; switch (compareTypeCode) { case type_int: replaceIndex = (unsigned)(value->getIntValue()-lower); break; case type_string: { StringBuffer temp; value->getStringValue(temp); replaceIndex = (unsigned)((unsigned char)temp.charAt(0)-lower); break; } default: throwUnexpectedType(compareType); } IHqlExpression * mapTo = cur.queryChild(1); if (mapTo->getOperator() != no_constant) throwUnexpected(); if (replaceIndex >= num) translator.reportWarning(CategoryIgnored, HQLWRN_CaseCanNeverMatch, "CASE entry %d can never match the test condition", replaceIndex); else values.replace(*LINK(mapTo),replaceIndex); } //Now replace the placeholders with the default values. for (idx = 0; idx < num; idx++) { if (&values.item(idx) == dft) values.replace(*defaultValue.getLink(),idx); } // use a var string type to get better C++ generated... ITypeInfo * storeType = getArrayElementType(resultType); ITypeInfo * listType = makeArrayType(storeType, values.ordinality()); OwnedHqlExpr lvalues = createValue(no_list, listType, values); CHqlBoundExpr boundTable; translator.buildExpr(ctx, lvalues, boundTable); LinkedHqlExpr tableIndex = indexExpr.expr; if (getIntValue(lowerTableBound, 0)) tableIndex.setown(createValue(no_sub, tableIndex->getType(), LINK(tableIndex), LINK(lowerTableBound))); IHqlExpression * ret = createValue(no_index, LINK(retType), LINK(boundTable.expr), LINK(tableIndex)); mapped.setown(createTranslatedOwned(ret)); }