Finish the first implementation of the compiler level list
This commit is contained in:
parent
d55b4a27f5
commit
8e90ea9813
141
CMakeLists.txt
141
CMakeLists.txt
|
@ -10,90 +10,87 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
|||
# Only do these if this is the main project, and not if it is included through add_subdirectory
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
|
||||
# specify the C++ standard
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
## Settings -----------------------------------------
|
||||
# specify the C++ standard
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
|
||||
set(SRC_DIR ${CMAKE_SOURCE_DIR}/src)
|
||||
set(BIN_DIR ${CMAKE_SOURCE_DIR}/bin)
|
||||
set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
|
||||
set(SRC_DIR ${CMAKE_SOURCE_DIR}/src)
|
||||
set(BIN_DIR ${CMAKE_SOURCE_DIR}/bin)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
|
||||
set(CMAKE_CXX_CLANG_TIDY clang-tidy-10)
|
||||
# Let's ensure -std=c++xx instead of -std=g++xx
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG
|
||||
"${CMAKE_CXX_FLAGS_DEBUG} -g -fno-omit-frame-pointer -fsanitize=address")
|
||||
set(CMAKE_LINKER_FLAGS_DEBUG
|
||||
"${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
|
||||
set(CMAKE_CXX_CLANG_TIDY clang-tidy-10)
|
||||
# Let's ensure -std=c++xx instead of -std=g++xx
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG
|
||||
"${CMAKE_CXX_FLAGS_DEBUG} -g -fno-omit-frame-pointer -fsanitize=address")
|
||||
set(CMAKE_LINKER_FLAGS_DEBUG
|
||||
"${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} -O3")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} -O3")
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
set(MemoryCheckCommand "valgrind")
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
set(MemoryCheckCommand "valgrind")
|
||||
|
||||
# Let's nicely support folders in IDEs
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
configure_file(${INCLUDE_DIR}/config.h.in config.h)
|
||||
|
||||
# Testing only available if this is the main app
|
||||
# Note this needs to be done in the main CMakeLists
|
||||
# since it calls enable_testing, which must be in the
|
||||
# main CMakeLists.
|
||||
include(CTest)
|
||||
# Let's nicely support folders in IDEs
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
# Docs only available if this is the main app
|
||||
find_package(Doxygen)
|
||||
if(Doxygen_FOUND)
|
||||
add_subdirectory(docs)
|
||||
else()
|
||||
message(STATUS "Doxygen not found, not building docs")
|
||||
endif()
|
||||
endif()
|
||||
## Options ------------------------------------------
|
||||
option(ENABLE_LOG "Enable logging" OFF)
|
||||
option(ENABLE_EXPR_LOG "Enable AExpr logging" OFF)
|
||||
option(ENABLE_READER_LOG "Enable reader logging" OFF)
|
||||
|
||||
include(cotire)
|
||||
include(FetchContent)
|
||||
# Testing only available if this is the main app
|
||||
# Note this needs to be done in the main CMakeLists
|
||||
# since it calls enable_testing, which must be in the
|
||||
# main CMakeLists.
|
||||
include(CTest)
|
||||
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
|
||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||
|
||||
include_directories(${LLVM_INCLUDE_DIRS})
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
|
||||
llvm_map_components_to_libnames(llvm_libs support core irreader)
|
||||
|
||||
# Formatting library
|
||||
FetchContent_Declare(
|
||||
fmtlib
|
||||
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
|
||||
GIT_TAG 7.0.1
|
||||
)
|
||||
FetchContent_MakeAvailable(fmtlib)
|
||||
# Docs only available if this is the main app
|
||||
find_package(Doxygen)
|
||||
if(Doxygen_FOUND)
|
||||
add_subdirectory(docs)
|
||||
else()
|
||||
message(STATUS "Doxygen not found, not building docs")
|
||||
endif()
|
||||
|
||||
|
||||
# The compiled library code is here
|
||||
add_subdirectory(src)
|
||||
include(cotire)
|
||||
include(FetchContent)
|
||||
|
||||
# The executable code is here
|
||||
add_subdirectory(bin)
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
|
||||
# Testing only available if this is the main app
|
||||
# Emergency override SERENE_CMAKE_BUILD_TESTING provided as well
|
||||
if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR SERENE_CMAKE_BUILD_TESTING) AND BUILD_TESTING)
|
||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||
|
||||
include_directories(${LLVM_INCLUDE_DIRS})
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
|
||||
llvm_map_components_to_libnames(llvm_libs support core irreader)
|
||||
|
||||
# Formatting library
|
||||
FetchContent_Declare(
|
||||
fmtlib
|
||||
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
|
||||
GIT_TAG 7.0.1
|
||||
)
|
||||
FetchContent_MakeAvailable(fmtlib)
|
||||
|
||||
|
||||
# The compiled library code is here
|
||||
add_subdirectory(src)
|
||||
|
||||
# The executable code is here
|
||||
add_subdirectory(bin)
|
||||
|
||||
# Testing only available if this is the main app
|
||||
# Emergency override SERENE_CMAKE_BUILD_TESTING provided as well
|
||||
if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR SERENE_CMAKE_BUILD_TESTING) AND BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
#configure_file(${INCLUDE_DIR}/config.h.in config.h)
|
||||
|
||||
|
||||
# target_link_libraries(serene ${llvm_libs})
|
||||
|
||||
# target_include_directories(serene SYSTEM PRIVATE $ENV{INCLUDE})
|
||||
# target_include_directories(serene PRIVATE ${INCLUDE_DIR})
|
||||
# target_include_directories(serene PUBLIC ${PROJECT_BINARY_DIR})
|
||||
# install(TARGETS serene DESTINATION bin)
|
||||
# install(FILES "${PROJECT_BINARY_DIR}/serene/config.h"
|
||||
# DESTINATION include
|
||||
# )
|
||||
|
|
|
@ -7,11 +7,10 @@ target_link_libraries(serene PRIVATE
|
|||
fmt::fmt
|
||||
)
|
||||
|
||||
|
||||
target_include_directories(serene SYSTEM PRIVATE $ENV{INCLUDE})
|
||||
target_include_directories(serene PRIVATE ${INCLUDE_DIR})
|
||||
target_include_directories(serene PUBLIC ${PROJECT_BINARY_DIR})
|
||||
|
||||
install(TARGETS serene DESTINATION bin)
|
||||
install(FILES "${PROJECT_BINARY_DIR}/serene/config.h"
|
||||
DESTINATION include
|
||||
)
|
||||
install(FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)
|
||||
cotire(serene)
|
||||
|
|
|
@ -36,16 +36,10 @@ int main(int argc, char *argv[]) {
|
|||
char *input_file = argv[1];
|
||||
Reader *r = new Reader(input_file);
|
||||
ast_tree &ast = r->read();
|
||||
cout << "Size: " << ast.size() << endl;
|
||||
|
||||
|
||||
cout << ast.at(2)->string_repr() << endl;
|
||||
|
||||
|
||||
// for(const ast_node& x : ast) {
|
||||
// cout << x->string_repr() << " >> ";
|
||||
// }
|
||||
for(const ast_node& x : ast) {
|
||||
cout << x->string_repr() << " ";
|
||||
}
|
||||
delete r;
|
||||
cout << "\nEND<<" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
44
builder
44
builder
|
@ -13,24 +13,32 @@ BUILD_DIR=$ROOT_DIR/build
|
|||
|
||||
scanbuild=scan-build-10
|
||||
|
||||
function pushed_build() {
|
||||
pushd $BUILD_DIR > /dev/null
|
||||
}
|
||||
|
||||
function popd_build() {
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
function compile() {
|
||||
pushd $BUILD_DIR
|
||||
pushed_build
|
||||
ninja
|
||||
popd
|
||||
popd_build
|
||||
}
|
||||
|
||||
function build() {
|
||||
pushd $BUILD_DIR
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug $ROOT_DIR
|
||||
pushed_build
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug "$@" $ROOT_DIR
|
||||
ninja -j `nproc`
|
||||
popd
|
||||
popd_build
|
||||
}
|
||||
|
||||
function build-release() {
|
||||
pushd $BUILD_DIR
|
||||
pushed_build
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release $ROOT_DIR
|
||||
ninja -j `nproc`
|
||||
popd
|
||||
popd_build
|
||||
}
|
||||
|
||||
function clean() {
|
||||
|
@ -38,21 +46,21 @@ function clean() {
|
|||
}
|
||||
|
||||
function run() {
|
||||
pushd $BUILD_DIR
|
||||
pushed_build
|
||||
$BUILD_DIR/bin/serene "$@"
|
||||
popd
|
||||
popd_build
|
||||
}
|
||||
|
||||
function memcheck() {
|
||||
pushd $BUILD_DIR
|
||||
pushed_build
|
||||
ctest -T memcheck
|
||||
popd
|
||||
popd_build
|
||||
}
|
||||
|
||||
function tests() {
|
||||
pushd $BUILD_DIR
|
||||
pushed_build
|
||||
ctest
|
||||
popd
|
||||
popd_build
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,29 +75,27 @@ case "$command" in
|
|||
"build")
|
||||
clean
|
||||
mkdir -p $BUILD_DIR
|
||||
build
|
||||
build "${@:2}"
|
||||
;;
|
||||
"build-release")
|
||||
clean
|
||||
mkdir -p $BUILD_DIR
|
||||
build
|
||||
build "${@:2}"
|
||||
;;
|
||||
"compile")
|
||||
compile
|
||||
;;
|
||||
"run")
|
||||
echo "##############"
|
||||
echo "${@:2}"
|
||||
run "${@:2}"
|
||||
;;
|
||||
|
||||
"scan-build")
|
||||
clean
|
||||
mkdir -p $BUILD_DIR
|
||||
pushd $BUILD_DIR
|
||||
pushed_build
|
||||
exec $scanbuild cmake $ROOT_DIR
|
||||
exec $scanbuild scan-build make -j 4
|
||||
popd
|
||||
popd_build
|
||||
;;
|
||||
"memcheck")
|
||||
memcheck
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
// the configured options and settings for Tutorial
|
||||
#define SERENE_VERSION_MAJOR @Serene_VERSION_MAJOR@
|
||||
#define SERENE_VERSION_MINOR @Serene_VERSION_MINOR@
|
||||
|
||||
#cmakedefine ENABLE_READER_LOG
|
||||
#cmakedefine ENABLE_EXPR_LOG
|
||||
#cmakedefine ENABLE_LOG
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,8 +26,15 @@
|
|||
#define EXPR_H
|
||||
|
||||
#include <string>
|
||||
#include "serene/logger.hpp"
|
||||
#include "serene/llvm/IR/Value.h"
|
||||
|
||||
#if defined(ENABLE_LOG) || defined(ENABLE_EXPR_LOG)
|
||||
#define EXPR_LOG(...) __LOG("EXPR", __VA_ARGS__);
|
||||
#else
|
||||
#define EXPR_LOG(...);
|
||||
#endif
|
||||
|
||||
namespace serene {
|
||||
class AExpr {
|
||||
public:
|
||||
|
|
|
@ -34,29 +34,35 @@ namespace serene {
|
|||
class ListNode {
|
||||
public:
|
||||
ast_node data;
|
||||
std::shared_ptr<ListNode> next;
|
||||
std::shared_ptr<ListNode> prev;
|
||||
ListNode(ast_node node_data) : data{move(node_data)},
|
||||
ListNode* next;
|
||||
ListNode* prev;
|
||||
ListNode(ast_node node_data) : data{std::move(node_data)},
|
||||
next{nullptr},
|
||||
prev{nullptr} {};
|
||||
};
|
||||
|
||||
class List: public AExpr {
|
||||
public:
|
||||
std::unique_ptr<ListNode> head;
|
||||
std::unique_ptr<ListNode> tail;
|
||||
ListNode* head;
|
||||
ListNode* tail;
|
||||
std::size_t len;
|
||||
|
||||
List(): head{nullptr}, tail{nullptr}, len{0} {};
|
||||
List(const List &list);
|
||||
List(List &&list);
|
||||
List(List &&list) noexcept;
|
||||
|
||||
List& operator=(const List& other);
|
||||
List& operator=(List&& other);
|
||||
|
||||
std::string string_repr();
|
||||
std::size_t length();
|
||||
|
||||
void cons(ast_node f);
|
||||
void add_tail(ast_node t);
|
||||
void append(ast_node t);
|
||||
|
||||
AExpr &first();
|
||||
List &rest();
|
||||
|
||||
void cleanup();
|
||||
|
||||
virtual ~List();
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* Serene programming language.
|
||||
*
|
||||
* Copyright (c) 2020 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include "config.h"
|
||||
|
||||
// DO NOT USE this macro directly. USE module specific macro.
|
||||
// Checkout `reader.cpp` for example.
|
||||
#define __LOG(M, ...) fmt::print("[{}] <{}:{}> in '{}': {}\n", \
|
||||
M, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__func__, \
|
||||
fmt::format(__VA_ARGS__));
|
||||
|
||||
#endif
|
|
@ -31,13 +31,17 @@
|
|||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <fmt/core.h>
|
||||
#include "serene/logger.hpp"
|
||||
#include "serene/expr.hpp"
|
||||
#include "serene/list.hpp"
|
||||
#include "serene/symbol.hpp"
|
||||
#include "serene/serene.hpp"
|
||||
|
||||
#define ENABLE_READER_LOG true
|
||||
#define READER_LOG(...) if(ENABLE_READER_LOG) { fmt::print(__VA_ARGS__); }
|
||||
#if defined(ENABLE_READER_LOG) || defined(ENABLE_LOG)
|
||||
#define READER_LOG(...) __LOG("READER", __VA_ARGS__);
|
||||
#else
|
||||
#define READER_LOG(...);
|
||||
#endif
|
||||
|
||||
namespace serene {
|
||||
|
||||
|
|
|
@ -29,8 +29,5 @@
|
|||
// and the fn signature right.
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
namespace serene {
|
||||
|
||||
}
|
||||
|
||||
namespace serene {}
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,7 @@ add_library(lserene
|
|||
# We need this directory, and users of our library will need it too
|
||||
target_include_directories(lserene PUBLIC "${INCLUDE_DIR}")
|
||||
target_compile_features(lserene PUBLIC cxx_std_20)
|
||||
target_include_directories(lserene PUBLIC ${PROJECT_BINARY_DIR})
|
||||
|
||||
# This depends on (header only) boost
|
||||
target_link_libraries(lserene ${llvm_libs} fmt::fmt)
|
||||
|
|
148
src/list.cpp
148
src/list.cpp
|
@ -31,65 +31,104 @@
|
|||
using namespace std;
|
||||
|
||||
namespace serene {
|
||||
List::List(const List &list) {
|
||||
ListNode *root = list.head;
|
||||
|
||||
ListNode *new_head{nullptr};
|
||||
ListNode *prev_new_head{nullptr};
|
||||
|
||||
while(root) {
|
||||
ListNode *temp = new ListNode(unique_ptr<AExpr>(root->data.get()));
|
||||
|
||||
if(new_head == nullptr) {
|
||||
new_head = temp;
|
||||
prev_new_head = new_head;
|
||||
|
||||
} else {
|
||||
prev_new_head->next = temp;
|
||||
prev_new_head = prev_new_head->next;
|
||||
}
|
||||
|
||||
root = root->next;
|
||||
}
|
||||
head = new_head;
|
||||
};
|
||||
|
||||
|
||||
List::List(List &&list) noexcept: head(list.head),
|
||||
tail(list.tail),
|
||||
len(std::exchange(list.len, 0)) {
|
||||
list.head = nullptr;
|
||||
list.tail = nullptr;
|
||||
};
|
||||
|
||||
List& List::operator=(const List& list) {
|
||||
ListNode *root = list.head;
|
||||
|
||||
ListNode *new_head{nullptr};
|
||||
ListNode *prev_new_head{nullptr};
|
||||
|
||||
while(root) {
|
||||
ListNode *temp = new ListNode(unique_ptr<AExpr>(root->data.get()));
|
||||
|
||||
if(new_head == nullptr) {
|
||||
new_head = temp;
|
||||
prev_new_head = new_head;
|
||||
|
||||
} else {
|
||||
prev_new_head->next = temp;
|
||||
prev_new_head = prev_new_head->next;
|
||||
}
|
||||
|
||||
root = root->next;
|
||||
}
|
||||
head = new_head;
|
||||
return *this;
|
||||
};
|
||||
|
||||
List& List::operator=(List&& list) {
|
||||
head = list.head;
|
||||
tail = list.tail;
|
||||
len = std::exchange(list.len, 0);
|
||||
list.head = nullptr;
|
||||
list.tail = nullptr;
|
||||
return *this;
|
||||
};
|
||||
|
||||
|
||||
void List::cons(ast_node f) {
|
||||
auto temp{std::make_unique<ListNode>(move(f))};
|
||||
ListNode *temp = new ListNode(move(f));
|
||||
|
||||
if(head) {
|
||||
temp->next = move(head);
|
||||
head->prev = move(temp);
|
||||
head = move(temp);
|
||||
temp->next = head;
|
||||
head->prev = temp;
|
||||
head = temp;
|
||||
}
|
||||
else {
|
||||
head = move(temp);
|
||||
head = temp;
|
||||
}
|
||||
len++;
|
||||
}
|
||||
|
||||
List::List(const List &list) {
|
||||
ListNode *root = list.head.get();
|
||||
|
||||
unique_ptr<ListNode> new_head{nullptr};
|
||||
ListNode *pnew_head{nullptr};
|
||||
|
||||
while(root) {
|
||||
auto temp{std::make_unique<ListNode>(unique_ptr<AExpr>(root->data.get()))};
|
||||
if(new_head == nullptr) {
|
||||
new_head = move(temp);
|
||||
pnew_head = new_head.get();
|
||||
|
||||
} else {
|
||||
pnew_head->next = move(temp);
|
||||
pnew_head = pnew_head->next.get();
|
||||
}
|
||||
|
||||
root = root->next.get();
|
||||
|
||||
}
|
||||
head = move(new_head);
|
||||
};
|
||||
|
||||
|
||||
List::List(List &&list) {
|
||||
head = move(list.head);
|
||||
}
|
||||
|
||||
void List::add_tail(ast_node t) {
|
||||
void List::append(ast_node t) {
|
||||
// TODO: Should we do it here?
|
||||
if(!t) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto temp{std::make_unique<ListNode>(move(t))};
|
||||
if(tail) {
|
||||
temp->prev = move(tail);
|
||||
tail->next = move(temp);
|
||||
tail = move(temp);
|
||||
ListNode *temp = new ListNode(move(t));
|
||||
temp->prev = tail;
|
||||
tail->next = temp;
|
||||
tail = temp;
|
||||
len++;
|
||||
}
|
||||
else {
|
||||
if (head) {
|
||||
head->next = move(temp);
|
||||
tail->prev = move(head);
|
||||
tail = move(temp);
|
||||
ListNode *temp = new ListNode(move(t));
|
||||
head->next = temp;
|
||||
tail = temp;
|
||||
tail->prev = head;
|
||||
len++;
|
||||
}
|
||||
else {
|
||||
|
@ -99,14 +138,22 @@ namespace serene {
|
|||
}
|
||||
|
||||
string List::string_repr() {
|
||||
fmt::print("sssssssssssssssssssssss {}\n", length());
|
||||
// TODO: Fix this function to print out the list completely
|
||||
if (head && head->data) {
|
||||
return fmt::format("<List: '{}'>",
|
||||
head->data->string_repr());
|
||||
string s{"("};
|
||||
|
||||
for(ListNode* current = head, *next; current;) {
|
||||
next = current->next;
|
||||
s = s + current->data->string_repr();
|
||||
current = next;
|
||||
if (next) {
|
||||
s = s + " ";
|
||||
}
|
||||
}
|
||||
return fmt::format("{})", s);
|
||||
|
||||
}
|
||||
else {
|
||||
return "<List: empty>";
|
||||
return "()";
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -115,13 +162,16 @@ namespace serene {
|
|||
}
|
||||
|
||||
void List::cleanup() {
|
||||
while(head) {
|
||||
head = move(head->next);
|
||||
for (ListNode* current = head, *next; current;)
|
||||
{
|
||||
next = current->next;
|
||||
delete current;
|
||||
current = next;
|
||||
}
|
||||
};
|
||||
|
||||
List::~List() {
|
||||
fmt::print("asdsadadsddddddddddddddddddddddddd\n");
|
||||
EXPR_LOG("Destroying list");
|
||||
cleanup();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace serene {
|
|||
};
|
||||
|
||||
Reader::~Reader() {
|
||||
fmt::print("DELETE reader\n");
|
||||
READER_LOG("Destroying the reader");
|
||||
}
|
||||
|
||||
char Reader::get_char(const bool skip_whitespace) {
|
||||
|
@ -91,7 +91,7 @@ namespace serene {
|
|||
bool empty = true;
|
||||
char c = get_char(false);
|
||||
|
||||
READER_LOG("Read symbol\n");
|
||||
READER_LOG("Reading symbol");
|
||||
if(!this->is_valid_for_identifier(c)) {
|
||||
|
||||
// TODO: Replece this with a tranceback function or something to raise
|
||||
|
@ -135,7 +135,7 @@ namespace serene {
|
|||
|
||||
default:
|
||||
unget_char();
|
||||
list->add_tail(read_expr());
|
||||
list->append(read_expr());
|
||||
}
|
||||
|
||||
} while(!list_terminated);
|
||||
|
@ -146,7 +146,7 @@ namespace serene {
|
|||
|
||||
ast_node Reader::read_expr() {
|
||||
char c = get_char(false);
|
||||
READER_LOG("CHAR: {}\n", c);
|
||||
READER_LOG("CHAR: {}", c);
|
||||
|
||||
unget_char();
|
||||
|
||||
|
@ -172,10 +172,8 @@ namespace serene {
|
|||
this->ast.push_back(move(tmp));
|
||||
}
|
||||
c = get_char(true);
|
||||
READER_LOG("11111 {}\n", c);
|
||||
}
|
||||
|
||||
READER_LOG("333333333333333\n");
|
||||
return this->ast;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -32,10 +32,10 @@ using namespace std;
|
|||
|
||||
namespace serene {
|
||||
string Symbol::string_repr() {
|
||||
return fmt::format("<Symbol: '{}'>", name);
|
||||
return name;
|
||||
};
|
||||
|
||||
Symbol::~Symbol() {
|
||||
fmt::print("symbol dest\n");
|
||||
EXPR_LOG("Destroying symbol");
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue