Add simple and naive string building functionality

This commit is contained in:
Konstantin Nazarov 2024-09-08 00:52:20 +01:00
parent 0b62026d27
commit 5cb8921c42
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
7 changed files with 60 additions and 4 deletions

View file

@ -58,6 +58,7 @@ set(CPP_TESTS
dict
array
symbol
string
)
set(LISP_TESTS

View file

@ -215,9 +215,11 @@ Result<GcRoot<T>> GcRoot<T>::create(T* ptr) {
template <class T>
requires std::derived_from<T, PodObject>
GcRoot<T>::GcRoot(GcRoot<T>&& rhs) {
rhs._node->update(this);
_ptr = rhs._ptr;
if (rhs._node != 0) {
rhs._node->update(this);
_node = rhs._node;
}
rhs._ptr = 0;
rhs._node = 0;
}
@ -227,9 +229,11 @@ template <class T>
GcRoot<T>& GcRoot<T>::operator=(GcRoot<T>&& rhs) {
if (_node != 0) _node->remove();
rhs._node->update(this);
_ptr = rhs._ptr;
if (rhs._node != 0) {
rhs._node->update(this);
_node = rhs._node;
}
rhs._ptr = 0;
rhs._node = 0;

View file

@ -196,10 +196,14 @@ Result<Value> String::copy_value() const {
return Value(String(TRY(_value.copy())));
}
Result<String> String::copy() const { return String(TRY(_value.copy())); }
Result<Value> Symbol::copy_value() const {
return Value(Symbol(TRY(_value.copy())));
}
Result<Symbol> Symbol::copy() const { return Symbol(TRY(_value.copy())); }
Result<Value> Syntax::copy_value() const {
return Value(Syntax(TRY(_value.copy())));
}
@ -836,3 +840,13 @@ Result<Value> Syntax::rest() const {
auto val = TRY(expression());
return val.rest();
}
Result<String> build_string(const Value& value) {
if (value.is<String>()) {
return value.to<String>()->copy();
}
return write_one(value);
}
Result<String> build_string(const char* value) { return String::create(value); }

View file

@ -1299,3 +1299,15 @@ Result<bool> syntax_is_list(const Value& value);
Result<bool> syntax_is_nil(const Value& value);
Result<Value> syntax_unwrap(const Value& value);
Result<Value> syntax_unwrap_all(const Value& value);
Result<String> build_string(const Value& value);
Result<String> build_string(const char* value);
template <class T, class... Args>
Result<String> build_string(const T& value, Args&&... args) {
auto first = TRY(build_string(value));
auto rest = TRY(build_string(std::forward<Args>(args)...));
first = TRY(first.concat(rest));
return first;
}

View file

@ -1,6 +1,18 @@
#include "error.hpp"
#include "common.hpp"
static const char* curerr = 0;
static Value errobj;
void seterr(const char* err) { curerr = err; }
const char* geterr(void) { return curerr; }
const Value& geterrobj(void) { return errobj; }
Result<void> seterrobj(const Value& val) {
errobj = TRY(val.copy());
return Result<void>();
}
void reseterrobj() { errobj = Value(); }

View file

@ -19,16 +19,27 @@ enum class ErrorCode {
Interrupt,
AssertionFailed,
DivisionByZero,
SyntaxError,
};
class Value;
template <class T>
class Result;
void seterr(const char* err);
const char* geterr(void);
const Value& geterrobj(void);
Result<void> seterrobj(const Value&);
void reseterrobj();
#define STRINGIZE_NESTED(A) #A
#define STRINGIZE(A) STRINGIZE_NESTED(A)
#define ERROR(code) \
(({ \
reseterrobj(); \
seterr("Error " STRINGIZE(code) " at " __FILE__ ":" STRINGIZE(__LINE__)); \
ErrorCode::code; \
}))

View file

@ -48,6 +48,8 @@ Result<void> run_repl() {
}
Result<void> run(int argc, const char* argv[]) {
auto t = TRY(build_string("foo", "bar", Value(TRY(Nil::create()))));
String src = TRY(String::create(""));
if (argc == 1) {
if (stdin_isatty()) {