Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | 12x 694x 694x 694x 694x 694x 694x 694x 694x 694x 694x 694x 694x 694x 678x 678x 678x 678x 678x 678x 678x 3x 3x 3x 675x | /**
* FunctionGenerator - Function Declaration Generation
*
* Generates C function declarations from C-Next function syntax.
*
* Example:
* fn add(i32 a, i32 b) -> i32 { return a + b; }
* ->
* int32_t add(int32_t* a, int32_t* b) { return *a + *b; }
*
* ADR-006: Pass-by-reference semantics for non-array, non-float parameters.
* ADR-029: Callback typedef generation for functions used as types.
*/
import * as Parser from "../../../../logic/parser/grammar/CNextParser";
import IGeneratorInput from "../IGeneratorInput";
import IGeneratorState from "../IGeneratorState";
import IGeneratorOutput from "../IGeneratorOutput";
import IOrchestrator from "../IOrchestrator";
import TGeneratorFn from "../TGeneratorFn";
/**
* Generate a C function from a C-Next function declaration.
*
* Handles:
* - Return type generation
* - Parameter generation with ADR-006 pointer semantics
* - Main function special cases (args parameter, int return type)
* - Callback typedef generation (ADR-029)
*/
const generateFunction: TGeneratorFn<Parser.FunctionDeclarationContext> = (
node: Parser.FunctionDeclarationContext,
_input: IGeneratorInput,
_state: IGeneratorState,
orchestrator: IOrchestrator,
): IGeneratorOutput => {
const returnType = orchestrator.generateType(node.type());
const name = node.IDENTIFIER().getText();
// Issue #269: Set current function name for pass-by-value lookup
orchestrator.setCurrentFunctionName(name);
// Issue #477: Set return type for enum inference in return statements
orchestrator.setCurrentFunctionReturnType(node.type().getText());
// Track parameters for ADR-006 pointer semantics
orchestrator.setParameters(node.parameterList() ?? null);
// ADR-016: Clear local variables and mark that we're in a function body
orchestrator.enterFunctionBody();
// Check for main function with args parameter (u8 args[][] or string args[])
const isMainWithArgs = orchestrator.isMainFunctionWithArgs(
name,
node.parameterList(),
);
let params: string = ""; // Will be set below
let actualReturnType: string;
// Issue #268: Generate body FIRST to track parameter modifications,
// then generate parameter list using that tracking info
Iif (isMainWithArgs) {
// Special case: main(u8 args[][]) -> int main(int argc, char *argv[])
actualReturnType = "int";
params = "int argc, char *argv[]";
// Store the args parameter name for translation in the body
const argsParam = node.parameterList()!.parameter()[0];
orchestrator.setMainArgsName(argsParam.IDENTIFIER().getText());
} else {
// For main() without args, always use int return type for C++ compatibility
actualReturnType = name === "main" ? "int" : returnType;
}
// Generate body first (this populates modifiedParameters)
const body = orchestrator.generateBlock(node.block());
// Issue #268: Update symbol's parameter info with auto-const before clearing
orchestrator.updateFunctionParamsAutoConst(name);
// Now generate parameter list (can use modifiedParameters for auto-const)
if (!isMainWithArgs) {
params = node.parameterList()
? orchestrator.generateParameterList(node.parameterList()!)
: "void";
}
// ADR-016: Clear local variables and mark that we're no longer in a function body
orchestrator.exitFunctionBody();
orchestrator.setCurrentFunctionName(null); // Issue #269: Clear function name
orchestrator.setCurrentFunctionReturnType(null); // Issue #477: Clear return type
orchestrator.clearParameters();
const functionCode = `${actualReturnType} ${name}(${params}) ${body}\n`;
// ADR-029: Generate callback typedef only if this function is used as a type
if (name !== "main" && orchestrator.isCallbackTypeUsedAsFieldType(name)) {
const typedef = orchestrator.generateCallbackTypedef(name);
Eif (typedef) {
return {
code: functionCode + typedef,
effects: [],
};
}
}
return {
code: functionCode,
effects: [],
};
};
export default generateFunction;
|