From 5cb8921c42298ab4fce0f255871f8b8437bb53fa Mon Sep 17 00:00:00 2001 From: Konstantin Nazarov Date: Sun, 8 Sep 2024 00:52:20 +0100 Subject: [PATCH] Add simple and naive string building functionality --- CMakeLists.txt | 1 + src/arena.hpp | 12 ++++++++---- src/common.cpp | 14 ++++++++++++++ src/common.hpp | 12 ++++++++++++ src/error.cpp | 12 ++++++++++++ src/error.hpp | 11 +++++++++++ src/valeri.cpp | 2 ++ 7 files changed, 60 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e5b31b..242958f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,7 @@ set(CPP_TESTS dict array symbol + string ) set(LISP_TESTS diff --git a/src/arena.hpp b/src/arena.hpp index af51b95..2d8fd8f 100644 --- a/src/arena.hpp +++ b/src/arena.hpp @@ -215,9 +215,11 @@ Result> GcRoot::create(T* ptr) { template requires std::derived_from GcRoot::GcRoot(GcRoot&& rhs) { - rhs._node->update(this); _ptr = rhs._ptr; - _node = rhs._node; + if (rhs._node != 0) { + rhs._node->update(this); + _node = rhs._node; + } rhs._ptr = 0; rhs._node = 0; } @@ -227,9 +229,11 @@ template GcRoot& GcRoot::operator=(GcRoot&& rhs) { if (_node != 0) _node->remove(); - rhs._node->update(this); _ptr = rhs._ptr; - _node = rhs._node; + if (rhs._node != 0) { + rhs._node->update(this); + _node = rhs._node; + } rhs._ptr = 0; rhs._node = 0; diff --git a/src/common.cpp b/src/common.cpp index dd8d970..28aec5a 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -196,10 +196,14 @@ Result String::copy_value() const { return Value(String(TRY(_value.copy()))); } +Result String::copy() const { return String(TRY(_value.copy())); } + Result Symbol::copy_value() const { return Value(Symbol(TRY(_value.copy()))); } +Result Symbol::copy() const { return Symbol(TRY(_value.copy())); } + Result Syntax::copy_value() const { return Value(Syntax(TRY(_value.copy()))); } @@ -836,3 +840,13 @@ Result Syntax::rest() const { auto val = TRY(expression()); return val.rest(); } + +Result build_string(const Value& value) { + if (value.is()) { + return value.to()->copy(); + } + + return write_one(value); +} + +Result build_string(const char* value) { return String::create(value); } diff --git a/src/common.hpp b/src/common.hpp index 1bb340e..67279fa 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -1299,3 +1299,15 @@ Result syntax_is_list(const Value& value); Result syntax_is_nil(const Value& value); Result syntax_unwrap(const Value& value); Result syntax_unwrap_all(const Value& value); + +Result build_string(const Value& value); +Result build_string(const char* value); + +template +Result build_string(const T& value, Args&&... args) { + auto first = TRY(build_string(value)); + auto rest = TRY(build_string(std::forward(args)...)); + + first = TRY(first.concat(rest)); + return first; +} diff --git a/src/error.cpp b/src/error.cpp index 6d07093..020db62 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -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 seterrobj(const Value& val) { + errobj = TRY(val.copy()); + return Result(); +} + +void reseterrobj() { errobj = Value(); } diff --git a/src/error.hpp b/src/error.hpp index 5133030..5df3a85 100644 --- a/src/error.hpp +++ b/src/error.hpp @@ -19,16 +19,27 @@ enum class ErrorCode { Interrupt, AssertionFailed, DivisionByZero, + SyntaxError, }; +class Value; + +template +class Result; + void seterr(const char* err); const char* geterr(void); +const Value& geterrobj(void); +Result 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; \ })) diff --git a/src/valeri.cpp b/src/valeri.cpp index 29f7c04..297f2c6 100644 --- a/src/valeri.cpp +++ b/src/valeri.cpp @@ -48,6 +48,8 @@ Result run_repl() { } Result 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()) {