Skip to content
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

Give match statements a "next" keyword instead of "continue" #4667

Closed
NationalityNZ opened this issue Jun 14, 2022 · 5 comments
Closed

Give match statements a "next" keyword instead of "continue" #4667

NationalityNZ opened this issue Jun 14, 2022 · 5 comments

Comments

@NationalityNZ
Copy link

Describe the project you are working on

A low-level scripting language that compiles into gdscript.

Describe the problem or limitation you are having in your project

I am trying to reformat source code into a more legible format for the compiler, but I also want to preserve line breaks inside quote marks, substitute tabs for different punctuation, etc. Rather than smash my head in with twenty different highly specific regexes, I've decided it's easier to go through the code character-by-character and rebuild the script.

It would be very useful to have a for loop that uses a match statement, a little like this one:

for i in sourceCode.length():
	var character = sourceCode[i]
	if escapeChar == true:
		processedCode += character
		escapeChar = false
		continue
	match character:
		"\\":
			escapeChar = true
		"\"":
			if quoteBlock == true:
				quoteBlock = false
			else:
				quoteBlock = true
		"\t":
			newLineStart = false
			if quoteBlock == false:
				tabCount += 1
				continue
		"\n":
			if quoteBlock == false:
				tabCount = 0
				newLineStart = true
				continue
			if newLineStart == true:
				continue
....lots more logic here. etc etc
	processedCode += character

You get the idea.
However, because the match statement has a different and conflicting use for the continue statement, there's no way to get out of the for loop without dispensing with the match statement and just using inelegant if-else statements.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Add a next keyword which will be used instead of the continue keyword in match statements, giving continue one specific meaning and freeing it solely for manipulating iterating loops, allowing for the use of the much more elegant match statement instead of forcing people to use long if-else chains.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

This pseudocode will format a text, removing extra spaces except within a quote block. This is a simple task that surely has simpler implementations, but it's a demonstration on how you can use this pattern for very complex formatting, selectively formatting text.

func a_cool_formatter(unformattedText):
	var formattedText := ""
	for i in unformattedText.length():
		var character = unformattedText[i]
		var space_block = false
		var quote_block = false
		match character:
			" ":
				if quote_block == true:
					next #preserves extra spaces in quote-marked text
				if space_block == true:
					continue #breaks out of the loop, so that it is entirely ignored
				else:
					space_block = true
					next #finds the next match, same as normal continue in for-loop helpful if we still want to process the space for some reason.
			"\"":
				if quote_block == true:
					quote_block = false
				else:
					quote_block == true
				next
			_:
				space_block = false
		formattedText += character

If this enhancement will not be used often, can it be worked around with a few lines of script?

Yes, you could use big if-else statements, but the entire point of a match statement is to avoid ugly if-else blocks. There is nothing an if-else could do that a match statement couldn't.

Is there a reason why this should be core and not an add-on in the asset library?

This is a fundamental change to the code.

@Calinou
Copy link
Member

Calinou commented Jun 14, 2022

Related to #160.

@YuriSizov
Copy link
Contributor

YuriSizov commented Jun 14, 2022

However, because the match statement has a different and conflicting use for the continue statement, there's no way to get out of the for loop without dispensing with the match statement and just using inelegant if-else statements.

There is also no way to escape several levels of nested for loops or while loops at the same time, and a new keyword wouldn't solve anything there.

@NationalityNZ
Copy link
Author

There is also no way to escape several levels of nested for loops or while loops at the same time, and a new keyword wouldn't solve anything there.

I deleted my original response, as I felt it was somewhat presumptive, but I'm not quite satisfied with this answer. Everything I've read says that a case-switch statement is not a loop, so presumably you would not be escaping from a nested for or while loop by using continue, it would just goto the end of the statement.

@YuriSizov
Copy link
Contributor

Everything I've read says that a case-switch statement is not a loop, so presumably you would not be escaping from a nested for or while loop by using continue, it would just goto the end of the statement.

My point was that there are other cases where you might want to break or continue with several layers of scopes nested. And other cases could not be helped by a new keyword, because they are homogeneous and use the same syntax. If your main issue is that you need to break from the parent scope, then this is just a tiny change that doesn't help a vast majority of cases.

@NationalityNZ
Copy link
Author

NationalityNZ commented Jun 14, 2022

My point was that there are other cases where you might want to break or continue with several layers of scopes nested. And other cases could not be helped by a new keyword, because they are homogeneous and use the same syntax. If your main issue is that you need to break from the parent scope, then this is just a tiny change that doesn't help a vast majority of cases.

So break and continue really control scope, not the loop, I think I understand now. This is why I ask these sorts of annoying questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants