//! Possible call target node types: //! - SymbolASTNode //! - ExprASTNode //! //! Possible call argument node types: //! - ExprASTNode //! - NULL OperationSequence * ConversionController::convertCallStatement(CallStatementASTNode * statement) { ExecuteOperation * op = NULL; try { // create operation from AST nodes op = new ExecuteOperation(); bool isHAB = statement->isHAB(); op->setTarget(createTargetFromNode(statement->getTarget())); // set argument value, which defaults to 0 if no expression was provided uint32_t arg = 0; ASTNode * argNode = statement->getArgument(); if (argNode) { ExprASTNode * argExprNode = dynamic_cast<ExprASTNode*>(argNode); if (!argExprNode) { throw semantic_error(format_string("line %d: call argument is unexpected type", argNode->getFirstLine())); } argExprNode = argExprNode->reduce(m_context); IntConstExprASTNode * intNode = dynamic_cast<IntConstExprASTNode*>(argExprNode); if (!intNode) { throw semantic_error(format_string("line %d: call argument did not evaluate to an integer", argExprNode->getFirstLine())); } arg = intNode->getValue(); } op->setArgument(arg); // set call type switch (statement->getCallType()) { case CallStatementASTNode::kCallType: op->setExecuteType(ExecuteOperation::kCall); break; case CallStatementASTNode::kJumpType: op->setExecuteType(ExecuteOperation::kJump); break; } // Set the HAB mode flag. op->setIsHAB(isHAB); return new OperationSequence(op); } catch (...) { // delete op and rethrow exception if (op) { delete op; } throw; } }
//! @param node The AST node instance for the assignment expression. //! @param[out] ident Upon exit this string will be set the the left hand side of the //! assignment expression, the identifier name. //! //! @return An object that is a subclass of Value is returned. The specific subclass will //! depend on the type of the right hand side of the assignment expression whose AST //! node was provided in the @a node argument. //! //! @exception semantic_error Thrown for any error where an AST node is an unexpected type. //! This may be the @a node argument itself, if it is not an AssignmentASTNode. Or it //! may be an unexpected type for either the right or left hand side of the assignment. //! The message for the exception will contain a description of the error. Value * ConversionController::convertAssignmentNodeToValue(ASTNode * node, std::string & ident) { Value * resultValue = NULL; // each item of the options list should be an assignment node AssignmentASTNode * assignmentNode = dynamic_cast<AssignmentASTNode*>(node); if (!node) { throw semantic_error(format_string("line %d: node is wrong type", assignmentNode->getFirstLine())); } // save the left hand side (the identifier) into ident ident = *assignmentNode->getIdent(); // get the right hand side and convert it to a Value instance ASTNode * valueNode = assignmentNode->getValue(); StringConstASTNode * str; ExprASTNode * expr; if (str = dynamic_cast<StringConstASTNode*>(valueNode)) { // the option value is a string constant resultValue = new StringValue(str->getString()); //#if PRINT_VALUES // Log::log("option %s => \'%s\'\n", ident->c_str(), str->getString()->c_str()); //#endif } else if (expr = dynamic_cast<ExprASTNode*>(valueNode)) { ExprASTNode * reducedExpr = expr->reduce(m_context); IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(reducedExpr); if (!intConst) { throw semantic_error(format_string("line %d: expression didn't evaluate to an integer", expr->getFirstLine())); } //#if PRINT_VALUES // Log::log("option "); // printIntConstExpr(*ident, intConst); //#endif resultValue = new SizedIntegerValue(intConst->getValue(), intConst->getSize()); } else { throw semantic_error(format_string("line %d: right hand side node is an unexpected type", valueNode->getFirstLine())); } return resultValue; }
DataSource * ConversionController::createIVTDataSource(IVTConstASTNode * ivtNode) { IVTDataSource * source = new IVTDataSource; // Iterate over the assignment statements in the IVT definition. ListASTNode * fieldList = ivtNode->getFieldAssignments(); if (fieldList) { ListASTNode::iterator it = fieldList->begin(); for (; it != fieldList->end(); ++it) { AssignmentASTNode * assignmentNode = dynamic_cast<AssignmentASTNode*>(*it); if (!assignmentNode) { throw std::runtime_error(format_string("line %d: unexpected node type in IVT definition", (*it)->getFirstLine())); } // Get the IVT field name. std::string * fieldName = assignmentNode->getIdent(); // Reduce the field expression and get the integer result. ASTNode * valueNode = assignmentNode->getValue(); ExprASTNode * valueExpr = dynamic_cast<ExprASTNode*>(valueNode); if (!valueExpr) { throw semantic_error("IVT field must have a valid expression"); } IntConstExprASTNode * valueIntExpr = dynamic_cast<IntConstExprASTNode*>(valueExpr->reduce(m_context)); if (!valueIntExpr) { throw semantic_error(format_string("line %d: IVT field '%s' does not evaluate to an integer", valueNode->getFirstLine(), fieldName->c_str())); } uint32_t value = static_cast<uint32_t>(valueIntExpr->getValue()); // Set the field in the IVT data source. if (!source->setFieldByName(*fieldName, value)) { throw semantic_error(format_string("line %d: unknown IVT field '%s'", assignmentNode->getFirstLine(), fieldName->c_str())); } } } return source; }