From 4adf9541b951e46304ba78579ce4a7388c318bb1 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Wed, 5 Jun 2024 00:01:46 +0800 Subject: [PATCH] :sparkles: add codegen for `??` operator --- src/nasal_codegen.cpp | 20 ++++++++++++++++++++ src/nasal_codegen.h | 1 + test/scalar.nas | 7 +++++++ 3 files changed, 28 insertions(+) diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index 2a0b3cc..5d9e132 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -1059,6 +1059,9 @@ void codegen::binary_gen(binary_operator* node) { calc_gen(node->get_right()); emit(op_btand, 0, node->get_location()); return; + case binary_operator::binary_type::nullchain: + null_chain_gen(node); + return; default: break; } switch(node->get_operator_type()) { @@ -1174,6 +1177,23 @@ void codegen::binary_gen(binary_operator* node) { } } +void codegen::null_chain_gen(binary_operator* node) { + calc_gen(node->get_left()); + emit(op_pnil, 0, node->get_location()); + emit(op_eq, 0, node->get_location()); + + const auto jmp_false_point = code.size(); + emit(op_jf, 0, node->get_location()); + + calc_gen(node->get_right()); + const auto jmp_direct_point = code.size(); + emit(op_jmp, 0, node->get_location()); + + code[jmp_false_point].num = code.size(); + emit(op_pop, 0, node->get_location()); + code[jmp_direct_point].num = code.size(); +} + void codegen::trino_gen(ternary_operator* node) { calc_gen(node->get_condition()); usize label_jump_false = code.size(); diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index 8501426..abc42c9 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -148,6 +148,7 @@ private: void and_gen(binary_operator*); void unary_gen(unary_operator*); void binary_gen(binary_operator*); + void null_chain_gen(binary_operator*); void trino_gen(ternary_operator*); void calc_gen(expr*); void repl_mode_info_output_gen(expr*); diff --git a/test/scalar.nas b/test/scalar.nas index 3773749..ca8b959 100644 --- a/test/scalar.nas +++ b/test/scalar.nas @@ -267,3 +267,10 @@ for(var i = 1; i<=10; i += 1) { die("test failed: expect " ~ i ~ ", but get " ~ closure_tester[1]()); } } + +func() { + var a = nil; + var b = nil; + var c = nil; + println(a??b??c??"a??b??c?? -> should print this text"); +}();