-
Notifications
You must be signed in to change notification settings - Fork 18
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
Types from beginning to end #37
Conversation
I forgot we have special ways to do that now
It seems that if we handle the case of loading an array turning into it's pointer, then we should be okay? |
So, there appears to be some issue with incomplete types now. Luckily, it seems like it's just that the typechecker isn't catching this, and codegen is choking on the incomplete type (the type with zero byte size). |
At this point, it is by no means perfect, but I'd say we have fully implemented types in the IR, all the way from beginning to end. So maybe it's becoming time to merge this PR very soon |
"Failing" tests:
|
I'd say it's much easier to see how subscript is handled when it isn't split between two different places :Þ
Promise, last one lmao. Still have to fix assignment source location, eventually
Okay I lied this is the last one, lmao.
This will eventually allow for typedefs to be a drop-in-place feature, rather than requiring extensive rewriting
This will now allow `ir_static_reference` to take in a direct `IRStaticVariable`, when necessary, instead of just a name span. Still not sure how to go about handling the local version of this, to be honest. Maybe a `copy`?
…uctions ``` femit_reg_to_reg(context, I_MOV, inst->rhs->result, REG_RCX); femit_reg(context, I_SAR, inst->lhs->result); femit_reg_to_reg(context, I_MOV, inst->lhs->result, inst->result); ``` This clobbers left, not the right.
One thing I've noticed; the type of
Excerpt from rule110.un example IR output with I feel like the type of |
Yeah, it should |
This seems to be the issue: load->type = address->type; should probably be Type* t = type_canonical(address->type);
ASSERT(type_is_pointer(t));
load->type = t->pointer.to; |
// TODO: `v->reference` may need to become list of references? I think this is why | ||
// optimisation is broken. | ||
// TODO: `v->reference` may need to become list of references? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well the original idea was that there would ever only be one IR_STATIC_REF for each static variable. That’s why there simply was no ir_create_static_ref()
, simply because the idea of such an operation would have been flawed to begin with, at least when I wrote this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting; so there's only some confusion in the fact that IR_STATIC_REF both creates a static as well as holds a reference to an existing static (it's address), in the same way that ALLOCA does. However, can't a static be referenced from multiple scopes? If so, won't each one need a reference to the static? Maybe I'm thinking about this the wrong way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you create a static variable, it creates an IRStaticVariable
, which is added to a vector in the context and it’s how the variables are emitted by the backend. This structure holds information about e.g. the name of a static variable:
https://github.com/LensPlaysGames/FUNCompiler/blob/8282edc50843fc5ec882469198e1aedb149dd46e/src/codegen.h#L40-L44
By contrast, an IR_STATIC_REF
is an instruction that wraps an IRStaticVariable
, in the same way that an IR_ALLOCA
wraps an IRStackAllocation
. The IRStaticVariable
is the variable, the IR_STATIC_REF
contains a pointer to that variable. The type of an IR_STATIC_REF
is a pointer to whatever the type of the static variable is, for the same reason that the type of an IR_ALLOCA
is a pointer to the allocated storage.
The IR_STATIC_REF
is just a way to refer to an IRStaticVariable
in IR. Only one is needed for each variable as just like the IR_STATIC_REF
holds a pointer to the IRStaticVariable
, so does the IRStaticVariable
contain a pointer to its IR_STATIC_REF
. This is why the (not ‘a’) IR_STATIC_REF
for a static variable is created together with that variable
Also add error for unhandled IR instruction types, just in case.
There are still some we need to transfer over, like `is_integer` and such... We'll get there.
I think we also need to be able to dereference integers (in the IR), right? Otherwise subscript operator would just break |
Or |
This is definitely the case and should be handled in Sema really. E.g. pointer+integer is a pointer, pointer-pointer is an integer, and pointer+pointer is a type error. ;Þ |
No, that doesn’t really make sense... Only pointer types can be dereferenced. If an operation produces something that can or should be dereferenced, then that something should have pointer type. |
This is sort of a bodge, but is work towards the final destination.
Right now, type information is thrown out as soon as code generation happens; type information is only ever stored in the AST. This was okay when
integer
was the only type, but it's coming time that we need to havebyte
types, and eventually even more complex types.This PR "carries through" type information from the syntactic/semantic analysis on through code generation, all the way to the backends, by storing type information of each IR instruction. The backend can then react to variables like the size of the type being operated on, whether or not it can fit in different registers, etc.