seq_runtime/string_ops/
basic.rs1use crate::seqstring::global_bytes;
4use crate::stack::{Stack, pop, push};
5use crate::value::Value;
6
7#[unsafe(no_mangle)]
10pub unsafe extern "C" fn patch_seq_string_empty(stack: Stack) -> Stack {
11 assert!(!stack.is_null(), "string_empty: stack is empty");
12
13 let (stack, value) = unsafe { pop(stack) };
14
15 match value {
16 Value::String(s) => {
17 let is_empty = s.as_bytes().is_empty();
19 unsafe { push(stack, Value::Bool(is_empty)) }
20 }
21 _ => panic!("string_empty: expected String on stack"),
22 }
23}
24
25#[unsafe(no_mangle)]
32pub unsafe extern "C" fn patch_seq_string_concat(stack: Stack) -> Stack {
33 assert!(!stack.is_null(), "string_concat: stack is empty");
34
35 let (stack, str2_val) = unsafe { pop(stack) };
36 assert!(!stack.is_null(), "string_concat: need two strings");
37 let (stack, str1_val) = unsafe { pop(stack) };
38
39 match (str1_val, str2_val) {
40 (Value::String(s1), Value::String(s2)) => {
41 let mut result = Vec::with_capacity(s1.as_bytes().len() + s2.as_bytes().len());
46 result.extend_from_slice(s1.as_bytes());
47 result.extend_from_slice(s2.as_bytes());
48 unsafe { push(stack, Value::String(global_bytes(result))) }
49 }
50 _ => panic!("string_concat: expected two strings on stack"),
51 }
52}
53
54#[unsafe(no_mangle)]
64pub unsafe extern "C" fn patch_seq_string_length(stack: Stack) -> Stack {
65 assert!(!stack.is_null(), "string_length: stack is empty");
66
67 let (stack, str_val) = unsafe { pop(stack) };
68
69 match str_val {
70 Value::String(s) => {
71 let len = s.as_str_or_empty().chars().count() as i64;
72 unsafe { push(stack, Value::Int(len)) }
73 }
74 _ => panic!("string_length: expected String on stack"),
75 }
76}
77
78#[unsafe(no_mangle)]
87pub unsafe extern "C" fn patch_seq_string_byte_length(stack: Stack) -> Stack {
88 assert!(!stack.is_null(), "string_byte_length: stack is empty");
89
90 let (stack, str_val) = unsafe { pop(stack) };
91
92 match str_val {
93 Value::String(s) => {
94 let len = s.as_bytes().len() as i64;
96 unsafe { push(stack, Value::Int(len)) }
97 }
98 _ => panic!("string_byte_length: expected String on stack"),
99 }
100}
101
102#[unsafe(no_mangle)]
112pub unsafe extern "C" fn patch_seq_string_equal(stack: Stack) -> Stack {
113 assert!(!stack.is_null(), "string_equal: stack is empty");
114
115 let (stack, str2_val) = unsafe { pop(stack) };
116 assert!(!stack.is_null(), "string_equal: need two strings");
117 let (stack, str1_val) = unsafe { pop(stack) };
118
119 match (str1_val, str2_val) {
120 (Value::String(s1), Value::String(s2)) => {
121 let equal = s1.as_bytes() == s2.as_bytes();
125 unsafe { push(stack, Value::Bool(equal)) }
126 }
127 _ => panic!("string_equal: expected two strings on stack"),
128 }
129}