From 47da9c1e9ac25b3248a808f4519e2c64ecb8e2b4 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sun, 15 Jun 2008 22:09:13 +0200 Subject: Add class MLKInteger. --- GNUmakefile | 9 ++++-- MLKInteger.h | 19 +++++++++++ MLKInteger.m | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ MLKRatio.h | 10 ++++-- MLKReader.m | 3 +- 5 files changed, 135 insertions(+), 7 deletions(-) create mode 100644 MLKInteger.m diff --git a/GNUmakefile b/GNUmakefile index 4b614b0..e9cbdd4 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -20,15 +20,18 @@ include $(GNUSTEP_MAKEFILES)/common.make TOOL_NAME = etoilisp etoilisp_OBJC_FILES = MLKCharacter.m MLKCons.m MLKDynamicContext.m \ MLKEndOfFileError.m MLKEnvironment.m MLKError.m \ - MLKLinkedList.m MLKLispValue.m MLKPackage.m \ - MLKReader.m MLKReadtable.m MLKReaderError.m \ - MLKStream.m MLKSymbol.m MLKThrowException.m \ + MLKInteger.m MLKLinkedList.m MLKLispValue.m \ + MLKPackage.m MLKReader.m MLKReadtable.m \ + MLKReaderError.m MLKStream.m MLKSymbol.m \ + MLKThrowException.m \ MLKUndefinedVariableException.m BUNDLE_NAME = Test Test_OBJC_FILES = $(etoilisp_OBJC_FILES) MLKLowLevelTests.m Test_OBJC_LIBS = -lUnitKit +ADDITIONAL_LDFLAGS = -lgmp + -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make include $(GNUSTEP_MAKEFILES)/tool.make diff --git a/MLKInteger.h b/MLKInteger.h index 38d319e..57687b4 100644 --- a/MLKInteger.h +++ b/MLKInteger.h @@ -18,18 +18,37 @@ #import "MLKLispValue.h" +#include +#include +#include + @class NSString; @interface MLKInteger : MLKLispValue { + mpz_t value; } +-(MLKInteger *) initWithMPZ:(mpz_t)mpz; +-(MLKInteger *) initWithString:(NSString *)string + negative:(BOOL)negative + base:(unsigned int)base; + ++(MLKInteger *) integerWithMPZ:(mpz_t)mpz; +(MLKInteger *) integerWithString:(NSString *)string negative:(BOOL)negative base:(unsigned int)base; -(int) intValue; +-(MLKInteger *) add:(MLKInteger *)arg; +-(MLKInteger *) subtract:(MLKInteger *)arg; +-(MLKInteger *) multiplyWith:(MLKInteger *)arg; +-(MLKInteger *) divideBy:(MLKInteger *)arg; + +-(NSString *) description; +-(NSString *) descriptionWithBase:(int)base; + -(void) dealloc; @end diff --git a/MLKInteger.m b/MLKInteger.m new file mode 100644 index 0000000..b9e9bf4 --- /dev/null +++ b/MLKInteger.m @@ -0,0 +1,101 @@ +/* -*- mode: objc; coding: utf-8 -*- */ +/* Étoilisp/Mulklisp, a Common Lisp subset for the Étoilé runtime. + * Copyright (C) 2008 Matthias Andreas Benkard. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import "MLKInteger.h" + +#import + + +@implementation MLKInteger +-(MLKInteger *) initWithMPZ:(mpz_t)mpz +{ + self = [super init]; + mpz_init_set (value, mpz); + return self; +} + +-(MLKInteger *) initWithString:(NSString *)string + negative:(BOOL)negative + base:(unsigned int)base +{ + self = [super init]; + mpz_init_set_str (value, [string UTF8String], base); + if (negative) mpz_neg (value, value); + return self; +} + ++(MLKInteger *) integerWithMPZ:(mpz_t)mpz +{ + return AUTORELEASE ([[MLKInteger alloc] initWithMPZ:mpz]); +} + ++(MLKInteger *) integerWithString:(NSString *)string + negative:(BOOL)negative + base:(unsigned int)base +{ + return AUTORELEASE ([[MLKInteger alloc] initWithString:string + negative:negative + base:base]); +} + +#define DEFINE_MPZ_OPERATION(selector, mpzop) \ + -(MLKInteger *) selector (MLKInteger *)arg \ + { \ + mpz_t mpz; \ + MLKInteger *result; \ + \ + mpz_init (mpz); \ + mpzop (mpz, self->value, arg->value); \ + result = [MLKInteger integerWithMPZ:mpz]; \ + mpz_clear (mpz); \ + \ + return result; \ + } + +DEFINE_MPZ_OPERATION (add:, mpz_add) +DEFINE_MPZ_OPERATION (subtract:, mpz_sub) +DEFINE_MPZ_OPERATION (multiplyWith:, mpz_mul) +DEFINE_MPZ_OPERATION (divideBy:, mpz_div) + +-(int) intValue +{ + return mpz_get_si (value); +} + +-(NSString *) description +{ + return [self descriptionWithBase:10]; +} + +-(NSString *) descriptionWithBase:(int)base +{ + NSString *str; + char cstr[mpz_sizeinbase (self->value, base) + 2]; + + mpz_get_str (cstr, base, self->value); + str = [NSString stringWithUTF8String:cstr]; + + return str; +} + +-(void) dealloc +{ + mpz_clear (value); + [super dealloc]; +} +@end diff --git a/MLKRatio.h b/MLKRatio.h index c67d7dd..37d5879 100644 --- a/MLKRatio.h +++ b/MLKRatio.h @@ -18,17 +18,21 @@ #import "MLKLispValue.h" +#include +#include +#include + @class NSString, MLKInteger; @interface MLKRatio : MLKLispValue { - MLKInteger *numerator; - MLKInteger *denominator; + mpq_t value; } +(MLKRatio *) ratioWithNumeratorString:(NSString *)numerString - denominatorString:(NSString *)denomString; + denominatorString:(NSString *)denomString + base:(unsigned int)base; -(void) dealloc; @end diff --git a/MLKReader.m b/MLKReader.m index 5663efb..14a6268 100644 --- a/MLKReader.m +++ b/MLKReader.m @@ -360,7 +360,8 @@ [token substringWithRange: NSMakeRange (firstNum, secondNum - firstNum - 1)] - denominatorString:[token substringFromIndex:secondNum]]; + denominatorString:[token substringFromIndex:secondNum] + base:[base intValue]]; } else { -- cgit v1.2.3