@@ -77,7 +77,8 @@ enum RT_FUNCS {
77
77
abs_c64 = 10 ,
78
78
equal_c32 = 11 ,
79
79
equal_c64 = 12 ,
80
- NO_OF_RT_FUNCS = 13 ,
80
+ string_cmp = 13 ,
81
+ NO_OF_RT_FUNCS = 14 ,
81
82
};
82
83
83
84
enum GLOBAL_VAR {
@@ -552,6 +553,93 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
552
553
});
553
554
}
554
555
556
+ void emit_string_cmp () {
557
+ using namespace wasm ;
558
+ m_wa.define_func ({i32, i32}, {i32}, {i32, i32, i32, i32, i32, i32}, " string_cmp" , [&](){
559
+ /*
560
+ local 0 (param 0): string 1 (s1)
561
+ local 1 (param 1): string 2 (s2)
562
+ local 2: len(s1)
563
+ local 3: len(s2)
564
+ local 4: min(len(s1), len(s2))
565
+ local 5: loop variable
566
+ local 6: temp variable to store s1[i] - s2[i]
567
+ local 7: return variable
568
+ */
569
+
570
+ m_wa.emit_local_get (0 );
571
+ m_wa.emit_i32_load (mem_align::b8, 4 );
572
+ m_wa.emit_local_set (2 );
573
+
574
+ m_wa.emit_local_get (1 );
575
+ m_wa.emit_i32_load (mem_align::b8, 4 );
576
+ m_wa.emit_local_set (3 );
577
+
578
+ m_wa.emit_if_else ([&](){
579
+ m_wa.emit_local_get (2 );
580
+ m_wa.emit_local_get (3 );
581
+ m_wa.emit_i32_le_s ();
582
+ }, [&](){
583
+ m_wa.emit_local_get (2 );
584
+ m_wa.emit_local_set (4 );
585
+ }, [&](){
586
+ m_wa.emit_local_get (3 );
587
+ m_wa.emit_local_set (4 );
588
+ });
589
+
590
+ m_wa.emit_i32_const (0 );
591
+ m_wa.emit_local_set (5 );
592
+
593
+ m_wa.emit_loop ([&](){
594
+ m_wa.emit_local_get (5 );
595
+ m_wa.emit_local_get (4 );
596
+ m_wa.emit_i32_lt_s ();
597
+ }, [&](){
598
+ m_wa.emit_local_get (0 );
599
+ m_wa.emit_local_get (5 );
600
+ m_wa.emit_i32_add ();
601
+ m_wa.emit_i32_load8_u (mem_align::b8, 8 );
602
+
603
+ m_wa.emit_local_get (1 );
604
+ m_wa.emit_local_get (5 );
605
+ m_wa.emit_i32_add ();
606
+ m_wa.emit_i32_load8_u (mem_align::b8, 8 );
607
+
608
+ m_wa.emit_i32_sub ();
609
+ m_wa.emit_local_set (6 );
610
+
611
+ m_wa.emit_local_get (6 );
612
+ m_wa.emit_i32_const (0 );
613
+ m_wa.emit_i32_ne ();
614
+
615
+ // branch to end of if, if char diff not equal to 0
616
+ m_wa.emit_br_if (m_wa.nest_lvl - m_wa.cur_loop_nest_lvl - 2U );
617
+
618
+ m_wa.emit_local_get (5 );
619
+ m_wa.emit_i32_const (1 );
620
+ m_wa.emit_i32_add ();
621
+ m_wa.emit_local_set (5 );
622
+ });
623
+
624
+ m_wa.emit_if_else ([&](){
625
+ m_wa.emit_local_get (5 );
626
+ m_wa.emit_local_get (4 );
627
+ m_wa.emit_i32_lt_s ();
628
+ }, [&](){
629
+ m_wa.emit_local_get (6 );
630
+ m_wa.emit_local_set (7 );
631
+ }, [&](){
632
+ m_wa.emit_local_get (2 );
633
+ m_wa.emit_local_get (3 );
634
+ m_wa.emit_i32_sub ();
635
+ m_wa.emit_local_set (7 );
636
+ });
637
+
638
+ m_wa.emit_local_get (7 );
639
+ m_wa.emit_return ();
640
+ });
641
+ }
642
+
555
643
void declare_global_var (ASR::Variable_t* v) {
556
644
if (v->m_type ->type == ASR::ttypeType::TypeParameter) {
557
645
// Ignore type variables
@@ -688,6 +776,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
688
776
m_rt_funcs_map[abs_c64] = &ASRToWASMVisitor::emit_complex_abs_64;
689
777
m_rt_funcs_map[equal_c32] = &ASRToWASMVisitor::emit_complex_equal_32;
690
778
m_rt_funcs_map[equal_c64] = &ASRToWASMVisitor::emit_complex_equal_64;
779
+ m_rt_funcs_map[string_cmp] = &ASRToWASMVisitor::emit_string_cmp;
691
780
692
781
{
693
782
// Pre-declare all functions first, then generate code
@@ -1915,6 +2004,47 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
1915
2004
}
1916
2005
}
1917
2006
2007
+ void handle_string_compare (const ASR::StringCompare_t &x) {
2008
+ if (x.m_value ) {
2009
+ visit_expr (*x.m_value );
2010
+ return ;
2011
+ }
2012
+ INCLUDE_RUNTIME_FUNC (string_cmp);
2013
+ this ->visit_expr (*x.m_left );
2014
+ this ->visit_expr (*x.m_right );
2015
+ m_wa.emit_call (m_rt_func_used_idx[string_cmp]);
2016
+ m_wa.emit_i32_const (0 );
2017
+ switch (x.m_op ) {
2018
+ case (ASR::cmpopType::Eq): {
2019
+ m_wa.emit_i32_eq ();
2020
+ break ;
2021
+ }
2022
+ case (ASR::cmpopType::Gt): {
2023
+ m_wa.emit_i32_gt_s ();
2024
+ break ;
2025
+ }
2026
+ case (ASR::cmpopType::GtE): {
2027
+ m_wa.emit_i32_ge_s ();
2028
+ break ;
2029
+ }
2030
+ case (ASR::cmpopType::Lt): {
2031
+ m_wa.emit_i32_lt_s ();
2032
+ break ;
2033
+ }
2034
+ case (ASR::cmpopType::LtE): {
2035
+ m_wa.emit_i32_le_s ();
2036
+ break ;
2037
+ }
2038
+ case (ASR::cmpopType::NotEq): {
2039
+ m_wa.emit_i32_ne ();
2040
+ break ;
2041
+ }
2042
+ default :
2043
+ throw CodeGenError (
2044
+ " handle_string_compare: ICE: Unknown string comparison operator" );
2045
+ }
2046
+ }
2047
+
1918
2048
void visit_IntegerCompare (const ASR::IntegerCompare_t &x) {
1919
2049
handle_integer_compare (x);
1920
2050
}
@@ -1931,8 +2061,8 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
1931
2061
handle_integer_compare (x);
1932
2062
}
1933
2063
1934
- void visit_StringCompare (const ASR::StringCompare_t & /* x */ ) {
1935
- throw CodeGenError ( " String Types not yet supported " );
2064
+ void visit_StringCompare (const ASR::StringCompare_t &x ) {
2065
+ handle_string_compare (x );
1936
2066
}
1937
2067
1938
2068
void visit_StringLen (const ASR::StringLen_t & x) {
0 commit comments