Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - lerno

Pages: 1 ... 11 12 [13] 14 15 ... 17
181
Ideas / Re: Switch statement
« on: October 26, 2018, 11:34:34 PM »
Let me go a bit further:

There is no real reason why switch can't have more extended functionality:

1. Allow "case" to be followed by any expression
2. Allow switch to be without value
3. Compile "expression"-case to nested ifs, and regular values to normal switch/case.

E.g.

Code: [Select]
// (1) Compiles to if/else
switch
{
  case (x > 0): do_something(); break;
  case (y < 10): do_something_else(); break;
  case (x + y < 1): foo(); break;
}

// (2) Compiles to if/else
switch (x)
{
  case 0: zero_handle(); break;
  case x > 0: do_something(); break;
  case y < 10: do_something_else(); break;
  case x + y < 1: foo(); break;
}

// (3) This compiles to switch/case
switch (x)
{
   case 0: ...  break;
   case 1: ... break;
   default: ... break;
}

To simplify, type (2) can be eliminated entirely. That also makes it clearer when we have possible jump tables and when not.

Compare case (1) with if/else:
Code: [Select]
switch
{
  case (x > 0):
     do_something();
     break;
  case (y < 10):
     do_something_else();
     break;
  case (x + y < 1):
     foo();
     break;
}

if (x > 0) {
  do_something();
} else if (y < 10) {
  do_something_else();
} else of (x + y < 1) {
  foo();
}

However, the "break" statement makes is a little less useful. In languages where "fallthrough" is required, this can be shortened further:

Code: [Select]
switch
{
  case (x > 0):
     do_something();
  case (y < 10):
     do_something_else();
  case (x + y < 1):
     foo();
}

A "break"-less switch would also allow for automatic scopes with each case. But that idea has to be refined a bit.

Anyway, just posting this as food for thought.

182
General Discussion / Re: Contribute / get into the code
« on: October 26, 2018, 11:19:12 PM »
I ran into that (1 << 2) + 3 bug in the compiler and at first I thought I'd done something seriously wrong. ;D Then – because I don't know the code so well, I had to spend quite some time narrowing down the problem. And finally fixing the bug, by that time you already fixed it from my bug report...  :)

Anyway, there's a pull req for updated precedence rules.

Because I wasn't sufficiently lazy I didn't find a way to just run a single test. It's probably dead easy, but please add that to the instructions somewhere because others might have the same problem.

Regarding cmake in the instructions for Mac, it's no longer necessary to get that from its own download. Using homebrew is fine.

183
Ideas / More on precedence rules
« on: October 26, 2018, 11:13:00 PM »
In Pony, all operators have mandatory ( ). That is going too far, but maybe we should require them where (1) two or more operators of the same precedence are chained. (2) and where the order of execution is important.

For example, consider a < b > c < d.

Under C/C2 rules that is (((a < b) > c) < d). Here it would be better to explicitly require ( ) be added.

With the new precedence rules == and < has the same precedence. Consequently a < b == c > b becomes ((a < b) == c) > b.

It's a nonsense expression and you should never really do that, but if you were relying on the C behaviour of (a < b) == (c > b) then it can be surprising, even though very few would use the version without parenthesis.

One could require parenthesis in these cases where there often is ambiguity, so the relational operators and possibly logical and/or as well.

It would go with the "don't make it possible to write incorrect code" idea.

184
General Discussion / Re: Contribute / get into the code
« on: October 26, 2018, 11:26:33 AM »
I'll have a look at it.

185
Ideas / Re: Fix C operator precedence rules
« on: October 26, 2018, 11:24:36 AM »
 :D

186
Ideas / Re: A group of function pointers & a struct
« on: October 26, 2018, 11:23:09 AM »
Yeah, exactly. Ideally we'd write something like:

Code: [Select]
interface @Foo {
  func void do_something(Foo *foo, i32 an_argument);
  func void do_something_else(Foo *foo, i32 bar, i32 baz);
}

struct Test {
  i32 a;
  i32 b;
}

func void Test.do_something(Test *test, i32 foek) { .... };
func void Test.do_something_else(Test *test, i32 foek, i32 foek) { .... };

Test *test = malloc(sizeof(Test));
@Foo foo = @Foo(test);

func void try_something(@Foo foo) {
  foo.do_something(123);
  foo.do_something_else(2, 3);
}

Possibilities:

- "foo" is RC / ARCed or manually memory managed
- foo "owns" test and deallocates it or test is managed on its own or either is allowed.

187
Ideas / Re: Preprocessor and Macros
« on: October 26, 2018, 11:11:37 AM »
As I've written before, I think generics is only truly needed for containers. Thus a sweet spot might be a syntax that allows for generic containers, but not anything else (also consider adding C11's _Generic).

I don't have this fully thought out yet so I'm unsure of how it should look.

Regarding G2 I have been looking at the counterproposals as well. None of them look exactly great. Again, what I want to avoid is stuff like foo<bar<baz>, bar<foobar<int, char *>>. Generics truly opens a Pandora's Box for verbose and unreadable code.

It's extremely reasonable to be able to write generic code that works on any array, and you also want to be able to write your own containers that can be used for any payload. But enabling that so often enables much more than you want to.

188
Ideas / Re: Restricted pointers (and the analogue with threads)
« on: October 26, 2018, 11:02:32 AM »
Yes, I mentioned this in the array proposal – depending on how we deal with aliasing/restrict then different ways of implementing arrays are also needed to detect aliasing.

189
Ideas / Re: Basic list of improvement points
« on: October 26, 2018, 11:00:19 AM »
The easiest way would be to start by filing them as issues on the c2compiler in github.

190
Ideas / Re: Real arrays
« on: October 26, 2018, 10:59:16 AM »
Discussion

1. Should slices have special syntax?

We could potentially use the bit-slice syntax to pull out parts of an array. However, since they don't really match up we have some freedom to decide whether we have <lower index>:<high index inclusive>, <lower index>:<high index exclusive>, <lower index>:<size>

Since arrays are used as first class objects, it makes sense that creating slices of arrays similarly has special syntax.

Code: [Select]
int[] a = { 1, 2, 3, 4, 5, 6 };
int[] b = a[2:3]; // { 3, 4 }, { 3 } or { 3, 4, 5 } depending on definition.

Note that a slice does not outlive the lifetime of an array.


2. Negative indexing

It is possible to use negative indices as shorthand for length - index. So a[-1] is the same as a[a.length - 1]. It's very convenient but means extra instructions. Basically it means unpacking any a to a.start + (i < 0 ? a.length - i : i). Expensive!

3. Extending array methods

Since arrays are generic-ish, we'd need some more generic way of expressing function on it. But it would be useful. The aforementioned negative indexing could be implemented as a function:

Code: [Select]
func any[].slice(any[] array, i64 index, i64 length) {
    index = index < 0 ? index + array.length;
    length = length < 0 ? length + array.length;
    return array[index:length];
}

(In general, considering generic functions is important!)

4. Growable arrays

This is a topic on its own. But let's just mention that it needs some kind of memory management and as such we should consider memory management a bit in detail (in another topic)

191
Ideas / Real arrays
« on: October 26, 2018, 10:36:10 AM »
The "problem" with real arrays have been discussed previously, but I start a new topic here since those discussions are pretty much dead. Instead of arguing for why, let me just write the proposal.

1. All arrays are always passed by reference.

Code: [Select]
func void some_function(int[] x)
{
    x[0] = 1;
}

int[3] x = { 2, 3, 4 };
some_function(x);
assert(x[0] == 1);

2. Passing an array is structurally identical to passing in a struct with length + pointer.

This means that the array some_type[] is exactly equivalent to:

Code: [Select]
type struct
{
   pointer_size length; // <- decide whether this should be platform independent or not.
   some_type *start;
}

BTW, I considered whether we should allow variable bit sizes for the length variable. My conclusion is that it would make the feature too complex. Custom structs are better if that is desired.

3. As a consequence we can define slices on an array, simply by varying the start and length.

Note that the strategy here has to be different if we go with "restrict by default" compared to only using restrict like C does it (aliasing by default). In the latter case, much performance can be gained by having pointer + offset + length instead of pointer + length. If space is an issue for the latter, we can rewrite the struct in this manner:

Code: [Select]
type struct
{
   half_pointer_size offset;
   half_pointer_size length;
   some_type *ptr;
}

This way it's easy to analyse the original pointer, even for slices of that array, and arrays / slices can be used interchangeably.

4. Arrays have manual memory management.

Not much to say about that except for needing an custom allocator function for arrays as it must set the length in the returning data.

5. It should be possible to cast an array to a struct.

Array layout should be fixed with the language, and casting an array to a struct (using whatever fixed layout we decide on) is fine.

6. Undefined behaviour

Changing the value of an underlying pointer, length, offset of an array leads to undefined behaviour.

7. Optional bounds check

Bounds checking is optionally inserted on debug builds.

192
Ideas / A group of function pointers & a struct
« on: October 26, 2018, 12:47:23 AM »
About the only thing I really miss when writing C is when you really want a bunch of different plugins for the same code. It can be different types of loggers, or swapping the printing engine.

In C you typically do that by sending over a struct of function pointers + an opaque struct.

In OO we simply define an interface and implement it.

A simpler way, but one that doesn’t go all the way would be nice. Has this been discussed?

193
General Discussion / Re: Mail of posts / this BBS
« on: October 26, 2018, 12:01:48 AM »
Found it now. It's the "Notify" button on each category you use to follow it.

194
General Discussion / Re: How should I set up the project for dev?
« on: October 25, 2018, 11:59:42 PM »
I got things up and running. As usual AppCode is very reluctant to search paths in a larger project :( So I'm using a mixture of AppCode and Xcode to actually code things. An XCode project can be generated by CMake. Unfortunately I made that one in /build and then did a regular make-based one in /build2. Later on I discovered that "make tests" seemed to rely on it being run in /build

Anyway, I'm fairly happy about today's venture into the code. I managed to write a wrapper for DiagosticsEngine (mostly anyway) and get that to actually compile and pass the tests. Not actually adding anything to the code, but following all uses game me a tour through the source code at the very least.

195
Implementation Details / Re: Why do we need Clang and LLVM?
« on: October 25, 2018, 11:53:20 PM »
BTW, at some point a document outlining the coding standard for the C++ part is needed. It's occasionally inconsistent, and because the indentation style differs from what I'm used to I need some sort of reference to work with in order to use auto formatting.

Pages: 1 ... 11 12 [13] 14 15 ... 17