Search in sources :

Example 1 with InferredType

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();
}
Also used : InferredType(org.lflang.InferredType) CodeBuilder(org.lflang.generator.CodeBuilder)

Example 2 with InferredType

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();
}
Also used : InferredType(org.lflang.InferredType) CodeBuilder(org.lflang.generator.CodeBuilder)

Aggregations

InferredType (org.lflang.InferredType)2 CodeBuilder (org.lflang.generator.CodeBuilder)2