-
-
Notifications
You must be signed in to change notification settings - Fork 614
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
Make tags use #+ syntax instead of //+ #4203
Make tags use #+ syntax instead of //+ #4203
Conversation
There was a suggestion in the discussion to use I could keep the syntax the same other than that. Then it'd be
However perhaps I'd change Or it could move to use a more
A third idea is to not have anything at all in front the the tags:
That should also be possible since we know if the tokenizer has seen the package line yet, so there can be a set of keywords that are only used in pre-package-line-land. However, that will again not play nicely with syntax highlighting etc since you must have very smart editors to know if you're before |
I like the idea of having something separate. I originally did the comment thing because it was trivial to do so with the current parser. But a custom token is not out of the question.
|
@gingerBill I prefer If we do this, should we just preserve the current syntax of the tags? It would then be
We could also change it so the style is similar to that of
The above has two differences: parenthesis around I feel like if we had used only # without the +, then moving to the #assert(...)-style would look good. But something about the + inbetween makes me prefer the first style (which is just the current style but replacing |
I really like this proposal, especially if it could also do error checking for unknown package attributes (or parameters)! I like Karl's suggestion for the syntax similar to |
This is already great, I wonder if we could also (not necessarily in this pr because it's already a huge improvement) make it more like normal expressions, something like |
That would involve operator precedence and things like that which probably balloons the scope of this^ |
@laytan Having more advanced syntax is a bit of trouble because currently the parsing of the tags happens directly in For example, look at One thing to consider here is that changing this several times is probably a bad idea, I approach this with the mindset that whatever we change these tags to be now, is how it is gonna be forever. |
And while I would prefer the same expression syntax as Laytan proposes, it would also deluge us with people asking why they can't use Which isn't something that can be cured without a catch-22 of having to parse the package before you know you whether you should parse the file in the package. It would necessarily have to be a restricted expression subset that itself would induce people to ask "why can I not X?", simply because it would work in a Given the required parser overhaul and the "why can't I" maintenance burden, I'd rather keep the current specific syntax with the newly proposed line prefix. |
I'm fine with leaving it, I just have to always look up what the syntax was again for any non-trivial case. Like the difference between these two already get my head spinning:
and
|
That's a good point; I hadn't thought of that when I suggested the I also suggested the possibility of no symbol in the discussion, which would be possible because these statements are valid only before the I think at that point it might just be a matter of style. The Thinking about it some more,
Those two have different results? |
@Feoramund Great point about I'm still very on the fence if I prefer If it did look like code then perhaps it should us real constants like @laytan I don't understand how the two examples you posted about have a different result, can you elaborate? I mean, you are on a certain platform. Either your platform is on the list or forbidden using the !, how can other platforms affect the one you are on right now? |
8ce0a64
to
0f5aabf
Compare
I have pushed some changes that makes this use I've also made the usage of unknown tags into an error instead of a warning. |
I really want this (and this is a big reason why Go changed from Changing the syntax would be a good opportunity to make sure that core is getting it right at least (and there were cases where we weren't in the past), so consider this a vote for future work ("on my wishlist enough that I will go further than an emoji"). |
Build if
Build if
The foot+gun potential here is quite high. While having complex-ish conditionals is likely rare, I am in the camp of "Go tried this syntax, and explicitly changed it because it was error prone, we should learn from their experiences". |
This isn't consistent with |
I see, while I agree that having better conditionals would a good idea, one comment about the above is this:
If you are on Windows you can never be on Linux at the same time. So isn't one solution to this to not allow more than one line with a build tag on it? Allowing more than one build tag line sounds like a bug to me. Or am I missing some benefit of allowing it? |
Both logical OR and AND are useful and arguably required for this use-case. The existing syntax does not allow for this unless you have multiple lines. |
That's not linux and not windows, so everything else, I don't think you can do that with one line. See how confusing these expressions are? |
@laytan Thanks for the example, I get the issue now. For anyone who hasn't understood:
The above will, contrary to what the user might think, build when you are on windows, because it will match the What I think that the user expects when they write something like the line above is that
The user expects this:
I.e. when they look at the following
then the users expects that they cannot be on any of the platforms with a @Kelimion As you see this can't work like Adding in this magic AND / OR stuff depending on the presence of |
I realized that you never mix
the above makes no sense. The moment you have something without the exclamation mark in there then all the other ones are not needed. Whenever we use build tags with Therefore the examples I've been using here such as Because of this, perhaps we should not have
and
Also, with this style having both
This says it builds only on linux but also says that it doesn't build on windows. The moment you have a Also with this style you cannot have multiple As an example, this stuff from
would be
|
From a discussion in the discord I have just learned that this uses OR:
and this uses AND:
The difference is the comma. This is used to combine OSes with architectures:
I.e. this gives us I should have read An idea on how to make this clearer is:
So you can never take apart an OS and an architecture.
Note that this is an uncommon case, but it needs to be supported. |
To keep things simple, things should just be the following: #+build os
#+build arch
#+build os arch, os arch
#+build os arch, !os arch etc |
And error messages should happen when some one does something like
which is an impossible combination |
@gingerBill I'll get on with making it like so. All the other stuff we talked about here went a bit over my head anyways. One question I have is about how we should handle the tokenization. Currently when I hit Update: I did like I said, skip line to newline or until start of comment. |
0f5aabf
to
6f36138
Compare
…ike a comment. Old style still works but is deprecated with a warning. Using unknown tags is now an error instead of a warning. There is a new token for #+ which consumes the whole line (or until it hits a comment). The tags are parsed like before. There are errors to tell you if you use something invalid in the pre-package-line block.
6f36138
to
dc767da
Compare
Edit: Nevermind this message, I had misread in the code how the ! worked. I thought it was per (os arch) group because of a silly assumption. @gingerBill Would you mind if I changed the syntax to
This has the benefits that it:
|
…ing multiple notted operating systems since it was misinformed.
@@ -6091,7 +6097,7 @@ gb_internal String build_tag_get_token(String s, String *out) { | |||
} | |||
|
|||
gb_internal bool parse_build_tag(Token token_for_pos, String s) { | |||
String const prefix = str_lit("+build"); | |||
String const prefix = str_lit("build"); |
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.
+
is now removed earlier because we do a deprecation check outside of parse_file_tag
that also skips over the +
bool first_invalid_token_set = false; | ||
Token first_invalid_token = {}; | ||
|
||
while (f->curr_token.kind != Token_package && f->curr_token.kind != Token_EOF) { |
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.
Since we need to find the file tag tokens and skip comment groups we now loop until we find the package token.
} else { | ||
if (!first_invalid_token_set) { | ||
first_invalid_token_set = true; | ||
first_invalid_token = f->curr_token; |
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.
This is used so we can get nice error message in both situations where there are incorrect things before package line but also so that "Expected a package declaration" ends up at the top token instead at the bottom of the file.
} else { | ||
docs = nullptr; | ||
} | ||
} |
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.
I don't think this check is needed anymore? It must have been in case there was some invalid between the comments at the top and the package line, right? Now we have the new stuff earlier in this proc that makes sure we only have file tags and comments above the package line.
The compiler parts of this is ready for review. I've done what Bill said, including putting in some new error messages. I put in a few review comments of my own to explain what I've done. If it all looks good then I can move on to fix the parser in |
…st of tags that the file tag parser can use later.
…ew #+ file tag syntax.
This is ready for review now. Summary of everything in this PR:
To help you find stuff in this jungle of changed things:
Sorry for all the confusion on my side earlier. I hadn't written much C in several years, so I misread some code and jumped to incorrect conclusions :) |
I want to merge this in at the end of the week. It appears to be absolutely fine! |
…usages in some code generators.
Great! Thanks for the review. I just pushed some additional |
This draft PR makes tags such as
instead look like this:
I.e. it no longer looks like a comment. A bigger example:
In this discussion post I outlined why using a comment for this is a problem: #4200
Here's what I've done
#+
called FileTag//+
with a deprecation warning//
or#+
before package linepackage_line_seen
bool to the tokenizer. This is not strictly necessary. But it ensures you get less crazy errors if you write!+
in the code after the package line. By havingpackage_line_seen
I can make sure to treat#+
as a "FileTag" token only if the package line has not yet been seen. Since I only allow comments or file tags before the package line, it all makes sense in the end.This is a draft PR and a proof-of-concept. I think this tag stuff has to change in some way, but it doesn't have to be
#+
.Also if we were to go through with something like this I would of course search-replace all the
//+
tags in core and base to the new format. And I'd also help with updatingcore:odin
Note: I did try using
+
instead of#+
. It worked fine after I introducedpackage_line_seen
. However it makes it hard to create syntax highlighting if you do it that way.UPDATE: Since starting this PR I have changed from
!+
to#+
based on the comments below. Currently the tag parsing still works like before. I.e. the only difference from before is that//+
has become#+
. See #4203 (comment) for an up-to-date summary of what I've changed.