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
|
Example
=======
This page contains an example that illustrates how to generate code in the Intermediate Language,
how to compile the listing to machine code using a function, and then how to execute the function.
```bs
use core:asm; // For code generation.
use core:lang; // For Function, Value, DynamicCode
use lang:bs:macro; // For named{} syntax
void callFromIR(Int param) {
print("Called from IR: ${param}");
}
Listing createListing() on Compiler {
// Create a non-member function that returns an integer.
Listing l(false, intDesc);
// It accepts a single parameter:
Var param = l.createParam(intDesc);
// Start generating code by emitting the prolog:
l << prolog;
// Double the parameter to the function:
l << mul(param, intConst(2));
// Call 'callFromIR':
var toCall = named{callFromIR<Int>};
l << fnParam(intDesc, param);
l << fnCall(toCall.ref, false);
// Add 5 and return it.
l << add(param, intConst(5));
l << fnRet(param);
print("Generated code:\n" + l.toS);
return l;
}
void main() on Compiler {
// Create a Function (a named entity) with a matching signature.
Value intVal(named{Int});
Function f(intVal, "f", [intVal]);
// Set its parent lookup to allow it to work properly. We could
// also add it to the name tree. This is enough to make it
// look like it is a member of the main function.
f.parentLookup = named{main};
// Set the code to our generated Listing. The DynamicCode
// compiles the listing into a Binary and associates it with
// the RefSource inside the function.
f.setCode(DynamicCode(createListing));
// Extract a pointer to the function and call it.
if (ptr = f.pointer() as Fn<Int, Int>) {
print("Calling the generated function...");
Int result = ptr.call(10);
print("Done. It returned: ${result}");
}
}
```
|