Compare commits
15 commits
6c0950dbe1
...
main
Author | SHA1 | Date | |
---|---|---|---|
Bruno BELANYI | c72032f0ce | ||
Bruno BELANYI | 34df20cdb7 | ||
Bruno BELANYI | 2e29dea2b6 | ||
Bruno BELANYI | 8b3288c1ce | ||
Bruno BELANYI | 33de39b62a | ||
Bruno BELANYI | d5507dce2d | ||
Bruno BELANYI | c9460c09d5 | ||
Bruno BELANYI | a382b299b0 | ||
Bruno BELANYI | 3e5133da1a | ||
Bruno BELANYI | 8cb26ee316 | ||
Bruno BELANYI | 4ea7a38b61 | ||
Bruno BELANYI | da8b08e4e3 | ||
Bruno BELANYI | 5c7c2af289 | ||
Bruno BELANYI | 171ef10a6d | ||
Bruno BELANYI | eb9295cfcd |
27
.drone.yml
27
.drone.yml
|
@ -1,27 +0,0 @@
|
|||
---
|
||||
kind: pipeline
|
||||
type: exec
|
||||
name: abacus checks
|
||||
|
||||
steps:
|
||||
- name: flake check
|
||||
commands:
|
||||
- nix flake check
|
||||
|
||||
- name: notifiy
|
||||
commands:
|
||||
- nix run github:ambroisie/matrix-notifier
|
||||
environment:
|
||||
ADDRESS:
|
||||
from_secret: matrix_homeserver
|
||||
ROOM:
|
||||
from_secret: matrix_roomid
|
||||
USER:
|
||||
from_secret: matrix_username
|
||||
PASS:
|
||||
from_secret: matrix_password
|
||||
when:
|
||||
status:
|
||||
- failure
|
||||
- success
|
||||
...
|
31
.woodpecker/check.yml
Normal file
31
.woodpecker/check.yml
Normal file
|
@ -0,0 +1,31 @@
|
|||
labels:
|
||||
type: exec
|
||||
|
||||
steps:
|
||||
- name: flake check
|
||||
image: bash
|
||||
commands:
|
||||
- nix flake check
|
||||
|
||||
- name: package check
|
||||
image: bash
|
||||
commands:
|
||||
- nix build
|
||||
|
||||
- name: notify
|
||||
image: bash
|
||||
secrets:
|
||||
- source: matrix_roomid
|
||||
target: room
|
||||
- source: matrix_username
|
||||
target: user
|
||||
- source: matrix_password
|
||||
target: pass
|
||||
- source: matrix_homeserver
|
||||
target: address
|
||||
commands:
|
||||
- nix run github:ambroisie/matrix-notifier
|
||||
when:
|
||||
status:
|
||||
- failure
|
||||
- success
|
|
@ -4,12 +4,15 @@ enable_testing()
|
|||
|
||||
add_library(common_options INTERFACE)
|
||||
target_compile_features(common_options INTERFACE
|
||||
cxx_std_17
|
||||
cxx_std_20
|
||||
)
|
||||
target_compile_options(common_options INTERFACE
|
||||
-Wall
|
||||
-Wextra
|
||||
)
|
||||
target_include_directories(common_options INTERFACE
|
||||
src
|
||||
)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(tests)
|
||||
|
|
76
flake.nix
76
flake.nix
|
@ -29,9 +29,40 @@
|
|||
};
|
||||
|
||||
outputs = { self, futils, nixpkgs, pre-commit-hooks }:
|
||||
futils.lib.eachDefaultSystem (system:
|
||||
{
|
||||
overlays.default = final: prev: {
|
||||
abacus = final.stdenv.mkDerivation {
|
||||
pname = "abacus";
|
||||
version = "0.0.0";
|
||||
|
||||
src = self;
|
||||
|
||||
nativeBuildInputs = with final; [
|
||||
bison
|
||||
cmake
|
||||
flex
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
checkInputs = with final; [
|
||||
gtest
|
||||
];
|
||||
|
||||
doCheck = true;
|
||||
|
||||
meta = with final.lib; {
|
||||
description = "A simple calculator using big numbers";
|
||||
homepage = "https://gitea.belanyi.fr/ambroisie/abacus";
|
||||
license = licenses.mit;
|
||||
maintainers = [ ambroisie ];
|
||||
platforms = platforms.unix;
|
||||
};
|
||||
};
|
||||
};
|
||||
} // futils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
pkgs = import nixpkgs { inherit system; overlays = [ self.overlays.default ]; };
|
||||
in
|
||||
{
|
||||
checks = {
|
||||
|
@ -56,46 +87,17 @@
|
|||
};
|
||||
};
|
||||
|
||||
defaultPackage = self.packages.${system}.abacus;
|
||||
|
||||
devShell = pkgs.mkShell {
|
||||
inherit (self.defaultPackage.${system})
|
||||
checkInputs
|
||||
nativeBuildInputs
|
||||
;
|
||||
devShells.default = pkgs.mkShell {
|
||||
inputsFrom = with self.packages.${system}; [
|
||||
abacus
|
||||
];
|
||||
|
||||
inherit (self.checks.${system}.pre-commit) shellHook;
|
||||
};
|
||||
|
||||
packages = futils.lib.flattenTree {
|
||||
abacus = pkgs.stdenv.mkDerivation {
|
||||
pname = "abacus";
|
||||
version = "0.0.0";
|
||||
|
||||
src = self;
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
bison
|
||||
cmake
|
||||
flex
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
checkInputs = with pkgs; [
|
||||
gtest
|
||||
];
|
||||
|
||||
doCheck = true;
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
description = "A simple calculator using big numbers";
|
||||
homepage = "https://gitea.belanyi.fr/ambroisie/abacus";
|
||||
license = licenses.mit;
|
||||
maintainers = [ ambroisie ];
|
||||
platforms = platforms.unix;
|
||||
};
|
||||
};
|
||||
inherit (pkgs) abacus;
|
||||
default = pkgs.abacus;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
13
meson.build
13
meson.build
|
@ -1,13 +0,0 @@
|
|||
project(
|
||||
'abacus',
|
||||
'cpp',
|
||||
version: '0.0.0',
|
||||
license: 'MIT',
|
||||
default_options: [
|
||||
'warning_level=3',
|
||||
'cpp_std=c++17',
|
||||
],
|
||||
)
|
||||
|
||||
subdir('src')
|
||||
subdir('tests')
|
|
@ -1,4 +1,4 @@
|
|||
#include "parser-driver.hh" // FIXME: I would like `parse/parser-driver.hh` path instead...
|
||||
#include "parse/parser-driver.hh"
|
||||
|
||||
int main() {
|
||||
abacus::parse::ParserDriver driver{};
|
||||
|
|
|
@ -3,7 +3,3 @@ add_library(bignum STATIC
|
|||
bignum.hh
|
||||
)
|
||||
target_link_libraries(bignum PRIVATE common_options)
|
||||
|
||||
target_include_directories(bignum PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <span>
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
@ -82,18 +83,17 @@ digits_type do_addition(digits_type const& lhs, digits_type const& rhs) {
|
|||
++it2;
|
||||
}
|
||||
|
||||
auto it = it1;
|
||||
auto end = end1;
|
||||
if (it1 == end1) {
|
||||
it = it2;
|
||||
end = end2;
|
||||
}
|
||||
auto leftover = [=]() {
|
||||
if (it1 != end1) {
|
||||
return std::span(it1, end1);
|
||||
}
|
||||
return std::span(it2, end2);
|
||||
}();
|
||||
|
||||
while (it != end) {
|
||||
int addition = *it + carry;
|
||||
for (auto value : leftover) {
|
||||
int addition = value + carry;
|
||||
carry = addition / BASE;
|
||||
res.push_back(addition % BASE);
|
||||
++it;
|
||||
}
|
||||
|
||||
if (carry != 0) {
|
||||
|
@ -107,7 +107,7 @@ digits_type do_substraction(digits_type const& lhs, digits_type const& rhs) {
|
|||
assert(!do_less_than(lhs, rhs));
|
||||
|
||||
digits_type complement;
|
||||
auto const take_complement = [](auto num) { return 9 - num; };
|
||||
auto const take_complement = [](auto num) { return BASE - 1 - num; };
|
||||
std::transform(lhs.begin(), lhs.end(), std::back_inserter(complement),
|
||||
take_complement);
|
||||
|
||||
|
@ -363,7 +363,11 @@ bool BigNum::less_than(BigNum const& rhs) const {
|
|||
return sign_ < rhs.sign_;
|
||||
}
|
||||
|
||||
return do_less_than(digits_, rhs.digits_);
|
||||
if (is_positive()) {
|
||||
return do_less_than(digits_, rhs.digits_);
|
||||
} else {
|
||||
return do_less_than(rhs.digits_, digits_);
|
||||
}
|
||||
}
|
||||
|
||||
void BigNum::canonicalize() {
|
||||
|
@ -381,15 +385,15 @@ bool BigNum::is_canonicalized() const {
|
|||
return sign_ == 0;
|
||||
}
|
||||
|
||||
auto const leading_zeros = std::find_if(digits_.rbegin(), digits_.rend(),
|
||||
[](auto v) { return v != 0; });
|
||||
if (leading_zeros != digits_.rbegin()) {
|
||||
// `back` is valid since there is at least one element
|
||||
auto const has_leading_zero = digits_.back() == 0;
|
||||
if (has_leading_zero) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto const overflow = std::find_if(digits_.begin(), digits_.end(),
|
||||
[](auto v) { return v >= BASE; });
|
||||
if (overflow != digits_.end()) {
|
||||
auto const has_overflow = std::any_of(digits_.begin(), digits_.end(),
|
||||
[](auto v) { return v >= BASE; });
|
||||
if (has_overflow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
bignum_sources = files(
|
||||
'bignum.cc',
|
||||
'bignum.hh',
|
||||
)
|
||||
|
||||
bignum_inc = include_directories('.')
|
||||
|
||||
bignum_lib = static_library(
|
||||
'bignum',
|
||||
sources: bignum_sources,
|
||||
)
|
||||
|
||||
bignum = declare_dependency(
|
||||
link_with: bignum_lib,
|
||||
include_directories: bignum_inc,
|
||||
)
|
|
@ -1,16 +0,0 @@
|
|||
abacus_sources = files(
|
||||
'abacus.cc',
|
||||
)
|
||||
|
||||
subdir('bignum')
|
||||
subdir('parse')
|
||||
|
||||
abacus = executable(
|
||||
'abacus',
|
||||
sources: abacus_sources,
|
||||
dependencies: [
|
||||
bignum,
|
||||
parse,
|
||||
],
|
||||
install: true,
|
||||
)
|
|
@ -18,6 +18,6 @@ target_link_libraries(parse PRIVATE
|
|||
)
|
||||
|
||||
target_include_directories(parse PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
)
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
flex_binary = find_program('flex', required: true)
|
||||
lexer_sources = custom_target(
|
||||
'lexer_sources',
|
||||
input: 'scanner.ll',
|
||||
output: 'scanner.cc',
|
||||
command: [
|
||||
flex_binary,
|
||||
'-o',
|
||||
'@OUTPUT@',
|
||||
'@INPUT@',
|
||||
],
|
||||
)
|
||||
|
||||
bison_binary = find_program('bison', required: true)
|
||||
parser_sources = custom_target(
|
||||
'parser_sources',
|
||||
input: 'parser.yy',
|
||||
output: [
|
||||
'parser.cc',
|
||||
'parser.hh',
|
||||
],
|
||||
command: [
|
||||
bison_binary,
|
||||
'@INPUT@',
|
||||
'--output=@OUTPUT0@',
|
||||
'--defines=@OUTPUT1@',
|
||||
'--graph',
|
||||
# FIXME: html output in bison 3.7.90
|
||||
],
|
||||
)
|
||||
|
||||
parse_inc = include_directories('.')
|
||||
|
||||
parse_lib = static_library(
|
||||
'parser',
|
||||
'parser-driver.cc',
|
||||
'parser-driver.hh',
|
||||
lexer_sources,
|
||||
parser_sources,
|
||||
dependencies: [
|
||||
bignum,
|
||||
],
|
||||
)
|
||||
|
||||
parse = declare_dependency(
|
||||
link_with: parse_lib,
|
||||
include_directories: parse_inc,
|
||||
)
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "parser.hh"
|
||||
|
||||
#include "bignum.hh" // FIXME: I would like `bignum/bignum.hh` path instead...
|
||||
#include "bignum/bignum.hh"
|
||||
|
||||
namespace abacus::parse {
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace abacus::parse {
|
|||
class ParserDriver;
|
||||
} // namespace abacus::parse
|
||||
|
||||
#include "bignum.hh" // FIXME: I would like `bignum/bignum.hh` path instead...
|
||||
#include "bignum/bignum.hh"
|
||||
}
|
||||
|
||||
%code provides {
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
subdir('unit')
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "bignum.hh"
|
||||
#include "bignum/bignum.hh"
|
||||
|
||||
using namespace abacus::bignum;
|
||||
|
||||
|
@ -68,6 +68,34 @@ TEST(BigNum, comparisons_digits) {
|
|||
EXPECT_GT(ten, nine);
|
||||
}
|
||||
|
||||
TEST(BigNum, comparisons_negative) {
|
||||
auto const zero = BigNum(0);
|
||||
auto const minus_one = BigNum(-1);
|
||||
auto const minus_two = BigNum(-2);
|
||||
|
||||
EXPECT_LT(minus_one, zero);
|
||||
EXPECT_LE(minus_one, zero);
|
||||
EXPECT_LT(minus_two, minus_one);
|
||||
EXPECT_LE(minus_two, minus_one);
|
||||
EXPECT_LE(minus_one, minus_one);
|
||||
EXPECT_GE(minus_two, minus_two);
|
||||
|
||||
EXPECT_GT(zero, minus_one);
|
||||
EXPECT_GE(zero, minus_one);
|
||||
EXPECT_GT(minus_one, minus_two);
|
||||
EXPECT_GE(minus_one, minus_two);
|
||||
EXPECT_GE(minus_one, minus_one);
|
||||
EXPECT_GE(minus_two, minus_two);
|
||||
}
|
||||
|
||||
TEST(BigNum, comparisons_digits_negative) {
|
||||
auto const minus_nine = BigNum(-9);
|
||||
auto const minus_ten = BigNum(-10);
|
||||
|
||||
EXPECT_LT(minus_ten, minus_nine);
|
||||
EXPECT_GT(minus_nine, minus_ten);
|
||||
}
|
||||
|
||||
TEST(BigNum, unary) {
|
||||
auto const zero = BigNum(0);
|
||||
auto const one = BigNum(1);
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
gtest = dependency(
|
||||
'gtest',
|
||||
main: true,
|
||||
required: false,
|
||||
)
|
||||
|
||||
if gtest.found()
|
||||
unit_test_sources = files(
|
||||
'bignum.cc',
|
||||
)
|
||||
|
||||
unit_tests = executable(
|
||||
'unit_tests',
|
||||
sources: unit_test_sources,
|
||||
dependencies: [
|
||||
bignum,
|
||||
gtest,
|
||||
],
|
||||
)
|
||||
|
||||
test(
|
||||
'unit tests',
|
||||
unit_tests,
|
||||
protocol: 'gtest',
|
||||
)
|
||||
endif
|
Loading…
Reference in a new issue