Ginger Bill 8 年之前
父節點
當前提交
574b82c0c7
共有 9 個文件被更改,包括 225 次插入34 次删除
  1. 5 4
      build.bat
  2. 192 11
      code/demo.odin
  3. 2 2
      core/_preload.odin
  4. 2 2
      core/_soft_numbers.odin
  5. 1 1
      core/fmt.odin
  6. 1 1
      src/build_settings.c
  7. 8 0
      src/check_expr.c
  8. 13 13
      src/integer128.c
  9. 1 0
      src/ir.c

+ 5 - 4
build.bat

@@ -4,7 +4,7 @@
 set exe_name=odin.exe
 
 :: Debug = 0, Release = 1
-set release_mode=0
+set release_mode=1
 set compiler_flags= -nologo -Oi -TC -fp:fast -fp:except- -Gm- -MP -FC -GS- -EHsc- -GR-
 
 if %release_mode% EQU 0 ( rem Debug
@@ -42,9 +42,10 @@ set linker_settings=%libs% %linker_flags%
 del *.pdb > NUL 2> NUL
 del *.ilk > NUL 2> NUL
 
-cl %compiler_settings% "src\main.c" ^
-	/link %linker_settings% -OUT:%exe_name% ^
-	&& odin run code/demo.odin
+odin run code/demo.odin
+rem cl %compiler_settings% "src\main.c" ^
+	rem /link %linker_settings% -OUT:%exe_name% ^
+	rem && odin run code/demo.odin
 	rem && odin build code/metagen.odin ^
 	rem && call "code\metagen.exe" "src\ast_nodes.metagen"
 	rem && odin run code/Jaze/src/main.odin

+ 192 - 11
code/demo.odin

@@ -1,18 +1,199 @@
+//
+// Odin v0.3 Demo
+//
+
 #import "fmt.odin";
 
 main :: proc() {
-	immutable program := "+ + * - /";
-	accumulator := 0;
-
-	for token in program {
-		match token {
-		case '+': accumulator += 1;
-		case '-': accumulator -= 1;
-		case '*': accumulator *= 2;
-		case '/': accumulator /= 2;
-		case: // Ignore everything else
+/*
+	Minor features
+	--------------
+
+	* Lexical sugar
+		- ≠, ≤, ≥
+	* Label syntax change
+		name: for {
+			break name;
+		}
+	* `#no_alias` (replacing keyword `no_alias`)
+	* `#ordered` reimplemented
+	* "bits.odin"
+	* `default:` is replaced with `case:`
+	* XOR for booleans
+	* Bug fixes
+	* Removed Quaternion types quaternion128 & quaternion256
+	* `rune` is a core type - allowing for extra type information at runtime
+	* `byte` is removed - use `u8` instead (which it was an alias for)
+*/
+
+	// 128 bit integers
+	{
+		x: u128 = 1234567890123;
+		y: u128 = 9876543210123;
+		z := (x * y) + x + y;
+		fmt.println(z);
+
+		a: i128 = +1234567890123;
+		b: i128 = -9876543210123;
+		c := (a * b) + a + b;
+		fmt.println(c);
+	}
+
+	// Divisor based modulo operator
+	{
+		x: i128 = -5;
+		y: i128 = 2;
+
+		fmt.println(x %  y); // Dividend based
+		fmt.println(x %% y); // Divisor based
+
+		// a %% b == ((a % b) + b) % b;
+	}
+
+	// Casting syntax
+	{
+		// Casting operations have had their syntax change for simplicity and consistency
+		// Original:
+		// Regular cast: `cast(type) expr`
+		// Bit cast:     `transmute(type) expr`
+		// Union cast:   `union_cast(type) expr`
+
+		// Regular Cast
+		f: f32 = 123.321;
+		i := i32(f); // type(expr)
+
+
+		// Bit cast
+		fbits := transmute(u32, f);
+
+
+
+		// Type assertion - replaces `union_cast`
+		Entity :: union {
+			id:       u64,
+			position: [vector 2]f32,
+			name:     string,
+			Tree{leaf_count: int},
+			Frog{ribbit_volume: f32},
+		}
+
+		e: Entity;
+		e = Entity.Frog{ribbit_volume = 0.5, name = "Trevor"};
+
+		if frog, ok := e.(Entity.Frog); ok {
+			fmt.printf("%s the frog ribbit's at %f\n", frog.name, frog.ribbit_volume);
+		}
+
+		// Panics if the type assertion fails
+		frog := e.(Entity.Frog);
+
+		{
+			// Type assertion can also be applied to `any`
+			foo: any = 123;
+			if i, ok := foo.(int); ok {
+				fmt.println("Foo =", i);
+			}
+		}
+	}
+
+	// Syntax changes
+	{
+		// Originally `^` was used to represent pointer types, pointer dereferencing, and addressing of variables
+		// The addressing of variable operation is not represented with `&`
+		// This is to make sure the concept of a pointer type is separate from that of a addressing
+		// it is also used for familiarity coming from other C-like languages
+		x: int  = 123;
+		y: ^int = &x;
+		z: int  = y^;
+
+		// This change also allows type casting to not require parentheses around the type for pointer evaluation
+		// and consitency with other operations
+
+		data := rawptr(&x);
+		int_ptr := ^int(data);
+
+		array: [10]int; // Type of the left
+		x = array[0];   // Usage on the right
+
+		ptr: ^int = &z; // Type of the left
+		x = ptr^;       // Usage on the right
+
+
+
+		// Minor addition - member access through number
+		TupleLike :: struct{int, f32, string}; // Fields all anonymous
+		t: TupleLike;
+		t.0 = 123;
+		t.1 = 46.432;
+		t.2 = "Foo";
+		fmt.println(t);
+	}
+
+	// Bit fields
+	{
+		BoxProps :: bit_field {
+			opaque:       1,
+			fill_colour:  3,
+			_:            4,
+			show_border:  1,
+			_:            3,
+			border_style: 2,
+			_:            2,
+			width:        4,
+			height:       4,
+		};
+
+		props: BoxProps;
+		props.fill_colour = 4;
+		props.show_border = 1;
+		props.width       = 12;
+		props.height      = 10;
+
+		fmt.printf("Width: %d, Height: %d\n", props.width, props.height);
+
+
+
+		Float32Data :: bit_field {
+			fraction: 23,
+			exponent:  8,
+			sign:      1,
 		}
+
+		f: f32 = -123.321;
+		data := transmute(Float32Data, f);
+		bits := transmute(u32, f);
+		fmt.printf("%#05x %#02x %v\n", data.fraction, data.exponent, bool(data.sign));
+		fmt.printf("%#08x\n", bits);
+	}
+
+	// Naming convention
+	{
+		// Odin has finally chose an official naming convention
+		// In general, PascalCase for types and snake_case for values
+
+		// Import Name:        snake_case (but prefer single word)
+		// Types:              PascalCase
+		// Union Variants:     PascalCase
+		// Enum Values:        PascalCase
+		// Procedures:         snake_case
+		// Local Variables:    snake_case
+		// Field Values:       snake_case
+		// Constant Variables: SCREAMING_SNAKE_CASE
 	}
 
-	fmt.printf("The program \"%s\" calculates the value %d\n", program, accumulator);
+	// Goals for v0.4 and further
+	//  * Compile as C++and use some of its constructs for sanity e.g. overloading
+	//  	- Safe array with bounds checking
+	//  	- Map type for self documentation
+	//  	- u128 i128 acting like core types
+	//  * Context system implemented as Implicit Parameter Passing (IPP) rather than Thread Local Storage (TLS)
+	//  * Parameter Polymorphism
+	//  	- Type parameter is procedures and types
+	//  * Decide upon a declaration syntax
+	//  	- Current Style (name: type;) vs Prefix Style (var name: type;)
+	//  * Import system with a "solution" for packages/modules/libraries
+	//  * Better foreign interfacing with C (and maybe C++)
+	//  	- Foreign variables
+	//  * Documentation Generation System for code
+	//  * General Documentation for Odin
 }

+ 2 - 2
core/_preload.odin

@@ -158,8 +158,8 @@ AllocatorMode :: enum u8 {
 	Resize,
 }
 AllocatorProc :: #type proc(allocator_data: rawptr, mode: AllocatorMode,
-                             size, alignment: int,
-                             old_memory: rawptr, old_size: int, flags: u64) -> rawptr;
+                            size, alignment: int,
+                            old_memory: rawptr, old_size: int, flags: u64) -> rawptr;
 Allocator :: struct #ordered {
 	procedure: AllocatorProc,
 	data:      rawptr,

+ 2 - 2
core/_soft_numbers.odin

@@ -27,8 +27,8 @@ __i128_quo_mod :: proc(a, b: i128, rem: ^i128) -> (quo: i128) #cc_odin #link_nam
 	s = a >> 127;
 	b = (a~s) - s;
 
-	urem: u128;
-	uquo := __u128_quo_mod(transmute(u128, a), transmute(u128, b), &urem);
+	uquo: u128;
+	urem := __u128_quo_mod(transmute(u128, a), transmute(u128, b), &uquo);
 	iquo := transmute(i128, uquo);
 	irem := transmute(i128, urem);
 

+ 1 - 1
core/fmt.odin

@@ -1023,7 +1023,7 @@ fmt_arg :: proc(fi: ^FmtInfo, arg: any, verb: rune) {
 	case i16:     fmt_int(fi, u128(a), true,  16, verb);
 	case i32:     fmt_int(fi, u128(a), true,  32, verb);
 	case i64:     fmt_int(fi, u128(a), true,  64, verb);
-	case i128:    fmt_int(fi, u128(a), false, 128, verb);
+	case i128:    fmt_int(fi, u128(a), true, 128, verb);
 
 	case uint:    fmt_int(fi, u128(a), false, 8*size_of(uint), verb);
 	case u8:      fmt_int(fi, u128(a), false, 8, verb);

+ 1 - 1
src/build_settings.c

@@ -263,7 +263,7 @@ String get_fullpath_core(gbAllocator a, String path) {
 void init_build_context(void) {
 	BuildContext *bc = &build_context;
 	bc->ODIN_VENDOR  = str_lit("odin");
-	bc->ODIN_VERSION = str_lit("0.2.1");
+	bc->ODIN_VERSION = str_lit("0.3.0");
 	bc->ODIN_ROOT    = odin_root_dir();
 
 #if defined(GB_SYSTEM_WINDOWS)

+ 8 - 0
src/check_expr.c

@@ -2643,6 +2643,14 @@ bool check_is_castable_to(Checker *c, Operand *operand, Type *y) {
 		return true;
 	}
 
+	if (is_type_bit_field_value(src) && is_type_integer(dst)) {
+		return true;
+	}
+
+	if (is_type_bit_field_value(src) && is_type_boolean(dst)) {
+		return src->BitFieldValue.bits == 1;
+	}
+
 	// Cast between pointers
 	if (is_type_pointer(src) && is_type_pointer(dst)) {
 		Type *s = base_type(type_deref(src));

+ 13 - 13
src/integer128.c

@@ -554,28 +554,28 @@ i128 i128_mul(i128 a, i128 b) {
 	return res;
 }
 
-void i128_divide(i128 num, i128 den, i128 *quo, i128 *rem) {
+void i128_divide(i128 a, i128 b, i128 *quo, i128 *rem) {
 	// TODO(bill): Which one is correct?!
-#if 0
-	i128 s = i128_shr(den, 127);
-	den = i128_sub(i128_xor(den, s), s);
-	s = i128_shr(num, 127);
-	den = i128_sub(i128_xor(num, s), s);
+#if 1
+	i128 s = i128_shr(b, 127);
+	b = i128_sub(i128_xor(b, s), s);
+	s = i128_shr(a, 127);
+	b = i128_sub(i128_xor(a, s), s);
 
 	u128 n, r = {0};
-	u128_divide(*cast(u128 *)&num, *cast(u128 *)&den, &n, &r);
+	u128_divide(*cast(u128 *)&a, *cast(u128 *)&b, &n, &r);
 	i128 ni = *cast(i128 *)&n;
 	i128 ri = *cast(i128 *)&r;
 
-	if (quo) *quo = i128_sub(i128_xor(ni, s), s);
-	if (rem) *rem = i128_sub(i128_xor(ri, s), s);
+	if (quo) *quo = i128_sub(i128_xor(ri, s), s);
+	if (rem) *rem = i128_sub(i128_xor(ni, s), s);
 #else
-	if (i128_eq(den, I128_ZERO)) {
-		if (quo) *quo = i128_from_u64(num.lo/den.lo);
+	if (i128_eq(b, I128_ZERO)) {
+		if (quo) *quo = i128_from_u64(a.lo/b.lo);
 		if (rem) *rem = I128_ZERO;
 	} else {
-		i128 n = num;
-		i128 d = den;
+		i128 n = a;
+		i128 d = b;
 		i128 x = I128_ONE;
 		i128 r = I128_ZERO;
 

+ 1 - 0
src/ir.c

@@ -3060,6 +3060,7 @@ bool ir_is_type_aggregate(Type *t) {
 	case Type_Tuple:
 	case Type_DynamicArray:
 	case Type_Map:
+	case Type_BitField:
 		return true;
 
 	case Type_Named: