Compare commits
No commits in common. "main" and "6c0950dbe15af558c2ba6fe2ad47f26d5dd44847" have entirely different histories.
main
...
6c0950dbe1
17 changed files with 211 additions and 128 deletions
27
.drone.yml
Normal file
27
.drone.yml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
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
|
||||
...
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
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,15 +4,12 @@ enable_testing()
|
|||
|
||||
add_library(common_options INTERFACE)
|
||||
target_compile_features(common_options INTERFACE
|
||||
cxx_std_20
|
||||
cxx_std_17
|
||||
)
|
||||
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,40 +29,9 @@
|
|||
};
|
||||
|
||||
outputs = { self, futils, nixpkgs, pre-commit-hooks }:
|
||||
{
|
||||
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:
|
||||
futils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; overlays = [ self.overlays.default ]; };
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
in
|
||||
{
|
||||
checks = {
|
||||
|
|
@ -87,17 +56,46 @@
|
|||
};
|
||||
};
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
inputsFrom = with self.packages.${system}; [
|
||||
abacus
|
||||
];
|
||||
defaultPackage = self.packages.${system}.abacus;
|
||||
|
||||
devShell = pkgs.mkShell {
|
||||
inherit (self.defaultPackage.${system})
|
||||
checkInputs
|
||||
nativeBuildInputs
|
||||
;
|
||||
|
||||
inherit (self.checks.${system}.pre-commit) shellHook;
|
||||
};
|
||||
|
||||
packages = futils.lib.flattenTree {
|
||||
inherit (pkgs) abacus;
|
||||
default = pkgs.abacus;
|
||||
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;
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
|||
13
meson.build
Normal file
13
meson.build
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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 "parse/parser-driver.hh"
|
||||
#include "parser-driver.hh" // FIXME: I would like `parse/parser-driver.hh` path instead...
|
||||
|
||||
int main() {
|
||||
abacus::parse::ParserDriver driver{};
|
||||
|
|
|
|||
|
|
@ -3,3 +3,7 @@ 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,7 +3,6 @@
|
|||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <span>
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
|
@ -83,17 +82,18 @@ digits_type do_addition(digits_type const& lhs, digits_type const& rhs) {
|
|||
++it2;
|
||||
}
|
||||
|
||||
auto leftover = [=]() {
|
||||
if (it1 != end1) {
|
||||
return std::span(it1, end1);
|
||||
}
|
||||
return std::span(it2, end2);
|
||||
}();
|
||||
auto it = it1;
|
||||
auto end = end1;
|
||||
if (it1 == end1) {
|
||||
it = it2;
|
||||
end = end2;
|
||||
}
|
||||
|
||||
for (auto value : leftover) {
|
||||
int addition = value + carry;
|
||||
while (it != end) {
|
||||
int addition = *it + 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 BASE - 1 - num; };
|
||||
auto const take_complement = [](auto num) { return 9 - num; };
|
||||
std::transform(lhs.begin(), lhs.end(), std::back_inserter(complement),
|
||||
take_complement);
|
||||
|
||||
|
|
@ -363,11 +363,7 @@ bool BigNum::less_than(BigNum const& rhs) const {
|
|||
return sign_ < rhs.sign_;
|
||||
}
|
||||
|
||||
if (is_positive()) {
|
||||
return do_less_than(digits_, rhs.digits_);
|
||||
} else {
|
||||
return do_less_than(rhs.digits_, digits_);
|
||||
}
|
||||
return do_less_than(digits_, rhs.digits_);
|
||||
}
|
||||
|
||||
void BigNum::canonicalize() {
|
||||
|
|
@ -385,15 +381,15 @@ bool BigNum::is_canonicalized() const {
|
|||
return sign_ == 0;
|
||||
}
|
||||
|
||||
// `back` is valid since there is at least one element
|
||||
auto const has_leading_zero = digits_.back() == 0;
|
||||
if (has_leading_zero) {
|
||||
auto const leading_zeros = std::find_if(digits_.rbegin(), digits_.rend(),
|
||||
[](auto v) { return v != 0; });
|
||||
if (leading_zeros != digits_.rbegin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto const has_overflow = std::any_of(digits_.begin(), digits_.end(),
|
||||
[](auto v) { return v >= BASE; });
|
||||
if (has_overflow) {
|
||||
auto const overflow = std::find_if(digits_.begin(), digits_.end(),
|
||||
[](auto v) { return v >= BASE; });
|
||||
if (overflow != digits_.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
16
src/bignum/meson.build
Normal file
16
src/bignum/meson.build
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
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,
|
||||
)
|
||||
16
src/meson.build
Normal file
16
src/meson.build
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
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_BINARY_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
)
|
||||
|
|
|
|||
48
src/parse/meson.build
Normal file
48
src/parse/meson.build
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
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/bignum.hh"
|
||||
#include "bignum.hh" // FIXME: I would like `bignum/bignum.hh` path instead...
|
||||
|
||||
namespace abacus::parse {
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace abacus::parse {
|
|||
class ParserDriver;
|
||||
} // namespace abacus::parse
|
||||
|
||||
#include "bignum/bignum.hh"
|
||||
#include "bignum.hh" // FIXME: I would like `bignum/bignum.hh` path instead...
|
||||
}
|
||||
|
||||
%code provides {
|
||||
|
|
|
|||
1
tests/meson.build
Normal file
1
tests/meson.build
Normal file
|
|
@ -0,0 +1 @@
|
|||
subdir('unit')
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "bignum/bignum.hh"
|
||||
#include "bignum.hh"
|
||||
|
||||
using namespace abacus::bignum;
|
||||
|
||||
|
|
@ -68,34 +68,6 @@ 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);
|
||||
|
|
|
|||
26
tests/unit/meson.build
Normal file
26
tests/unit/meson.build
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
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…
Add table
Add a link
Reference in a new issue