diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 905ceaba..6f5479ed 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -21,13 +21,13 @@ jobs:
DIST: 'ce-specific'
NAME: 'ce-specific'
# - ARCH: 'arm64'
- # DIST: 'macos-11'
+ # DIST: 'macos-13'
# NAME: 'darwin'
- #- ARCH: 'x86_64' # FIXME:
- # DIST: 'macos-11'
- # NAME: 'darwin'
+ - ARCH: 'x86_64'
+ DIST: 'macos-13'
+ NAME: 'darwin'
# - ARCH: 'arm64' # TODO
- # DIST: 'macos-11'
+ # DIST: 'macos-13'
# NAME: 'darwin'
name: Build ${{ matrix.NAME }} (${{ matrix.ARCH }}) [${{ matrix.DIST }}]
env:
@@ -43,6 +43,10 @@ jobs:
if [[ "$OSTYPE" != "darwin"* ]]; then
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
sudo apt install cmake
+ else
+ brew install llvm@16
+ brew install gcc
+ brew install zstd
fi
- name: Build in Docker
@@ -55,6 +59,6 @@ jobs:
ls ~/.snowball
ls ~/.snowball/stdlib/
- - name: Execute tests
- run: |
- ./bin/Release/snowball test --no-progress
\ No newline at end of file
+ #- name: Execute tests
+ # run: |
+ # ./bin/Release/snowball test --no-progress
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f7470b08..c684adae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -100,6 +100,7 @@ if(backtrace_ADDED)
"${backtrace_SOURCE_DIR}/simple.c"
"${backtrace_SOURCE_DIR}/sort.c"
"${backtrace_SOURCE_DIR}/state.c")
+ set(backtrace_INCLUDE_DIRS "${backtrace_SOURCE_DIR}")
# https://go.googlesource.com/gollvm/+/refs/heads/master/cmake/modules/LibbacktraceUtils.cmake
set(BACKTRACE_SUPPORTED 1)
@@ -131,14 +132,11 @@ if(backtrace_ADDED)
endif()
CPMAddPackage(
- NAME sigsegv
- GIT_REPOSITORY "https://git.savannah.gnu.org/git/libsigsegv.git"
- GIT_TAG "v2.14"
+ NAME zstd
+ GIT_REPOSITORY "https://github.com/facebook/zstd.git"
+ GIT_TAG "v1.5.5"
DOWNLOAD_ONLY YES)
-if(sigsegv_ADDED)
- if (APPLE)
- message(STATUS "TODO: add sigsegv to the build")
- endif()
+if(zstd_ADDED)
endif()
message(STATUS ${LLVM_DEFINITIONS})
@@ -212,12 +210,9 @@ else()
endif()
#add_dependencies(snowballrt backtrace sigsegv)
-target_include_directories(snowballrt PRIVATE ${backtrace_SOURCE_DIR} ${sigsegv_SOURCE_DIR})
-if(APPLE)
- target_link_libraries(snowballrt PRIVATE zstd backtrace)
-else()
- target_link_libraries(snowballrt PRIVATE zstd backtrace sigsegv)
-endif()
+target_include_directories(snowballrt PRIVATE ${backtrace_SOURCE_DIR})
+target_link_libraries(snowballrt PRIVATE backtrace)
+target_include_directories(snowballrt PRIVATE ${backtrace_INCLUDE_DIRS})
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
message(STATUS "Changing rpath origin destination (for macos)")
@@ -291,7 +286,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC
$
$
$ PRIVATE source)
- target_include_directories(${PROJECT_NAME} PUBLIC ${LLVM_INCLUDE_DIRS} ${PROJECT_INCLUDE_DIRS})
+ target_include_directories(${PROJECT_NAME} PUBLIC ${LLVM_INCLUDE_DIRS} ${PROJECT_INCLUDE_DIRS} ${backtrace_INCLUDE_DIRS})
target_link_libraries (${PROJECT_NAME} PUBLIC ${llvm_libs} ${GLIB_LIBRARIES} ${llvm_libraries} ${targets} ${PROJECT_LIBRARIES} snowballrt)
target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_COMPILE_DEFINITIONS})
diff --git a/README.md b/README.md
index bfbced97..69d143bf 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
Explore the docs »
- Website · Report Bug · Request Feature
+ Website · Report Bug · Request Feature
@@ -54,11 +54,8 @@ sudo make install -j100
First, you will need a new snowball project. For that, create a new directory and execute the following command:
-```
-mkdir myProject
-cd myProject
-
-snowball init
+```sh
+snowball new --name myProject
```
### Executing snowball code
diff --git a/app/commands/init.h b/app/commands/init.h
index 8d4451c7..03564ee1 100644
--- a/app/commands/init.h
+++ b/app/commands/init.h
@@ -47,7 +47,7 @@ namespace commands {
void init_create_cfg(bool yes, std::string entry, app::Options::InitOptions p_opts) {
std::ofstream outfile(CONFIGURATION_FILE);
- std::string version = "1.0.0";
+ std::string version = "0.0.1";
// TODO: ask questions if p_opts.yes is false
std::string toml_result;
@@ -61,7 +61,7 @@ void init_create_cfg(bool yes, std::string entry, app::Options::InitOptions p_op
outfile << toml.str() << std::endl;
outfile.close();
- Logger::message("Configuration", FMT("created configuration file (%s)", CONFIGURATION_FILE));
+ Logger::message("Configuration", FMT("Configured project file (%s)", CONFIGURATION_FILE));
}
// TODO: Output messages
@@ -69,7 +69,7 @@ int init(app::Options::InitOptions p_opts) {
auto start = high_resolution_clock::now();
if (p_opts.create_dir) {
- Logger::message("Creating", FMT("creating snowball project directory (%s)", p_opts.name.c_str()));
+ Logger::message("Creating", FMT("Snowball project at directory %s", p_opts.name.c_str()));
if (!fs::exists(p_opts.name)) fs::create_directory(p_opts.name);
fs::current_path(p_opts.name);
}
@@ -82,11 +82,11 @@ int init(app::Options::InitOptions p_opts) {
std::getline(std::cin, answer);
if (answer != "y" && answer != "Y") {
- Logger::message("Aborted", "snowball project creation");
+ Logger::message("Aborted", "Snowball project creation");
return 0;
}
- Logger::message("Deleting", "deleting all files in the current directory");
+ Logger::message("Deleting", "All files in the current directory");
for (auto &p : fs::directory_iterator(fs::current_path())) {
fs::remove_all(p);
}
@@ -96,7 +96,7 @@ int init(app::Options::InitOptions p_opts) {
init_create_cfg(p_opts.yes, EXECUTABLE_ENTRY, p_opts);
return 0;
} else if (p_opts.lib) {
- Logger::message("Initalizing", FMT("creating snowball project [library]", CONFIGURATION_FILE));
+ Logger::message("Initalizing", FMT("Current project [library]", CONFIGURATION_FILE));
Logger::warning("Library example is not yet supported by "
"current snowball!");
@@ -108,7 +108,7 @@ int init(app::Options::InitOptions p_opts) {
outfile << LIBRARY_MAIN << std::endl;
outfile.close();
} else {
- Logger::message("Initalizing", FMT("creating snowball project [executable]", CONFIGURATION_FILE));
+ Logger::message("Initalizing", FMT("Current project [executable]", CONFIGURATION_FILE));
if (!fs::exists("src")) fs::create_directory("src");
if (!p_opts.skip_cfg) init_create_cfg(p_opts.yes, EXECUTABLE_ENTRY, p_opts);
diff --git a/build_scripts/release_build.sh b/build_scripts/release_build.sh
index 1f09cb62..f18d3f59 100644
--- a/build_scripts/release_build.sh
+++ b/build_scripts/release_build.sh
@@ -36,6 +36,7 @@ if [[ "$OSTYPE" == "darwin"* ]]; then
else
brew install llvm@16
brew install gcc
+ brew install zstd
fi
export LLVM_DIR="/usr/local/opt/llvm@16/lib/cmake"
diff --git a/runtime/libs/backtrace.cc b/runtime/libs/backtrace.cc
index fed9dfba..8c1804cd 100644
--- a/runtime/libs/backtrace.cc
+++ b/runtime/libs/backtrace.cc
@@ -1,5 +1,5 @@
-#include "backtrace.h"
+#include "backtracing.h"
#include "runtime.h"
namespace snowball {
@@ -60,36 +60,37 @@ void print_backtrace(Backtrace backtrace, std::ostringstream &oss) {
if (!(snowball::snowball_flags & SNOWBALL_FLAG_DEBUG))
return;
- if (getenv("SN_BACKTRACE") == NULL) {
- oss << "\n\e[1;37mnote:\e[0m run with \e[1;37m`SN_BACKTRACE=1`\e[0m environment variable to get a backtrace";
- return;
- }
+ if (getenv("SN_BACKTRACE") == NULL) {
+ oss << "\n\e[1;37mnote:\e[0m run with \e[1;37m`SN_BACKTRACE=1`\e[0m environment variable to get a backtrace";
+ return;
+ }
- oss << "\n";
- oss << "\n\033[1mBacktrace (most recent call first):\033[0m\n";
+ oss << "\n";
+ oss << "\n\033[1mBacktrace (most recent call first):\033[0m\n";
- if (backtrace.frame_count <= 1) {
- oss << " (no backtrace available)\n";
- return;
- }
-
- for (int i = 1; i < backtrace.frame_count; i++) {
- BacktraceFrame frame = backtrace.frames[i];
- if (!frame.function || !frame.filename) {
- oss << " (#" << i << "): \e[1;30m[" << (void*)frame.address << "]\e[0m - ????\n";
- continue;
- }
- // TODO: demangle function names
- oss << " (#" << i << "): \e[1;30m[" << (void*)frame.address << "]\e[0m - " << frame.function << "\n";
- oss << "\t\tat \e[1;32m" << frame.filename << "\e[1;36m:" << frame.lineno << "\e[0m\n";
- }
+ if (backtrace.frame_count <= 1) {
+ oss << " (no backtrace available)\n";
+ return;
+ }
+
+ for (int i = 1; i < backtrace.frame_count; i++) {
+ BacktraceFrame frame = backtrace.frames[i];
+ if (!frame.function || !frame.filename) {
+ oss << " (#" << i << "): \e[1;30m[" << (void*)frame.address << "]\e[0m - ????\n";
+ continue;
+ }
+ // TODO: demangle function names
+ oss << " (#" << i << "): \e[1;30m[" << (void*)frame.address << "]\e[0m - " << frame.function << "\n";
+ oss << "\t\tat \e[1;32m" << frame.filename << "\e[1;36m:" << frame.lineno << "\e[0m\n";
+ }
- oss << "\e[0m\n";
- //backtrace.pls_free();
+ oss << "\e[0m\n";
+ //backtrace.pls_free();
}
void get_backtrace(Backtrace &backtrace) {
if (!(snowball::snowball_flags & SNOWBALL_FLAG_DEBUG)) {
+ backtrace = Backtrace();
return;
}
diff --git a/runtime/libs/backtrace.h b/runtime/libs/backtracing.h
similarity index 100%
rename from runtime/libs/backtrace.h
rename to runtime/libs/backtracing.h
diff --git a/runtime/libs/exceptions.cc b/runtime/libs/exceptions.cc
index 6f274aa3..eee5c8ea 100644
--- a/runtime/libs/exceptions.cc
+++ b/runtime/libs/exceptions.cc
@@ -625,7 +625,6 @@ void end_stack(void* exep) {
} else {
buf << "\033[0m";
}
-
print_backtrace(base->backtrace, buf);
buf << "\n\n";
diff --git a/runtime/libs/exceptions.h b/runtime/libs/exceptions.h
index dd64b8c0..66642f15 100644
--- a/runtime/libs/exceptions.h
+++ b/runtime/libs/exceptions.h
@@ -2,7 +2,7 @@
#ifndef _SNOWBALL_RUNTIME_EXCEPTIONS_H_
#define _SNOWBALL_RUNTIME_EXCEPTIONS_H_
-#include "backtrace.h"
+#include "backtracing.h"
namespace snowball {
uint64_t exception_class();
diff --git a/runtime/libs/segfault.cc b/runtime/libs/segfault.cc
index 86d7f7ea..cbe6e8c1 100644
--- a/runtime/libs/segfault.cc
+++ b/runtime/libs/segfault.cc
@@ -3,16 +3,18 @@
// TODO: Add support for macOS.
#include "runtime.h"
-#include "backtrace.h"
-
-#include
+#include "backtracing.h"
+#include
+#include
+#include
+#include
namespace snowball {
-int segfault_handler(void *fault_address, int serious) {
+void segfault_handler(int signal, siginfo_t *fault_info, void *arg) {
std::ostringstream buf;
error_log(buf, "Segmentation fault");
- buf << ": \033[0mSegmentation fault at address \e[1;37m" << std::hex << (void*)fault_address << std::dec << "\e[0m";
+ buf << ": \033[0mSegmentation fault at address \e[1;37m" << std::hex << (void*)fault_info->si_addr << std::dec << "\e[0m";
Backtrace base;
get_backtrace(base);
@@ -24,11 +26,17 @@ int segfault_handler(void *fault_address, int serious) {
fwrite(output.data(), 1, output.size(), stderr);
exit(1);
- return 0;
}
void initialize_segfault_handler() {
- sigsegv_install_handler(&segfault_handler);
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(struct sigaction));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_sigaction = segfault_handler;
+ sa.sa_flags = SA_SIGINFO;
+
+ sigaction(SIGSEGV, &sa, NULL);
// TODO: buffer overflow, etc...
}
}
diff --git a/scripts/install.sh b/scripts/install.sh
index bb07c8d6..59771783 100644
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -213,10 +213,11 @@ log info "Updating configuration file"
update_config_file "$shell"
-printf "\n ${green}snowball-${OS}-${ARCH}${normal} - successfully installed with stdlib\n\n"
+printf "\n ${green}snowball-${OS}-${ARCH}${normal} - successfully installed with runtime included\n"
+printf " ${green}snowball-stdlib${normal} - standard library for snowball\n\n"
log info "Snowball successfully installed at: $(pwd)"
log info "Snowball is ready to use! type: \`snowball --help\` to check that it works."
-echo ""
+echo "\n===================== GREAT! =====================\n"
log info "Checkoutt the documentation at: https://snowball-lang.gitbook.io/docs/fundamentals/hello-world"
log info "Happy coding! 🐱"
diff --git a/snowball.version.id b/snowball.version.id
index 88f28d3b..d8ff0b9b 100644
--- a/snowball.version.id
+++ b/snowball.version.id
@@ -1 +1 @@
-0x000008
\ No newline at end of file
+0x000009
\ No newline at end of file
diff --git a/snowball.version.str b/snowball.version.str
index 7d6b3eb3..429d94ae 100644
--- a/snowball.version.str
+++ b/snowball.version.str
@@ -1 +1 @@
-0.0.8
\ No newline at end of file
+0.0.9
\ No newline at end of file
diff --git a/src/ast/cache/FunctionCache.cc b/src/ast/cache/FunctionCache.cc
index 52f0d016..dafd2289 100644
--- a/src/ast/cache/FunctionCache.cc
+++ b/src/ast/cache/FunctionCache.cc
@@ -85,6 +85,11 @@ void Functions::performInheritance(types::DefinedType* ty, types::DefinedType* p
for (auto fn : functions) { setFunction(name, fn.function, fn.state); }
}
+ for (auto f : parent->getFields()) {
+ ty->addField(f);
+ }
+ ty->hasVtable = parent->hasVtable;
+
return;
}
diff --git a/src/ast/types/DefinedType.cc b/src/ast/types/DefinedType.cc
index 3b17b1c3..956a0ec3 100644
--- a/src/ast/types/DefinedType.cc
+++ b/src/ast/types/DefinedType.cc
@@ -139,11 +139,12 @@ std::int64_t DefinedType::sizeOf() const {
address += (typeAlignment - (address % typeAlignment)) % typeAlignment;
address += typeSize;
}
- if (address == 0) address = 1; // prevent 0-sized types
auto alignment = alignmentOf();
address += (address - (address % alignment)) % alignment;
address += (alignment - (address % alignment)) % alignment;
- return address + (hasVtable * 8);
+ address += (hasVtable * 8);
+ if (address == 0) address = 1; // prevent 0-sized types
+ return address;
}
std::int64_t DefinedType::alignmentOf() const {
diff --git a/src/builder/linker/macos/ld.cc b/src/builder/linker/macos/ld.cc
index 307b6cd9..be878412 100644
--- a/src/builder/linker/macos/ld.cc
+++ b/src/builder/linker/macos/ld.cc
@@ -51,7 +51,6 @@ void Linker::constructLinkerArgs(std::string& input, std::string& output, std::v
linkerArgs.push_back("-L/opt/homebrew/lib");
linkerArgs.push_back("-L/usr/local/lib");
linkerArgs.push_back("-L/usr/lib");
- linkerArgs.push_back("-L/opt/homebrew/opt/zstd/lib");
// TODO: we might not find it and we will need to search for System.B
linkerArgs.push_back("-lSystem");
diff --git a/src/builder/llvm/initializeVariable.cc b/src/builder/llvm/initializeVariable.cc
index b39969dd..89e4eb18 100644
--- a/src/builder/llvm/initializeVariable.cc
+++ b/src/builder/llvm/initializeVariable.cc
@@ -9,8 +9,8 @@ namespace snowball {
namespace codegen {
void LLVMBuilder::initializeVariable(llvm::Value* var, llvm::Type* ty, unsigned int size) {
- assert(llvm::isa(ty));
- auto llvmType = llvm::cast(ty);
+ assert(llvm::isa(ty));
+ auto llvmType = llvm::cast(ty);
auto initializerName =
FMT("__const.default.%s", llvmType->getName().str().c_str());
auto constInitializer = module->getNamedGlobal(initializerName);
diff --git a/stdlib/map.sn b/stdlib/map.sn
index 4760c24c..1d4f4c62 100644
--- a/stdlib/map.sn
+++ b/stdlib/map.sn
@@ -65,25 +65,6 @@ public:
}
throw new MapIndexException("Map::get(): key not found inside map!");
}
- /**
- * Retrieves the value associated with the specified key or a default value if the key is not present.
- * @param {K} key - The key to search for.
- * @param {V} val - The default value to return if the key is not found.
- * @return {&V} A mutable reference to the associated value if the key is present, otherwise the default value.
- * @example
- * const myMap = new Map();
- * const value = myMap.get_or("foo", 42); // Returns 42 as "foo" is not in the map
- * @endexample
- */
- func get_or(key: K, val: V) &mut V {
- for let i = 0; i < self.size(); i = i + 1 {
- let entry = self.table[i];
- if (entry.first == key) {
- return entry.second;
- }
- }
- return val;
- }
/**
* Sets the value associated with the specified key. If the key already exists, the value is updated;
* otherwise, a new key-value pair is added to the map.
diff --git a/tests/lambdas.sn b/tests/lambdas.sn
index f60f56fc..dfde71b5 100644
--- a/tests/lambdas.sn
+++ b/tests/lambdas.sn
@@ -1,4 +1,7 @@
import std::io;
+@use_macros
+import std::asserts;
+
namespace test {
@@ -101,6 +104,17 @@ func usage_after_lambda() i32 {
return x + z;
}
+@test(expect = 10)
+func usage_after_lambda2() i32 {
+ let mut x = "hello";
+ let y = func() i32 {
+ return x.size();
+ };
+ let z = y();
+ assert!(x == "hello")
+ return x.size() + z;
+}
+
struct TestStruct {
public let x: i32;
}
diff --git a/tests/main.sn b/tests/main.sn
index fa9c5c9a..0dc5e047 100644
--- a/tests/main.sn
+++ b/tests/main.sn
@@ -34,12 +34,11 @@ import std::io;
//import std::io::{ println };
public func main() i32 {
- let x = "25";
-
+ let mut x: String;
+ x = "awd";
let a = (func() i32 {
//io::println(x);
io::println(x);
})();
-
io::println(x);
}
diff --git a/tests/map.sn b/tests/map.sn
index ce8f07f9..cfc09c29 100644
--- a/tests/map.sn
+++ b/tests/map.sn
@@ -48,15 +48,6 @@ func has() i32 {
return true;
}
-@test
-func get_or() i32 {
- let mut m = new Map();
- m.set(1, 2);
- assert_eq!(m.get_or(1, 3), 2);
- assert_eq!(m.get_or(2, 3), 3);
- return true;
-}
-
@test(expect = 7)
func change() i32 {
let mut m = new Map();
diff --git a/tests/string.sn b/tests/string.sn
index df759260..0fa1c6d2 100644
--- a/tests/string.sn
+++ b/tests/string.sn
@@ -75,8 +75,6 @@ func ljust() i32 {
func split() i32 {
let s = "hello world";
let x = s.split(" ");
- io::println(x[0]);
- io::println(x[1]);
assert!(x[0] == "hello");
assert!(x[1] == "world");
return x.size();