diff options
-rw-r--r-- | GNUmakefile | 9 | ||||
-rw-r--r-- | MLKInteger.h | 19 | ||||
-rw-r--r-- | MLKInteger.m | 101 | ||||
-rw-r--r-- | MLKRatio.h | 10 | ||||
-rw-r--r-- | MLKReader.m | 3 |
5 files changed, 135 insertions, 7 deletions
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 <stdarg.h> +#include <stdio.h> +#include <gmp.h> + @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 <http://www.gnu.org/licenses/>. + */ + +#import "MLKInteger.h" + +#import <Foundation/NSString.h> + + +@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 @@ -18,17 +18,21 @@ #import "MLKLispValue.h" +#include <stdarg.h> +#include <stdio.h> +#include <gmp.h> + @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 { |