aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-03-05 20:34:30 +0000
committergingerBill <bill@gingerbill.org>2020-03-05 20:34:30 +0000
commite92fdb4a99bf9d27009dd35fdd074ff14facfc03 (patch)
treee74c13d12da216f2548db0a8359e491263dc6acd /core
parent2fe0eaf2adf952867d4ce4fba53b4b3ac75e1ba5 (diff)
`x if cond else y` and `x when cond else y` expressions
Diffstat (limited to 'core')
-rw-r--r--core/c/c.odin6
-rw-r--r--core/fmt/fmt.odin10
-rw-r--r--core/log/file_console_logger.odin2
-rw-r--r--core/log/log.odin2
-rw-r--r--core/math/linalg/general.odin6
-rw-r--r--core/math/linalg/specific.odin32
-rw-r--r--core/math/math.odin8
-rw-r--r--core/odin/ast/ast.odin18
-rw-r--r--core/odin/parser/parser.odin39
-rw-r--r--core/odin/tokenizer/token.odin6
-rw-r--r--core/reflect/types.odin2
-rw-r--r--core/runtime/internal.odin10
-rw-r--r--core/strconv/generic_float.odin4
-rw-r--r--core/strings/strings.odin2
-rw-r--r--core/time/time.odin2
15 files changed, 107 insertions, 42 deletions
diff --git a/core/c/c.odin b/core/c/c.odin
index 3ed49c0c2..757abcac9 100644
--- a/core/c/c.odin
+++ b/core/c/c.odin
@@ -14,8 +14,8 @@ ushort :: b.u16;
int :: b.i32;
uint :: b.u32;
-long :: (ODIN_OS == "windows" || size_of(b.rawptr) == 4) ? b.i32 : b.i64;
-ulong :: (ODIN_OS == "windows" || size_of(b.rawptr) == 4) ? b.u32 : b.u64;
+long :: b.i32 when (ODIN_OS == "windows" || size_of(b.rawptr) == 4) else b.i64;
+ulong :: b.u32 when (ODIN_OS == "windows" || size_of(b.rawptr) == 4) else b.u64;
longlong :: b.i64;
ulonglong :: b.u64;
@@ -32,4 +32,4 @@ ptrdiff_t :: b.int;
uintptr_t :: b.uintptr;
intptr_t :: b.int;
-wchar_t :: (ODIN_OS == "windows") ? b.u16 : b.u32;
+wchar_t :: b.u16 when (ODIN_OS == "windows") else b.u32;
diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin
index c061c1c47..626b0797d 100644
--- a/core/fmt/fmt.odin
+++ b/core/fmt/fmt.odin
@@ -732,7 +732,7 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
}
strings.write_string(fi.buf, "0h");
- _fmt_int(fi, u, 16, false, bit_size, verb == 'h' ? __DIGITS_LOWER : __DIGITS_UPPER);
+ _fmt_int(fi, u, 16, false, bit_size, __DIGITS_LOWER if verb == 'h' else __DIGITS_UPPER);
case:
@@ -1154,7 +1154,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
is_soa := b.soa_kind != .None;
strings.write_string(fi.buf, info.name);
- strings.write_byte(fi.buf, is_soa ? '[' : '{');
+ strings.write_byte(fi.buf, '[' if is_soa else '{');
hash := fi.hash; defer fi.hash = hash;
indent := fi.indent; defer fi.indent -= 1;
@@ -1165,7 +1165,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
if hash do strings.write_byte(fi.buf, '\n');
defer {
if hash do for in 0..<indent do strings.write_byte(fi.buf, '\t');
- strings.write_byte(fi.buf, is_soa ? ']' : '}');
+ strings.write_byte(fi.buf, ']' if is_soa else '}');
}
if is_soa {
@@ -1415,8 +1415,8 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
is_soa := info.soa_kind != .None;
- strings.write_byte(fi.buf, is_soa ? '[' : '{');
- defer strings.write_byte(fi.buf, is_soa ? ']' : '}');
+ strings.write_byte(fi.buf, '[' if is_soa else '{');
+ defer strings.write_byte(fi.buf, ']' if is_soa else '}');
fi.indent += 1; defer fi.indent -= 1;
hash := fi.hash; defer fi.hash = hash;
diff --git a/core/log/file_console_logger.odin b/core/log/file_console_logger.odin
index 89e88d75e..3136f967b 100644
--- a/core/log/file_console_logger.odin
+++ b/core/log/file_console_logger.odin
@@ -64,7 +64,7 @@ file_console_logger_proc :: proc(logger_data: rawptr, level: Level, text: string
data := cast(^File_Console_Logger_Data)logger_data;
h : os.Handle;
if(data.file_handle != os.INVALID_HANDLE) do h = data.file_handle;
- else do h = level <= Level.Error ? context.stdout : context.stderr;
+ else do h = context.stdout if level <= Level.Error else context.stderr;
backing: [1024]byte; //NOTE(Hoej): 1024 might be too much for a header backing, unless somebody has really long paths.
buf := strings.builder_from_slice(backing[:]);
diff --git a/core/log/log.odin b/core/log/log.odin
index 899f9274e..291d9b739 100644
--- a/core/log/log.odin
+++ b/core/log/log.odin
@@ -125,6 +125,6 @@ log :: proc(level : Level, args : ..any, location := #caller_location) {
logf :: proc(level : Level, fmt_str : string, args : ..any, location := #caller_location) {
logger := context.logger;
if level < logger.lowest_level do return;
- str := len(args) > 0 ? fmt.tprintf(fmt_str, ..args) : fmt.tprint(fmt_str); //NOTE(Hoej): While tprint isn't thread-safe, no logging is.
+ str := fmt.tprintf(fmt_str, ..args) if len(args) > 0 else fmt.tprint(fmt_str); //NOTE(Hoej): While tprint isn't thread-safe, no logging is.
logger.procedure(logger.data, level, str, logger.options, location);
}
diff --git a/core/math/linalg/general.odin b/core/math/linalg/general.odin
index 921d56c80..c7b455781 100644
--- a/core/math/linalg/general.odin
+++ b/core/math/linalg/general.odin
@@ -54,11 +54,11 @@ normalize :: proc{vector_normalize, quaternion_normalize};
vector_normalize0 :: proc(v: $T/[$N]$E) -> T where IS_NUMERIC(E) {
m := length(v);
- return m == 0 ? 0 : v/m;
+ return 0 if m == 0 else v/m;
}
quaternion_normalize0 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
m := abs(q);
- return m == 0 ? 0 : q/m;
+ return 0 if m == 0 else q/m;
}
normalize0 :: proc{vector_normalize0, quaternion_normalize0};
@@ -258,7 +258,7 @@ vector_mix :: proc(x, y, a: $V/[$N]$E) -> V where IS_NUMERIC(E) {
vector_step :: proc(edge, x: $V/[$N]$E) -> V where IS_NUMERIC(E) {
s: V;
for i in 0..<N {
- s[i] = x[i] < edge[i] ? 0 : 1;
+ s[i] = 0 if x[i] < edge[i] else 1;
}
return s;
}
diff --git a/core/math/linalg/specific.odin b/core/math/linalg/specific.odin
index e940ee05d..fefd7ee2b 100644
--- a/core/math/linalg/specific.odin
+++ b/core/math/linalg/specific.odin
@@ -8,7 +8,7 @@ import "intrinsics"
Float :: f32;
-FLOAT_EPSILON :: size_of(Float) == 4 ? 1e-7 : 1e-15;
+FLOAT_EPSILON :: 1e-7 when size_of(Float) == 4 else 1e-15;
Vector2 :: distinct [2]Float;
Vector3 :: distinct [3]Float;
@@ -39,7 +39,7 @@ Matrix2 :: Matrix2x2;
Matrix3 :: Matrix3x3;
Matrix4 :: Matrix4x4;
-Quaternion :: distinct (size_of(Float) == size_of(f32) ? quaternion128 : quaternion256);
+Quaternion :: distinct (quaternion128 when size_of(Float) == size_of(f32) else quaternion256);
MATRIX1_IDENTITY :: Matrix1{{1}};
MATRIX2_IDENTITY :: Matrix2{{1, 0}, {0, 1}};
@@ -71,8 +71,20 @@ vector3_orthogonal :: proc(v: Vector3) -> Vector3 {
y := abs(v.y);
z := abs(v.z);
- other: Vector3 = x < y ? (x < z ? {1, 0, 0} : {0, 0, 1}) : (y < z ? {0, 1, 0} : {0, 0, 1});
-
+ other: Vector3;
+ if x < y {
+ if x < z {
+ other = {1, 0, 0};
+ } else {
+ other = {0, 0, 1};
+ }
+ } else {
+ if y < z {
+ other = {0, 1, 0};
+ } else {
+ other = {0, 0, 1};
+ }
+ }
return normalize(cross(v, other));
}
@@ -124,7 +136,7 @@ vector4_hsl_to_rgb :: proc(h, s, l: Float, a: Float = 1) -> Vector4 {
g = l;
b = l;
} else {
- q := l < 0.5 ? l * (1+s) : l+s - l*s;
+ q := l * (1+s) if l < 0.5 else l+s - l*s;
p := 2*l - q;
r = hue_to_rgb(p, q, h + 1.0/3.0);
g = hue_to_rgb(p, q, h);
@@ -147,10 +159,10 @@ vector4_rgb_to_hsl :: proc(col: Vector4) -> Vector4 {
if v_max != v_min {
d: = v_max - v_min;
- s = l > 0.5 ? d / (2.0 - v_max - v_min) : d / (v_max + v_min);
+ s = d / (2.0 - v_max - v_min) if l > 0.5 else d / (v_max + v_min);
switch {
case v_max == r:
- h = (g - b) / d + (g < b ? 6.0 : 0.0);
+ h = (g - b) / d + (6.0 if g < b else 0.0);
case v_max == g:
h = (b - r) / d + 2.0;
case v_max == b:
@@ -627,9 +639,9 @@ matrix4_inverse :: proc(m: Matrix4) -> Matrix4 {
matrix4_minor :: proc(m: Matrix4, c, r: int) -> Float {
cut_down: Matrix3;
for i in 0..<3 {
- col := i < c ? i : i+1;
+ col := i if i < c else i+1;
for j in 0..<3 {
- row := j < r ? j : j+1;
+ row := j if j < r else j+1;
cut_down[i][j] = m[col][row];
}
}
@@ -638,7 +650,7 @@ matrix4_minor :: proc(m: Matrix4, c, r: int) -> Float {
matrix4_cofactor :: proc(m: Matrix4, c, r: int) -> Float {
sign, minor: Float;
- sign = (c + r) % 2 == 0 ? 1 : -1;
+ sign = 1 if (c + r) % 2 == 0 else -1;
minor = matrix4_minor(m, c, r);
return sign * minor;
}
diff --git a/core/math/math.odin b/core/math/math.odin
index d5ec9f3ae..cb7231b86 100644
--- a/core/math/math.odin
+++ b/core/math/math.odin
@@ -115,7 +115,7 @@ unlerp :: proc{unlerp_f32, unlerp_f64};
wrap :: proc(x, y: $T) -> T where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
tmp := mod(x, y);
- return tmp < 0 ? wrap + tmp : tmp;
+ return wrap + tmp if tmp < 0 else tmp;
}
angle_diff :: proc(a, b: $T) -> T where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
@@ -128,7 +128,7 @@ angle_lerp :: proc(a, b, t: $T) -> T where intrinsics.type_is_numeric(T), !intri
}
step :: proc(edge, x: $T) -> T where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
- return x < edge ? 0 : 1;
+ return 0 if x < edge else 1;
}
smoothstep :: proc(edge0, edge1, x: $T) -> T where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
@@ -246,10 +246,10 @@ trunc_f64 :: proc(x: f64) -> f64 {
trunc :: proc{trunc_f32, trunc_f64};
round_f32 :: proc(x: f32) -> f32 {
- return x < 0 ? ceil(x - 0.5) : floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
}
round_f64 :: proc(x: f64) -> f64 {
- return x < 0 ? ceil(x - 0.5) : floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
}
round :: proc{round_f32, round_f64};
diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin
index 931000a7c..4bd50abd7 100644
--- a/core/odin/ast/ast.odin
+++ b/core/odin/ast/ast.odin
@@ -200,6 +200,24 @@ Ternary_Expr :: struct {
y: ^Expr,
}
+Ternary_If_Expr :: struct {
+ using node: Expr,
+ x: ^Expr,
+ op1: tokenizer.Token,
+ cond: ^Expr,
+ op2: tokenizer.Token,
+ y: ^Expr,
+}
+
+Ternary_When_Expr :: struct {
+ using node: Expr,
+ x: ^Expr,
+ op1: tokenizer.Token,
+ cond: ^Expr,
+ op2: tokenizer.Token,
+ y: ^Expr,
+}
+
Type_Assertion :: struct {
using node: Expr,
expr: ^Expr,
diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin
index 3f81cb61d..c4e6d8142 100644
--- a/core/odin/parser/parser.odin
+++ b/core/odin/parser/parser.odin
@@ -1028,7 +1028,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
if tok.kind != .Fallthrough && p.curr_tok.kind == .Ident {
label = parse_ident(p);
}
- end := label != nil ? label.end : end_pos(tok);
+ end := label.end if label != nil else end_pos(tok);
s := ast.new(ast.Branch_Stmt, tok.pos, end);
expect_semicolon(p, s);
return s;
@@ -1132,6 +1132,8 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
token_precedence :: proc(p: ^Parser, kind: tokenizer.Token_Kind) -> int {
#partial switch kind {
case .Question:
+ case .If:
+ case .When:
return 1;
case .Ellipsis, .Range_Half:
if !p.allow_range {
@@ -2453,7 +2455,7 @@ parse_literal_value :: proc(p: ^Parser, type: ^ast.Expr) -> ^ast.Comp_Lit {
close := expect_token_after(p, .Close_Brace, "compound literal");
- pos := type != nil ? type.pos : open.pos;
+ pos := type.pos if type != nil else open.pos;
lit := ast.new(ast.Comp_Lit, pos, end_pos(close));
lit.type = type;
lit.open = open.pos;
@@ -2714,6 +2716,13 @@ parse_binary_expr :: proc(p: ^Parser, lhs: bool, prec_in: int) -> ^ast.Expr {
if op_prec != prec {
break;
}
+ if op.kind == .If || op.kind == .When {
+ if p.prev_tok.pos.line < op.pos.line {
+ // NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition
+ break;
+ }
+ }
+
expect_operator(p);
if op.kind == .Question {
@@ -2729,6 +2738,32 @@ parse_binary_expr :: proc(p: ^Parser, lhs: bool, prec_in: int) -> ^ast.Expr {
te.y = y;
expr = te;
+ } else if op.kind == .If {
+ x := expr;
+ cond := parse_expr(p, lhs);
+ else_tok := expect_token(p, .Else);
+ y := parse_expr(p, lhs);
+ te := ast.new(ast.Ternary_If_Expr, expr.pos, end_pos(p.prev_tok));
+ te.x = x;
+ te.op1 = op;
+ te.cond = cond;
+ te.op2 = else_tok;
+ te.y = y;
+
+ expr = te;
+ } else if op.kind == .When {
+ x := expr;
+ cond := parse_expr(p, lhs);
+ op2 := expect_token(p, .Else);
+ y := parse_expr(p, lhs);
+ te := ast.new(ast.Ternary_When_Expr, expr.pos, end_pos(p.prev_tok));
+ te.x = x;
+ te.op1 = op;
+ te.cond = cond;
+ te.op2 = else_tok;
+ te.y = y;
+
+ expr = te;
} else {
right := parse_binary_expr(p, false, prec+1);
if right == nil {
diff --git a/core/odin/tokenizer/token.odin b/core/odin/tokenizer/token.odin
index c5f0247f4..997ca7ac1 100644
--- a/core/odin/tokenizer/token.odin
+++ b/core/odin/tokenizer/token.odin
@@ -17,13 +17,13 @@ Pos :: struct {
pos_compare :: proc(lhs, rhs: Pos) -> int {
if lhs.offset != rhs.offset {
- return (lhs.offset < rhs.offset) ? -1 : +1;
+ return -1 if (lhs.offset < rhs.offset) else +1;
}
if lhs.line != rhs.line {
- return (lhs.line < rhs.line) ? -1 : +1;
+ return -1 if (lhs.line < rhs.line) else +1;
}
if lhs.column != rhs.column {
- return (lhs.column < rhs.column) ? -1 : +1;
+ return -1 if (lhs.column < rhs.column) else +1;
}
return strings.compare(lhs.file, rhs.file);
}
diff --git a/core/reflect/types.odin b/core/reflect/types.odin
index 42ab9828a..3ea121bc3 100644
--- a/core/reflect/types.odin
+++ b/core/reflect/types.odin
@@ -321,7 +321,7 @@ write_type :: proc(buf: ^strings.Builder, ti: ^rt.Type_Info) {
case uint: write_string(buf, "uint");
case uintptr: write_string(buf, "uintptr");
case:
- write_byte(buf, info.signed ? 'i' : 'u');
+ write_byte(buf, 'i' if info.signed else 'u');
write_i64(buf, i64(8*ti.size), 10);
switch info.endianness {
case .Platform: // Okay
diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin
index 60359fd6c..68d613c1b 100644
--- a/core/runtime/internal.odin
+++ b/core/runtime/internal.odin
@@ -191,7 +191,7 @@ print_type :: proc(fd: os.Handle, ti: ^Type_Info) {
case uint: os.write_string(fd, "uint");
case uintptr: os.write_string(fd, "uintptr");
case:
- os.write_byte(fd, info.signed ? 'i' : 'u');
+ os.write_byte(fd, 'i' if info.signed else 'u');
print_u64(fd, u64(8*ti.size));
}
case Type_Info_Rune:
@@ -421,7 +421,7 @@ memory_compare :: proc "contextless" (a, b: rawptr, n: int) -> int #no_bounds_ch
a := (^byte)(x+pos)^;
b := (^byte)(y+pos)^;
if a ~ b != 0 {
- return (int(a) - int(b)) < 0 ? -1 : +1;
+ return -1 if (int(a) - int(b)) < 0 else +1;
}
}
}
@@ -431,7 +431,7 @@ memory_compare :: proc "contextless" (a, b: rawptr, n: int) -> int #no_bounds_ch
a := (^byte)(x+offset)^;
b := (^byte)(y+offset)^;
if a ~ b != 0 {
- return (int(a) - int(b)) < 0 ? -1 : +1;
+ return -1 if (int(a) - int(b)) < 0 else +1;
}
}
@@ -456,7 +456,7 @@ memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int #no_bounds_
for pos := curr_block*SU; pos < n; pos += 1 {
a := (^byte)(x+pos)^;
if a ~ 0 != 0 {
- return int(a) < 0 ? -1 : +1;
+ return -1 if int(a) < 0 else +1;
}
}
}
@@ -465,7 +465,7 @@ memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int #no_bounds_
for /**/; offset < n; offset += 1 {
a := (^byte)(x+offset)^;
if a ~ 0 != 0 {
- return int(a) < 0 ? -1 : +1;
+ return -1 if int(a) < 0 else +1;
}
}
diff --git a/core/strconv/generic_float.odin b/core/strconv/generic_float.odin
index 622dcd044..ad0c51880 100644
--- a/core/strconv/generic_float.odin
+++ b/core/strconv/generic_float.odin
@@ -110,7 +110,7 @@ format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slic
switch fmt {
case 'f', 'F':
- add_bytes(&b, neg ? '-' : '+');
+ add_bytes(&b, '-' if neg else '+');
// integer, padded with zeros when needed
if digs.decimal_point > 0 {
@@ -138,7 +138,7 @@ format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slic
return to_bytes(b);
case 'e', 'E':
- add_bytes(&b, neg ? '-' : '+');
+ add_bytes(&b, '-' if neg else '+');
ch := byte('0');
if digs.count != 0 {
diff --git a/core/strings/strings.odin b/core/strings/strings.odin
index a477b9e13..fd3808684 100644
--- a/core/strings/strings.odin
+++ b/core/strings/strings.odin
@@ -325,7 +325,7 @@ last_index :: proc(s, substr: string) -> int {
case n == 1:
return last_index_byte(s, substr[0]);
case n == len(s):
- return substr == s ? 0 : -1;
+ return 0 if substr == s else -1;
case n > len(s):
return -1;
}
diff --git a/core/time/time.odin b/core/time/time.odin
index 51c77a468..93fa7f8b3 100644
--- a/core/time/time.odin
+++ b/core/time/time.odin
@@ -92,7 +92,7 @@ duration_round :: proc(d, m: Duration) -> Duration {
return MAX_DURATION;
}
duration_truncate :: proc(d, m: Duration) -> Duration {
- return m <= 0 ? d : d - d%m;
+ return d if m <= 0 else d - d%m;
}