Compare commits

...

15 commits

Author SHA1 Message Date
Bruno BELANYI c72032f0ce ci: fix deprecated syntax
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2023-12-06 12:02:08 +00:00
Bruno BELANYI 34df20cdb7 nix: fix deprecated flake attributes 2023-12-06 12:02:08 +00:00
Bruno BELANYI 2e29dea2b6 abacus: bignum: use base to compute complement
All checks were successful
ci/woodpecker/push/check Pipeline was successful
Instead of hard-coding 9 for base-10 computations.
2023-12-06 11:54:28 +00:00
Bruno BELANYI 8b3288c1ce ci: remove Drone CI
All checks were successful
ci/woodpecker/push/check Pipeline was successful
ci/woodpecker/manual/check Pipeline was successful
2023-04-01 17:13:24 +01:00
Bruno BELANYI 33de39b62a ci: add Woodpecker CI workflow
Some checks failed
ci/woodpecker/push/check Pipeline was successful
continuous-integration/drone/push Build is failing
2023-04-01 16:48:35 +01:00
Bruno BELANYI d5507dce2d nix: use overlay
All checks were successful
continuous-integration/drone/push Build is passing
2022-02-17 10:27:11 +01:00
Bruno BELANYI c9460c09d5 abacus: bignum: simplify is_canonicalized
All checks were successful
continuous-integration/drone/push Build is passing
2022-02-17 10:13:29 +01:00
Bruno BELANYI a382b299b0 abacus: bignum: fix comparison of negative numbers 2022-02-17 10:03:21 +01:00
Bruno BELANYI 3e5133da1a ci: add package check phase
All checks were successful
continuous-integration/drone/push Build is passing
This takes care of launching the test suite.
2021-10-12 15:44:21 +02:00
Bruno BELANYI 8cb26ee316 abacus: bignum: use span
All checks were successful
continuous-integration/drone/push Build is passing
Once again, the code looks cleaner that way.
2021-10-12 15:05:43 +02:00
Bruno BELANYI 4ea7a38b61 abacus: use C++20 2021-10-12 15:05:43 +02:00
Bruno BELANYI da8b08e4e3 abacus: bignum: use IIFE
I think it looks cleaner to use Immediately Invoked Function Expressions
in such cases.
2021-10-12 15:02:37 +02:00
Bruno BELANYI 5c7c2af289 nix: use 'inputsFrom'
All checks were successful
continuous-integration/drone/push Build is passing
2021-10-08 15:47:26 +02:00
Bruno BELANYI 171ef10a6d abacus: fix include directories
All checks were successful
continuous-integration/drone/push Build is passing
This cleans up one of my major pain points with the Meson way of doing
things.

The Meson solution to have nice includes would have been to create an
`include/<name>` directory per library I create...
2021-09-01 19:43:02 +02:00
Bruno BELANYI eb9295cfcd abacus: remove meson build system 2021-09-01 19:37:00 +02:00
17 changed files with 128 additions and 211 deletions

View file

@ -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
View 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

View file

@ -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)

View file

@ -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;
};
});
}

View file

@ -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')

View file

@ -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{};

View file

@ -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}>
)

View file

@ -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;
}

View file

@ -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,
)

View file

@ -1,16 +0,0 @@
abacus_sources = files(
'abacus.cc',
)
subdir('bignum')
subdir('parse')
abacus = executable(
'abacus',
sources: abacus_sources,
dependencies: [
bignum,
parse,
],
install: true,
)

View file

@ -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}>
)

View file

@ -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,
)

View file

@ -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 {

View file

@ -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 {

View file

@ -1 +0,0 @@
subdir('unit')

View file

@ -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);

View file

@ -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