summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-06-15 22:09:13 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-06-15 22:09:13 +0200
commit47da9c1e9ac25b3248a808f4519e2c64ecb8e2b4 (patch)
tree8a237a5a18e7b91a2c83473bd6b0a9db381daab0
parentc2efa347a8e5f1d83427c34defa953e594a2bb12 (diff)
Add class MLKInteger.
-rw-r--r--GNUmakefile9
-rw-r--r--MLKInteger.h19
-rw-r--r--MLKInteger.m101
-rw-r--r--MLKRatio.h10
-rw-r--r--MLKReader.m3
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
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 <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
{