mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
"Maybe-fy" operator
This commit is contained in:
+1
-11
@@ -1,16 +1,6 @@
|
|||||||
#import "fmt.odin"
|
#import "fmt.odin"
|
||||||
|
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
maybe_print :: proc(x: ?int) {
|
x := ?123
|
||||||
if v, ok := x?; ok {
|
|
||||||
fmt.println(v)
|
|
||||||
} else {
|
|
||||||
fmt.println("nowt")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
maybe_print(123) // 123
|
|
||||||
maybe_print(nil) // nowt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+28
-2
@@ -1044,6 +1044,9 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c
|
|||||||
if (ue->op.kind == Token_Pointer) {
|
if (ue->op.kind == Token_Pointer) {
|
||||||
type = make_type_pointer(c->allocator, check_type(c, ue->expr));
|
type = make_type_pointer(c->allocator, check_type(c, ue->expr));
|
||||||
goto end;
|
goto end;
|
||||||
|
} else if (ue->op.kind == Token_Maybe) {
|
||||||
|
type = make_type_maybe(c->allocator, check_type(c, ue->expr));
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
@@ -1365,7 +1368,8 @@ b32 check_is_expr_vector_index(Checker *c, AstNode *expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
||||||
if (op.kind == Token_Pointer) { // Pointer address
|
switch (op.kind) {
|
||||||
|
case Token_Pointer: { // Pointer address
|
||||||
if (o->mode != Addressing_Variable ||
|
if (o->mode != Addressing_Variable ||
|
||||||
check_is_expr_vector_index(c, o->expr)) {
|
check_is_expr_vector_index(c, o->expr)) {
|
||||||
ast_node(ue, UnaryExpr, node);
|
ast_node(ue, UnaryExpr, node);
|
||||||
@@ -1380,6 +1384,27 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Token_Maybe: { // Make maybe
|
||||||
|
Type *t = default_type(o->type);
|
||||||
|
b32 is_value =
|
||||||
|
o->mode == Addressing_Variable ||
|
||||||
|
o->mode == Addressing_Value ||
|
||||||
|
o->mode == Addressing_Constant;
|
||||||
|
|
||||||
|
if (!is_value || is_type_untyped(t)) {
|
||||||
|
ast_node(ue, UnaryExpr, node);
|
||||||
|
gbString str = expr_to_string(ue->expr);
|
||||||
|
defer (gb_string_free(str));
|
||||||
|
error(op, "Cannot convert `%s` to a maybe", str);
|
||||||
|
o->mode = Addressing_Invalid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
o->mode = Addressing_Value;
|
||||||
|
o->type = make_type_maybe(c->allocator, t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!check_unary_op(c, o, op)) {
|
if (!check_unary_op(c, o, op)) {
|
||||||
o->mode = Addressing_Invalid;
|
o->mode = Addressing_Invalid;
|
||||||
return;
|
return;
|
||||||
@@ -1399,8 +1424,9 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
|||||||
|
|
||||||
|
|
||||||
i32 precision = 0;
|
i32 precision = 0;
|
||||||
if (is_type_unsigned(type))
|
if (is_type_unsigned(type)) {
|
||||||
precision = cast(i32)(8 * type_size_of(c->sizes, c->allocator, type));
|
precision = cast(i32)(8 * type_size_of(c->sizes, c->allocator, type));
|
||||||
|
}
|
||||||
o->value = exact_unary_operator_value(op, o->value, precision);
|
o->value = exact_unary_operator_value(op, o->value, precision);
|
||||||
|
|
||||||
if (is_type_typed(type)) {
|
if (is_type_typed(type)) {
|
||||||
|
|||||||
+15
-13
@@ -2099,24 +2099,26 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
|
|
||||||
case_ast_node(ue, UnaryExpr, expr);
|
case_ast_node(ue, UnaryExpr, expr);
|
||||||
switch (ue->op.kind) {
|
switch (ue->op.kind) {
|
||||||
case Token_Pointer: {
|
case Token_Pointer:
|
||||||
return ssa_emit_zero_gep(proc, ssa_build_addr(proc, ue->expr).addr);
|
return ssa_emit_zero_gep(proc, ssa_build_addr(proc, ue->expr).addr); // Make a copy of the pointer
|
||||||
}
|
|
||||||
|
case Token_Maybe:
|
||||||
|
return ssa_emit_conv(proc, ssa_build_expr(proc, ue->expr), type_of_expr(proc->module->info, expr));
|
||||||
|
|
||||||
case Token_Add:
|
case Token_Add:
|
||||||
return ssa_build_expr(proc, ue->expr);
|
return ssa_build_expr(proc, ue->expr);
|
||||||
case Token_Sub: {
|
|
||||||
// NOTE(bill): -`x` == 0 - `x`
|
case Token_Sub: // NOTE(bill): -`x` == 0 - `x`
|
||||||
ssaValue *left = v_zero;
|
return ssa_emit_arith(proc, ue->op, v_zero, ssa_build_expr(proc, ue->expr), tv->type);
|
||||||
ssaValue *right = ssa_build_expr(proc, ue->expr);
|
|
||||||
return ssa_emit_arith(proc, ue->op, left, right, tv->type);
|
case Token_Not: // Boolean not
|
||||||
} break;
|
|
||||||
case Token_Not: // Boolean not
|
|
||||||
case Token_Xor: { // Bitwise not
|
case Token_Xor: { // Bitwise not
|
||||||
// NOTE(bill): "not" `x` == `x` "xor" `-1`
|
// NOTE(bill): "not" `x` == `x` "xor" `-1`
|
||||||
ExactValue neg_one = make_exact_value_integer(-1);
|
|
||||||
ssaValue *left = ssa_build_expr(proc, ue->expr);
|
ssaValue *left = ssa_build_expr(proc, ue->expr);
|
||||||
ssaValue *right = ssa_add_module_constant(proc->module, tv->type, neg_one);
|
ssaValue *right = ssa_add_module_constant(proc->module, tv->type, make_exact_value_integer(-1));
|
||||||
return ssa_emit_arith(proc, ue->op, left, right, tv->type);
|
return ssa_emit_arith(proc, ue->op,
|
||||||
|
left, right,
|
||||||
|
tv->type);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
case_end;
|
case_end;
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ struct ExactValue {
|
|||||||
union {
|
union {
|
||||||
b32 value_bool;
|
b32 value_bool;
|
||||||
String value_string;
|
String value_string;
|
||||||
i64 value_integer;
|
i64 value_integer; // NOTE(bill): This must be an integer and not a pointer
|
||||||
f64 value_float;
|
f64 value_float;
|
||||||
i64 value_pointer;
|
i64 value_pointer;
|
||||||
AstNode *value_compound;
|
AstNode *value_compound;
|
||||||
|
|||||||
@@ -1610,6 +1610,7 @@ AstNode *parse_type(AstFile *f);
|
|||||||
AstNode *parse_unary_expr(AstFile *f, b32 lhs) {
|
AstNode *parse_unary_expr(AstFile *f, b32 lhs) {
|
||||||
switch (f->curr_token.kind) {
|
switch (f->curr_token.kind) {
|
||||||
case Token_Pointer:
|
case Token_Pointer:
|
||||||
|
case Token_Maybe:
|
||||||
case Token_Add:
|
case Token_Add:
|
||||||
case Token_Sub:
|
case Token_Sub:
|
||||||
case Token_Not:
|
case Token_Not:
|
||||||
|
|||||||
Reference in New Issue
Block a user