Phasor 3.3.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
string.cpp
Go to the documentation of this file.
1#include "StdLib.hpp"
2#include <string>
3#include <phsint.hpp>
4
5namespace Phasor
6{
7
26
27static std::vector<PhsString>& getSbPool()
28{
29 static std::vector<PhsString> pool;
30 return pool;
31}
32
33static std::vector<size_t>& getSbFreeIndices()
34{
35 static std::vector<size_t> freeIndices;
36 return freeIndices;
37}
38
39i64 StdLib::str_find(const std::vector<Value> &args, VM *)
40{
41 checkArgCount(args, 2, "find", true);
42 PhsString s = args[0].asString();
43 PhsString sub = args[1].asString();
44 size_t pos;
45 if (args.size() == 3)
46 {
47 i64 start = args[2].asInt();
48 pos = s.find(sub, start);
49 if (pos != PhsString::npos)
50 {
51 return static_cast<i64>(pos);
52 }
53 return -1;
54 }
55 else if (args.size() == 4)
56 {
57 i64 start = args[2].asInt();
58 i64 end = args[3].asInt();
59 pos = s.find(sub, start);
60 if (pos != PhsString::npos && pos < static_cast<size_t>(end))
61 {
62 return static_cast<i64>(pos);
63 }
64 return -1;
65 }
66 else
67 {
68 pos = s.find(sub);
69 }
70 return pos != PhsString::npos ? static_cast<i64>(pos) : false;
71}
72
73i64 StdLib::sb_new(const std::vector<Value> &args, VM *)
74{
75 StdLib::checkArgCount(args, 0, "sb_new");
76 size_t idx;
77 if (!getSbFreeIndices().empty())
78 {
79 idx = getSbFreeIndices().back();
80 getSbFreeIndices().pop_back();
81 getSbPool()[idx] = "";
82 }
83 else
84 {
85 idx = getSbPool().size();
86 getSbPool().push_back("");
87 }
88 return static_cast<i64>(idx);
89}
90
91Value StdLib::sb_append(const std::vector<Value> &args, VM *)
92{
93 StdLib::checkArgCount(args, 2, "sb_append");
94 i64 idx = args[0].asInt();
95 if (idx < 0 || idx >= static_cast<i64>(getSbPool().size()))
96 throw std::runtime_error("Invalid StringBuilder handle");
97
98 getSbPool()[idx] += args[1].toString();
99 return args[0]; // Return handle for chaining
100}
101
102PhsString StdLib::sb_to_string(const std::vector<Value> &args, VM *)
103{
104 StdLib::checkArgCount(args, 1, "sb_to_string");
105 i64 idx = args[0].asInt();
106 if (idx < 0 || idx >= static_cast<i64>(getSbPool().size()))
107 throw std::runtime_error("Invalid StringBuilder handle");
108
109 return getSbPool()[idx];
110}
111
112PhsString StdLib::sb_free(const std::vector<Value> &args, VM *)
113{
114 StdLib::checkArgCount(args, 1, "sb_free");
115 size_t idx = args[0].asInt();
116 PhsString value = getSbPool()[idx];
117 getSbFreeIndices().push_back(idx);
118 return value;
119}
120
121Value StdLib::sb_clear(const std::vector<Value> &args, VM *)
122{
123 StdLib::checkArgCount(args, 1, "sb_clear");
124 size_t idx = args[0].asInt();
125 if (idx >= getSbPool().size())
126 throw std::runtime_error("Invalid StringBuilder handle");
127 getSbPool()[idx].clear();
128 return args[0]; // Return handle for chaining
129}
130
131Value StdLib::str_char_at(const std::vector<Value> &args, VM *)
132{
133 checkArgCount(args, 2, "char_at");
134 if (args[0].isString())
135 {
136 const PhsString &s = args[0].asString();
137 i64 idx = args[1].asInt();
138 if (idx < 0 || idx >= static_cast<i64>(s.length()))
139 return Value("");
140 return Value(PhsString(1, s[idx]));
141 }
142 throw std::runtime_error("char_at() expects a string");
143}
144
145Value StdLib::str_substr(const std::vector<Value> &args, VM *)
146{
147 checkArgCount(args, 2, "substr", true);
148 if (args.size() > 3)
149 {
150 throw std::runtime_error("substr() expects 2 or 3 arguments");
151 }
152 PhsString s = args[0].asString();
153 i64 start = args[1].asInt();
154 i64 len = (i64)args.size() == 3 ? args[2].asInt() : (i64)s.length() - start;
155
156 if (start < 0 || start >= static_cast<i64>(s.length()))
157 {
158 return Value("");
159 }
160
161 return Value(s.substr(start, len));
162}
163
164PhsString StdLib::str_concat(const std::vector<Value> &args, VM *)
165{
166 checkArgCount(args, 2, "concat", true);
167 PhsString result = "";
168 for (const auto &arg : args)
169 {
170 result += arg.toString();
171 }
172 return result;
173}
174
175i64 StdLib::str_len(const std::vector<Value> &args, VM *)
176{
177 checkArgCount(args, 1, "len");
178 PhsString s = args[0].toString();
179 return static_cast<i64>(s.length());
180}
181
182PhsString StdLib::str_upper(const std::vector<Value> &args, VM *)
183{
184 checkArgCount(args, 1, "to_upper");
185 PhsString s = args[0].asString();
186 std::transform(s.begin(), s.end(), s.begin(), ::toupper);
187 return s;
188}
189
190PhsString StdLib::str_lower(const std::vector<Value> &args, VM *)
191{
192 checkArgCount(args, 1, "to_lower");
193 PhsString s = args[0].asString();
194 std::transform(s.begin(), s.end(), s.begin(), ::tolower);
195 return s;
196}
197
198Value StdLib::str_starts_with(const std::vector<Value> &args, VM *)
199{
200 checkArgCount(args, 2, "starts_with");
201 std::string s = args[0].string();
202 std::string prefix = args[1].string();
203 if (s.length() >= prefix.length())
204 {
205 return Value(s.compare(0, prefix.length(), prefix) == 0);
206 }
207 return Value(false);
208}
209
210Value StdLib::str_ends_with(const std::vector<Value> &args, VM *)
211{
212 checkArgCount(args, 2, "ends_with");
213 std::string s = args[0].string();
214 std::string suffix = args[1].string();
215 if (s.length() >= suffix.length())
216 {
217 return Value(s.compare(s.length() - suffix.length(), suffix.length(), suffix) == 0);
218 }
219 return Value(false);
220}
221} // namespace Phasor
static constexpr std::size_t npos
static Value sb_clear(const std::vector< Value > &args, VM *vm)
Clear string builder.
Definition string.cpp:121
static Value str_char_at(const std::vector< Value > &args, VM *vm)
Get character at index.
Definition string.cpp:131
static i64 sb_new(const std::vector< Value > &args, VM *vm)
Create new string builder.
Definition string.cpp:73
static void registerStringFunctions(VM *vm)
Definition string.cpp:8
static PhsString sb_free(const std::vector< Value > &args, VM *vm)
Free string builder.
Definition string.cpp:112
static i64 str_find(const std::vector< Value > &args, VM *vm)
Find string in string.
Definition string.cpp:39
static void checkArgCount(const std::vector< Value > &args, size_t minimumArguments, const std::string &name, bool allowMoreArguments=false)
Definition StdLib.cpp:44
static Value str_substr(const std::vector< Value > &args, VM *vm)
Get substring.
Definition string.cpp:145
static PhsString sb_to_string(const std::vector< Value > &args, VM *vm)
Convert string builder to string.
Definition string.cpp:102
static PhsString str_upper(const std::vector< Value > &args, VM *vm)
Convert to uppercase.
Definition string.cpp:182
static PhsString str_lower(const std::vector< Value > &args, VM *vm)
Convert to lowercase.
Definition string.cpp:190
static i64 str_len(const std::vector< Value > &args, VM *vm)
Get string length.
Definition string.cpp:175
static Value sb_append(const std::vector< Value > &args, VM *vm)
Append to string builder.
Definition string.cpp:91
static Value str_ends_with(const std::vector< Value > &args, VM *vm)
Check if string ends with.
Definition string.cpp:210
static Value str_starts_with(const std::vector< Value > &args, VM *vm)
Check if string starts with.
Definition string.cpp:198
static PhsString str_concat(const std::vector< Value > &args, VM *vm)
Concatenate strings.
Definition string.cpp:164
Virtual Machine.
Definition VM.hpp:36
void registerNativeFunction(const std::string &name, NativeFunction fn)
Register a native function.
Definition Native.cpp:5
A value in the Phasor VM.
Definition Value.hpp:59
static Phasor::u64 s[2]
Definition random.cpp:7
The Phasor Programming Language and Runtime.
Definition AST.hpp:13
int64_t i64
Definition phsint.hpp:16
static std::vector< PhsString > & getSbPool()
Definition string.cpp:27
static std::vector< size_t > & getSbFreeIndices()
Definition string.cpp:33