aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-06-07 22:09:16 +0100
committerGinger Bill <bill@gingerbill.org>2017-06-07 22:09:16 +0100
commit574b82c0c7e266bcd1bc16ee709d32936625cf46 (patch)
tree2490104e638424a41d86d37395aefc99a00e5451
parentf60c772c11154d16c12d30a7f19c2c2e07068642 (diff)
v0.3.0
-rw-r--r--build.bat9
-rw-r--r--code/demo.odin203
-rw-r--r--core/_preload.odin4
-rw-r--r--core/_soft_numbers.odin4
-rw-r--r--core/fmt.odin2
-rw-r--r--src/build_settings.c2
-rw-r--r--src/check_expr.c8
-rw-r--r--src/integer128.c26
-rw-r--r--src/ir.c1
9 files changed, 225 insertions, 34 deletions
diff --git a/build.bat b/build.bat
index 51dfc84b4..b5ceccaf1 100644
--- a/build.bat
+++ b/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
diff --git a/code/demo.odin b/code/demo.odin
index c67cee184..e21d689c1 100644
--- a/code/demo.odin
+++ b/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
}
diff --git a/core/_preload.odin b/core/_preload.odin
index c13622c4e..4e5d9e9e4 100644
--- a/core/_preload.odin
+++ b/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,
diff --git a/core/_soft_numbers.odin b/core/_soft_numbers.odin
index fd7dc2905..6b1a86557 100644
--- a/core/_soft_numbers.odin
+++ b/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);
diff --git a/core/fmt.odin b/core/fmt.odin
index c1057a406..e436a5e46 100644
--- a/core/fmt.odin
+++ b/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);
diff --git a/src/build_settings.c b/src/build_settings.c
index 1a6b8fdf5..0ba38e30f 100644
--- a/src/build_settings.c
+++ b/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)
diff --git a/src/check_expr.c b/src/check_expr.c
index 75d38f4fc..1ed7378e5 100644
--- a/src/check_expr.c
+++ b/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));
diff --git a/src/integer128.c b/src/integer128.c
index ed05a1471..6cce03143 100644
--- a/src/integer128.c
+++ b/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;
diff --git a/src/ir.c b/src/ir.c
index e014cb229..3acc78afe 100644
--- a/src/ir.c
+++ b/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: