use of org.lflang.InferredType in project lingua-franca by lf-lang.
the class CReactionGenerator method generateInputVariablesInReaction.
/**
* Generate into the specified string builder the code to
* initialize local variables for the specified input port
* in a reaction function from the "self" struct.
* @param builder The string builder.
* @param input The input statement from the AST.
* @param reactor The reactor.
*/
private static String generateInputVariablesInReaction(Input input, ReactorDecl decl, CTypes types) {
String structType = CGenerator.variableStructType(input, decl).toString();
InferredType inputType = ASTUtils.getInferredType(input);
CodeBuilder builder = new CodeBuilder();
String inputName = input.getName();
String inputWidth = generateWidthVariable(inputName);
// Easy case first.
if (!input.isMutable() && !CUtil.isTokenType(inputType, types) && !ASTUtils.isMultiport(input)) {
// Non-mutable, non-multiport, primitive type.
builder.pr(structType + "* " + inputName + " = self->_lf_" + inputName + ";");
} else if (input.isMutable() && !CUtil.isTokenType(inputType, types) && !ASTUtils.isMultiport(input)) {
// Mutable, non-multiport, primitive type.
builder.pr(String.join("\n", "// Mutable input, so copy the input into a temporary variable.", "// The input value on the struct is a copy.", structType + " _lf_tmp_" + inputName + " = *(self->_lf_" + inputName + ");", structType + "* " + inputName + " = &_lf_tmp_" + inputName + ";"));
} else if (!input.isMutable() && CUtil.isTokenType(inputType, types) && !ASTUtils.isMultiport(input)) {
// Non-mutable, non-multiport, token type.
builder.pr(String.join("\n", structType + "* " + inputName + " = self->_lf_" + inputName + ";", "if (" + inputName + "->is_present) {", " " + inputName + "->length = " + inputName + "->token->length;", " " + inputName + "->value = (" + types.getTargetType(inputType) + ")" + inputName + "->token->value;", "} else {", " " + inputName + "->length = 0;", "}"));
} else if (input.isMutable() && CUtil.isTokenType(inputType, types) && !ASTUtils.isMultiport(input)) {
// Mutable, non-multiport, token type.
builder.pr(String.join("\n", "// Mutable input, so copy the input struct into a temporary variable.", structType + " _lf_tmp_" + inputName + " = *(self->_lf_" + inputName + ");", structType + "* " + inputName + " = &_lf_tmp_" + inputName + ";", "if (" + inputName + "->is_present) {", " " + inputName + "->length = " + inputName + "->token->length;", " lf_token_t* _lf_input_token = " + inputName + "->token;", " " + inputName + "->token = writable_copy(_lf_input_token);", " if (" + inputName + "->token != _lf_input_token) {", " // A copy of the input token has been made.", " // This needs to be reference counted.", " " + inputName + "->token->ref_count = 1;", " // Repurpose the next_free pointer on the token to add to the list.", " " + inputName + "->token->next_free = _lf_more_tokens_with_ref_count;", " _lf_more_tokens_with_ref_count = " + inputName + "->token;", " }", " " + inputName + "->value = (" + types.getTargetType(inputType) + ")" + inputName + "->token->value;", "} else {", " " + inputName + "->length = 0;", "}"));
} else if (!input.isMutable() && ASTUtils.isMultiport(input)) {
// Non-mutable, multiport, primitive or token type.
builder.pr(structType + "** " + inputName + " = self->_lf_" + inputName + ";");
} else if (CUtil.isTokenType(inputType, types)) {
// Mutable, multiport, token type
builder.pr(String.join("\n", "// Mutable multiport input, so copy the input structs", "// into an array of temporary variables on the stack.", structType + " _lf_tmp_" + inputName + "[" + CUtil.multiportWidthExpression(input) + "];", structType + "* " + inputName + "[" + CUtil.multiportWidthExpression(input) + "];", "for (int i = 0; i < " + CUtil.multiportWidthExpression(input) + "; i++) {", " " + inputName + "[i] = &_lf_tmp_" + inputName + "[i];", " _lf_tmp_" + inputName + "[i] = *(self->_lf_" + inputName + "[i]);", " // If necessary, copy the tokens.", " if (" + inputName + "[i]->is_present) {", " " + inputName + "[i]->length = " + inputName + "[i]->token->length;", " lf_token_t* _lf_input_token = " + inputName + "[i]->token;", " " + inputName + "[i]->token = writable_copy(_lf_input_token);", " if (" + inputName + "[i]->token != _lf_input_token) {", " // A copy of the input token has been made.", " // This needs to be reference counted.", " " + inputName + "[i]->token->ref_count = 1;", " // Repurpose the next_free pointer on the token to add to the list.", " " + inputName + "[i]->token->next_free = _lf_more_tokens_with_ref_count;", " _lf_more_tokens_with_ref_count = " + inputName + "[i]->token;", " }", " " + inputName + "[i]->value = (" + types.getTargetType(inputType) + ")" + inputName + "[i]->token->value;", " } else {", " " + inputName + "[i]->length = 0;", " }", "}"));
} else {
// Mutable, multiport, primitive type
builder.pr(String.join("\n", "// Mutable multiport input, so copy the input structs", "// into an array of temporary variables on the stack.", structType + " _lf_tmp_" + inputName + "[" + CUtil.multiportWidthExpression(input) + "];", structType + "* " + inputName + "[" + CUtil.multiportWidthExpression(input) + "];", "for (int i = 0; i < " + CUtil.multiportWidthExpression(input) + "; i++) {", " " + inputName + "[i] = &_lf_tmp_" + inputName + "[i];", " // Copy the struct, which includes the value.", " _lf_tmp_" + inputName + "[i] = *(self->_lf_" + inputName + "[i]);", "}"));
}
// Set the _width variable for all cases. This will be -1
// for a variable-width multiport, which is not currently supported.
// It will be -2 if it is not multiport.
builder.pr("int " + inputWidth + " = self->_lf_" + inputWidth + ";");
return builder.toString();
}
use of org.lflang.InferredType in project lingua-franca by lf-lang.
the class CReactionGenerator method generateActionVariablesInReaction.
/**
* Generate action variables for a reaction.
* @param builder Where to write the code.
* @param action The action.
* @param reactor The reactor.
*/
private static String generateActionVariablesInReaction(Action action, ReactorDecl decl, CTypes types) {
String structType = CGenerator.variableStructType(action, decl).toString();
// If the action has a type, create variables for accessing the value.
InferredType type = ASTUtils.getInferredType(action);
// Pointer to the lf_token_t sent as the payload in the trigger.
String tokenPointer = "(self->_lf__" + action.getName() + ".token)";
CodeBuilder builder = new CodeBuilder();
builder.pr(String.join("\n", "// Expose the action struct as a local variable whose name matches the action name.", structType + "* " + action.getName() + " = &self->_lf_" + action.getName() + ";", "// Set the fields of the action struct to match the current trigger.", action.getName() + "->is_present = (bool)self->_lf__" + action.getName() + ".status;", action.getName() + "->has_value = (" + tokenPointer + " != NULL && " + tokenPointer + "->value != NULL);", action.getName() + "->token = " + tokenPointer + ";"));
// Set the value field only if there is a type.
if (!type.isUndefined()) {
// The value field will either be a copy (for primitive types)
// or a pointer (for types ending in *).
builder.pr("if (" + action.getName() + "->has_value) {");
builder.indent();
if (CUtil.isTokenType(type, types)) {
builder.pr(action.getName() + "->value = (" + types.getTargetType(type) + ")" + tokenPointer + "->value;");
} else {
builder.pr(action.getName() + "->value = *(" + types.getTargetType(type) + "*)" + tokenPointer + "->value;");
}
builder.unindent();
builder.pr("}");
}
return builder.toString();
}
Aggregations