Giter Club home page Giter Club logo

odin's Introduction

Odin logo
The Data-Oriented Language for Sane Software Development.


The Odin Programming Language

Odin is a general-purpose programming language with distinct typing, built for high performance, modern systems, and built-in data-oriented data types. The Odin Programming Language, the C alternative for the joy of programming.

Website: https://odin-lang.org/

package main

import "core:fmt"

main :: proc() {
	program := "+ + * πŸ˜ƒ - /"
	accumulator := 0

	for token in program {
		switch token {
		case '+': accumulator += 1
		case '-': accumulator -= 1
		case '*': accumulator *= 2
		case '/': accumulator /= 2
		case 'πŸ˜ƒ': accumulator *= accumulator
		case: // Ignore everything else
		}
	}

	fmt.printf("The program \"%s\" calculates the value %d\n",
	           program, accumulator)
}

Documentation

Instructions for downloading and installing the Odin compiler and libraries.

Get the latest nightly builds of Odin.

Learning Odin

An overview of the Odin programming language.

Answers to common questions about Odin.

Documentation for all the official packages part of the core and vendor library collections.

A wiki maintained by the Odin community.

Get live support and talk with other Odin programmers on the Odin Discord.

Articles

The official blog of the Odin programming language, featuring announcements, news, and in-depth articles by the Odin team and guests.

Warnings

  • The Odin compiler is still in development.

odin's People

Contributors

avanspector avatar blob1807 avatar colrdavidson avatar danielgavin avatar flysand7 avatar ftphikari avatar gingerbill avatar gonzooo avatar graphitemaster avatar jakubtomsu avatar jasonkercher avatar jon-lipstate avatar karl-zylinski avatar kelimion avatar lachsinc avatar laytan avatar lperlind avatar naught00 avatar oskarnp avatar perogycook avatar platin21 avatar semarie avatar skytrias avatar tetralux avatar thebirk avatar thephtest avatar thetarnav avatar thisdevdane avatar vassvik avatar yawning avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

odin's Issues

Pointer Arithmetic - Difference Produces Unexpected Value

While writing a test program, I came across some behaviour when doing pointer arithmetic. Trying to minus one pointer from another ended up with a value that wasn't correct (at least, wasn't what I expected). I produced a test program to see if I could reproduce it, and I could.

Here's the program.

#import "fmt.odin";

main :: proc()
{
	b : [1000]byte;

	using fmt;

	println();
	println("Pointer of Address 0");
	println(^b[0]);
	println();
	println("Pointer of Address 50");
	println(^b[50]);
	println();
	println("Difference between 50 and 0");
	println(^b[50] - ^b[0]);
}

And the result for 50 - 0 was...

image

... 6. Not quite the result I was expecting. I wasn't able to cast them to numbers that I could manipulate either.

Weird lambda behavior

Ok so I freshly cloned and rebuilt the compiler now before writing this :)

I wrote a function that gets an input value and a function pointer and returns the result of the pointed function fed with the input value.

Now if I call that mapping function, with a constant function, everything is fine. When additionally called with a lambda it works too. However just using a lambda crashes the compiler.

#load "fmt.odin";

mapFunction :: proc(i: int, func: proc(int) -> string) -> string
{
	return func(i);
}

main :: proc()
{
	i : int = 4;

	f :: proc(i: int) -> string {
		return aprint(i);
	}

	// if you uncomment these lines it works
	//res1 := mapFunction(i, f);
	//print(res1, "\n");

	res2 := mapFunction(i,
			proc(i: int) -> string {
				return aprint(i);
			}
		);
	print(res2, "\n");
}

Also note that the lambda and constant functions are literally the same.

Regarding C compatibility

Hi Bill,

I've watched your videos and read part of your code, I have to say, it is a very nice proposal this language of yours, I'd be happy to experiment with it.

I'd like to know what are your thoughts about C compatibility. I know it sounds strange this question, let me put my rationale to your judgment.

Assembly programming was successfully replaced by the C programming language, as we know today, yet, it is observable that you can still write assembly inside C code. C compilers support it since there's always a corner situation that developers might want to write assembly, such as optimization, integrating old code base or dealing with platform specificities. I anxiously wait for the day that C will be replaced, and the Odin programming language seems to be a competent candidate for that, but as we can learn from C vs assembly, I believe the the replacement will have to support C in a very considerable extent to make the replacement more likely to happen. We have already a lot of code written in C, even more that we had with assembly, also we live in times where there's really a huge amount of different platforms and providers where C runs, creating a very segmented ecosystem that relays on C as its foundation, which will impose even more resistance to a language migration. In face of that facts, I believe that we cannot simply replace C, but we'd have to embrace it in order to later replace it.

That's why I wonder how Odin is stands on this matter.

Best,
Felipe

Improve error messages

  • Show exactly one error in the output; don't flood the user with them.
  • Improve the quality of errors in general.

e.g: Currently, using #include to include a file results in two messages for every
use of it:

C:\path\to\file\test.odin(1:2) Syntax Error: Expected `;`
C:\path\to\file\test.odin(1:1) Syntax Error: Only declarations are allowed at file scope tag statement

Instead, it should say something more like: no such directive '#include'.
And of course, bonus points for use '#load' instead.` ;)

Error printing negative values with fmt.println and fmt.print

Hey Bill,

I was playing around with Odin last night (I love what you have done so far) and noticed a bug in trying to print the value -1 using fmt.print and fmt.println. The value produced was -18,446,744,073,709,551,615. I am using v0.0.6 of the compiler btw in case this has since been fixed. It may just be a conversion error in the printing functions since I used the value containing -1 elsewhere in other expressions and everything worked fine.

FYI: I just tried it again this morning and the error still occurs. It looks like it is happening with negative values in general. I didn't test too many numbers but thought I should update my comment.

A place to chat about Odin

Hey,

I toy around, still being a beginner both at C but as well at Odin, so at times I have questions I normally would look up in the documentation. Odin by Example just doesn't cover every case yet and browsing the source here on GitHub mostly get me going but is a tedious process πŸ˜„

So I would like to suggest there'll be an "official" IRC channel for the Odin language or possibly a Slack if you're more into that.

Personally I'm more of an IRC kind of guy but I'm open to alternatives.
If anyone's up for a small chat I'll (for now) be in #OdinLanguage on freenode.

Does not build

The demo.odin file references the sync.odin file which does not exist in the repo.

Build error

C:\Users\pc\Desktop\Odin>"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"

C:\Users\pc\Desktop\Odin>build.bat
main.c
c:\users\pc\desktop\odin\src\checker\types.c(1454): error C2220: warning treated as error - no 'object' file generated
c:\users\pc\desktop\odin\src\checker\types.c(1454): warning C4028: formal parameter 4 different from declaration
C:\Users\pc\Desktop\Odin>

bit shifting

is something like bit shifting and other similar operations in the language yet?

Vec2 crash

using a variable in a vec2 results into a hard crash of odin.exe
error:
w:\odin\src\ir.c:1750: Assert Failure: is_type_array(st) || is_type_vector(st)

example code:
i :f32= 1.0;
b := Vec2{i};

it works fine with constant values

Incorrect out of bounds check for slices

Repro code

#import "fmt.odin";

main :: proc()
{
  array: [10]f32;
  fmt.printf("%v\n", array[0..10]);
}

expectedly throws:

main.odin(6:31) Index `10` is out of bounds range 0..<10

But correct version

#import "fmt.odin";

main :: proc()
{
  array: [10]f32;
  fmt.printf("%v\n", array[0..<10]);
}

throws the same error:

main.odin(6:32) Index `10` is out of bounds range 0..<10

Big Numbers for Constants

In this language, I want constants to work very similar to how they work in Go. This requires the need for a big numbers library as it needs arbitrary precision for numbers to behaviour as numbers.

NUM_A :: 1<<100;
NUM_B :: NUM_A>>90;

Should be valid and result in NUM_B == 1<<10.

Blog article on how Go constants work: https://blog.golang.org/constants

'when' syntax for #foreign_system_library not entirely functional

When making bindings for libraries that are platform independent (let's take SDL2 for example), it would be nice to have some way of signaling that for Linux you want to link with "-lSDL2" but for Win32 you'll want to link with "sdl2.lib"

This is a very low priority issue, and it can be worked around by conditionally loading files that just act to link with the library, but it's something that would be nice to have.

Function writes to struct but struct remains unchanged

When I have the struct S with a field state, and I call a function to change the state, the state actually only changes in the scope of the function.

#load "fmt.odin";

S :: struct {
	state : u32,
}

changeState :: proc(using s : S) {
	state = 1;
	print("State is: ", state, "\n");
}

main :: proc()
{
	a : S;
	changeState(a);
	print("State is: ", a.state);
	// prints: 
	//State is: 1
	//State is: 0
}

Printing bug

Printing out a really really large number crashes the compiler.

e  := 4.94065645841247E-324;
ie := 1/e;
print(ie);

Odin.exe crashes, however also the message
<path>Odin\core\decimal.odin(160:13) Index -1 is out of bounds range 0..<384
is printed.

Unused return values are ignored by default?

#import "fmt.odin";

main :: proc()
{
  using fmt;

  Func :: proc() -> int {
    return 10;
  }

  Func();

  printf("Isn't Func supposed to trigger a compile time error?\n");
  printf("And the true way of calling it would be _ := Func()?\n");
}

Calling Func() like that doesn't trigger a compile time error.

Sublime Syntax Highlighting

Hi Bill,

Would it be possible for you to include your sublime text syntax highlighting package?

Thank you for making this public! It's an awesome project and I look forward to working with it.

Thank you.

Implicit assignment for rawptr on function pointers?

AddProc: proc(a, b: int) -> int;
SomePtr: rawptr = nil;
AddProc = SomePtr;

This doesn't work without explicitly casting SomePtr to proc(a, b: int) -> int, but isn't the whole point of rawptr is implicit casting? I can do this in C:

int (*AddProc)(int, int);
void *SomePtr = NULL;
AddProc = SomePtr;

And it works.

I know a cast like this is not "safe", but if I wanted safety I wouldn't use rawptr in the first place.

Allow negative indices

Index `-1` cannot be a negative value

No it can :P

Since Odin doesn't have C-like pointer arithmetic, the only way to index a rawptr is by converting it to a slice with slice_ptr(), but slices don't allow negative indices.

The problem: I have a rawptr from some other lib that points not to the beginning, but to the middle of an array:

1 2 3 4
  ^

I need to access value 1, but, currently, it's not possible in Odin.

IR error for slice/array decleration

This example produces an IR error

main :: proc() {
    vertices := []f32 {
        -0.5, -0.5, 0.0,
         0.5, -0.5, 0.0,
         0.0,  0.5, 0.0
    };
}

Error:

E:\Odin\bin/opt: E:\Repo\Random\src\main.ll:4395:120: error: expected type
                store {float*, i64, i64} {float* getelementptr inbounds ([9 x float], [9 x float]* @.__csba$0, i64 0, i32 0), i64 9, 9}, {float*, i64, i64}* %0
                                                                                                                                     ^

Negative integers in fmt.*

negative := -10;
fmt.println(negative);

printing out negative integers result in odd outputs
-18446744073709551606

How to disable mangling for bss variables?

I want to share some global variables with C code, but Odin mangles them with a file name and some number. I can tag a function with #link_name and specify the exact linking name I need, can I do the same for global variables? Thanks!

Dynamic any array printing

Dynamic arrays of a standard type print just fine, however any arrays just print [, , ,], with the number of commas depending on the length of the array

arr :[dynamic]any;
append(arr, "123", 123, 3.14159265359878, true);
print(arr, "\n");

Iterating over the array and printing each element works fine though.

Linux ABI issue (passing structs by value)

Repro:

main.c, compiled with clang -shared -fPIC -o libmyfunc.so main.c

#include <stdio.h>

struct vec3 { float x, y, z; };

void CFunction(struct vec3 x) {
  printf("Received struct vec3: %f %f %f\n", x.x, x.y, x.z);
}

main.odin:

#foreign_system_library myfunc "myfunc";

vec3 :: struct #ordered { x, y, z: f32 }

CFunction :: proc(x: vec3) #foreign myfunc;

main :: proc() {
  x: vec3;
  x.x = 1;
  x.y = 2;
  x.z = 3;
  CFunction(x);
}

Prints:

Received struct vec3: 1.000000 0.000000 2.000000

I myself like to pass everything by pointer, but I'm currently working with a 3rd party C library that passes structs by value everywhere.

Compile-time asserts still fail even if the file is when'd out.

When a file is included with a 'when' statement that evaluates to false, any compile_assert is still executed. For example, take this example.

// test.odin
#import "failure.odin" when false;
main::proc(){}

// failure.odin
_ := compile_assert(false);

I'll end up with failure.odin(2:6) Compile time assertion: 'false' even though failure.odin's asserts shouldn't have run in the first place.

Of course, this doesn't just happen with an expression that is literally 'false'.
It also happens in the standard library. When a program is compiled on any platform other than Windows, it loads os.odin, and evaluates the compile_assert in sys/windows.odin, even though that file isn't actually being included.

os.read_entire_file: program crashes when file is completely empty.

#import os "os.odin";
#import fmt "fmt.odin";

main :: proc()  {
    fpath := os.args[0];
    // Crashes when file is completely empty
    file, ok := os.read_entire_file(fpath);
    if !ok {
        fmt.println("error opening file");
        return;
    }
}

Error: C:\Odin\core\os_windows.odin(217:11) Index 0 is out of bounds range 0..0

Struct with a function pointer and baked value

So I played around with structs and making oop style classes to see what was possible.
My minimal example code is:

// File: minimal.odin
#load "fmt.odin";

Human :: struct {
	toString : proc() -> string
}

CreateHuman :: proc(name : string) -> Human {
	ret : Human;
	ret.toString = proc() -> string {
		return name;
	};
	return ret;
}

main :: proc() {
	felix := CreateHuman("Felix");
	print(felix.toString(), "\n");
}

So I am trying to see if I can build a Java like class here with a toString method.
When I compile I get the message:

<path>\odin-v0.1.3\bin/opt: <path>\minimal.ll:3364:2: error: instruction forward referenced with type '%..string*'
        %0 = load %..string, %..string* %0, align 8

Invalid LLVM IR produced when tagged union used in struct

When attempting to compile the following code:

Test1 :: type union {
	A: int;
	B: int;
};

Test :: type struct {
	a: Test1;
};

main :: proc() {
	test: Test;
	match type x : ^test.a {
	}
};

This error is produced:

opt: test2.ll:1193:62: error: '%1' defined with type '{ [0 x <8 x i8>], [8 x i8], i64 }*'
        %2 = getelementptr inbounds %test2-2.Test1, %test2-2.Test1* %1, i64 0
                                                                    ^

It seems the compiler is printing union types inline instead of a named reference.

Multiple Assignment with one declared, one undeclared variable

Hey there,

I was coding some stuff with Odin and I am currently facing this "problem" (not sure if it is by design or not).

So imagine you have procedures A and B which both return (AType, string) and (AnotherType, string), respectively. And you have this snippet of code:

aType, errorString := A();
anotherType, errorString := B();

The compiler will complain since the call to procedure B will attempt to redeclare errorString. However, the intent was to reuse errorString, from the declaration of calling A earlier, and declare anotherType. Due to using := the compiler will interpret as declaring both variables. Using = the compiler will complain saying that anotherType isn't defined.

Is there going to be support to declaring only some variables in a multiple return values procedure call? I know this can be fixed by just declaring all variables earlier, but since Odin does a good job at reducing LOC this could further help reducing it.

Cheers,
Rui RosΓ‘rio

example code, not code from actual situation

Lambda scopes are broken

Repro code:

#import "fmt.odin";

main :: proc()
{
  using fmt;

  x := 0;

  Q_rsqrt_v2 := proc(num: f32) -> f32 {
    x := num * 0.5;
    y := num;
    i := transmute(i32)y;
    i = 0x5f3759df - i >> 1;
    y = transmute(f32)i;
    y *= 1.5 - x * y * y;
    return y;
  };

  printf("%v\n", Q_rsqrt_v2(2));
}

Generates errors:

main.odin(10:3) Redeclaration of `x` in this scope at main.odin(7:2)
main.odin(10:8) Undeclared name: num
main.odin(11:8) Undeclared name: num
main.odin(13:3) Assignment count mismatch `1` = `0`
main.odin(14:3) Assignment count mismatch `1` = `0`

Change Q_rsqrt_v2 := to Q_rsqrt_v2 :: and it works as it should.

Sublime Build Settings / Syntax Highlighting

Do you have/are you planning on uploading your sublime build settings/syntax highlighting at all?

Edit: Just to note, I'm just playing around with Odin for fun, not planning on doing any serious coding at the moment (trying a few 'simple' programs)

Struct Type Introspection crashing

Hey Bill,

I was trying to use the type introspection features of the language on a struct, namely trying to access the field names composing the struct. When I went to print the values the program crashed. Subsequent runs fared similarly. I figured it might just be something with the name field of the Type_Info_Member struct so I tried looking up the offset and was receiving garbage values as well.

Not sure if the type introspection is still in a working state or not, but I figured I should let you know.

Below is my actual code in case I wasn't accessing the data appropriately.

#import "fmt.odin";
#import "mem.odin";

NewType :: struct {

	field1: int,
	field2: int,
	field3: int,
}

main :: proc() {

	newtype := NewType {
		field1 = 10,
		field2 = 11,
		field3 = 12,
	};

	newtype_info := cast(^Type_Info.Struct) type_info_of_val( newtype );
	newtype_members := newtype_info^.fields;

	fmt.println( "", newtype_members[0].name );   // crash
	fmt.println( "", newtype_members[0].offset ); // garbage value when i comment out the above line

}

fmt.sprintf() format string width error

If you pass a number that is in the hundreds to sprintf with the format %3d any number under 100 prints fine but anything that is 100-999 doesn't get printed at all.
fmtsprintf.("%3d:");

Interval Syntax

Currently, Odin uses .. for a half-closed interval: a..b from a, up to but not including b [a, b). This interval syntax is used for slicing and for in statements:

x[..]; // slice
x[a..b]; // low and high indices
x[a..b..c]; // low, high, and max indices
for x in 0..10 {}
// similar to 
for x := 0; x < 10; x++{}

The questions I have are:

  • Should intervals just be "half-closed" or should they support open ranges too [a, b]? Should the syntax be a..b for open and a..<b for half-closed?
  • Should an interval/range be a core type which could be can be passed around?
  • How do you specify an iteration to step at different ranges e.g. +2, -1, etc?

Make slice out of underlying using array

Currently for a variable v of type:

vec3 :: raw_union {
  using array: [3]f32,
  using elems: struct { x, y, z: f32 }
}

you can access its elements with v[0], v[1], v[2] just fine, but making a slice as v[..] currently won't work, throwing:

Cannot slice `v`

error. Explicitly getting v.array[..] works, but it would be nice if slicing could respect using keyword :)

Ability to loop over enums

Would be great if you could loop over an enum at get each single enum value.

Test :: enum {
     test1,
     test2,
     test3,
}

main :: proc() {
    for t in Test {
       // t == Test.test1/Test.test2/Test.3
    }
}

`union_cast` Syntax and Semantics

At the moment, if you want to get the variant type of a union, you will need to use either a match in statement or a union_cast.

match x in y {
case TypeA:
case TypeB:
}
x := union_cast(T)y; // panics if `y` is not of type `T`
x, ok := union_cast(T)y;

The problem with a union_cast is partially its name and its use. any can use match in to get the underlying value but it cannot use union_cast. Should the syntax for this operation be different compared to the other types of casting (cast and transmute) to allow for any too?

Should the syntax be similar to Go's type assertions:

x := y.(T);
x, ok := y.(T);

or something completely different to be more Odin-like?

Short if as parameter

Is this a bug?

println(i % 3 == 0 ? "Fizz" : i);
// <file>.odin(7:24) Cannot convert `Fizz` to `int`

Procedure overloading not resolving for ..any

main :: proc() {
    foo("FOO");
    foo("FOO", "FOO");
    foo("FOO", "FOO", "FOO");
}

foo :: proc(test : string, test1 : string, args : ...any) { ... }

foo :: proc(test : string) { ... }

This code snippet produces No overloads for 'Foo' that match with the given arguments on the third Foo(...) call

Compiler can't handle spaces in project directory

I just downloaded and compiled Odin (congratulations on having a simple Windows compilation process!) and came across a bug with your compiler.

image

The code is just a simple Hello World program as follows and compiles (did you re-add the need for ; at end of statements after your November stream? Haven't watched this months one yet).

#import "fmt.odin";

main :: proc() {
fmt.println("Hello World!");
}

I'm presuming that when you call the opt.exe that you don't consider the current directory could be one with spaces in it. I plan on having a look at the code myself, but in case you happen to see this before I have a chance to or know exactly where to look...

(I don't normally have spaces in directory names being a Linux guy, but when on Windows I have a hard time not using them)

Cyclic Type Checking

At the moment, there is no cyclic type checking and if a type has a cyclical definition, it will cause the compiler to go into an infinite loop.

Examples:

A :: type A

B :: type struct {
	c: C;
};

C :: type struct {
	b: B;
};

More lambdas in structs

I played around more with what I had (and wrote weird code) and I found 2 more weird behaviors.

#load "fmt.odin";

Human :: struct {
	name : string,
	toString : proc(h: Human) -> string
}

CreateHuman :: proc(name : string) -> Human {
	return Human {
		name,
		proc(h: Human) -> string {
			return "test";
		}
	};
}

main :: proc() {
	felix := CreateHuman("Felix");
	print(felix.toString(felix), "\n");
}

This crashes odin.exe.

And this doesn't compile and he complains:
minimal.odin(12:11) Undeclared name: h

#load "fmt.odin";

Human :: struct {
	name : string,
	toString : proc(h: Human) -> string
}

CreateHuman :: proc(name : string) -> Human {
	return Human {
		name,
		proc(h: Human) -> string {
			return h.name; // h is undeclared?
		}
	};
}

main :: proc() {
	felix := CreateHuman("Felix");
	print(felix.toString(felix), "\n");
}

I know this is weird code but I just wanted to play around with it.

Zero sized struct when used inside itself

Odin thinks SymbolTreeNode has size 0.

SymbolTreeNode :: struct {
	symbolType : SymbolType,
	symbol     : rune,
	children   : [dynamic]SymbolTreeNode
}
// Zero sized element type `SymbolTreeNode` is not allowed

Pointer arithmetic doesn't work

Repro code:

#import "fmt.odin";

main :: proc() {
  buffer := make([]u32, 1);
  buffer[0] = 23;
  fmt.printf("initial buffer: %v\n", buffer);

  p: rawptr = ^buffer[0];

  p_u32 := cast(^u32)p;
  p_u32^ = 42;

  fmt.printf("changed buffer: %v\n", buffer);

  fmt.printf("p_u32 (should be 42): %d\n", p_u32^);
  p_u32 += 1;
  p_u32 -= 1;
  fmt.printf("p_u32 (should be 42): %d\n", p_u32^);
}

Prints:

initial buffer: [23]
changed buffer: [42]
p_u32 (should be 42): 42
p_u32 (should be 42): 0

LLVM Error when returning a ? type

I was just trying to implement some basic 'file' reading (actually stdin) functionality just for my own testing of the language, and was thinking about how one could use your ? 'maybe' functionality.

My goal was to write a function that returns a ?byte instead of having to return an EOF like in the C fgetc implementation.

#import "fmt.odin";
#import "os.odin";

fgetc :: proc(fd : os.Handle) -> ?byte
{
	c : [1]byte;

	if bytes_read, _ := os.read(fd, c[:]); bytes_read == 0
	{
		return nil;
	}

	return c[0];
}

main :: proc ()
{
	b := fgetc(os.stdin);

	if bv, ok := b?; ok
	{
		fmt.println(b);
	}
}

However, when compiling, I end up with the following (llvm?) error

test.ll:1128:9: error: expected type
store zeroinitializer, * %19

I believe the relevant segment in the LLVM bytecode is as follows:

if.then-1:
	; ReturnStmt
	store {i8, i1} zeroinitializer, {i8, i1}* %4
	%19 = getelementptr inbounds {i8, i1}, {i8, i1}* %4, i64 0, i32 0
	%20 = getelementptr inbounds {i8, i1}, {i8, i1}* %4, i64 0, i32 1
	store  zeroinitializer, * %19
	store i1 true, i1* %20
	%21 = load {i8, i1}, {i8, i1}* %4, align 1
	ret {i8, i1} %21

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.