From c50f5cd58337e96609479484c2cfd7fcd80db182 Mon Sep 17 00:00:00 2001 From: dos-reis Date: Sun, 17 Aug 2014 09:15:57 +0000 Subject: OpenAxiom::VM::Fixnum is now a distinct type. --- src/include/vm.H | 19 +++++++++++-------- src/rt/Database.cc | 5 +++-- src/rt/Lisp.cc | 14 +++++++------- src/rt/vm.cc | 4 ++-- 4 files changed, 23 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/include/vm.H b/src/include/vm.H index d386e4c3..0ef6f973 100644 --- a/src/include/vm.H +++ b/src/include/vm.H @@ -166,25 +166,28 @@ namespace OpenAxiom { // VM integers are divided into classes: small numbers, // and large numbers. A small number fits entirely in a register. // A large number is allocated and represented by its address. - using Fixnum = intptr_t; + using FixnumBits = intptr_t; + enum class Fixnum : FixnumBits { + minimum = FixnumBits(~(~ValueBits() >> 2)), + zero = FixnumBits(0), + one = FixnumBits(1), + maximum = FixnumBits(~ValueBits() >> 2), + }; constexpr ValueBits fix_tag = 0x1; constexpr bool is_fixnum(Value v) { - return (v & 0x1) == fix_tag; + return (ValueBits(v) & 0x1) == fix_tag; } constexpr Fixnum to_fixnum(Value v) { - return Fixnum(v >> 1); + return Fixnum(FixnumBits(v) >> 1); } constexpr Value from_fixnum(Fixnum i) { - return (Fixnum(i) << 1 ) | fix_tag; + return (ValueBits(i) << 1 ) | fix_tag; } - constexpr Fixnum fixnum_maximum = to_fixnum(~Value{ }); - constexpr Fixnum fixnum_minimum = -fixnum_maximum - 1; - // ------------ // -- String -- // ------------ @@ -262,7 +265,7 @@ namespace OpenAxiom { inline Fixnum count_nodes(Value v) { if (auto p = to_pair_if_can(v)) return count_nodes(p); - return 0; + return Fixnum::zero; } // --------------- diff --git a/src/rt/Database.cc b/src/rt/Database.cc index ee620711..df6ec0a3 100644 --- a/src/rt/Database.cc +++ b/src/rt/Database.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2013, Gabriel Dos Reis. +// Copyright (C) 2013-2014, Gabriel Dos Reis. // All rights reserved. // Written by Gabriel Dos Reis. // @@ -47,7 +47,8 @@ namespace OpenAxiom { auto x = reader.read(); auto offset = Lisp::retract_to_fixnum (Lisp::retract_to_pair(ctx.make_value(x))->head); - reader.position(offset); + auto n = FixnumBits(offset); + reader.position(n); toc = Lisp::retract_to_pair(ctx.make_value(reader.read())); } else if (auto data = Lisp::assoc(key, toc)) diff --git a/src/rt/Lisp.cc b/src/rt/Lisp.cc index 12684181..6f125bf7 100644 --- a/src/rt/Lisp.cc +++ b/src/rt/Lisp.cc @@ -77,17 +77,17 @@ namespace OpenAxiom { integer_too_large(const Sexpr::IntegerSyntax& x) { std::string s { x.lexeme().begin(), x.lexeme().end() }; throw IntegerOverflow{ s + " is too large for Fixnum; max value is " - + std::to_string(fixnum_maximum) }; + + std::to_string(FixnumBits(Fixnum::maximum)) }; } - constexpr auto fixmax_by_ten = fixnum_maximum / 10; - constexpr auto fixmax_lsd = fixnum_maximum % 10; + constexpr auto fixmax_by_ten = FixnumBits(Fixnum::maximum) / 10; + constexpr auto fixmax_lsd = FixnumBits(Fixnum::maximum) % 10; static Value construct(Evaluator* ctx, const Sexpr::IntegerSyntax& x) { bool neg = false; auto cur = x.lexeme().begin(); - Fixnum val = 0; + FixnumBits val = 0; switch (*cur) { case '-': neg = true; case '+': ++cur; @@ -102,12 +102,12 @@ namespace OpenAxiom { val = 10 * val + d; } if (neg) { - if (val > fixnum_maximum) + if (val > FixnumBits(Fixnum::maximum)) integer_too_large(x); val = -val; } } - return VM::from_fixnum(val); + return VM::from_fixnum(Fixnum(val)); } static Value @@ -250,7 +250,7 @@ namespace OpenAxiom { if (v == nil) os << "NIL"; else if (is_fixnum(v)) - os << to_fixnum(v); + os << FixnumBits(to_fixnum(v)); else if (auto p = to_pair_if_can(v)) format(p, os); else if (auto s = to_string_if_can(v)) diff --git a/src/rt/vm.cc b/src/rt/vm.cc index 2fe4da1c..a0f4f2e3 100644 --- a/src/rt/vm.cc +++ b/src/rt/vm.cc @@ -44,10 +44,10 @@ namespace OpenAxiom { Fixnum count_nodes(Pair p) { - Fixnum n = 1; + FixnumBits n = 1; for (; auto q = to_pair_if_can(p->tail); p = q) ++n; - return n; + return Fixnum(n); } // -- BasicContext -- -- cgit v1.2.3