Can you explain that slop though?
comments
WPF stalled, MAUI skipped Linux, WinUI 3 stays Windows-native
Valid points, but it's not like there aren't solid cross-platform UIs already that support Linux. Avalonia and Uno, for example.
I lovehate this and you're a cool guy
Interesting! I'll have to give this a try.
My current approach for building Linux desktop apps with C# is to use Gir.Core, which can support any GObject-based APIs, including Gtk4 and Adwaita. I use Blueprint for the markup for the UI. Here's an example app: https://github.com/Daniel15/WebCamControl
In the .NET world, Entity Framework Core and Dapper are the industry standards. However, many less popular tools are also used in real-world projects. RepoDB and SqlSugar are among these ORMs.
In this article, we'll look at them through the lens of PVS-Studio static analyzer. Instead of comparing API capabilities or performance, we'll check the projects' source code for potential bugs and suspicious constructs.
Despite the substantial amount of code and extensive functionality of the projects, the analysis revealed only a few suspicious code fragments. This suggests that both projects are well written and maintained at a high standard.
I'm all for syntactic sugar, but these ad-hoc extensions appear to increase the complexity of the language without adding anything relevant in return.
I cannot wait for union type, I built a lot of kludge for the past decade trying to mitigate the lack of it
Stack doesn't actually allow indexing, and ElementAt is an extension method implemented by accessing Stack's iterator. My honest recommendation is to not use Stack, even if that's what the book was using. Stacks are not really meant to be traversed. They're meant to be pushed to, and popped (or peeked) from. Each ElementAt call requires O(N) time to retrieve. I recommend switching to List and implementing 'push', 'pop', and 'peek' as such:
// Instead of Push
scopes.Add(item);
// Instead of Peek
int peeked = scopes[^1];
// Instead of Pop
int popped = scopes[^1];
scopes.RemoveAt(scopes.Count - 1);
However, I understand that is a bit of a change. If you'd prefer to keep it as a stack, a simple reversal of the for loop can get the job done.
// Resolve local variable assignment
private void ResolveLocal(Expr expr, Token name) {
// Decrement through scopes
for (int i = 0; i < scopes.Count; i++) {
// Pass amount of layers since declaration to interpreter
if (scopes.ElementAt(i).ContainsKey(name.getLexeme())) {
interpreter.Resolve(expr, i);
return;
}
}
}
That's enough to get these scripts running.
>for(var i = 0; i < 10; i = i + 1) { print i;}
0
1
2
3
4
5
6
7
8
9
>var a = 0; var temp; for(var b= 1; a < 10000; b = temp + b) { print a; temp = a; a = b;}
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
By the way, I noticed that redefining a global variable will crash as well, but a scoped variable will display an error as intended.
Hard bug to spot for sure. It's due to a difference between C# and Java. C#'s Stack.ElementAt() is not the same thing as Java's Stack.elementAt()/Stack.get(). They're actually reversed. Also, ElementAt is a Linq extension method and not a default method like in Java. See the below code/output:
import java.util.Stack;
Stack<Integer> stack = new Stack<Integer>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(stack.elementAt(0));
Output: 1
using System;
using System.Collections.Generic;
using System.Linq;
Stack<int> stack = new();
stack.Push(1);
stack.Push(2);
stack.Push(3);
Console.WriteLine(stack.ElementAt(0));
Output: 3
This would also work:
while (!(Peek() == '*' && PeekAhead() == '/') && !IsAtEnd())
while (Peek() != '*' && PeekAhead() != '/' && !IsAtEnd()) {
Probably this guy.
If you encounter an asterisk or a slash, then it stops. You want to stop when you encounter an asterisk and a slash, so:
while (!(Peek() == '*' && PeekAhead() == '/') && !IsAtEnd()) {
I also find your detection of when to remove the comment a bit scary, but that might be because you haven't shown the Match method.
It's not strictly speaking a bug, but the behavior of Advance is a bit confusing.
Based on how you use it in the code snippets, I would suggest changing it to
private void Advance() {
current++;
}
So that it only does what it says, and then changing the place where you read the next char to
char c = Peek();
Advance();
Alternatively, you could rename it to something like ReadChar, which more closely matches its current behavior, since a read is expected to return the data (character) at the current position, and then advance the position
That is the case. But if you are at a *, then the original while statement reads while (false && …) { and immediately breaks. The remaining checks are not evaluated, since they cannot affect the outcome when the first check fails
The problem is fairly simple:
while (Peek() != '*' && PeekAhead() != '/' && !IsAtEnd()) {
You are breaking the loop if either the current character is a * or if the next character is a /. In other words, you don't require the full */ token.
Instead, you'll want something like
while ((Peek() != '*' || PeekAhead() != '/') && !IsAtEnd()) {
private char Advance() {
return source[current++];
}
This is wrong. At least as I would expect advance to behave. While you do advance, you are returning the old value, not the new one. ++current would return the new value.
Also, it would help if you said what the wrong behaviour was.
Damn that's interesting.
You’d think an AI-generated article might at least take a paragraph to explain what problem the pattern solves and when you might or might not want to use it.
I do hate that all these features are yet more keywords and weird syntax. It’s becoming C##.
It's called sharp because you can cut yourself. /s
Like them.
They have their downsides, so they're no more than an alternative to other approaches. They can condense code and concerns in some cases. The more complex the type is, the less obvious the primary constructor parameters become.
I'd be happier if only annotated classes get registered 🤷♂️
Funnily enough, that engineer also disallowed Linq because it was slow. It's been 7 years since I've worked with him. wonder if he ever changed his tune.
Me personally? Hate 'em. In every scenario. They force you to break standard naming semantics.