Added 'drop' instruction for ignored function return values
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 20 Jul 2020 22:11:45 +0000 (17:11 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 20 Jul 2020 22:11:45 +0000 (17:11 -0500)
include/onyxtypes.h
onyx
progs/structs.onyx
src/onyxchecker.c
src/onyxtypes.c
src/onyxwasm.c

index f7feda572ecd9597d28b96027624454f8c79fe39..1f7ff86471ec29f4435963985e44047ec716896f 100644 (file)
@@ -104,5 +104,6 @@ StructMember type_struct_lookup_member(Type* type, char* member);
 b32 type_is_pointer(Type* type);
 b32 type_is_struct(Type* type);
 b32 type_is_bool(Type* type);
+b32 type_results_in_void(Type* type);
 
 #endif // #ifndef ONYX_TYPES
diff --git a/onyx b/onyx
index 91945452d1234bb1987909f35894949e666073fe..b260910cf00a23a6a8e48f85596b3ca9e4968dda 100755 (executable)
Binary files a/onyx and b/onyx differ
index ad96f3cec34ce6336d85915682a42fa8a82d76f4..1bf7f3e24ddd7e82638ada2d3942e3f1fa34c82f 100644 (file)
@@ -105,12 +105,17 @@ link_create :: proc (data: i32, parent: ^^Link) {
     *parent = link;
 }
 
-link_print :: proc (start: ^Link) {
+link_print :: proc (start: ^Link) -> i32 {
+    count := 0;
+
     walker := start;
     while (walker as i32) != 0 {
         print(walker.data);
         walker = walker.next;
+        count += 1;
     }
+
+    return count;
 }
 
 link_test :: proc #export "main2" {
index 604989c3ccedeaed5dc1b3fe4a0aec98b4fc9cbd..7fe714b45cc7453161cc0cf5a360acbeeada4271 100644 (file)
@@ -380,6 +380,8 @@ CHECK(binaryop, AstBinaryOp* binop, b32 assignment_is_ok) {
     if (binop->operation >= Binary_Op_Equal
             && binop->operation <= Binary_Op_Greater_Equal) {
         binop->type = &basic_types[Basic_Kind_Bool];
+    } else if (binop_is_assignment(binop)) {
+        binop->type = &basic_types[Basic_Kind_Void];
     } else {
         binop->type = binop->left->type;
     }
@@ -575,16 +577,17 @@ CHECK(global, AstGlobal* global) {
 
 CHECK(statement, AstNode* stmt) {
     switch (stmt->kind) {
+        case Ast_Kind_Break:      return 0;
+        case Ast_Kind_Continue:   return 0;
+
         case Ast_Kind_Return:     return check_return((AstReturn *) stmt);
         case Ast_Kind_If:         return check_if((AstIf *) stmt);
         case Ast_Kind_While:      return check_while((AstWhile *) stmt);
         case Ast_Kind_For:        return check_for((AstFor *) stmt);
-        case Ast_Kind_Call:       return check_call((AstCall *) stmt);
         case Ast_Kind_Block:      return check_block((AstBlock *) stmt);
-        case Ast_Kind_Binary_Op:  return check_binaryop((AstBinaryOp *) stmt, 1);
-
-        case Ast_Kind_Break:      return 0;
-        case Ast_Kind_Continue:   return 0;
+        case Ast_Kind_Binary_Op:
+            stmt->flags |= Ast_Flag_Expr_Ignored;
+            return check_binaryop((AstBinaryOp *) stmt, 1);
 
         default:
             stmt->flags |= Ast_Flag_Expr_Ignored;
index f23b880295ddd1e4a047231baea286e9581a47be..6b10c3c9eae5ec8f8c77825c8eb93dca05a63318 100644 (file)
@@ -277,3 +277,11 @@ b32 type_is_struct(Type* type) {
 b32 type_is_bool(Type* type) {
     return type != NULL && type->kind == Type_Kind_Basic && type->Basic.kind == Basic_Kind_Bool;
 }
+
+b32 type_results_in_void(Type* type) {
+    return (type == NULL)
+        || (type->kind == Type_Kind_Basic && type->Basic.kind == Basic_Kind_Void)
+        || (   (type->kind == Type_Kind_Function)
+            && (type->Function.return_type->kind == Type_Kind_Basic)
+            && (type->Function.return_type->Basic.kind == Basic_Kind_Void));
+}
index cfeb97b9269d1accf0b36d4228ff4f618e99faec..c5d9cc7e65c23ac7f04b80dcf5427b21b78db85e 100644 (file)
@@ -913,6 +913,10 @@ COMPILE_FUNC(expression, AstTyped* expr) {
             assert(0);
     }
 
+    if (expr->flags & Ast_Flag_Expr_Ignored &&
+        !type_results_in_void(expr->type))
+        WI(WI_DROP);
+
     *pcode = code;
 }