Compare commits

...

69 Commits

Author SHA1 Message Date
240e93a90f +++ 2024-01-28 23:20:45 +01:00
bc41dcda4a --- 2024-01-28 23:15:34 +01:00
f62030772a ,,, 2024-01-28 23:10:28 +01:00
43663714ca ... 2024-01-28 23:06:11 +01:00
38bfd5c7d9 add heap size 2024-01-28 23:02:03 +01:00
nilspolek
f348174229 gc 2024-01-28 22:29:20 +01:00
nilspolek
bc8a037a30 gc 2024-01-28 22:26:50 +01:00
nilspolek
958c383f85 changed objref to prevent bugs 2024-01-28 10:30:39 +01:00
nilspolek
f3829559d4 null problems are now not more 2024-01-28 00:14:19 +01:00
nilspolek
9155216fd2 now breakpoints are possible 2024-01-27 23:29:33 +01:00
nilspolek
b6320ecba7 updated the test 2024-01-27 23:21:18 +01:00
nilspolek
3bd8b9ac20 updated the test 2024-01-27 23:20:25 +01:00
root
147415beef s 2024-01-27 22:14:18 +00:00
nilspolek
5fb42ff984 updated the test 2024-01-27 23:09:29 +01:00
nilspolek
d7bb53687d updated the test 2024-01-27 23:08:21 +01:00
root
ee27de7481 factor.asm 2024-01-27 22:01:18 +00:00
root
eaab6ab023 s 2024-01-27 21:55:35 +00:00
nilspolek
38f06b1575 updated the test 2024-01-27 22:52:29 +01:00
nilspolek
6ebc065a7a added a method for testing arrays 2024-01-27 22:43:34 +01:00
nilspolek
8c45b02769 added njvm2 2024-01-27 21:19:57 +01:00
nilspolek
4cc117fdd4 added tests 2024-01-27 21:18:34 +01:00
nilspolek
49e4911238 added tests 2024-01-27 21:17:06 +01:00
nilspolek
21c1f8fee6 made some updates 2024-01-27 20:53:05 +01:00
root
30311a393d s 2024-01-27 19:36:30 +00:00
root
daacbc705d added njc8l 2024-01-27 19:33:56 +00:00
nilspolek
b77ea3d3d8 made some updates 2024-01-27 20:11:56 +01:00
nilspolek
29dc364f94 made some updates 2024-01-27 20:01:28 +01:00
nilspolek
fd15e54cdd made some updates 2024-01-27 19:59:01 +01:00
nilspolek
460def3fc6 made some updates 2024-01-27 18:53:42 +01:00
nilspolek
4cf1a82974 made some updates 2024-01-27 18:52:39 +01:00
nilspolek
bc56a6a1c2 made some updates 2024-01-27 18:51:14 +01:00
nilspolek
84320f00c7 made some updates 2024-01-27 18:49:59 +01:00
nilspolek
8d667ec836 removed sda from stack.c 2024-01-27 18:45:27 +01:00
nilspolek
520cfa57d5 removed sda from stack.c 2024-01-27 18:32:29 +01:00
nilspolek
2df1debe1a removed sda from stack.c 2024-01-27 18:31:36 +01:00
nilspolek
9475dd6666 changed version 2024-01-27 18:27:57 +01:00
nilspolek
03b88a8a76 added some things to GC 2024-01-27 10:25:27 +01:00
nilspolek
91b36a53d5 changed stack size 2024-01-26 19:13:42 +01:00
nilspolek
169217fd2c changed stack size 2024-01-26 17:01:07 +01:00
084b715729 testing sth 2024-01-25 20:22:33 +00:00
7d2e5ad1cd made some improvements 2024-01-25 19:51:24 +00:00
nilspolek
08109a4f16 changed stack size 2024-01-23 22:49:23 +01:00
nilspolek
ade4f8e18d changed version 2024-01-23 22:46:55 +01:00
nilspolek
9f7cd4aefc forgot what ive done 2024-01-23 22:45:49 +01:00
nilspolek
82704187f9 Arrays work now 2024-01-23 22:15:49 +01:00
nilspolek
4f0fc8a364 Arrays work now 2024-01-23 22:05:23 +01:00
nilspolek
797bfa45eb corrected CMakeLists.txt 2024-01-23 21:44:03 +01:00
nilspolek
1c0d85b5c9 added sth 2024-01-23 21:10:06 +01:00
nilspolek
dc5a98c401 added sth 2024-01-23 20:04:06 +01:00
nilspolek
c174108e09 fixed some mistakes 2024-01-23 17:18:54 +01:00
nilspolek
e8b4062331 added some sht 2024-01-23 16:58:57 +01:00
nilspolek
f0d74a7e17 forgotten to add new in instructions.c 2024-01-23 16:03:04 +01:00
nilspolek
1ea539ddea removed the fib program 2024-01-23 15:49:05 +01:00
nilspolek
69b4a1afb4 Added some instructions for cmp 2024-01-23 15:47:43 +01:00
nilspolek
3a046d6f89 Added some instructions for cmp 2024-01-23 15:41:31 +01:00
eba9656631 sjkbdsfjk 2024-01-18 21:07:59 +01:00
nils polek
f60e82b46b Chanded versin 2024-01-18 19:56:11 +00:00
1f02f49cdf fix comparisons 2024-01-18 20:18:21 +01:00
nils polek
6319ddcad9 some shit 2024-01-18 19:15:56 +00:00
9b4a9faa8d update version to 6 2024-01-18 18:54:53 +01:00
4d24ab038c remove unused tmp variable 2024-01-18 18:54:20 +01:00
82d3201374 add bigint to execute 2024-01-18 18:53:46 +01:00
e5f2858a5c update 2024-01-18 18:25:16 +01:00
906ea30be2 update 2024-01-18 18:25:00 +01:00
nils polek
70dbd0253b Big int works 2024-01-18 17:17:07 +00:00
5039f95153 Revert "update"
This reverts commit dbafdbeea5.
2024-01-18 17:24:01 +01:00
dbafdbeea5 update 2024-01-18 16:21:34 +01:00
nils polek
ac57431ac4 added big int lib 2024-01-15 16:28:41 +00:00
nils polek
3935d2778b alle rechenobjekte im stack sind jetzt pointer 2024-01-15 15:32:02 +00:00
105 changed files with 36719 additions and 210 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

1
.gitignore vendored
View File

@@ -3,4 +3,3 @@ cmake-build-debug
njvm njvm
njvm.dSYM njvm.dSYM
njvm.exe njvm.exe
njvm2

View File

@@ -5,5 +5,22 @@ set(CMAKE_C_STANDARD 99)
add_compile_options(-g -Wall -pedantic) add_compile_options(-g -Wall -pedantic)
add_executable(ninja njvm.c add_executable(njvm njvm.c
SDA.c) njvm.h)
# Include directories for njvm executable
target_include_directories(njvm PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/bigint/build/include)
# Add the library
add_library(bigint STATIC ${CMAKE_SOURCE_DIR}/bigint/src/bigint.c
support.c
GC.c
heap.c
heap.h)
# Include directories for the bigint library
target_include_directories(bigint PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bigint/build/include)
# Link the executable with the library
target_link_libraries(njvm PRIVATE bigint)

99
GC.c Normal file
View File

@@ -0,0 +1,99 @@
#ifndef GC
#define GC
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stackslot.c"
#include "stack.c"
#include "bigint.h"
#include "instruktion.c"
#include "record.c"
#include "SDA.c"
typedef struct {
unsigned int freiZeiger;
unsigned int size;
unsigned char *data;
} *heapPartRef;
// SDA
struct sda sda;
// Stack
struct stack stack;
#define SIZE 1000;
//Register
struct stack reg;
//heapPartRef primary;
//heapPartRef secondary;
//unsigned int heapSize;
//void initHeap(int size){
// heapSize = 2 * sizeof (unsigned int) + size;
// if ((primary = malloc(heapSize)) == NULL) perror("malloc");
// if ((secondary = malloc(heapSize)) == NULL) perror("malloc");
//}
//
//
//// nimmt obj und copier es in den secondary Speicher
//void copy(ObjRef obj){
// if(obj->brokenHeart == true) return;
// obj->brokenHeart = true;
// if (IS_PRIMITIVE(obj)){
// if(obj->size > secondary->size-secondary->freiZeiger) perror("Heap is to Small");
// obj->forward_pointer = memcpy((void *) secondary->data[secondary->freiZeiger], obj, obj->size);
// secondary->freiZeiger += obj->size;
// } else {
// if(sizeof(*obj) + (GET_ELEMENT_COUNT(obj) * sizeof(void *)) > secondary->size-secondary->freiZeiger) perror("Heap is to Small");
// GET_ELEMENT_COUNT(obj);
// obj->forward_pointer = memcpy((void *) secondary->data[secondary->freiZeiger], obj, sizeof(*obj) + (GET_ELEMENT_COUNT(obj) * sizeof(void *)));
// secondary->freiZeiger += sizeof(*obj) + (GET_ELEMENT_COUNT(obj) * sizeof(void *));
// for (int i = 0; i < GET_ELEMENT_COUNT(obj); ++i) {
// copy(getField(obj,i));
// }
// }
//}
//
//void runGC(){
// int rootSize = *sda.size + *reg.size + *stack.size + 4;
// ObjRef* rootObjs = malloc(sizeof(ObjRef) * rootSize);
// if(rootObjs == NULL) perror("malloc");
// int counter = 0;
// //Bip
// rootObjs[0] = bip.op1;
// rootObjs[counter++] = bip.op2;
// rootObjs[counter++] = bip.res;
// rootObjs[counter++] = bip.rem;
// //SDA
// for (int i = 0; i < *sda.size; ++i) {
// rootObjs[counter++] = sda.sda[i];
// }
// //REG
// for (int i = 0; i < *reg.size; ++i) {
// rootObjs[counter++] = reg.stack[i].u.objRef;
// }
// //STACK
// for (int i = 0; i < *stack.size; ++i) {
// rootObjs[counter++] = stack.stack[i].u.objRef;
// }
//
// for (int i = 0; i < rootSize; ++i) {
// if(rootObjs[i] == NULL) continue;
// copy(rootObjs[i]);
// }
// heapPartRef temp = primary;
// primary = secondary;
// secondary = temp;
//
//}
//
//void *alloc(size_t size){
// if(primary->size-primary->freiZeiger < size){
// runGC();
// }
// primary->freiZeiger += size;
// return (void *) primary->data[primary->freiZeiger - size];
//}
#endif

View File

@@ -1,35 +1,12 @@
# Makefile for a simple C program # Makefile for a simple C program
build:
cd ./bigint; make; cd ..
gcc -g -Wall -Ibigint/build/include -o support.o -c support.c
gcc -g -Wall -Ibigint/build/include -o njvm.o -c njvm.c
gcc -g -Wall -Lbigint/build/lib -o njvm njvm.o support.o -lbigint
# Compiler run: build
CC = gcc ./njvm prog.bin
# program to Run debug: build
F = prog.bin ./njvm --debug prog.bin
# Compiler flags
CFLAGS = -g -Wall -std=c99 -pedantic
# Source file
SRC = njvm.c
# Executable name
TARGET = njvm
# Default target
all:
$(CC) $(CFLAGS) -o $(TARGET) $(SRC)
# Clean up
clean:
rm -f $(OBJ) $(TARGET)
debug: all
./$(TARGET) --debug $(F)
run: all
./$(TARGET) $(F)
nja: ./nja/nja$(V)
./nja/nja$(V) $(IN) $(OUT)
njc: ./njc/njc$(V)
./njc/njc$(V) $(IN) $(OUT)

43
Makefile3 Normal file
View File

@@ -0,0 +1,43 @@
# Makefile for a simple C program
# Compiler
CC = gcc
# program to Run
F = prog.bin
# Compiler flags
CFLAGS = -g -Wall -Ibigint/build/include
LDFLAGS = -g -Wall -Lbigint/build/lib
# Source file
SRC = njvm.c
# Executable name
TARGET = njvm
njvm.o:
$(CC) $(CFLAGS) -o njvm.o -c njvm.c
support.o:
$(CC) $(CFLAGS) -o support.o -c support.c
# Default target
all: njvm.o support.o
$(CC) $(LDFLAGS) -o $(TARGET) njvm.o support.o -lbigint
# Clean up
clean:
rm -f $(OBJ) $(TARGET)
debug: all
./$(TARGET) --debug $(F)
run: all
./$(TARGET) $(F)
nja: ./nja/nja$(V)
./nja/nja$(V) $(IN) $(OUT)
njc: ./njc/njc$(V)
./njc/njc$(V) $(IN) $(OUT)

1
SDA.c
View File

@@ -15,6 +15,7 @@ ObjRef getSDA(int i, struct sda s) {
} }
void setSDA(int point, ObjRef val, struct sda s) { void setSDA(int point, ObjRef val, struct sda s) {
if (val == NULL) perror("Value is null");
s.sda[point] = val; s.sda[point] = val;
} }

BIN
a.out Executable file

Binary file not shown.

22
bigint/Makefile Normal file
View File

@@ -0,0 +1,22 @@
#
# Makefile for big integer library and test
#
DIRS = src tst
all: clean
for i in $(DIRS) ; do \
$(MAKE) -C $$i install ; \
done
clean:
for i in $(DIRS) ; do \
$(MAKE) -C $$i clean ; \
done
rm -rf ./build
rm -f *~
dist: clean
(cd .. ; \
tar -cvf bigint.tar bigint ; \
gzip -f bigint.tar)

92
bigint/README Normal file
View File

@@ -0,0 +1,92 @@
The "bigint" Package
====================
1. What is it?
--------------
This package implements a multiple-precision integer arithmetic package,
i.e., a collection of functions which can calculate with integers having
arbitrarily many digits. The algorithms are taken from [D. Knuth: The
Art of Computer Programming, Vol. 2, Seminumerical Algorithms], the
implementation language is C.
2. "Multiple Precision" - how does it work?
-------------------------------------------
Each integer number is represented as an array of digits. The array
is large enough to hold the number of digits necessary to represent
the number. Each digit occupies a single byte, so the number base of
this representation is 256. Addition, subtraction, and multiplication
work as we all have learned it: perform the desired operation digit
by digit, starting from the least significant digit, and observing
any "carries" from one place to the next higher one. Division is a
little bit more complicated because there is a certain amount of
guesswork involved. Knuth gives a formal treatment of this guesswork.
3. How do I use it?
-------------------
Because every big integer may have a differently sized array to hold
its digits, these structures are dynamically allocated on the heap of
the C runtime system, and accessed by pointers. If you want to perform
an arithmetic operation on one or two big integers, you have to load
the corresponding pointers into a structure called BIP ("Big Integer
Processor"), and call the arithmetic function. When the function has
returned, the pointer to the result of the operation can be found in
another component of the BIP. The following functions are available:
int bigSgn(void); /* sign */
int bigCmp(void); /* comparison */
void bigNeg(void); /* negation */
void bigAdd(void); /* addition */
void bigSub(void); /* subtraction */
void bigMul(void); /* multiplication */
void bigDiv(void); /* division */
void bigFromInt(int n); /* conversion int --> big */
int bigToInt(void); /* conversion big --> int */
void bigRead(FILE *in); /* read a big integer */
void bigPrint(FILE *out); /* print a big integer */
void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer */
Some of these functions accept or return ordinary integers. For the
exact definition of each function's interface, please see the comments
in the function's source.
4. What else is needed?
-----------------------
The library tries to detect fatal errors in using its functions (e.g.,
null pointers to operands) as well as internal errors (which "cannot
happen"). In either case a user-supplied error routine is called, which
is supposed to print an error message and then to terminate the program.
The library does not attempt to manage memory. For this purpose, it
relies on a user-supplied function "void* newPrimObject(int dataSize)",
which should allocate sufficiently many bytes and return a pointer to
a created object. In addition, the library needs to access a data field
- that implements the size-as-needed cocept - within the created object,
to actualy manage the data structures that represent the values of the
integer number. For this, the following function can be used:
void * getPrimObjectDataPointer(void * obj){
ObjRef oo = ((ObjRef) (obj));
return oo->data;
}
This function must also be a user-supplied function that must be
implemented by the program that wants to use this library.
For details about these three user-supplied functions take a look in
the file "support.c" in the directory "tst".
5. What is in the directory "tst"?
----------------------------------
Well, you may have guessed it already: these are test cases for the
library. You can learn how to link against the library by inspecting
the "Makefile" for the tests, and you can find a simple implementation
of the support library.

BIN
bigint/build/bin/testbip Executable file

Binary file not shown.

View File

@@ -0,0 +1,60 @@
/*
* bigint.h -- big integer library
*/
#ifndef _BIGINT_H_
#define _BIGINT_H_
/* object representation */
typedef void* BigObjRef;
#include <stdio.h>
typedef struct {
int nd; /* number of digits; array may be bigger */
/* nd = 0 exactly when number = 0 */
unsigned char sign; /* one of BIG_NEGATIVE or BIG_POSITIVE */
/* zero always has BIG_POSITIVE here */
unsigned char digits[1]; /* the digits proper; number base is 256 */
/* LS digit first; MS digit is not zero */
} Big;
#include "support.h"
/* big integer processor registers */
typedef struct {
BigObjRef op1; /* first (or single) operand */
BigObjRef op2; /* second operand (if present) */
BigObjRef res; /* result of operation */
BigObjRef rem; /* remainder in case of division */
} BIP;
extern BIP bip; /* registers of the processor */
/* big integer processor functions */
int bigSgn(void); /* sign */
int bigCmp(void); /* comparison */
void bigNeg(void); /* negation */
void bigAdd(void); /* addition */
void bigSub(void); /* subtraction */
void bigMul(void); /* multiplication */
void bigDiv(void); /* division */
void bigFromInt(int n); /* conversion int --> big */
int bigToInt(void); /* conversion big --> int */
void bigRead(FILE *in); /* read a big integer */
void bigPrint(FILE *out); /* print a big integer */
void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer object */
#endif /* _BIGINT_H_ */

View File

@@ -0,0 +1,15 @@
/*
* support.h -- object representation and support functions
*/
#ifndef _SUPPORT_H_
#define _SUPPORT_H_
/* support functions */
void fatalError(char *msg); /* print a message and exit */
void * newPrimObject(int dataSize); /* create a new primitive object */
void * getPrimObjectDataPointer(void * primObject);
#endif /* _SUPPORT_H_ */

Binary file not shown.

26
bigint/src/Makefile Normal file
View File

@@ -0,0 +1,26 @@
#
# Makefile for big integer library
#
BUILD = ../build
CC = gcc
CFLAGS = -g -Wall
all: support.h bigint.h libbigint.a
install: all
mkdir -p $(BUILD)/include
cp support.h $(BUILD)/include
cp bigint.h $(BUILD)/include
mkdir -p $(BUILD)/lib
cp libbigint.a $(BUILD)/lib
libbigint.a: bigint.o
ar -crs libbigint.a bigint.o
bigint.o: bigint.c bigint.h support.h
$(CC) $(CFLAGS) -o bigint.o -c bigint.c
clean:
rm -f *~ bigint.o libbigint.a

987
bigint/src/bigint.c Normal file
View File

@@ -0,0 +1,987 @@
/*
* bigint.c -- big integer library
*/
#include <stdio.h>
#include <ctype.h>
#include "bigint.h"
/**************************************************************/
/* debugging */
#define DIV_CHK_01 0
#define DIV_CHK_02 0
#define DIV_CHK_03 0
#define DIV_CHK_04 0
#define DIV_CHK_05 0
#define DIV_CHK_06 0
#define DIV_CHK_07 0
#define DIV_CHK_08 0
#define DIV_CHK_09 0
#define DIV_CHK_10 0
#define DIV_CHK_11 0
/**************************************************************/
/* big integer representation */
#define BIG_NEGATIVE ((unsigned char) 0)
#define BIG_POSITIVE ((unsigned char) 1)
#define BIG_PTR(bigObjRef) ((Big *) (getPrimObjectDataPointer(bigObjRef)))
#define GET_ND(bigObjRef) (BIG_PTR(bigObjRef)->nd)
#define SET_ND(bigObjRef, val) (BIG_PTR(bigObjRef)->nd = (val))
#define GET_SIGN(bigObjRef) (BIG_PTR(bigObjRef)->sign)
#define SET_SIGN(bigObjRef, val) (BIG_PTR(bigObjRef)->sign = (val))
#define GET_DIGIT(bigObjRef, i) (BIG_PTR(bigObjRef)->digits[i])
#define SET_DIGIT(bigObjRef, i, val) (BIG_PTR(bigObjRef)->digits[i] = (val))
/**************************************************************/
/* global data */
/*
* registers of the big integer processor
*/
BIP bip = {
NULL, /* op1 */
NULL, /* op2 */
NULL, /* res */
NULL, /* rem */
};
/**************************************************************/
/*
* construct a new big integer object
*
* number of digits is given by parameter
* a reference to a proper object is returned
* but no component of the big integer is set
*
* ATTENTION: All object references stored in
* places other than the bip registers may become
* invalid as soon as this function is called!
*/
static BigObjRef newBig(int nd) {
int dataSize;
BigObjRef bigObjRef;
dataSize = sizeof(int) + 1 + nd;
bigObjRef = newPrimObject(dataSize);
return bigObjRef;
}
/**************************************************************/
/* big integer unsigned arithmetic */
/*
* exchange bip.op1 and bip.op2
*/
static void bigXchg(void) {
BigObjRef tmp;
tmp = bip.op1;
bip.op1 = bip.op2;
bip.op2 = tmp;
}
/*
* big integer unsigned comparison
*
* operands in bip.op1 and bip.op2
* result is < 0, = 0, or > 0 if and only if the
* same relation holds for bip.op1 and bip.op2
*/
static int bigUcmp(void) {
int nd1;
int nd2;
int diff;
/* compare sizes */
nd1 = GET_ND(bip.op1);
nd2 = GET_ND(bip.op2);
if (nd1 != nd2) {
/* sizes are different: we know the bigger number */
return nd1 - nd2;
}
/* sizes are equal: we must look at the digits */
while (nd1--) {
diff = (int) GET_DIGIT(bip.op1, nd1) -
(int) GET_DIGIT(bip.op2, nd1);
if (diff != 0) {
return diff;
}
}
/* the numbers are equal */
return 0;
}
/*
* big integer unsigned addition
*
* operands in bip.op1 and bip.op2
* result in bip.res
*/
static void bigUadd(void) {
int nd1;
int nd2;
int i;
unsigned short carry;
unsigned short aux;
int xchgFlag;
/* make sure op1 has at least as many digits as op2 */
nd1 = GET_ND(bip.op1);
nd2 = GET_ND(bip.op2);
if (nd1 < nd2) {
/* exchange operands */
bigXchg();
i = nd1;
nd1 = nd2;
nd2 = i;
xchgFlag = 1;
} else {
/* don't exchange operands */
xchgFlag = 0;
}
/* allocate result */
bip.res = newBig(nd1 + 1);
/* copy op2 to result */
for (i = 0; i < nd2; i++) {
SET_DIGIT(bip.res, i, GET_DIGIT(bip.op2, i));
}
/* fill result with 0 up to size of op1 */
for (; i < nd1; i++) {
SET_DIGIT(bip.res, i, 0);
}
/* res = op1 + res */
carry = 0x00;
for (i = 0; i < nd1; i++) {
aux = (unsigned short) GET_DIGIT(bip.op1, i) +
(unsigned short) GET_DIGIT(bip.res, i) +
carry;
SET_DIGIT(bip.res, i, aux & 0xFF);
carry = aux >> 8;
}
SET_DIGIT(bip.res, i, carry);
/* determine actual size of result */
i = nd1 + 1;
while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
SET_ND(bip.res, i + 1);
/* restore operands */
if (xchgFlag) {
bigXchg();
}
}
/*
* big integer unsigned subtraction
*
* operands in bip.op1 and bip.op2
* result in bip.res, must not be negative
*/
static void bigUsub(void) {
int nd1;
int nd2;
int i;
unsigned short carry;
unsigned short aux;
/* op1 must have at least as many digits as op2 */
nd1 = GET_ND(bip.op1);
nd2 = GET_ND(bip.op2);
if (nd1 < nd2) {
/* unsigned subtraction would yield negative result */
fatalError("internal library error #1 - THIS SHOULD NEVER HAPPEN!");
}
/* allocate result */
bip.res = newBig(nd1);
/* copy op2 to result */
for (i = 0; i < nd2; i++) {
SET_DIGIT(bip.res, i, GET_DIGIT(bip.op2, i));
}
/* fill result with 0 up to size of op1 */
for (; i < nd1; i++) {
SET_DIGIT(bip.res, i, 0);
}
/* res = op1 - res */
carry = 0x01;
for (i = 0; i < nd1; i++) {
aux = (unsigned short) GET_DIGIT(bip.op1, i) -
(unsigned short) GET_DIGIT(bip.res, i) +
carry + 0xFF;
SET_DIGIT(bip.res, i, aux & 0xFF);
carry = aux >> 8;
}
if (carry != 0x01) {
/* unsigned subtraction would yield negative result */
fatalError("internal library error #2 - THIS SHOULD NEVER HAPPEN!");
}
/* determine actual size of result */
i = nd1;
while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
SET_ND(bip.res, i + 1);
}
/*
* big integer unsigned multiplication
*
* operands in bip.op1 and bip.op2
* result in bip.res
*/
static void bigUmul(void) {
int nd1;
int nd2;
int i, j, k;
unsigned short carry;
unsigned short aux;
/* get sizes of operands */
nd1 = GET_ND(bip.op1);
nd2 = GET_ND(bip.op2);
/* allocate result */
bip.res = newBig(nd1 + nd2);
/* reset lower nd1 digits of result */
for (i = 0; i < nd1; i++) {
SET_DIGIT(bip.res, i, 0);
}
/* res = op1 * op2 */
for (j = 0; j < nd2; j++) {
carry = 0x00;
for (k = j, i = 0; i < nd1; k++, i++) {
aux = (unsigned short) GET_DIGIT(bip.op1, i) *
(unsigned short) GET_DIGIT(bip.op2, j) +
(unsigned short) GET_DIGIT(bip.res, k) +
carry;
SET_DIGIT(bip.res, k, aux & 0xFF);
carry = aux >> 8;
}
SET_DIGIT(bip.res, k, carry);
}
/* determine actual size of result */
i = nd1 + nd2;
while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
SET_ND(bip.res, i + 1);
}
/*
* big integer unsigned division by single digit divisor
*
* dividend in bip.rem, divisor in parameter
* quotient in bip.rem, remainder is returned
*/
static unsigned char bigUdiv1(unsigned char divisor) {
BigObjRef tmp;
int nd;
int i;
unsigned short d, r;
unsigned short aux;
/* get size of dividend */
nd = GET_ND(bip.rem);
/* check for division by zero */
d = (unsigned short) divisor;
if (d == 0) {
fatalError("internal library error #3 - THIS SHOULD NEVER HAPPEN!");
}
/* allocate result */
tmp = newBig(nd);
/* tmp = dividend / divisor, r = dividend % divisor */
r = 0;
for (i = nd - 1; i >= 0; i--) {
aux = (r << 8) | (unsigned short) GET_DIGIT(bip.rem, i);
SET_DIGIT(tmp, i, aux / d);
r = aux % d;
}
/* determine actual size of quotient */
i = nd;
while (--i >= 0 && GET_DIGIT(tmp, i) == 0) ;
SET_ND(tmp, i + 1);
/* store quotient */
bip.rem = tmp;
/* return remainder */
return (unsigned char) r;
}
/*
* big integer unsigned division
*
* dividend in bip.op1, divisor in bip.op2
* quotient in bip.res, remainder in bip.rem
*/
static void bigUdiv(void) {
BigObjRef tmp;
int nd1;
int nd2;
int nd3;
int i, j, k, l;
unsigned char r;
unsigned short scale;
unsigned short carry;
unsigned short aux;
unsigned short qhat;
unsigned short v1, v2;
unsigned short uj0, uj1, uj2, two;
/* get sizes of operands */
nd1 = GET_ND(bip.op1);
nd2 = GET_ND(bip.op2);
/* check for division by zero */
if (nd2 == 0) {
fatalError("division by zero");
}
/* check for small dividend */
if (bigUcmp() < 0) {
/* res = 0 */
bip.res = newBig(0);
SET_ND(bip.res, 0);
/* rem = op1; BUT THIS HAS TO BE A COPY! */
bip.rem = newBig(nd1);
for (i = 0; i < nd1; i++) {
SET_DIGIT(bip.rem, i, GET_DIGIT(bip.op1, i));
}
SET_ND(bip.rem, nd1);
return;
}
/* check for single digit divisor */
if (nd2 == 1) {
/* yes - use simple division by single digit divisor */
bip.rem = bip.op1;
r = bigUdiv1(GET_DIGIT(bip.op2, 0));
bip.res = bip.rem;
if (r == 0) {
bip.rem = newBig(0);
SET_ND(bip.rem, 0);
} else {
bip.rem = newBig(1);
SET_ND(bip.rem, 1);
SET_DIGIT(bip.rem, 0, r);
}
return;
}
/*
* now for the general case
*/
#if DIV_CHK_01
printf("div_chk #01: division, general case\n");
printf(" dividend = ");
bigDump(stdout, bip.op1);
printf("\n");
printf(" divisor = ");
bigDump(stdout, bip.op2);
printf("\n");
#endif
/* determine scale factor for normalization */
scale = (unsigned short) 256 /
((unsigned short) GET_DIGIT(bip.op2, nd2 - 1) + 1);
#if DIV_CHK_02
printf("div_chk #02: scale factor = %02X\n", scale);
#endif
/* normalize dividend, result is in bip.rem */
bip.rem = newBig(nd1 + 1);
carry = 0x00;
for (i = 0; i < nd1; i++) {
aux = (unsigned short) GET_DIGIT(bip.op1, i) * scale +
carry;
SET_DIGIT(bip.rem, i, aux & 0xFF);
carry = aux >> 8;
}
SET_DIGIT(bip.rem, i, carry);
SET_ND(bip.rem, nd1 + 1);
#if DIV_CHK_03
printf("div_chk #03: normalized dividend = ");
bigDump(stdout, bip.rem);
printf("\n");
#endif
/* normalize divisor, result is in bip.res */
bip.res = newBig(nd2);
carry = 0x00;
for (i = 0; i < nd2; i++) {
aux = (unsigned short) GET_DIGIT(bip.op2, i) * scale +
carry;
SET_DIGIT(bip.res, i, aux & 0xFF);
carry = aux >> 8;
}
if (carry != 0x00) {
/* overflow in divisor normalization */
fatalError("internal library error #4 - THIS SHOULD NEVER HAPPEN!");
}
SET_ND(bip.res, nd2);
#if DIV_CHK_04
printf("div_chk #04: normalized divisor = ");
bigDump(stdout, bip.res);
printf("\n");
#endif
/* allocate quotient */
nd3 = nd1 - nd2 + 1;
tmp = newBig(nd3);
/* extract the two most significand digits of divisor */
v1 = (unsigned short) GET_DIGIT(bip.res, nd2 - 1);
v2 = (unsigned short) GET_DIGIT(bip.res, nd2 - 2);
/* loop on digits of dividend and compute digits of quotient */
/* j is index into dividend, k is index into quotient */
for (j = nd1, k = nd3 - 1; k >= 0; j--, k--) {
#if DIV_CHK_05
printf("div_chk #05: j = %d, k = %d\n", j, k);
#endif
/* calculate qhat */
uj0 = (unsigned short) GET_DIGIT(bip.rem, j);
uj1 = (unsigned short) GET_DIGIT(bip.rem, j - 1);
uj2 = (unsigned short) GET_DIGIT(bip.rem, j - 2);
two = (uj0 << 8) | uj1;
if (uj0 == v1) {
qhat = (unsigned short) 255;
#if DIV_CHK_06
printf("div_chk #06a: qhat = %02X\n", qhat);
#endif
} else {
qhat = two / v1;
#if DIV_CHK_06
printf("div_chk #06b: qhat = %02X\n", qhat);
#endif
}
while (qhat * v2 > (((two - qhat * v1) << 8) | uj2)) {
qhat--;
#if DIV_CHK_07
printf("div_chk #07: qhat decremented, is now %02X\n", qhat);
#endif
}
/* multiply and subtract */
/* l is index into dividend, i is index into divisor */
carry = 0xFF;
for (l = j - nd2, i = 0; i < nd2; l++, i++) {
aux = (unsigned short) GET_DIGIT(bip.rem, l) -
(unsigned short) GET_DIGIT(bip.res, i) * qhat +
carry + 0xFE01;
SET_DIGIT(bip.rem, l, aux & 0xFF);
carry = aux >> 8;
}
aux = (unsigned short) GET_DIGIT(bip.rem, l) +
carry + 0xFE01;
SET_DIGIT(bip.rem, l, aux & 0xFF);
carry = aux >> 8;
#if DIV_CHK_08
printf("div_chk #08: remainder = ");
bigDump(stdout, bip.rem);
printf("\n");
#endif
/* test remainder and possibly add back */
if (carry != 0xFF) {
/* qhat is one too large */
qhat--;
#if DIV_CHK_09
printf("div_chk #09: qhat final correction, is now %02X\n", qhat);
#endif
/* add back */
/* l is index into dividend, i is index into divisor */
carry = 0x00;
for (l = j - nd2, i = 0; i < nd2; l++, i++) {
aux = (unsigned short) GET_DIGIT(bip.rem, l) +
(unsigned short) GET_DIGIT(bip.res, i) +
carry;
SET_DIGIT(bip.rem, l, aux & 0xFF);
carry = aux >> 8;
}
aux = (unsigned short) GET_DIGIT(bip.rem, l) +
carry;
SET_DIGIT(bip.rem, l, aux & 0xFF);
carry = aux >> 8;
if (carry != 0x01) {
/* missing carry in add-back sum */
fatalError("internal library error #5 - THIS SHOULD NEVER HAPPEN!");
}
#if DIV_CHK_10
printf("div_chk #10: remainder = ");
bigDump(stdout, bip.rem);
printf("\n");
#endif
}
/* store quotient digit */
SET_DIGIT(tmp, k, qhat);
#if DIV_CHK_11
printf("div_chk #11: quotient digit = %02X\n", qhat);
#endif
}
/* finish quotient */
i = nd3;
while (--i >= 0 && GET_DIGIT(tmp, i) == 0) ;
SET_ND(tmp, i + 1);
bip.res = tmp;
/* finish and unnormalize remainder */
i = nd1 + 1;
while (--i >= 0 && GET_DIGIT(bip.rem, i) == 0) ;
SET_ND(bip.rem, i + 1);
r = bigUdiv1(scale);
if (r != 0) {
/* non-zero remainder in unnormalization */
fatalError("internal library error #6 - THIS SHOULD NEVER HAPPEN!");
}
}
/**************************************************************/
/* nil reference exception */
static void nilRefException(void) {
fatalError("big integer library detected illegal nil reference");
}
/**************************************************************/
/* big integer arithmetic */
/*
* big integer sign
*
* operand in bip.op1
* result is < 0, = 0, or > 0 if and only if
* the same relation holds for bip.op1
*/
int bigSgn(void) {
if (bip.op1 == NULL) {
nilRefException();
}
if (GET_ND(bip.op1) == 0) {
return 0;
}
if (GET_SIGN(bip.op1) == BIG_POSITIVE) {
return 1;
} else {
return -1;
}
}
/*
* big integer comparison
*
* operands in bip.op1 and bip.op2
* result is < 0, = 0, or > 0 if and only if the
* same relation holds for bip.op1 and bip.op2
*/
int bigCmp(void) {
if (bip.op1 == NULL ||
bip.op2 == NULL) {
nilRefException();
}
if (GET_SIGN(bip.op1) == BIG_POSITIVE) {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 >= 0 and op2 >= 0 */
return bigUcmp();
} else {
/* op1 >= 0 and op2 < 0 */
return 1;
}
} else {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 < 0 and op2 >= 0 */
return -1;
} else {
/* op1 < 0 and op2 < 0 */
return -bigUcmp();
}
}
}
/*
* big integer negation
*
* operand in bip.op1
* result in bip.res
*/
void bigNeg(void) {
int nd;
int i;
if (bip.op1 == NULL) {
nilRefException();
}
/* make copy of operand */
nd = GET_ND(bip.op1);
bip.res = newBig(nd);
for (i = 0; i < nd; i++) {
SET_DIGIT(bip.res, i, GET_DIGIT(bip.op1, i));
}
SET_ND(bip.res, nd);
/* store inverted sign */
if (GET_SIGN(bip.op1) == BIG_NEGATIVE || nd == 0) {
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
SET_SIGN(bip.res, BIG_NEGATIVE);
}
}
/*
* big integer addition
*
* operands in bip.op1 and bip.op2
* result in bip.res
*/
void bigAdd(void) {
if (bip.op1 == NULL ||
bip.op2 == NULL) {
nilRefException();
}
if (GET_SIGN(bip.op1) == BIG_POSITIVE) {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 >= 0 and op2 >= 0 */
bigUadd();
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
/* op1 >= 0 and op2 < 0 */
if (bigUcmp() >= 0) {
/* |op1| >= |op2| */
bigUsub();
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
/* |op1| < |op2| */
bigXchg();
bigUsub();
SET_SIGN(bip.res, BIG_NEGATIVE);
bigXchg();
}
}
} else {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 < 0 and op2 >= 0 */
if (bigUcmp() <= 0) {
/* |op1| <= |op2| */
bigXchg();
bigUsub();
SET_SIGN(bip.res, BIG_POSITIVE);
bigXchg();
} else {
/* |op1| > |op2| */
bigUsub();
SET_SIGN(bip.res, BIG_NEGATIVE);
}
} else {
/* op1 < 0 and op2 < 0 */
bigUadd();
SET_SIGN(bip.res, BIG_NEGATIVE);
}
}
}
/*
* big integer subtraction
*
* operands in bip.op1 and bip.op2
* result in bip.res
*/
void bigSub(void) {
if (bip.op1 == NULL ||
bip.op2 == NULL) {
nilRefException();
}
if (GET_SIGN(bip.op1) == BIG_POSITIVE) {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 >= 0 and op2 >= 0 */
if (bigUcmp() >= 0) {
/* |op1| >= |op2| */
bigUsub();
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
/* |op1| < |op2| */
bigXchg();
bigUsub();
SET_SIGN(bip.res, BIG_NEGATIVE);
bigXchg();
}
} else {
/* op1 >= 0 and op2 < 0 */
bigUadd();
SET_SIGN(bip.res, BIG_POSITIVE);
}
} else {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 < 0 and op2 >= 0 */
bigUadd();
SET_SIGN(bip.res, BIG_NEGATIVE);
} else {
/* op1 < 0 and op2 < 0 */
if (bigUcmp() <= 0) {
/* |op1| <= |op2| */
bigXchg();
bigUsub();
SET_SIGN(bip.res, BIG_POSITIVE);
bigXchg();
} else {
/* |op1| > |op2| */
bigUsub();
SET_SIGN(bip.res, BIG_NEGATIVE);
}
}
}
}
/*
* big integer multiplication
*
* operands in bip.op1 and bip.op2
* result in bip.res
*/
void bigMul(void) {
if (bip.op1 == NULL ||
bip.op2 == NULL) {
nilRefException();
}
bigUmul();
if (GET_SIGN(bip.op1) == GET_SIGN(bip.op2) || GET_ND(bip.res) == 0) {
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
SET_SIGN(bip.res, BIG_NEGATIVE);
}
}
/*
* big integer division, truncating towards zero
*
* dividend in bip.op1, divisor in bip.op2
* quotient in bip.res, remainder in bip.rem
*/
void bigDiv(void) {
if (bip.op1 == NULL ||
bip.op2 == NULL) {
nilRefException();
}
bigUdiv();
if (GET_SIGN(bip.op1) == GET_SIGN(bip.op2) || GET_ND(bip.res) == 0) {
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
SET_SIGN(bip.res, BIG_NEGATIVE);
}
if (GET_SIGN(bip.op1) == BIG_POSITIVE || GET_ND(bip.rem) == 0) {
SET_SIGN(bip.rem, BIG_POSITIVE);
} else {
SET_SIGN(bip.rem, BIG_NEGATIVE);
}
}
/**************************************************************/
/* big integer conversions */
/*
* conversion int --> big
*
* operand in parameter
* result in bip.res
*/
void bigFromInt(int n) {
int i;
bip.res = newBig(sizeof(int));
if (n < 0) {
n = -n;
SET_SIGN(bip.res, BIG_NEGATIVE);
} else {
SET_SIGN(bip.res, BIG_POSITIVE);
}
for (i = 0; i < sizeof(int); i++) {
SET_DIGIT(bip.res, i, n & 0xFF);
n >>= 8;
}
while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
SET_ND(bip.res, i + 1);
}
/*
* conversion big --> int
*
* operand in bip.op1
* result is returned
*/
int bigToInt(void) {
int nd;
int i;
int res;
if (bip.op1 == NULL) {
nilRefException();
}
nd = GET_ND(bip.op1);
if (nd > 4 ||
(nd == 4 && GET_DIGIT(bip.op1, 3) >= 0x80)) {
fatalError("big integer too big for conversion to int");
}
res = 0;
for (i = nd - 1; i >= 0; i--) {
res <<= 8;
res |= (unsigned int) GET_DIGIT(bip.op1, i);
}
if (GET_SIGN(bip.op1) == BIG_NEGATIVE) {
res = -res;
}
return res;
}
/**************************************************************/
/* big integer I/O */
/*
* read a big integer
*
* stream to read from in parameter
* result in bip.res
*/
void bigRead(FILE *in) {
int c;
int positive;
c = fgetc(in);
while (isspace(c)) {
c = fgetc(in);
}
if (c == '-') {
positive = 0;
c = fgetc(in);
} else {
positive = 1;
if (c == '+') {
c = fgetc(in);
}
}
if (!isdigit(c)) {
fatalError("no digits in input");
}
bigFromInt(10);
bip.rem = bip.res;
bigFromInt(0);
while (isdigit(c)) {
bip.op1 = bip.res;
bip.op2 = bip.rem;
bigUmul();
bip.op1 = bip.res;
bigFromInt(c - '0');
bip.op2 = bip.res;
bigUadd();
c = fgetc(in);
}
ungetc(c, in);
if (positive || GET_ND(bip.res) == 0) {
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
SET_SIGN(bip.res, BIG_NEGATIVE);
}
}
/*
* print a big integer
*
* stream to write to in parameter
* number to print in bip.op1
*/
void bigPrint(FILE *out) {
int nd;
unsigned char r;
int skipZero;
if (bip.op1 == NULL) {
nilRefException();
}
nd = GET_ND(bip.op1);
if (nd == 0) {
fprintf(out, "0");
return;
}
if (GET_SIGN(bip.op1) == BIG_NEGATIVE) {
fprintf(out, "-");
}
/* number of digits in base 10 = number of digits
in base 256 * log10(256), and log10(256) < 2.5 */
nd = 2 * nd + nd / 2;
bip.rem = bip.op1;
bigFromInt(10);
bip.op2 = bip.res;
bigFromInt(1);
while (nd != 0) {
bip.op1 = bip.res;
bigUmul();
nd--;
}
bip.op1 = bip.rem;
bip.op2 = bip.res;
skipZero = 1;
do {
bigUdiv();
if (GET_ND(bip.res) == 0) {
if (!skipZero) {
fprintf(out, "0");
}
} else {
if (GET_ND(bip.res) != 1) {
fatalError("internal library error #7 - THIS SHOULD NEVER HAPPEN!");
}
fprintf(out, "%c", GET_DIGIT(bip.res, 0) + '0');
skipZero = 0;
}
bip.op1 = bip.rem;
bip.rem = bip.op2;
r = bigUdiv1(10);
bip.op2 = bip.rem;
} while (r == 0);
}
/**************************************************************/
/* debugging */
/*
* dump a big integer object
*/
void bigDump(FILE *out, BigObjRef bigObjRef) {
int nd;
unsigned char sign;
int i;
if (bigObjRef == NULL) {
nilRefException();
}
nd = GET_ND(bigObjRef);
sign = GET_SIGN(bigObjRef);
fprintf(out, "[%d %c", nd, sign == BIG_POSITIVE ? '+' : '-');
for (i = 0; i < nd; i++) {
fprintf(out, " %02X", GET_DIGIT(bigObjRef, i));
}
fprintf(out, "]");
}

60
bigint/src/bigint.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* bigint.h -- big integer library
*/
#ifndef _BIGINT_H_
#define _BIGINT_H_
/* object representation */
typedef void* BigObjRef;
#include <stdio.h>
typedef struct {
int nd; /* number of digits; array may be bigger */
/* nd = 0 exactly when number = 0 */
unsigned char sign; /* one of BIG_NEGATIVE or BIG_POSITIVE */
/* zero always has BIG_POSITIVE here */
unsigned char digits[1]; /* the digits proper; number base is 256 */
/* LS digit first; MS digit is not zero */
} Big;
#include "support.h"
/* big integer processor registers */
typedef struct {
BigObjRef op1; /* first (or single) operand */
BigObjRef op2; /* second operand (if present) */
BigObjRef res; /* result of operation */
BigObjRef rem; /* remainder in case of division */
} BIP;
extern BIP bip; /* registers of the processor */
/* big integer processor functions */
int bigSgn(void); /* sign */
int bigCmp(void); /* comparison */
void bigNeg(void); /* negation */
void bigAdd(void); /* addition */
void bigSub(void); /* subtraction */
void bigMul(void); /* multiplication */
void bigDiv(void); /* division */
void bigFromInt(int n); /* conversion int --> big */
int bigToInt(void); /* conversion big --> int */
void bigRead(FILE *in); /* read a big integer */
void bigPrint(FILE *out); /* print a big integer */
void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer object */
#endif /* _BIGINT_H_ */

BIN
bigint/src/bigint.o Normal file

Binary file not shown.

BIN
bigint/src/libbigint.a Normal file

Binary file not shown.

15
bigint/src/support.h Normal file
View File

@@ -0,0 +1,15 @@
/*
* support.h -- object representation and support functions
*/
#ifndef _SUPPORT_H_
#define _SUPPORT_H_
/* support functions */
void fatalError(char *msg); /* print a message and exit */
void * newPrimObject(int dataSize); /* create a new primitive object */
void * getPrimObjectDataPointer(void * primObject);
#endif /* _SUPPORT_H_ */

28
bigint/tst/Makefile Normal file
View File

@@ -0,0 +1,28 @@
#
# Makefile for big integer test
#
BUILD = ../build
CC = gcc
CFLAGS = -g -Wall -I$(BUILD)/include
LDFLAGS = -g -Wall -L$(BUILD)/lib
LDLIBS = -lbigint
all: testbip
install: all
mkdir -p $(BUILD)/bin
cp testbip $(BUILD)/bin
testbip: testbip.o support.o
$(CC) $(LDFLAGS) -o testbip testbip.o support.o $(LDLIBS)
testbip.o: testbip.c
$(CC) $(CFLAGS) -o testbip.o -c testbip.c
support.o: support.c
$(CC) $(CFLAGS) -o support.o -c support.c
clean:
rm -f *~ testbip.o support.o testbip

55
bigint/tst/support.c Normal file
View File

@@ -0,0 +1,55 @@
/*
* support.c -- support functions for big integer library
*/
#include <stdio.h>
#include <stdlib.h>
#include "support.h"
typedef struct {
unsigned int size; /* byte count of payload data */
unsigned char data[1]; /* payload data, size as needed */
} *ObjRef;
/*
* This routine is called in case a fatal error has occurred.
* It should print the error message and terminate the program.
*/
void fatalError(char *msg) {
printf("Fatal error: %s\n", msg);
exit(1);
}
/*
* This function is called whenever a new primitive object with
* a certain amount of internal memory is needed. It should return
* an object reference to a regular object, which contains a freely
* usable memory area of at least the requested size (measured in
* bytes). The memory area need not be initialized in any way.
*
* Note that this function may move all objects in memory at will
* (due to, e.g., garbage collection), as long as the pointers in
* the global "bip" structure point to the correct objects when
* the function returns.
*/
void * newPrimObject(int dataSize) {
ObjRef bigObjRef;
int size = sizeof(unsigned int) + dataSize * sizeof(unsigned char);
bigObjRef = malloc(size);
bigObjRef->size = size;
if (bigObjRef == NULL) {
fatalError("newPrimObject() got no memory");
}
bigObjRef->size = size;
return bigObjRef;
}
void * getPrimObjectDataPointer(void * obj){
ObjRef oo = ((ObjRef) (obj));
return oo->data;
}

BIN
bigint/tst/support.o Normal file

Binary file not shown.

BIN
bigint/tst/testbip Executable file

Binary file not shown.

1253
bigint/tst/testbip.c Normal file

File diff suppressed because it is too large Load Diff

BIN
bigint/tst/testbip.o Normal file

Binary file not shown.

3
compile_flags.txt Normal file
View File

@@ -0,0 +1,3 @@
-Ibigint/build/include
-Lbigint/build/lib
-lbigint

View File

@@ -1,6 +1,6 @@
#ifndef CONSTS #ifndef CONSTS
#define CONSTS #define CONSTS
#define VERSION 5 #define VERSION 8
#endif /* ifndef CONSTS #endif /* ifndef CONSTS
#define CONSTS #define CONSTS

View File

@@ -7,29 +7,44 @@
#include "stack.c" #include "stack.c"
void inspect(struct stack s, int fp){ void inspect(struct stack s, int fp){
//todo Does not work dont know why
char input[20]; char input[20];
char ref[20];
char refStr[20];
printf("DEBUG [inspect]: stack, datam object?"); printf("DEBUG [inspect]: stack, datam object?");
fgets(input,20,stdin); fgets(input,20,stdin);
if (input[0] == 's') printStack(s, fp); if (input[0] == 's') printStack(s, fp);
if (input[0] == 'd'){/* todo */ } if (input[0] == 'd'){/* todo */ }
if (input[0] == 'o'){/* todo */} if (input[0] == 'o'){
scanf("%19s",ref);
ObjRefContainer container;
for (int i = 0; i<= container.size; i++) {
sprintf(refStr, "%p", (void *)&container.refs[i]);
if(strcmp(ref, refStr) == 0) printf("Adress exists\n");
else printf("Adress doeas not exist\n");
printf("%s",refStr);
} }
void list(){ }
}
void list(void){
//todo //todo
} }
void breakpoint(){ void breakpoint(int *bp){
//todo printf("BREAKPOINT: ");
char input[20];
fgets(input,20,stdin);
*bp = atoi(input);
} }
void debugMenu(int fp, struct stack stack, int* debug){ void debugMenu(int fp, struct stack stack, int* debug, int point, int* bp){
char input[20]; char input[20];
while (true) { while (true) {
printf("DEBUG: inspect, list, breakpoint, run, step, quit?"); printf("DEBUG(%i): inspect, list, breakpoint, run, step, quit?",point);
fgets(input, 20, stdin); fgets(input, 20, stdin);
printf("%s",input); printf("%s",input);
if(input[0] == 'i') {inspect(stack,fp);} if(input[0] == 'i') {inspect(stack,fp);}
if(input[0] == 'l') list(); if(input[0] == 'l') list();
if(input[0] == 'b') breakpoint(); if(input[0] == 'b') breakpoint(bp);
if(input[0] == 's') break; if(input[0] == 's') break;
if(input[0] == 'r') {*debug = 0; break;}; if(input[0] == 'r') {*debug = 0; break;};
if(input[0] == 'q') exit(0); if(input[0] == 'q') exit(0);

8301
factor.asm Normal file

File diff suppressed because it is too large Load Diff

BIN
factor.bin Normal file

Binary file not shown.

794
factor.nj Normal file
View File

@@ -0,0 +1,794 @@
//
// factor.nj -- factorize the numbers 10^n+1, n = 1..30
//
//--------------------------------------------------------------
// handle list of factors
type List = record {
Integer value;
List next;
};
List addToList(Integer value, List next) {
local List newList;
newList = new(List);
newList.value = value;
newList.next = next;
return newList;
}
List sortList(List list) {
local List result;
local List element;
local List p;
result = nil;
while (list != nil) {
element = list;
list = list.next;
if (result == nil || element.value < result.value) {
element.next = result;
result = element;
} else {
p = result;
while (p.next != nil && element.value >= p.next.value) {
p = p.next;
}
element.next = p.next;
p.next = element;
}
}
return result;
}
void showList(List list) {
if (list == nil) {
writeString("1");
} else {
while (true) {
writeInteger(list.value);
list = list.next;
if (list == nil) {
break;
}
writeString(" * ");
}
}
writeString("\n");
}
Integer evalList(List list) {
local Integer result;
result = 1;
while (list != nil) {
result = result * list.value;
list = list.next;
}
return result;
}
List fuseLists(List list1, List list2) {
local List element;
while (list1 != nil) {
element = list1;
list1 = list1.next;
element.next = list2;
list2 = element;
}
return list2;
}
//--------------------------------------------------------------
// compute 10^n+1
Integer computeTarget(Integer n) {
local Integer x;
local Integer i;
x = 1;
i = 0;
while (i < n) {
x = x * 10;
i = i + 1;
}
x = x + 1;
return x;
}
void testComputeTarget() {
writeString("computeTarget()\n");
writeString("---------------\n");
writeString("target(1) = ");
writeInteger(computeTarget(1));
writeString("\n");
writeString("target(2) = ");
writeInteger(computeTarget(2));
writeString("\n");
writeString("target(3) = ");
writeInteger(computeTarget(3));
writeString("\n");
writeString("target(4) = ");
writeInteger(computeTarget(4));
writeString("\n");
writeString("\n");
}
//--------------------------------------------------------------
// build a table of small primes
global Integer smallPrimesLimit;
global Integer[] primes;
global Integer numPrimes;
void showSmallPrimes() {
local Integer i;
local Integer k;
i = 0;
k = 0;
while (i < numPrimes) {
writeInteger(primes[i]);
writeString(" ");
k = k + 1;
if (k == 8) {
k = 0;
writeString("\n");
}
i = i + 1;
}
if (k != 0) {
writeString("\n");
}
}
void enterSmallPrime(Integer p) {
local Integer n;
local Integer[] a;
local Integer i;
if (sizeof(primes) == numPrimes) {
n = 2 * numPrimes;
a = new(Integer[n]);
i = 0;
while (i < numPrimes) {
a[i] = primes[i];
i = i + 1;
}
primes = a;
}
primes[numPrimes] = p;
numPrimes = numPrimes + 1;
}
Boolean isPrime(Integer n) {
local Integer t;
t = 3;
while (t * t <= n) {
if (n % t == 0) {
return false;
}
t = t + 2;
}
return true;
}
void calcSmallPrimes(Integer limit) {
local Integer i;
smallPrimesLimit = limit;
primes = new(Integer[256]);
numPrimes = 0;
enterSmallPrime(2);
enterSmallPrime(3);
i = 5;
while (true) {
if (i > smallPrimesLimit) {
break;
}
if (isPrime(i)) {
enterSmallPrime(i);
}
i = i + 2;
if (i > smallPrimesLimit) {
break;
}
if (isPrime(i)) {
enterSmallPrime(i);
}
i = i + 4;
}
}
void testCalcSmallPrimes() {
writeString("calcSmallPrimes()\n");
writeString("-----------------\n");
writeString("primes less than or equal to 100:\n");
calcSmallPrimes(100);
showSmallPrimes();
writeString("number of primes less than or equal to 100: ");
writeInteger(numPrimes);
writeString("\n");
calcSmallPrimes(1000);
writeString("number of primes less than or equal to 1000: ");
writeInteger(numPrimes);
writeString("\n");
calcSmallPrimes(10000);
writeString("number of primes less than or equal to 10000: ");
writeInteger(numPrimes);
writeString("\n");
calcSmallPrimes(100000);
writeString("number of primes less than or equal to 100000: ");
writeInteger(numPrimes);
writeString("\n");
writeString("\n");
}
//--------------------------------------------------------------
// try to find a small prime factor of a given number
Integer smallPrimeFactor(Integer n) {
local Integer i;
i = 0;
while (i < numPrimes) {
if (n % primes[i] == 0) {
// prime factor found
return primes[i];
}
i = i + 1;
}
// no prime factor less than or equal to smallPrimesLimit found
return 0;
}
void testSmallPrimeFactor() {
calcSmallPrimes(10000);
writeString("smallPrimeFactor()\n");
writeString("------------------\n");
writeString("small prime factor of 2: ");
writeInteger(smallPrimeFactor(2));
writeString("\n");
writeString("small prime factor of 222: ");
writeInteger(smallPrimeFactor(222));
writeString("\n");
writeString("small prime factor of 17*19*23: ");
writeInteger(smallPrimeFactor(17*19*23));
writeString("\n");
writeString("small prime factor of 7919: ");
writeInteger(smallPrimeFactor(7919));
writeString("\n");
writeString("small prime factor of 987654323: ");
writeInteger(smallPrimeFactor(987654323));
writeString("\n");
writeString("\n");
}
//--------------------------------------------------------------
// compute b^n mod m
Integer powerMod(Integer b, Integer n, Integer m) {
local Integer a;
a = 1;
while (n != 0) {
if (n % 2 == 0) {
b = (b * b) % m;
n = n / 2;
} else {
a = (a * b) % m;
n = n - 1;
}
}
return a;
}
void testPowerMod() {
writeString("powerMod()\n");
writeString("----------\n");
writeString("2^16 mod 7: ");
writeInteger(powerMod(2, 16, 7));
writeString("\n");
writeString("3^10 mod 19: ");
writeInteger(powerMod(3, 10, 19));
writeString("\n");
writeString("123^987654323 mod 987654323: ");
writeInteger(powerMod(123, 987654323, 987654323));
writeString("\n");
writeString("\n");
}
//--------------------------------------------------------------
// compute greatest common divisor
Integer GCD(Integer a, Integer b) {
local Integer r;
if (a < 0) {
a = -a;
}
if (b < 0) {
b = -b;
}
while (b != 0) {
r = a % b;
a = b;
b = r;
}
return a;
}
void testGCD() {
writeString("GCD()\n");
writeString("-----\n");
writeString("GCD(3*5*5*11*37, 2*2*5*37*53) = ");
writeInteger(GCD(3*5*5*11*37, 2*2*5*37*53));
writeString("\n");
writeString("\n");
}
//--------------------------------------------------------------
// Rabin-Miller test
Boolean isComposite(Integer n) {
local Integer q;
local Integer t;
local Integer i;
local Integer a;
local Integer e;
local Integer b;
q = n - 1;
t = 0;
while (q % 2 == 0) {
q = q / 2;
t = t + 1;
}
i = 0;
while (i < 20) {
a = primes[i];
if (a >= n) {
break;
}
e = 0;
b = powerMod(a, q, n);
if (b != 1) {
while (b != 1 && b != n - 1 && e <= t - 2) {
b = (b * b) % n;
e = e + 1;
}
if (b != n - 1) {
return true;
}
}
i = i + 1;
}
return false;
}
void testIsComposite() {
local Integer n;
local Integer k;
writeString("isComposite()\n");
writeString("-------------\n");
writeString("odd numbers in [3..99] which are probably prime:\n");
n = 3;
k = 0;
while (n < 100) {
if (!isComposite(n)) {
writeInteger(n);
writeString(" ");
k = k + 1;
if (k == 8) {
k = 0;
writeString("\n");
}
}
n = n + 2;
}
if (k != 0) {
writeString("\n");
}
n = 1234567;
while (n < 1234607) {
writeInteger(n);
writeString(" is ");
if (isComposite(n)) {
writeString("definitely composite\n");
} else {
writeString("probably prime\n");
}
n = n + 2;
}
writeString("\n");
}
//--------------------------------------------------------------
Boolean provePrime(Integer n) {
// not implemented yet
return false;
}
void testProvePrime() {
writeString("provePrime()\n");
writeString("------------\n");
writeString("<not implemented yet>\n");
writeString("\n");
}
//--------------------------------------------------------------
// Pollard's rho method
Integer findFactor1(Integer n) {
local Integer y;
local Integer x;
local Integer x1;
local Integer k;
local Integer l;
local Integer p;
local Integer c;
local Integer g;
local Integer r;
y = 2;
x = 2;
x1 = 2;
k = 1;
l = 1;
p = 1;
c = 0;
while (true) {
x = (x * x + 1) % n;
p = (p * (x1 - x)) % n;
c = c + 1;
if (c == 20) {
g = GCD(p, n);
if (g > 1) {
break;
}
y = x;
c = 0;
}
k = k - 1;
if (k == 0) {
g = GCD(p, n);
if (g > 1) {
break;
}
x1 = x;
k = l;
l = 2 * l;
r = 0;
while (r < k) {
x = (x * x + 1) % n;
r = r + 1;
}
y = x;
c = 0;
}
}
do {
y = (y * y + 1) % n;
g = GCD(x1 - y, n);
} while (g == 1);
if (g < n) {
return g;
} else {
return 0;
}
}
Integer findFactor2(Integer n) {
local Integer y;
local Integer x;
local Integer x1;
local Integer k;
local Integer l;
local Integer p;
local Integer c;
local Integer g;
local Integer r;
y = 2;
x = 2;
x1 = 2;
k = 1;
l = 1;
p = 1;
c = 0;
while (true) {
x = (x * x - 1) % n;
p = (p * (x1 - x)) % n;
c = c + 1;
if (c == 20) {
g = GCD(p, n);
if (g > 1) {
break;
}
y = x;
c = 0;
}
k = k - 1;
if (k == 0) {
g = GCD(p, n);
if (g > 1) {
break;
}
x1 = x;
k = l;
l = 2 * l;
r = 0;
while (r < k) {
x = (x * x - 1) % n;
r = r + 1;
}
y = x;
c = 0;
}
}
do {
y = (y * y - 1) % n;
g = GCD(x1 - y, n);
} while (g == 1);
if (g < n) {
return g;
} else {
return 0;
}
}
Integer findFactor3(Integer n) {
local Integer y;
local Integer x;
local Integer x1;
local Integer k;
local Integer l;
local Integer p;
local Integer c;
local Integer g;
local Integer r;
y = 2;
x = 2;
x1 = 2;
k = 1;
l = 1;
p = 1;
c = 0;
while (true) {
x = (x * x + 3) % n;
p = (p * (x1 - x)) % n;
c = c + 1;
if (c == 20) {
g = GCD(p, n);
if (g > 1) {
break;
}
y = x;
c = 0;
}
k = k - 1;
if (k == 0) {
g = GCD(p, n);
if (g > 1) {
break;
}
x1 = x;
k = l;
l = 2 * l;
r = 0;
while (r < k) {
x = (x * x + 3) % n;
r = r + 1;
}
y = x;
c = 0;
}
}
do {
y = (y * y + 3) % n;
g = GCD(x1 - y, n);
} while (g == 1);
if (g < n) {
return g;
} else {
return 0;
}
}
Integer findFactor(Integer n) {
local Integer r;
r = findFactor1(n);
if (r != 0) {
return r;
}
r = findFactor2(n);
if (r != 0) {
return r;
}
r = findFactor3(n);
return r;
}
void testFindFactor() {
writeString("findFactor()\n");
writeString("------------\n");
writeString("5*5*5 = ");
writeInteger(5*5*5);
writeString(" is a multiple of ");
writeInteger(findFactor(5*5*5));
writeString("\n");
writeString("4421*5743*7699 = ");
writeInteger(4421*5743*7699);
writeString(" is a multiple of ");
writeInteger(findFactor(4421*5743*7699));
writeString("\n");
writeInteger(9999000099990001);
writeString(" is a multiple of ");
writeInteger(findFactor(9999000099990001));
writeString("\n");
writeString("\n");
}
//--------------------------------------------------------------
List factorize(Integer x, Boolean verbose) {
local List factors;
local Integer f;
local Integer f1;
local Integer f2;
local List moreFactors;
if (verbose) {
writeString("factorize(");
writeInteger(x);
writeString(")\n");
}
factors = nil;
while (x > 1) {
f = smallPrimeFactor(x);
if (f == 0) {
// no small prime factor found
if (x < smallPrimesLimit * smallPrimesLimit) {
// we know that x is prime
f = x;
} else {
// we don't know anything
break;
}
}
if (verbose) {
writeString("detected small prime factor ");
writeInteger(f);
writeString("\n");
}
factors = addToList(f, factors);
x = x / f;
}
if (x == 1) {
// x has been completely factorized
if (verbose) {
writeString("the number has been completely factorized\n");
}
return factors;
}
if (verbose) {
writeString("interim result:\n the remaining factor ");
writeInteger(x);
writeString("\n doesn't have any prime factors < ");
writeInteger(smallPrimesLimit);
writeString("\n ");
}
if (isComposite(x)) {
// x is definitely composite
if (verbose) {
writeString("but is definitely composite\n");
}
f1 = findFactor(x);
if (f1 == 0) {
// cannot factorize x, give up
writeString("cannot factorize ");
writeInteger(x);
writeString(", giving up\n");
factors = addToList(x, factors);
} else {
// x = f1 * f2
f2 = x / f1;
if (verbose) {
writeString("this number can be split into ");
writeInteger(f1);
writeString(" and ");
writeInteger(f2);
writeString("\n");
}
moreFactors = factorize(f1, verbose);
factors = fuseLists(moreFactors, factors);
moreFactors = factorize(f2, verbose);
factors = fuseLists(moreFactors, factors);
}
} else {
// x is very probably prime
if (verbose) {
writeString("and is very probably prime\n");
}
if (provePrime(x)) {
if (verbose) {
writeString("the primality of ");
writeInteger(x);
writeString(" has been proven\n");
}
} else {
writeString("cannot prove the primality of ");
writeInteger(x);
writeString(", giving up\n");
}
factors = addToList(x, factors);
}
return factors;
}
void testFactorize(Boolean verbose) {
local List factors;
writeString("factorize()\n");
writeString("-----------\n");
calcSmallPrimes(7);
showSmallPrimes();
writeString("3*5*7*7*141*49 = \n");
factors = factorize(3*5*7*7*141*49, verbose);
showList(sortList(factors));
writeString("\n");
}
//--------------------------------------------------------------
void showBar() {
writeString("---------------------------------");
writeString("-------------------------------\n");
}
void run(Boolean verbose) {
local Integer i;
local Integer x;
local List factors;
local Integer y;
calcSmallPrimes(10000);
showBar();
i = 1;
while (i <= 30) {
writeString("10^");
writeInteger(i);
writeString("+1 = ");
x = computeTarget(i);
writeInteger(x);
writeString(" = \n");
factors = factorize(x, verbose);
factors = sortList(factors);
showList(factors);
writeString("check: product = ");
y = evalList(factors);
writeInteger(y);
writeString("\n");
showBar();
i = i+ 1;
}
}
//--------------------------------------------------------------
void tests(Boolean verbose) {
writeString("\nTests\n");
writeString("=====\n\n");
testComputeTarget();
testCalcSmallPrimes();
testSmallPrimeFactor();
testPowerMod();
testGCD();
testIsComposite();
testProvePrime();
testFindFactor();
testFactorize(verbose);
}
//--------------------------------------------------------------
void main() {
//tests(true);
run(true);
}

33
heap.c Normal file
View File

@@ -0,0 +1,33 @@
//
// Created by Elias Bennour on 28.01.24.
//
#ifndef HEAP
#define HEAP
#include <stdlib.h>
#include <stdio.h>
int maxHeapSize = 8192 * 1024;
void* my_malloc(size_t size) {
static size_t total_allocated = 0;
if (total_allocated + size > maxHeapSize) {
perror("Memory limit exceeded\n");
exit(1);
}
void* ptr = malloc(size);
if (ptr != NULL) {
total_allocated += size;
}
return ptr;
}
void initHeap(int size) {
maxHeapSize = size;
}
#endif //NINJA_NJVM_H

12
heap.h Normal file
View File

@@ -0,0 +1,12 @@
//
// Created by Elias Bennour on 28.01.24.
//
#ifndef NINJA_HEAP_H
#define NINJA_HEAP_H
#include <stdlib.h>
void* my_malloc(size_t size);
#endif //NINJA_HEAP_H

View File

@@ -2,8 +2,11 @@
#define INSREUKTION #define INSREUKTION
#define IMMEDIATE(x) ((x) & 0x00FFFFFF) #define IMMEDIATE(x) ((x) & 0x00FFFFFF)
#define MSB (1 << (8 * sizeof(unsigned int) - 1))
#define IS_PRIMITIVE(objRef) (((objRef)->size & MSB) == 0)
#define SIGN_EXTEND(i) ((i) & 0x00800000 ? (i) | 0xFF000000 : (i)) #define SIGN_EXTEND(i) ((i) & 0x00800000 ? (i) | 0xFF000000 : (i))
#define GET_ELEMENT_COUNT(objRef) ((objRef)->size & ~MSB)
#define GET_REFS_PTR(objRef) ((ObjRef *) (objRef)-> data)
#define HALT 0 #define HALT 0
#define PUSHC 1 #define PUSHC 1
@@ -37,5 +40,15 @@
#define PUSHR 29 #define PUSHR 29
#define POPR 30 #define POPR 30
#define DUP 31 #define DUP 31
#define NEW 32
#define GETF 33
#define PUTF 34
#define NEWA 35
#define GETFA 36
#define PUTFA 37
#define GETSZ 38
#define PUSHN 39
#define REFEQ 40
#define REFNE 41
#endif /* ifndef INSREUKTION */ #endif /* ifndef INSREUKTION */

778
matinv.asm Normal file
View File

@@ -0,0 +1,778 @@
//
// version
//
.vers 8
//
// execution framework
//
__start:
call _main
call _exit
__stop:
jmp __stop
//
// Integer readInteger()
//
_readInteger:
asf 0
rdint
popr
rsf
ret
//
// void writeInteger(Integer)
//
_writeInteger:
asf 0
pushl -3
wrint
rsf
ret
//
// Character readCharacter()
//
_readCharacter:
asf 0
rdchr
popr
rsf
ret
//
// void writeCharacter(Character)
//
_writeCharacter:
asf 0
pushl -3
wrchr
rsf
ret
//
// Integer char2int(Character)
//
_char2int:
asf 0
pushl -3
popr
rsf
ret
//
// Character int2char(Integer)
//
_int2char:
asf 0
pushl -3
popr
rsf
ret
//
// void exit()
//
_exit:
asf 0
halt
rsf
ret
//
// void writeString(String)
//
_writeString:
asf 1
pushc 0
popl 0
jmp _writeString_L2
_writeString_L1:
pushl -3
pushl 0
getfa
call _writeCharacter
drop 1
pushl 0
pushc 1
add
popl 0
_writeString_L2:
pushl 0
pushl -3
getsz
lt
brt _writeString_L1
rsf
ret
//
// Integer gcd(Integer, Integer)
//
_gcd:
asf 1
jmp __2
__1:
pushl -4
pushl -3
mod
popl 0
pushl -3
popl -4
pushl 0
popl -3
__2:
pushl -3
pushc 0
ne
brt __1
__3:
pushl -4
popr
jmp __0
__0:
rsf
ret
//
// record { Integer num; Integer den; } newFraction(Integer, Integer)
//
_newFraction:
asf 4
pushl -4
pushc 0
lt
brf __5
pushc 0
pushl -4
sub
popl 0
jmp __6
__5:
pushl -4
popl 0
__6:
pushl -3
pushc 0
lt
brf __7
pushc 0
pushl -3
sub
popl 1
jmp __8
__7:
pushl -3
popl 1
__8:
pushl 0
pushl 1
call _gcd
drop 2
pushr
popl 2
new 2
popl 3
pushl -4
pushc 0
lt
pushl -3
pushc 0
lt
ne
brf __9
pushl 3
pushc 0
pushl 0
sub
pushl 2
div
putf 0
jmp __10
__9:
pushl 3
pushl 0
pushl 2
div
putf 0
__10:
pushl 3
pushl 1
pushl 2
div
putf 1
pushl 3
popr
jmp __4
__4:
rsf
ret
//
// void writeFraction(record { Integer num; Integer den; })
//
_writeFraction:
asf 0
pushl -3
getf 0
call _writeInteger
drop 1
pushc 1
newa
dup
pushc 0
pushc 47
putfa
call _writeString
drop 1
pushl -3
getf 1
call _writeInteger
drop 1
__11:
rsf
ret
//
// record { Integer num; Integer den; } negFraction(record { Integer num; Integer den; })
//
_negFraction:
asf 0
pushc 0
pushl -3
getf 0
sub
pushl -3
getf 1
call _newFraction
drop 2
pushr
popr
jmp __12
__12:
rsf
ret
//
// record { Integer num; Integer den; } addFraction(record { Integer num; Integer den; }, record { Integer num; Integer den; })
//
_addFraction:
asf 0
pushl -4
getf 0
pushl -3
getf 1
mul
pushl -3
getf 0
pushl -4
getf 1
mul
add
pushl -4
getf 1
pushl -3
getf 1
mul
call _newFraction
drop 2
pushr
popr
jmp __13
__13:
rsf
ret
//
// record { Integer num; Integer den; } subFraction(record { Integer num; Integer den; }, record { Integer num; Integer den; })
//
_subFraction:
asf 0
pushl -4
getf 0
pushl -3
getf 1
mul
pushl -3
getf 0
pushl -4
getf 1
mul
sub
pushl -4
getf 1
pushl -3
getf 1
mul
call _newFraction
drop 2
pushr
popr
jmp __14
__14:
rsf
ret
//
// record { Integer num; Integer den; } mulFraction(record { Integer num; Integer den; }, record { Integer num; Integer den; })
//
_mulFraction:
asf 0
pushl -4
getf 0
pushl -3
getf 0
mul
pushl -4
getf 1
pushl -3
getf 1
mul
call _newFraction
drop 2
pushr
popr
jmp __15
__15:
rsf
ret
//
// record { Integer num; Integer den; } divFraction(record { Integer num; Integer den; }, record { Integer num; Integer den; })
//
_divFraction:
asf 0
pushl -4
getf 0
pushl -3
getf 1
mul
pushl -4
getf 1
pushl -3
getf 0
mul
call _newFraction
drop 2
pushr
popr
jmp __16
__16:
rsf
ret
//
// Fraction[][] newMatrix(record { Integer num; Integer den; }, record { Integer num; Integer den; }, record { Integer num; Integer den; }, record { Integer num; Integer den; })
//
_newMatrix:
asf 1
pushc 2
newa
popl 0
pushl 0
pushc 0
pushc 2
newa
putfa
pushl 0
pushc 1
pushc 2
newa
putfa
pushl 0
pushc 0
getfa
pushc 0
pushl -6
putfa
pushl 0
pushc 0
getfa
pushc 1
pushl -5
putfa
pushl 0
pushc 1
getfa
pushc 0
pushl -4
putfa
pushl 0
pushc 1
getfa
pushc 1
pushl -3
putfa
pushl 0
popr
jmp __17
__17:
rsf
ret
//
// void writeMatrix(Fraction[][])
//
_writeMatrix:
asf 2
pushc 0
popl 0
jmp __20
__19:
pushc 0
popl 1
jmp __23
__22:
pushl -3
pushl 0
getfa
pushl 1
getfa
call _writeFraction
drop 1
pushc 2
newa
dup
pushc 0
pushc 32
putfa
dup
pushc 1
pushc 32
putfa
call _writeString
drop 1
pushl 1
pushc 1
add
popl 1
__23:
pushl 1
pushl -3
pushl 0
getfa
getsz
lt
brt __22
__24:
pushc 1
newa
dup
pushc 0
pushc 10
putfa
call _writeString
drop 1
pushl 0
pushc 1
add
popl 0
__20:
pushl 0
pushl -3
getsz
lt
brt __19
__21:
pushc 1
newa
dup
pushc 0
pushc 10
putfa
call _writeString
drop 1
__18:
rsf
ret
//
// Fraction[][] invertMatrix(Fraction[][])
//
_invertMatrix:
asf 1
pushl -3
pushc 0
getfa
pushc 0
getfa
pushl -3
pushc 1
getfa
pushc 1
getfa
call _mulFraction
drop 2
pushr
pushl -3
pushc 0
getfa
pushc 1
getfa
pushl -3
pushc 1
getfa
pushc 0
getfa
call _mulFraction
drop 2
pushr
call _subFraction
drop 2
pushr
popl 0
pushl 0
getf 0
pushc 0
eq
brf __26
pushc 33
newa
dup
pushc 0
pushc 101
putfa
dup
pushc 1
pushc 114
putfa
dup
pushc 2
pushc 114
putfa
dup
pushc 3
pushc 111
putfa
dup
pushc 4
pushc 114
putfa
dup
pushc 5
pushc 58
putfa
dup
pushc 6
pushc 32
putfa
dup
pushc 7
pushc 109
putfa
dup
pushc 8
pushc 97
putfa
dup
pushc 9
pushc 116
putfa
dup
pushc 10
pushc 114
putfa
dup
pushc 11
pushc 105
putfa
dup
pushc 12
pushc 120
putfa
dup
pushc 13
pushc 32
putfa
dup
pushc 14
pushc 99
putfa
dup
pushc 15
pushc 97
putfa
dup
pushc 16
pushc 110
putfa
dup
pushc 17
pushc 110
putfa
dup
pushc 18
pushc 111
putfa
dup
pushc 19
pushc 116
putfa
dup
pushc 20
pushc 32
putfa
dup
pushc 21
pushc 98
putfa
dup
pushc 22
pushc 101
putfa
dup
pushc 23
pushc 32
putfa
dup
pushc 24
pushc 105
putfa
dup
pushc 25
pushc 110
putfa
dup
pushc 26
pushc 118
putfa
dup
pushc 27
pushc 101
putfa
dup
pushc 28
pushc 114
putfa
dup
pushc 29
pushc 116
putfa
dup
pushc 30
pushc 101
putfa
dup
pushc 31
pushc 100
putfa
dup
pushc 32
pushc 10
putfa
call _writeString
drop 1
call _exit
__26:
pushl -3
pushc 1
getfa
pushc 1
getfa
pushl 0
call _divFraction
drop 2
pushr
pushl -3
pushc 0
getfa
pushc 1
getfa
call _negFraction
drop 1
pushr
pushl 0
call _divFraction
drop 2
pushr
pushl -3
pushc 1
getfa
pushc 0
getfa
call _negFraction
drop 1
pushr
pushl 0
call _divFraction
drop 2
pushr
pushl -3
pushc 0
getfa
pushc 0
getfa
pushl 0
call _divFraction
drop 2
pushr
call _newMatrix
drop 4
pushr
popr
jmp __25
__25:
rsf
ret
//
// void main()
//
_main:
asf 3
pushc 1
newa
dup
pushc 0
pushc 10
putfa
call _writeString
drop 1
pushc 7
pushc 1
call _newFraction
drop 2
pushr
pushc 4
pushc 1
call _newFraction
drop 2
pushr
pushc 6
pushc 1
call _newFraction
drop 2
pushr
pushc 5
pushc 1
call _newFraction
drop 2
pushr
call _newMatrix
drop 4
pushr
popl 0
pushl 0
call _writeMatrix
drop 1
pushl 0
call _invertMatrix
drop 1
pushr
popl 1
pushl 1
call _writeMatrix
drop 1
pushl 1
call _invertMatrix
drop 1
pushr
popl 2
pushl 2
call _writeMatrix
drop 1
__27:
rsf
ret

BIN
matinv.bin Normal file

Binary file not shown.

146
matinv.nj Normal file
View File

@@ -0,0 +1,146 @@
//
// matinv.nj -- invert 2x2 matrices of fractions
//
//--------------------------------------------------------------
// greatest common divisor
Integer gcd(Integer a, Integer b) {
local Integer h;
while (b != 0) {
h = a % b;
a = b;
b = h;
}
return a;
}
//--------------------------------------------------------------
// fractions
type Fraction = record {
Integer num;
Integer den;
};
Fraction newFraction(Integer num, Integer den) {
local Integer n;
local Integer d;
local Integer g;
local Fraction r;
if (num < 0) {
n = -num;
} else {
n = num;
}
if (den < 0) {
d = -den;
} else {
d = den;
}
g = gcd(n, d);
r = new(Fraction);
if ((num < 0) != (den < 0)) {
r.num = -n / g;
} else {
r.num = n / g;
}
r.den = d / g;
return r;
}
void writeFraction(Fraction f) {
writeInteger(f.num);
writeString("/");
writeInteger(f.den);
}
Fraction negFraction(Fraction f) {
return newFraction(-f.num, f.den);
}
Fraction addFraction(Fraction f1, Fraction f2) {
return newFraction(f1.num * f2.den + f2.num * f1.den, f1.den * f2.den);
}
Fraction subFraction(Fraction f1, Fraction f2) {
return newFraction(f1.num * f2.den - f2.num * f1.den, f1.den * f2.den);
}
Fraction mulFraction(Fraction f1, Fraction f2) {
return newFraction(f1.num * f2.num, f1.den * f2.den);
}
Fraction divFraction(Fraction f1, Fraction f2) {
return newFraction(f1.num * f2.den, f1.den * f2.num);
}
//--------------------------------------------------------------
// 2x2 matrices of fractions
type Matrix = Fraction[][];
Matrix newMatrix(Fraction a00, Fraction a01,
Fraction a10, Fraction a11) {
local Matrix m;
m = new(Fraction[2][]);
m[0] = new(Fraction[2]);
m[1] = new(Fraction[2]);
m[0][0] = a00;
m[0][1] = a01;
m[1][0] = a10;
m[1][1] = a11;
return m;
}
void writeMatrix(Matrix m) {
local Integer i;
local Integer j;
i = 0;
while (i < sizeof(m)) {
j = 0;
while (j < sizeof(m[i])) {
writeFraction(m[i][j]);
writeString(" ");
j = j + 1;
}
writeString("\n");
i = i + 1;
}
writeString("\n");
}
Matrix invertMatrix(Matrix m) {
local Fraction det;
det = subFraction(mulFraction(m[0][0], m[1][1]),
mulFraction(m[0][1], m[1][0]));
if (det.num == 0) {
writeString("error: matrix cannot be inverted\n");
exit();
}
return newMatrix(
divFraction(m[1][1], det), divFraction(negFraction(m[0][1]), det),
divFraction(negFraction(m[1][0]), det), divFraction(m[0][0], det)
);
}
//--------------------------------------------------------------
void main() {
local Matrix matrix;
local Matrix result1;
local Matrix result2;
writeString("\n");
matrix = newMatrix(
newFraction(7, 1), newFraction(4, 1),
newFraction(6, 1), newFraction(5, 1)
);
writeMatrix(matrix);
result1 = invertMatrix(matrix);
writeMatrix(result1);
result2 = invertMatrix(result1);
writeMatrix(result2);
}

BIN
nja/nja7

Binary file not shown.

BIN
nja/nja8l Executable file

Binary file not shown.

BIN
nja/nja?inline=false Normal file

Binary file not shown.

BIN
njc/njc7

Binary file not shown.

BIN
njc/njc8

Binary file not shown.

BIN
njc/njc8l Executable file

Binary file not shown.

11070
njlisp.asm Normal file

File diff suppressed because it is too large Load Diff

BIN
njlisp.bin Normal file

Binary file not shown.

2580
njlisp.nj Normal file

File diff suppressed because it is too large Load Diff

225
njvm.c
View File

@@ -1,30 +1,25 @@
#ifndef NJVM
#define NJVM
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "instruktion.c" #include "instruktion.c"
#include "code.c"
#include "stack.c" #include "stack.c"
#include "program.c" #include "program.c"
#include "codeReader.c" #include "codeReader.c"
#include "SDA.c"
#include "reg.c"
#include "debugMenu.c" #include "debugMenu.c"
#include "bigint.h"
#include "record.c"
#include "GC.c"
#include "heap.c"
// Debug // Debug
int debug = 0; int debug = 0;
// Stack
struct stack stack;
#define SIZE 1000
//Register
struct reg reg;
// Program // Program
struct program program; struct program program;
// SDA
struct sda sda;
unsigned fp; unsigned fp;
void version(void) { void version(void) {
@@ -36,63 +31,82 @@ void help(void) {
} }
void execute(struct program program) { void execute(struct program program) {
int bp = -1;
int i; int i;
int intInput;
unsigned int temp;
char charInput; char charInput;
StackSlot tempSlot; StackSlot tempSlot;
ObjRef tempObj;
ObjRef tempObj2;
int tempInt;
for (i = 0; i < *program.size; ++i) { for (i = 0; i < *program.size; ++i) {
if (debug == 1) debugMenu(fp,stack,&debug); if (debug == 1 || bp == i) debugMenu(fp, stack, &debug, i, &bp);
if(debug == 1) printf("(%i)",i);
switch (program.program[i] >> 24) { switch (program.program[i] >> 24) {
case HALT: case HALT:
if (debug == 1) printf("halt\n"); if (debug == 1) printf("halt\n");
goto end; goto end;
case PUSHC: case PUSHC:
if (debug == 1) printf("pushc: %i\n", IMMEDIATE(program.program[i])); if (debug == 1) printf("pushc: %i\n", IMMEDIATE(program.program[i]));
push(stack, stackSlotWithObjRef(getIntObj(SIGN_EXTEND(IMMEDIATE(program.program[i]))))); bigFromInt(SIGN_EXTEND(IMMEDIATE(program.program[i])));
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case ADD: case ADD:
if (debug == 1) printf("add: %i + %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("add: %i + %i\n", peek(stack, 2), peek(stack, 1));
push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) + getIntValfromStackSlot(pop(stack))))); bip.op2 = pop(stack).u.objRef;
bip.op1 = pop(stack).u.objRef;
bigAdd();
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case SUB: case SUB:
if (debug == 1) printf("sub: %i - %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("sub: %i - %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack)); bip.op2 = pop(stack).u.objRef;
push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) - temp))); bip.op1 = pop(stack).u.objRef;
bigSub();
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case MUL: case MUL:
if (debug == 1) printf("mul: %i * %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("mul: %i * %i\n", peek(stack, 2), peek(stack, 1));
push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) * getIntValfromStackSlot(pop(stack))))); bip.op2 = pop(stack).u.objRef;
bip.op1 = pop(stack).u.objRef;
bigMul();
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case DIV: case DIV:
if (debug == 1) printf("div: %i / %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("div: %i / %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack)); bip.op2 = pop(stack).u.objRef;
push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) / temp))); bip.op1 = pop(stack).u.objRef;
bigDiv();
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case MOD: case MOD:
if (debug == 1) printf("mod: %i %% %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("mod: %i %% %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack)); bip.op2 = pop(stack).u.objRef;
push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack))))); bip.op1 = pop(stack).u.objRef;
bigDiv();
push(stack, stackSlotWithObjRef(bip.rem));
break; break;
case RDINT: case RDINT:
if (debug == 1) printf("rdint\n"); if (debug == 1) printf("rdint\n");
scanf("%i", &intInput); bigRead(stdin);
push(stack, stackSlotWithObjRef(getIntObj(intInput))); push(stack, stackSlotWithObjRef(bip.res));
if (debug == 1) printf("pushed %i\n", intInput); if (debug == 1) printf("pushed %i\n", peek(stack, 1));
break; break;
case WRINT: case WRINT:
if (debug == 1) printf("wrint: %i\n", peek(stack, 1)); if (debug == 1) printf("wrint: %i\n", peek(stack, 1));
printf("%i", getIntValfromStackSlot(pop(stack))); bip.op1 = pop(stack).u.objRef;
bigPrint(stdout);
break; break;
case RDCHR: case RDCHR:
if (debug == 1) printf("rdchr\n"); if (debug == 1) printf("rdchr\n");
scanf("%c", &charInput); scanf("%c", &charInput);
push(stack, stackSlotWithObjRef(getIntObj(charInput))); bigFromInt(charInput);
push(stack, stackSlotWithObjRef(bip.res));
if (debug == 1) printf("pushed %c\n", charInput); if (debug == 1) printf("pushed %c\n", charInput);
break; break;
case WRCHR: case WRCHR:
if (debug == 1) printf("wrchr: %c\n", peek(stack, 1)); if (debug == 1) printf("wrchr: %c\n", peek(stack, 1));
printf("%c", getIntValfromStackSlot(pop(stack))); bip.op1 = pop(stack).u.objRef;
printf("%c", bigToInt());
break; break;
case PUSHG: case PUSHG:
if (debug == 1) printf("pushg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("pushg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
@@ -113,7 +127,7 @@ void execute(struct program program) {
*stack.current = fp; *stack.current = fp;
if (debug == 1) printf("pop: %i\n", peek(stack, 1)); if (debug == 1) printf("pop: %i\n", peek(stack, 1));
tempSlot = pop(stack); tempSlot = pop(stack);
fp = getIntValfromStackSlot(tempSlot); fp = tempSlot.u.number;
break; break;
case POPL: case POPL:
if (debug == 1) printf("popl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("popl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
@@ -125,52 +139,70 @@ void execute(struct program program) {
break; break;
case NE: case NE:
if (debug == 1) printf("ne: %i != %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("ne: %i != %i\n", peek(stack, 2), peek(stack, 1));
if (getIntValfromStackSlot(pop(stack)) != getIntValfromStackSlot(pop(stack))) push(stack, stackSlotWitchNumber(1)); bip.op2 = pop(stack).u.objRef;
else push(stack, stackSlotWitchNumber(0)); bip.op1 = pop(stack).u.objRef;
bigFromInt(bigCmp() != 0);
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case EQ: case EQ:
if (debug == 1) printf("eq: %i == %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("eq: %i == %i\n", peek(stack, 2), peek(stack, 1));
if (getIntValfromStackSlot(pop(stack)) == getIntValfromStackSlot(pop(stack))) push(stack, stackSlotWitchNumber(1)); bip.op2 = pop(stack).u.objRef;
else push(stack, stackSlotWitchNumber(0)); bip.op1 = pop(stack).u.objRef;
bigFromInt(bigCmp() == 0);
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case LT: case LT:
if (debug == 1) printf("lt: %i < %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("lt: %i < %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack)); bip.op2 = pop(stack).u.objRef;
if (getIntValfromStackSlot(pop(stack)) < temp) push(stack, stackSlotWitchNumber(1)); bip.op1 = pop(stack).u.objRef;
else push(stack, stackSlotWitchNumber(0)); bigFromInt(bigCmp() < 0);
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case LE: case LE:
if (debug == 1) printf("le: %i <= %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("le: %i <= %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack)); bip.op2 = pop(stack).u.objRef;
if (getIntValfromStackSlot(pop(stack)) <= temp) push(stack, stackSlotWitchNumber(1)); bip.op1 = pop(stack).u.objRef;
else push(stack, stackSlotWitchNumber(0)); bigFromInt(bigCmp() <= 0);
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case GT: case GT:
if (debug == 1) printf("gt: %i > %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("gt: %i > %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack)); bip.op2 = pop(stack).u.objRef;
if (getIntValfromStackSlot(pop(stack)) > temp) push(stack, stackSlotWitchNumber(1)); bip.op1 = pop(stack).u.objRef;
else push(stack, stackSlotWitchNumber(0)); bigFromInt(bigCmp() > 0);
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case GE: case GE:
if (debug == 1) printf("ge: %i >= %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("ge: %i >= %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack)); bip.op2 = pop(stack).u.objRef;
if (getIntValfromStackSlot(pop(stack)) >= temp) push(stack, stackSlotWitchNumber(1)); bip.op1 = pop(stack).u.objRef;
else push(stack, stackSlotWitchNumber(0)); bigFromInt(bigCmp() >= 0);
push(stack, stackSlotWithObjRef(bip.res));
break; break;
case BRF: case BRF:
if (debug == 1) printf("brf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("brf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
if (debug == 1) printf("pop: %i\n", peek(stack, 1)); if (debug == 1) printf("pop: %i\n", peek(stack, 1));
if (getIntValfromStackSlot(pop(stack)) == 0) { bip.op1 = pop(stack).u.objRef;
int b = bigToInt();
if (b == false) {
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1; i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
if (debug == 1) printf("new i: %i\n", i); if (debug == 1) printf("new i: %i\n", i);
} else if (b != true) {
printf("Error: brf: %i\n", b);
exit(EXIT_FAILURE);
} }
break; break;
case BRT: case BRT:
if (debug == 1) printf("brt: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("brt: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
if (debug == 1) printf("pop: %i\n", peek(stack, 1)); if (debug == 1) printf("pop: %i\n", peek(stack, 1));
if (getIntValfromStackSlot(pop(stack)) == 1) { bip.op1 = pop(stack).u.objRef;
b = bigToInt();
if (b == true) {
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1; i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
if (debug == 1) printf("new i: %i\n", i); if (debug == 1) printf("new i: %i\n", i);
} else if (b != false) {
printf("Error: brt: %i\n", b);
exit(EXIT_FAILURE);
} }
break; break;
case JMP: case JMP:
@@ -197,19 +229,75 @@ void execute(struct program program) {
break; break;
case DUP: case DUP:
if (debug == 1) printf("dup\n"); if (debug == 1) printf("dup\n");
temp = getIntValfromStackSlot(pop(stack)); tempObj = pop(stack).u.objRef;
push(stack, stackSlotWitchNumber(temp)); push(stack, stackSlotWithObjRef(tempObj));
push(stack, stackSlotWitchNumber(temp)); push(stack, stackSlotWithObjRef(tempObj));
break; break;
case POPR: case POPR:
if (debug==1) printf("popr") ; if (debug == 1) printf("popr\n");
pushR(reg, getIntValfromStackSlot(pop(stack))); push(reg, pop(stack));
if(debug == 1) printStackR(reg);
break; break;
case PUSHR: case PUSHR:
if(debug == 1) printf("pushr"); if (debug == 1) printf("pushr\n");
push(stack, stackSlotWitchNumber(popR(reg))); push(stack, pop(reg));
if(debug == 1) printStackR(reg); break;
case NEW:
if (debug == 1) printf("new\t%i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
push(stack, stackSlotWithObjRef(newRecord(SIGN_EXTEND(IMMEDIATE(program.program[i])))));
break;
case GETF:
if (debug == 1) printf("getf\n");
tempObj = pop(stack).u.objRef;
push(stack, stackSlotWithObjRef(getField(tempObj,SIGN_EXTEND(IMMEDIATE(program.program[i])))));
break;
case PUTF:
if (debug == 1) printf("putf\t%i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
tempObj = pop(stack).u.objRef;
tempObj2 = pop(stack).u.objRef;
setField(tempObj2, SIGN_EXTEND(IMMEDIATE(program.program[i])),tempObj);
break;
case NEWA:
if(debug == 1) printf("newa\n");
bip.op1 = pop(stack).u.objRef;
push(stack, stackSlotWithObjRef(newRecord(bigToInt())));
break;
case GETFA:
if(debug == 1) printf("getfa\n");
bip.op1 = pop(stack).u.objRef;
tempInt = bigToInt();
tempObj = pop(stack).u.objRef;
push(stack, stackSlotWithObjRef(getField(tempObj,bigToInt())));
break;
case PUTFA:
if (debug == 1) printf("putfa\n");
tempObj = pop(stack).u.objRef; // Value
tempObj2 = pop(stack).u.objRef; // Index
bip.op1 = tempObj2;
tempInt = bigToInt();
setField(pop(stack).u.objRef, tempInt,tempObj);
break;
case GETSZ:
if (debug == 1) printf("getsz\n");
tempObj = pop(stack).u.objRef;
if(IS_PRIMITIVE(tempObj)) bigFromInt(-1);
else bigFromInt(GET_ELEMENT_COUNT(tempObj));
push(stack, stackSlotWithObjRef(bip.res));
break;
case PUSHN:
if (debug == 1) printf("pushn\n");
push(stack, stackSlotWithObjRef(NULL));
break;
case REFEQ:
if (debug == 1) printf("refeq\n");
if(pop(stack).u.objRef == pop(stack).u.objRef) bigFromInt(true);
else bigFromInt(false);
push(stack, stackSlotWithObjRef(bip.res));
break;
case REFNE:
if (debug == 1) printf("refeq\n");
if(pop(stack).u.objRef != pop(stack).u.objRef) bigFromInt(true);
else bigFromInt(false);
push(stack, stackSlotWithObjRef(bip.res));
break; break;
} }
} }
@@ -218,30 +306,31 @@ void execute(struct program program) {
} }
void tests(void) { void tests(void) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// Initialize the Stack // Initialize the Stack
int size = SIZE; int size = SIZE;
int current = 0; int current = 0;
StackSlot s[SIZE];
stack.size = &size; stack.size = &size;
stack.current = &current; stack.current = &current;
stack.stack = s; stack.stack = malloc(size * 1024);
if (stack.stack == NULL) {
perror("malloc");
}
// Initialize the registery // Initialize the registery
int rSize = SIZE; int rSize = 100000;
int rCurrent = 0; int rCurrent = 0;
unsigned int r[SIZE]; StackSlot r[100000];
reg.size = &rSize; reg.size = &rSize;
reg.current = &rCurrent; reg.current = &rCurrent;
reg.stack = r; reg.stack = r;
// Initialize ProgrammSpeicher // Initialize ProgrammSpeicher
int psize = 1000; int psize = 100000;
int saveProgram = 0; int saveProgram = 0;
unsigned int p[1000]; unsigned int p[100000];
program.size = &psize; program.size = &psize;
program.program = p; program.program = p;
program.saveProgram = &saveProgram; program.saveProgram = &saveProgram;
@@ -264,7 +353,9 @@ int main(int argc, char *argv[]) {
// TODO: implement stack size // TODO: implement stack size
} else if (strcmp(argv[i], "--heap") == 0) { } else if (strcmp(argv[i], "--heap") == 0) {
i++; i++;
// TODO: implement heap size initHeap(atoi(argv[i]));
} else if (strcmp(argv[i], "--gcpurge") == 0) {
// TODO: implement gcpurge
} else { } else {
sizeSDA = fromFile(argv[i], program); sizeSDA = fromFile(argv[i], program);
run = 1; run = 1;
@@ -289,3 +380,5 @@ int main(int argc, char *argv[]) {
return 1; return 1;
} }
} }
#endif /* ifndef NJVM */

BIN
njvm.o Normal file

Binary file not shown.

BIN
njvm2 Executable file

Binary file not shown.

BIN
njvm6 Executable file

Binary file not shown.

BIN
njvm7 Executable file

Binary file not shown.

BIN
njvm?inline=false.2 Normal file

Binary file not shown.

12
objref.c Normal file
View File

@@ -0,0 +1,12 @@
#ifndef OBJREF
#define OBJREF
#include <stdbool.h>
typedef struct ObjRef{
unsigned int size;
unsigned char data[1];
} *ObjRef;
#endif /* ifndef OBJREF
#define OBJREF */

8301
prog.asm Normal file

File diff suppressed because it is too large Load Diff

BIN
prog.bin

Binary file not shown.

778
programs/matrix.asm Normal file
View File

@@ -0,0 +1,778 @@
//
// version
//
.vers 7
//
// execution framework
//
__start:
call _main
call _exit
__stop:
jmp __stop
//
// Integer readInteger()
//
_readInteger:
asf 0
rdint
popr
rsf
ret
//
// void writeInteger(Integer)
//
_writeInteger:
asf 0
pushl -3
wrint
rsf
ret
//
// Character readCharacter()
//
_readCharacter:
asf 0
rdchr
popr
rsf
ret
//
// void writeCharacter(Character)
//
_writeCharacter:
asf 0
pushl -3
wrchr
rsf
ret
//
// Integer char2int(Character)
//
_char2int:
asf 0
pushl -3
popr
rsf
ret
//
// Character int2char(Integer)
//
_int2char:
asf 0
pushl -3
popr
rsf
ret
//
// void exit()
//
_exit:
asf 0
halt
rsf
ret
//
// void writeString(String)
//
_writeString:
asf 1
pushc 0
popl 0
jmp _writeString_L2
_writeString_L1:
pushl -3
pushl 0
getfa
call _writeCharacter
drop 1
pushl 0
pushc 1
add
popl 0
_writeString_L2:
pushl 0
pushl -3
getsz
lt
brt _writeString_L1
rsf
ret
//
// Integer gcd(Integer, Integer)
//
_gcd:
asf 1
jmp __2
__1:
pushl -4
pushl -3
mod
popl 0
pushl -3
popl -4
pushl 0
popl -3
__2:
pushl -3
pushc 0
ne
brt __1
__3:
pushl -4
popr
jmp __0
__0:
rsf
ret
//
// record { Integer num; Integer den; } newFraction(Integer, Integer)
//
_newFraction:
asf 4
pushl -4
pushc 0
lt
brf __5
pushc 0
pushl -4
sub
popl 0
jmp __6
__5:
pushl -4
popl 0
__6:
pushl -3
pushc 0
lt
brf __7
pushc 0
pushl -3
sub
popl 1
jmp __8
__7:
pushl -3
popl 1
__8:
pushl 0
pushl 1
call _gcd
drop 2
pushr
popl 2
new 2
popl 3
pushl -4
pushc 0
lt
pushl -3
pushc 0
lt
ne
brf __9
pushl 3
pushc 0
pushl 0
sub
pushl 2
div
putf 0
jmp __10
__9:
pushl 3
pushl 0
pushl 2
div
putf 0
__10:
pushl 3
pushl 1
pushl 2
div
putf 1
pushl 3
popr
jmp __4
__4:
rsf
ret
//
// void writeFraction(record { Integer num; Integer den; })
//
_writeFraction:
asf 0
pushl -3
getf 0
call _writeInteger
drop 1
pushc 1
newa
dup
pushc 0
pushc 47
putfa
call _writeString
drop 1
pushl -3
getf 1
call _writeInteger
drop 1
__11:
rsf
ret
//
// record { Integer num; Integer den; } negFraction(record { Integer num; Integer den; })
//
_negFraction:
asf 0
pushc 0
pushl -3
getf 0
sub
pushl -3
getf 1
call _newFraction
drop 2
pushr
popr
jmp __12
__12:
rsf
ret
//
// record { Integer num; Integer den; } addFraction(record { Integer num; Integer den; }, record { Integer num; Integer den; })
//
_addFraction:
asf 0
pushl -4
getf 0
pushl -3
getf 1
mul
pushl -3
getf 0
pushl -4
getf 1
mul
add
pushl -4
getf 1
pushl -3
getf 1
mul
call _newFraction
drop 2
pushr
popr
jmp __13
__13:
rsf
ret
//
// record { Integer num; Integer den; } subFraction(record { Integer num; Integer den; }, record { Integer num; Integer den; })
//
_subFraction:
asf 0
pushl -4
getf 0
pushl -3
getf 1
mul
pushl -3
getf 0
pushl -4
getf 1
mul
sub
pushl -4
getf 1
pushl -3
getf 1
mul
call _newFraction
drop 2
pushr
popr
jmp __14
__14:
rsf
ret
//
// record { Integer num; Integer den; } mulFraction(record { Integer num; Integer den; }, record { Integer num; Integer den; })
//
_mulFraction:
asf 0
pushl -4
getf 0
pushl -3
getf 0
mul
pushl -4
getf 1
pushl -3
getf 1
mul
call _newFraction
drop 2
pushr
popr
jmp __15
__15:
rsf
ret
//
// record { Integer num; Integer den; } divFraction(record { Integer num; Integer den; }, record { Integer num; Integer den; })
//
_divFraction:
asf 0
pushl -4
getf 0
pushl -3
getf 1
mul
pushl -4
getf 1
pushl -3
getf 0
mul
call _newFraction
drop 2
pushr
popr
jmp __16
__16:
rsf
ret
//
// Fraction[][] newMatrix(record { Integer num; Integer den; }, record { Integer num; Integer den; }, record { Integer num; Integer den; }, record { Integer num; Integer den; })
//
_newMatrix:
asf 1
pushc 2
newa
popl 0
pushl 0
pushc 0
pushc 2
newa
putfa
pushl 0
pushc 1
pushc 2
newa
putfa
pushl 0
pushc 0
getfa
pushc 0
pushl -6
putfa
pushl 0
pushc 0
getfa
pushc 1
pushl -5
putfa
pushl 0
pushc 1
getfa
pushc 0
pushl -4
putfa
pushl 0
pushc 1
getfa
pushc 1
pushl -3
putfa
pushl 0
popr
jmp __17
__17:
rsf
ret
//
// void writeMatrix(Fraction[][])
//
_writeMatrix:
asf 2
pushc 0
popl 0
jmp __20
__19:
pushc 0
popl 1
jmp __23
__22:
pushl -3
pushl 0
getfa
pushl 1
getfa
call _writeFraction
drop 1
pushc 2
newa
dup
pushc 0
pushc 32
putfa
dup
pushc 1
pushc 32
putfa
call _writeString
drop 1
pushl 1
pushc 1
add
popl 1
__23:
pushl 1
pushl -3
pushl 0
getfa
getsz
lt
brt __22
__24:
pushc 1
newa
dup
pushc 0
pushc 10
putfa
call _writeString
drop 1
pushl 0
pushc 1
add
popl 0
__20:
pushl 0
pushl -3
getsz
lt
brt __19
__21:
pushc 1
newa
dup
pushc 0
pushc 10
putfa
call _writeString
drop 1
__18:
rsf
ret
//
// Fraction[][] invertMatrix(Fraction[][])
//
_invertMatrix:
asf 1
pushl -3
pushc 0
getfa
pushc 0
getfa
pushl -3
pushc 1
getfa
pushc 1
getfa
call _mulFraction
drop 2
pushr
pushl -3
pushc 0
getfa
pushc 1
getfa
pushl -3
pushc 1
getfa
pushc 0
getfa
call _mulFraction
drop 2
pushr
call _subFraction
drop 2
pushr
popl 0
pushl 0
getf 0
pushc 0
eq
brf __26
pushc 33
newa
dup
pushc 0
pushc 101
putfa
dup
pushc 1
pushc 114
putfa
dup
pushc 2
pushc 114
putfa
dup
pushc 3
pushc 111
putfa
dup
pushc 4
pushc 114
putfa
dup
pushc 5
pushc 58
putfa
dup
pushc 6
pushc 32
putfa
dup
pushc 7
pushc 109
putfa
dup
pushc 8
pushc 97
putfa
dup
pushc 9
pushc 116
putfa
dup
pushc 10
pushc 114
putfa
dup
pushc 11
pushc 105
putfa
dup
pushc 12
pushc 120
putfa
dup
pushc 13
pushc 32
putfa
dup
pushc 14
pushc 99
putfa
dup
pushc 15
pushc 97
putfa
dup
pushc 16
pushc 110
putfa
dup
pushc 17
pushc 110
putfa
dup
pushc 18
pushc 111
putfa
dup
pushc 19
pushc 116
putfa
dup
pushc 20
pushc 32
putfa
dup
pushc 21
pushc 98
putfa
dup
pushc 22
pushc 101
putfa
dup
pushc 23
pushc 32
putfa
dup
pushc 24
pushc 105
putfa
dup
pushc 25
pushc 110
putfa
dup
pushc 26
pushc 118
putfa
dup
pushc 27
pushc 101
putfa
dup
pushc 28
pushc 114
putfa
dup
pushc 29
pushc 116
putfa
dup
pushc 30
pushc 101
putfa
dup
pushc 31
pushc 100
putfa
dup
pushc 32
pushc 10
putfa
call _writeString
drop 1
call _exit
__26:
pushl -3
pushc 1
getfa
pushc 1
getfa
pushl 0
call _divFraction
drop 2
pushr
pushl -3
pushc 0
getfa
pushc 1
getfa
call _negFraction
drop 1
pushr
pushl 0
call _divFraction
drop 2
pushr
pushl -3
pushc 1
getfa
pushc 0
getfa
call _negFraction
drop 1
pushr
pushl 0
call _divFraction
drop 2
pushr
pushl -3
pushc 0
getfa
pushc 0
getfa
pushl 0
call _divFraction
drop 2
pushr
call _newMatrix
drop 4
pushr
popr
jmp __25
__25:
rsf
ret
//
// void main()
//
_main:
asf 3
pushc 1
newa
dup
pushc 0
pushc 10
putfa
call _writeString
drop 1
pushc 7
pushc 1
call _newFraction
drop 2
pushr
pushc 4
pushc 1
call _newFraction
drop 2
pushr
pushc 6
pushc 1
call _newFraction
drop 2
pushr
pushc 5
pushc 1
call _newFraction
drop 2
pushr
call _newMatrix
drop 4
pushr
popl 0
pushl 0
call _writeMatrix
drop 1
pushl 0
call _invertMatrix
drop 1
pushr
popl 1
pushl 1
call _writeMatrix
drop 1
pushl 1
call _invertMatrix
drop 1
pushr
popl 2
pushl 2
call _writeMatrix
drop 1
__27:
rsf
ret

146
programs/matrix.nj Normal file
View File

@@ -0,0 +1,146 @@
//
// matinv.nj -- invert 2x2 matrices of fractions
//
//--------------------------------------------------------------
// greatest common divisor
Integer gcd(Integer a, Integer b) {
local Integer h;
while (b != 0) {
h = a % b;
a = b;
b = h;
}
return a;
}
//--------------------------------------------------------------
// fractions
type Fraction = record {
Integer num;
Integer den;
};
Fraction newFraction(Integer num, Integer den) {
local Integer n;
local Integer d;
local Integer g;
local Fraction r;
if (num < 0) {
n = -num;
} else {
n = num;
}
if (den < 0) {
d = -den;
} else {
d = den;
}
g = gcd(n, d);
r = new(Fraction);
if ((num < 0) != (den < 0)) {
r.num = -n / g;
} else {
r.num = n / g;
}
r.den = d / g;
return r;
}
void writeFraction(Fraction f) {
writeInteger(f.num);
writeString("/");
writeInteger(f.den);
}
Fraction negFraction(Fraction f) {
return newFraction(-f.num, f.den);
}
Fraction addFraction(Fraction f1, Fraction f2) {
return newFraction(f1.num * f2.den + f2.num * f1.den, f1.den * f2.den);
}
Fraction subFraction(Fraction f1, Fraction f2) {
return newFraction(f1.num * f2.den - f2.num * f1.den, f1.den * f2.den);
}
Fraction mulFraction(Fraction f1, Fraction f2) {
return newFraction(f1.num * f2.num, f1.den * f2.den);
}
Fraction divFraction(Fraction f1, Fraction f2) {
return newFraction(f1.num * f2.den, f1.den * f2.num);
}
//--------------------------------------------------------------
// 2x2 matrices of fractions
type Matrix = Fraction[][];
Matrix newMatrix(Fraction a00, Fraction a01,
Fraction a10, Fraction a11) {
local Matrix m;
m = new(Fraction[2][]);
m[0] = new(Fraction[2]);
m[1] = new(Fraction[2]);
m[0][0] = a00;
m[0][1] = a01;
m[1][0] = a10;
m[1][1] = a11;
return m;
}
void writeMatrix(Matrix m) {
local Integer i;
local Integer j;
i = 0;
while (i < sizeof(m)) {
j = 0;
while (j < sizeof(m[i])) {
writeFraction(m[i][j]);
writeString(" ");
j = j + 1;
}
writeString("\n");
i = i + 1;
}
writeString("\n");
}
Matrix invertMatrix(Matrix m) {
local Fraction det;
det = subFraction(mulFraction(m[0][0], m[1][1]),
mulFraction(m[0][1], m[1][0]));
if (det.num == 0) {
writeString("error: matrix cannot be inverted\n");
exit();
}
return newMatrix(
divFraction(m[1][1], det), divFraction(negFraction(m[0][1]), det),
divFraction(negFraction(m[1][0]), det), divFraction(m[0][0], det)
);
}
//--------------------------------------------------------------
void main() {
local Matrix matrix;
local Matrix result1;
local Matrix result2;
writeString("\n");
matrix = newMatrix(
newFraction(7, 1), newFraction(4, 1),
newFraction(6, 1), newFraction(5, 1)
);
writeMatrix(matrix);
result1 = invertMatrix(matrix);
writeMatrix(result1);
result2 = invertMatrix(result1);
writeMatrix(result2);
}

26
programs/newFraction.asm Normal file
View File

@@ -0,0 +1,26 @@
_subFraction:
asf 0
pushl -4
getf 0
pushl -3
getf 1
mul
pushl -3
getf 0
pushl -4
getf 1
mul
sub
pushl -4
getf 1
pushl -3
getf 1
mul
call _newFraction
drop 2
pushr
popr
jmp __14
__14:
rsf
ret

55
record.c Normal file
View File

@@ -0,0 +1,55 @@
//
// Created by Nils Polek on 23.01.24.
//
#ifndef RECORD
#define RECORD
#include "stackslot.c"
#include "instruktion.c"
ObjRef newRecord(int size){
ObjRef record;
unsigned int objSize;
objSize = sizeof(*record) + (size * sizeof(void *));
if((record = my_malloc(objSize)) == NULL){
perror("malloc");
}
record->size = MSB;
record->size = record->size + size;
for(int i = 0; i < size; i++) {
GET_REFS_PTR(record)[i] = NULL;
}
return record;
}
int getSize(ObjRef arr){
if(arr == NULL) return 0;
return GET_ELEMENT_COUNT(arr);
}
ObjRef getField(ObjRef arr, int point){
if(arr == NULL) perror("Record is null");
if(0 > point || point > getSize(arr)){
printf("Index %i out of bounds for length %i\n",point, getSize(arr));
}
return *(ObjRef *)GET_REFS_PTR(arr)[point]->data;
}
void setField(ObjRef arr, int point, ObjRef value){
bool isNull = false;
if(value == NULL) isNull = true;
if(0 > point || point >= getSize(arr)){
printf("Index %i out of bounds for length %i\n",point, getSize(arr));
exit(EXIT_FAILURE);
}
if(arr == NULL) perror("Record is null");
if(IS_PRIMITIVE(arr)) perror("Record is a primitive");
int size;
if (isNull) size = sizeof(void *);
else {
if (IS_PRIMITIVE(value))
size = value->size;
else
size = sizeof(*value) + (GET_ELEMENT_COUNT(value) * sizeof(void *));
}
if((GET_REFS_PTR(arr)[point] = my_malloc(size)) == NULL) perror("malloc");
GET_REFS_PTR(arr)[point] ->size = size;
* (ObjRef *)GET_REFS_PTR(arr)[point]->data = value;
}
#endif

48
reg.c
View File

@@ -1,48 +0,0 @@
//
// Created by Nils on 29.10.2023.
//
#ifndef REG
#define REG
#include <stdio.h>
#include <stdlib.h>
struct reg {
int* size;
int* current;
unsigned int *stack;
};
void printStackR(struct reg stack) {
printf("Regurn reg\nSize:\t\t%i\nCurrent:\t%i\n", *stack.size, *stack.current);
for (int i = *stack.current-1; i > 0; --i) {
printf("||%i||\n", stack.stack[i]);
}
}
void pushR(struct reg s, unsigned int value) {
if (*s.current >= *s.size) {
printf("Stack Overflow\n");
exit(EXIT_FAILURE);
}
s.stack[*s.current] = value;
*s.current=*s.current + 1;
}
unsigned int popR(struct reg s) {
if (*s.current == 0) {
printf("Stack Underflow\n");
exit(EXIT_FAILURE);
}
*s.current = *s.current -1;
return s.stack[*s.current];
}
unsigned int peekR(struct reg s, int steps) {
if (*s.current - steps < 0) {
printf("Stack Underflow\n");
exit(EXIT_FAILURE);
}
return s.stack[*s.current - steps];
}
#endif

24
stack.c
View File

@@ -14,12 +14,19 @@ struct stack {
StackSlot *stack; StackSlot *stack;
}; };
typedef struct {
unsigned int size;
ObjRef *refs;
}ObjRefContainer;
void printStack(struct stack stack, int fp) { void printStack(struct stack stack, int fp) {
printf("Stack\nSize:\t\t%i\nCurrent:\t%i\n", *stack.size, *stack.current); printf("Stack\nSize:\t\t%i\nCurrent:\t%i\n", *stack.size, *stack.current);
for (int i = *stack.current -1; i >= 0; --i) { for (int i = *stack.current -1; i >= 0; --i) {
printf("%i\t",i); printf("%i\t",i);
if(stack.stack[i].u.objRef == NULL) printf("|NULL|");
else
if(stack.stack[i].isObjRef){ if(stack.stack[i].isObjRef){
printf("|%p|", stack.stack[i].u.objRef); printf("|%p|", (void *)stack.stack[i].u.objRef);
if(stack.stack[i].u.objRef->size == sizeof(int)) if(stack.stack[i].u.objRef->size == sizeof(int))
printf("(%i)",*(int *)stack.stack[i].u.objRef->data); printf("(%i)",*(int *)stack.stack[i].u.objRef->data);
}else { }else {
@@ -31,6 +38,21 @@ void printStack(struct stack stack, int fp) {
} }
} }
//ObjRefContainer getRefs(struct stack stack){
// ObjRefContainer continer;
// int counter = 0;
// for (int i = 0; i <= *stack.current; i++) {
// if(stack.stack[i].isObjRef == true) counter++;
// }
// continer.size = counter;
// ObjRef *list = (ObjRef *)malloc(counter * sizeof(ObjRef));
// for (int i = 0; i<= *stack.current; i++)
// if(stack.stack[i].isObjRef == true)
// list[counter--] = stack.stack[i].u.objRef;
// continer.refs = list;
// return continer;
//}
void push(struct stack s, StackSlot value) { void push(struct stack s, StackSlot value) {
if (*s.current >= *s.size) { if (*s.current >= *s.size) {
printf("Stack Overflow\n"); printf("Stack Overflow\n");

View File

@@ -1,13 +1,13 @@
#ifndef STACKSLOT
#define STACKSLOT
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifndef STACKSLOT #include "objref.c"
#define STACKSLOT #include "heap.h"
typedef int Object; typedef int Object;
typedef struct {
unsigned int size;
unsigned char data[1];
} *ObjRef;
typedef struct { typedef struct {
bool isObjRef; bool isObjRef;
@@ -19,39 +19,49 @@ typedef struct{
ObjRef getIntObj(int val) { ObjRef getIntObj(int val) {
ObjRef intObject; ObjRef intObject;
unsigned int objSize = sizeof(unsigned int) + sizeof(int); unsigned int objSize = sizeof(ObjRef) + sizeof(int);
if ((intObject = malloc(objSize)) == NULL) { if ((intObject = my_malloc(objSize)) == NULL) {
perror("malloc"); perror("malloc");
} }
*(int *) intObject->data = val; *(int *) intObject->data = val;
intObject->size=sizeof(int); intObject->size = objSize;
return intObject; return intObject;
} }
int getValFromIntObj(ObjRef iref) { int getValFromIntObj(ObjRef iref) {
if (iref == NULL) perror("ObjRef is null");
return *(int *) iref->data; return *(int *) iref->data;
} }
int getIntValfromStackSlot(StackSlot s) { int getIntValfromStackSlot(StackSlot s) {
if (s.isObjRef) { if (s.isObjRef) {
return *(int *) s.u.objRef->data; return *(int *) s.u.objRef->data;
} }
return s.u.number; return s.u.number;
} }
void setValIntObj(ObjRef iref, int val) { void setValIntObj(ObjRef iref, int val) {
iref->size=sizeof(int); if (iref == NULL) perror("ObjRef is null");
iref->size = sizeof(int)+sizeof(ObjRef);
*(int *) iref->data = val; *(int *) iref->data = val;
} }
StackSlot stackSlotWithObjRef(ObjRef val) { StackSlot stackSlotWithObjRef(ObjRef val) {
StackSlot *stackSlot; StackSlot *stackSlot;
stackSlot=malloc(sizeof(StackSlot)); stackSlot = my_malloc(sizeof(StackSlot));
if(stackSlot == NULL) perror("malloc");
stackSlot->isObjRef = true; stackSlot->isObjRef = true;
stackSlot->u.objRef = val; stackSlot->u.objRef = val;
return *stackSlot; return *stackSlot;
} }
StackSlot stackSlotWitchNumber(int val) { StackSlot stackSlotWitchNumber(int val) {
StackSlot *stackSlot; StackSlot *stackSlot;
stackSlot= malloc(sizeof(StackSlot)); stackSlot = my_malloc(sizeof(StackSlot));
if(stackSlot == NULL) perror("malloc");
stackSlot->isObjRef = false; stackSlot->isObjRef = false;
stackSlot->u.number = val; stackSlot->u.number = val;
return *stackSlot; return *stackSlot;
} }
#endif #endif

28
support.c Normal file
View File

@@ -0,0 +1,28 @@
#include "support.h"
#include <stdio.h>
#include <stdlib.h>
#include "objref.c"
#include "heap.h"
void fatalError(char *msg){
printf("Fatal error: %s\n", msg);
exit(1);
}
void * newPrimObject(int dataSize) {
ObjRef bigObjRef;
bigObjRef = my_malloc(sizeof(unsigned int) +
dataSize * sizeof(unsigned char));
if (bigObjRef == NULL) {
fatalError("newPrimObject() got no memory");
}
bigObjRef->size = sizeof(unsigned int) + dataSize * sizeof(unsigned char);
return bigObjRef;
}
void * getPrimObjectDataPointer(void * obj){
ObjRef oo = ((ObjRef) (obj));
return oo->data;
}

BIN
support.o Normal file

Binary file not shown.

155
test.asm Normal file
View File

@@ -0,0 +1,155 @@
//
// version
//
.vers 7
//
// execution framework
//
__start:
call _main
call _exit
__stop:
jmp __stop
//
// Integer readInteger()
//
_readInteger:
asf 0
rdint
popr
rsf
ret
//
// void writeInteger(Integer)
//
_writeInteger:
asf 0
pushl -3
wrint
rsf
ret
//
// Character readCharacter()
//
_readCharacter:
asf 0
rdchr
popr
rsf
ret
//
// void writeCharacter(Character)
//
_writeCharacter:
asf 0
pushl -3
wrchr
rsf
ret
//
// Integer char2int(Character)
//
_char2int:
asf 0
pushl -3
popr
rsf
ret
//
// Character int2char(Integer)
//
_int2char:
asf 0
pushl -3
popr
rsf
ret
//
// void exit()
//
_exit:
asf 0
halt
rsf
ret
//
// void writeString(String)
//
_writeString:
asf 1
pushc 0
popl 0
jmp _writeString_L2
_writeString_L1:
pushl -3
pushl 0
getfa
call _writeCharacter
drop 1
pushl 0
pushc 1
add
popl 0
_writeString_L2:
pushl 0
pushl -3
getsz
lt
brt _writeString_L1
rsf
ret
//
// void main()
//
_main:
asf 2
new 2
popl 1
pushl 1
pushc 5
putf 0
pushl 1
getf 0
popl 0
pushl 1
pushc 2
pushl 0
mul
putf 1
pushl 1
getf 0
call _writeInteger
drop 1
pushc 1
newa
dup
pushc 0
pushc 10
putfa
call _writeString
drop 1
pushl 1
getf 1
call _writeInteger
drop 1
pushc 1
newa
dup
pushc 0
pushc 10
putfa
call _writeString
drop 1
__0:
rsf
ret

3
test.nj Normal file
View File

@@ -0,0 +1,3 @@
void main(){
}

BIN
test/.DS_Store vendored Normal file

Binary file not shown.

BIN
test/tests/1.bin Normal file

Binary file not shown.

BIN
test/tests/10.bin Normal file

Binary file not shown.

BIN
test/tests/11.bin Normal file

Binary file not shown.

BIN
test/tests/12.bin Normal file

Binary file not shown.

BIN
test/tests/13.bin Normal file

Binary file not shown.

BIN
test/tests/14.bin Normal file

Binary file not shown.

BIN
test/tests/15.bin Normal file

Binary file not shown.

BIN
test/tests/2.bin Normal file

Binary file not shown.

BIN
test/tests/3.bin Normal file

Binary file not shown.

BIN
test/tests/4.bin Normal file

Binary file not shown.

BIN
test/tests/5.bin Normal file

Binary file not shown.

BIN
test/tests/6.bin Normal file

Binary file not shown.

BIN
test/tests/7.bin Normal file

Binary file not shown.

BIN
test/tests/8.bin Normal file

Binary file not shown.

BIN
test/tests/9.bin Normal file

Binary file not shown.

18
test/tests/arrTest.asm Normal file
View File

@@ -0,0 +1,18 @@
new 3
popg 0
pushg 0
pushc 10
putf 0
pushg 0
pushc 11
putf 1
pushg 0
getf 0
pushg 0
getf 1
add
wrint
halt
// Sollte 10 + 11 ergeben

View File

@@ -0,0 +1,13 @@
asf 5
pushc 11
call x
wrint
rsf
halt
x:
asf 3
pushc 22
wrint
rsf

View File

@@ -0,0 +1,125 @@
//
// version
//
.vers 7
//
// execution framework
//
__start:
call _main
call _exit
__stop:
jmp __stop
//
// Integer readInteger()
//
_readInteger:
asf 0
rdint
popr
rsf
ret
//
// void writeInteger(Integer)
//
_writeInteger:
asf 0
pushl -3
wrint
rsf
ret
//
// Character readCharacter()
//
_readCharacter:
asf 0
rdchr
popr
rsf
ret
//
// void writeCharacter(Character)
//
_writeCharacter:
asf 0
pushl -3
wrchr
rsf
ret
//
// Integer char2int(Character)
//
_char2int:
asf 0
pushl -3
popr
rsf
ret
//
// Character int2char(Integer)
//
_int2char:
asf 0
pushl -3
popr
rsf
ret
//
// void exit()
//
_exit:
asf 0
halt
rsf
ret
//
// void writeString(String)
//
_writeString:
asf 1
pushc 0
popl 0
jmp _writeString_L2
_writeString_L1:
pushl -3
pushl 0
getfa
call _writeCharacter
drop 1
pushl 0
pushc 1
add
popl 0
_writeString_L2:
pushl 0
pushl -3
getsz
lt
brt _writeString_L1
rsf
ret
//
// void main()
//
_main:
asf 0
pushc 4421
pushc 5743
mul
pushc 7699
mul
call _writeInteger
drop 1
__0:
rsf
ret

View File

@@ -0,0 +1,5 @@
pushc 5
pushc 4
add
wrint
halt

View File

@@ -0,0 +1,5 @@
pushc 5
pushc 4
div
wrint
halt

View File

@@ -0,0 +1,5 @@
pushc 5
pushc 4
mod
wrint
halt

View File

@@ -0,0 +1,5 @@
pushc 5
pushc 4
mul
wrint
halt

View File

@@ -0,0 +1,5 @@
pushc 5
pushc 4
sub
wrint
halt

16
test/tests/brfTest1.asm Normal file
View File

@@ -0,0 +1,16 @@
pushc 3
pushc 4
eq
brf L1
pushc 4
L1:
pushc 7
wrint
pushc 10
wrchr
halt

17
test/tests/brfTest2.asm Normal file
View File

@@ -0,0 +1,17 @@
pushc 4
pushc 4
eq
brf L1
pushc 6
wrint
pushc 10
wrchr
halt
L1:
pushc 7
wrint
pushc 10
wrchr
halt

19
test/tests/brtTest1.asm Normal file
View File

@@ -0,0 +1,19 @@
pushc 3
pushc 4
eq
brt L1
pushc 5
wrint
pushc 10
wrchr
halt
L1:
pushc 7
wrint
pushc 10
wrchr
halt

17
test/tests/brtTest2.asm Normal file
View File

@@ -0,0 +1,17 @@
pushc 4
pushc 4
eq
brt L1
pushc 6
wrint
pushc 10
wrchr
halt
L1:
pushc 7
wrint
pushc 10
wrchr
halt

15
test/tests/equalsTest.asm Normal file
View File

@@ -0,0 +1,15 @@
pushc 3
pushc 4
eq
wrint
pushc 10
wrchr
pushc 6
pushc 6
eq
wrint
pushc 10
wrchr
halt

View File

@@ -0,0 +1,24 @@
pushc 3
pushc 4
ge
wrint
pushc 10
wrchr
pushc 8
pushc 4
ge
wrint
pushc 10
wrchr
pushc 6
pushc 6
ge
wrint
pushc 10
wrchr
halt

View File

@@ -0,0 +1,24 @@
pushc 3
pushc 4
gt
wrint
pushc 10
wrchr
pushc 8
pushc 4
gt
wrint
pushc 10
wrchr
pushc 6
pushc 6
gt
wrint
pushc 10
wrchr
halt

19
test/tests/jumpTest.asm Normal file
View File

@@ -0,0 +1,19 @@
pushc 3
pushc 4
wrint
pushc 10
wrchr
pushc 3
jmp L1
pushc 4
L1:
wrint
pushc 10
wrchr
halt

View File

@@ -0,0 +1,24 @@
pushc 3
pushc 4
le
wrint
pushc 10
wrchr
pushc 8
pushc 4
le
wrint
pushc 10
wrchr
pushc 6
pushc 6
le
wrint
pushc 10
wrchr
halt

Some files were not shown because too many files have changed in this diff Show More