-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
printf proof of concept #167
Comments
See #167 Need to troubleshoot when we send 2 slices to printf. It goes into an infinite loop. This commit introduces 4 builtin functions: * `@isInteger` * `@isFloat` * `@canImplictCast` * `@typeName`
Small example of the current thing preventing this from working: fn foo(b: bool) {
inline while (true) {
const result = if (b) false else true;
}
} The problem is that we generate basic blocks for the Then and Else parts of the if statement, since b is known at runtime.
When we analyze the EndIf basic block, we inline the goto back to the while condition since the while loop is inlined, so we put this in the new basic block:
We follow and inline the while body:
Now we're done inlining because we're going to branch to Then_12 or Else_13 based on a runtime value. And luckily we've already generated those basic blocks. So we're left with the analyzed IR:
So the EndIf block gets stuff inlined into it that maybe shouldn't be. At some point we need to have a separation of runtime and compile time. |
OK here's the idea I'm going to try. When a basic block inlines another basic block, for example the |
This code works now: const io = @import("std").io;
pub fn main(args: [][]u8) -> %void {
%%io.stdout.printf("hello\n");
%%io.stdout.printf("here is a number: {} and here is a string: {}\n", i32(1234), args[0]);
} |
What happened to |
|
Thank you! const stdoutFile = try std.io.getStdOut();
const stdout = &stdoutFile.outStream().stream;
stdout.print("hello!"); The problem I was having with
|
https://ziglang.org/documentation/master/#Hello-World using a stream for stdout is the right approach because it will force you to deal with errors writing to stdout. |
That link doesn't mention anything about streams or print |
This is the next big hurdle for Zig. It solves one of the most tricky use cases that we've been as yet unable to tackle elegantly:
printf
.This proposal changes the meaning of
inline
functions. It supersedes #132.With this proposal, marking a function
inline
tells the compiler to attempt to evaluate the function at compile time - to the extent possible. What it will do is, per callsite, codegen a unique LLVM function marked with thealwaysinline
attribute, and then begin to interpret the function at compile time. Obviously if any of the arguments are known at compile time, that makes this interpretation probably do more work.As Zig interprets the function, any expressions that cannot be interpreted, because they depend on runtime data or have runtime side effects, are emitted into the function's codegen.
Worst case scenario, nothing could be interpreted, and the function is codegened identical to a normal function, marked with the
alwaysinline
LLVM attribute.Best case scenario, large swaths of control structures and loops are eliminated and what is left is a series of straightforward expressions that LLVM can further optimize.
You can see how this is relevant for printf. This example uses variable argument functions (#77) which are not yet implemented, but you can see how they would work together.
The unique function zig would generate for
os.print("percent sign: %%, integer: %d, float: %f\n", a_u32_value, a_float_value)
while interpreting this function would look like:Careful readers will notice that this implementation could be more efficient if it figured out how to merge these strings together "percent sign: ", "%", and ", integer: ".
One can easily imagine how this concept would also be used to have compile time checked regular expressions. Make the
regex_execute
function inline with the regex string inline as well and the compiler does all the work.Semi related, we currently have
#attribute("noinline")
but let's move that to an actualnoinline
keyword that can be used in place ofinline
, for consistency.The text was updated successfully, but these errors were encountered: