Some Current Syntax Questions

I've been trying to do a few code examples in Odin, just to see how I might code some things in this language. Few syntax questions I have at the moment:

* Is there any way to loop backwards? As in...

1
for(int i = 10; i >= 0; i--)


I've noticed two styles of for loop from looking through your compiler,

1
2
3
for x : 0..<10 // range-based loop

for x : something... // array-iterating loop? May have got the syntax wrong


From what I gather, you can only currently loop forward (and I'm not 100% sure what the ... does, but a guess)

* Currently, os_windows.read() provides a byte array. Is there any way to place/cast this into a string? I'm thinking of this to use the current printing functionality.

* It seems at the moment (or forever) the size of arrays only be determined at compile time?

I think that's everything for the moment. In the mean time, more looking through compiler code (I'm slowly working my way through and understanding the compiler, currently made my way through the tokenizer and making my way through the parser. Long way to go still!). I haven't particularly studied compilers in any form, so it's quite interesting to learn.




FalconJon

* It seems at the moment (or forever) the size of arrays only be determined at compile time?


If the array size isn't a compile time constant you make a slice instead.

1
 foo := new_slice(byte, bar.count+1); 
Hjortshoej
If the array size isn't a compile time constant you make a slice instead.

1
 foo := new_slice(byte, bar.count+1); 


Looking through the compiler, I see there are two 'new's: new and new_slice. Is the new for single values, and the slice for an array? At least, that's what I gathered.

Do these need to be 'free'd in any way? I can't find a keyword in a quick search of the compiler.
FalconJon
Hjortshoej
If the array size isn't a compile time constant you make a slice instead.

1
 foo := new_slice(byte, bar.count+1); 


Looking through the compiler, I see there are two 'new's: new and new_slice. Is the new for single values, and the slice for an array? At least, that's what I gathered.

Do these need to be 'free'd in any way? I can't find a keyword in a quick search of the compiler.


I don't know what the intention for new is really, and you just do free(foo) to free a slice, it uses the current context allocators procedure to free.
At this current time, there is no reverse iteration method. However, this new for loop hasn't been demonstrated yet so I'd wait until then to understand the entirety of it.

To emulate a C-like for loop, you could do something like this (this isn't exactly the same though).

1
2
3
4
while i := 10; i >= 0; {
    defer i -= 1;
    // Rest of code
}


---

As for casting, you can cast between slices of bytes ([]byte) and strings (string) with whatever the casting syntax of that version you are using (I've changed it in the current build which is not release yet).

---

The slice of an array must be known at compile time. If you want a "runtime"-like array, what you want is a slice.

1
2
[10]int // array 10 of int
[]int   // slice of int


A slice is just a pointer and a count, and as such, can be used as sort of "array reference".

If you need to generate a slice from data, there are 4 main methods:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// #1
a := array_or_slice[1:23]; // Slice expression (similar to python or go)

// #2
b := slice_ptr(ptr, 64); // Creates a slice from a pointer and a count

// #3
c := new_slice(int, 64); // Allocates a new pointer of type `int` and of length `64` from the current context's allocator

// #4
d: []int; // Manual construction
d.data = ptr;
d.count = 123;


---

n.m. my compiler's design isn't very "typical" for a compiler but it works for me.

gingerBill
At this current time, there is no reverse iteration method. However, this new for loop hasn't been demonstrated yet so I'd wait until then to understand the entirety of it.

To emulate a C-like for loop, you could do something like this (this isn't exactly the same though).

1
2
3
4
while i := 10; i >= 0; {
    defer i -= 1;
    // Rest of code
}


---

As for casting, you can cast between slices of bytes ([]byte) and strings (string) with whatever the casting syntax of that version you are using (I've changed it in the current build which is not release yet).

---

The slice of an array must be known at compile time. If you want a "runtime"-like array, what you want is a slice.

1
2
[10]int // array 10 of int
[]int   // slice of int


A slice is just a pointer and a count, and as such, can be used as sort of "array reference".

If you need to generate a slice from data, there are 4 main methods:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// #1
a := array_or_slice[1:23]; // Slice expression (similar to python or go)

// #2
b := slice_ptr(ptr, 64); // Creates a slice from a pointer and a count

// #3
c := new_slice(int, 64); // Allocates a new pointer of type `int` and of length `64` from the current context's allocator

// #4
d: []int; // Manual construction
d.data = ptr;
d.count = 123;


---

n.m. my compiler's design isn't very "typical" for a compiler but it works for me.



I didn't realise that you could have an initial statement in the while loop. I presume the defer you've got here is scope-based rather than method/function based.

Understanding what a slice actually is was a key point I was missing. Thanks.

And in my books, anything goes with regards to design as long as it's not been overly complicated for the sake of it, like people who... rely too heavily on object oriented design. Thanks for the heads-up that it's not typical though. I'll have to look into what is more typical further down the line.