Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
509dc5e947 | ||
|
|
c6ae64250d | ||
|
|
ffc04172ae | ||
|
|
f5cab7c013 | ||
| de248a5943 | |||
| 4994bd6071 | |||
| 0b042fb912 | |||
|
|
77cae7467e | ||
| 6ea2a7e735 | |||
| 8a89c6bf70 | |||
| 88271c91ca |
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ cmake-build-debug
|
||||
njvm
|
||||
njvm.dSYM
|
||||
njvm.exe
|
||||
njvm2
|
||||
|
||||
@ -5,22 +5,5 @@ set(CMAKE_C_STANDARD 99)
|
||||
|
||||
add_compile_options(-g -Wall -pedantic)
|
||||
|
||||
add_executable(njvm njvm.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)
|
||||
|
||||
add_executable(ninja njvm.c
|
||||
SDA.c)
|
||||
|
||||
99
GC.c
99
GC.c
@ -1,99 +0,0 @@
|
||||
#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
|
||||
35
Makefile
35
Makefile
@ -1,12 +1,29 @@
|
||||
# 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
|
||||
|
||||
run: build
|
||||
./njvm prog.bin
|
||||
# Compiler
|
||||
CC = gcc
|
||||
|
||||
debug: build
|
||||
./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)
|
||||
|
||||
run: all
|
||||
./$(TARGET)
|
||||
|
||||
nja: ./nja/nja$(V)
|
||||
./nja/nja$(V) $(IN) $(OUT)
|
||||
|
||||
njc: ./njc/njc$(V)
|
||||
./njc/njc$(V) $(IN) $(OUT)
|
||||
|
||||
43
Makefile3
43
Makefile3
@ -1,43 +0,0 @@
|
||||
# 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)
|
||||
22
SDA.c
22
SDA.c
@ -4,24 +4,24 @@
|
||||
#ifndef SDA
|
||||
#define SDA
|
||||
#include <stdio.h>
|
||||
#include "stackslot.c"
|
||||
|
||||
struct sda {
|
||||
int *size;
|
||||
ObjRef *sda;
|
||||
unsigned int *sda;
|
||||
int size;
|
||||
};
|
||||
|
||||
ObjRef getSDA(int i, struct sda s) {
|
||||
return s.sda[i];
|
||||
int getSDA(unsigned int offset, struct sda *sda) {
|
||||
return sda->sda[offset];
|
||||
}
|
||||
|
||||
void setSDA(int point, ObjRef val, struct sda s) {
|
||||
if (val == NULL) perror("Value is null");
|
||||
s.sda[point] = val;
|
||||
void setSDA(unsigned int offset, int value, struct sda *sda) {
|
||||
sda->sda[offset] = value;
|
||||
}
|
||||
|
||||
void printSDA(struct sda s) {
|
||||
for (int i = 0; i < *s.size; i++) {
|
||||
printf("%i\n", *(int *)getSDA(i, s)->data);
|
||||
void printSDA(struct sda *sda) {
|
||||
printf("SDA:\n");
|
||||
for (int i = 0; i < sda->size; ++i) {
|
||||
printf("[%d] = %d\n", i, sda->sda[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
#
|
||||
# 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)
|
||||
@ -1,92 +0,0 @@
|
||||
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.
|
||||
Binary file not shown.
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* 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_ */
|
||||
@ -1,15 +0,0 @@
|
||||
/*
|
||||
* 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.
@ -1,26 +0,0 @@
|
||||
#
|
||||
# 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
|
||||
@ -1,987 +0,0 @@
|
||||
/*
|
||||
* 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, "]");
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* 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_ */
|
||||
Binary file not shown.
Binary file not shown.
@ -1,15 +0,0 @@
|
||||
/*
|
||||
* 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_ */
|
||||
@ -1,28 +0,0 @@
|
||||
#
|
||||
# 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
|
||||
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
1253
bigint/tst/testbip.c
1253
bigint/tst/testbip.c
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -6,13 +6,13 @@
|
||||
#include <stdlib.h>
|
||||
#include "program.c"
|
||||
|
||||
unsigned int fromFile(char *path, struct program program) {
|
||||
unsigned int fromFile(char *path, struct program *program) {
|
||||
unsigned int countInstructions;
|
||||
unsigned int staticVars;
|
||||
FILE *fptr;
|
||||
fptr = fopen(path, "r");
|
||||
if (fptr == NULL) {
|
||||
printf("Error: cannot open code file %s", path);
|
||||
printf("Error: cannot open code file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
unsigned int buffer[4];
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
-Ibigint/build/include
|
||||
-Lbigint/build/lib
|
||||
-lbigint
|
||||
6
consts.c
6
consts.c
@ -1,7 +1,5 @@
|
||||
#ifndef CONSTS
|
||||
#define CONSTS
|
||||
#define VERSION 8
|
||||
#define VERSION 4
|
||||
|
||||
#endif /* ifndef CONSTS
|
||||
#define CONSTS
|
||||
#define VERSION 2; */
|
||||
#endif
|
||||
|
||||
55
debugMenu.c
55
debugMenu.c
@ -1,55 +0,0 @@
|
||||
#ifndef DEBUGMENU
|
||||
#define DEBUGMENU
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "stack.c"
|
||||
#include "stack.c"
|
||||
|
||||
void inspect(struct stack s, int fp){
|
||||
//todo Does not work dont know why
|
||||
char input[20];
|
||||
char ref[20];
|
||||
char refStr[20];
|
||||
printf("DEBUG [inspect]: stack, datam object?");
|
||||
fgets(input,20,stdin);
|
||||
if (input[0] == 's') printStack(s, fp);
|
||||
if (input[0] == 'd'){/* 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){
|
||||
//todo
|
||||
}
|
||||
void breakpoint(int *bp){
|
||||
printf("BREAKPOINT: ");
|
||||
char input[20];
|
||||
fgets(input,20,stdin);
|
||||
*bp = atoi(input);
|
||||
}
|
||||
|
||||
void debugMenu(int fp, struct stack stack, int* debug, int point, int* bp){
|
||||
char input[20];
|
||||
while (true) {
|
||||
printf("DEBUG(%i): inspect, list, breakpoint, run, step, quit?",point);
|
||||
fgets(input, 20, stdin);
|
||||
printf("%s",input);
|
||||
if(input[0] == 'i') {inspect(stack,fp);}
|
||||
if(input[0] == 'l') list();
|
||||
if(input[0] == 'b') breakpoint(bp);
|
||||
if(input[0] == 's') break;
|
||||
if(input[0] == 'r') {*debug = 0; break;};
|
||||
if(input[0] == 'q') exit(0);
|
||||
strcpy(input, "");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ifndef DEBUGMENU */
|
||||
8301
factor.asm
8301
factor.asm
File diff suppressed because it is too large
Load Diff
BIN
factor.bin
BIN
factor.bin
Binary file not shown.
794
factor.nj
794
factor.nj
@ -1,794 +0,0 @@
|
||||
//
|
||||
// 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
33
heap.c
@ -1,33 +0,0 @@
|
||||
//
|
||||
// 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
12
heap.h
@ -1,12 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
@ -2,11 +2,8 @@
|
||||
#define INSREUKTION
|
||||
|
||||
#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 GET_ELEMENT_COUNT(objRef) ((objRef)->size & ~MSB)
|
||||
#define GET_REFS_PTR(objRef) ((ObjRef *) (objRef)-> data)
|
||||
|
||||
#define HALT 0
|
||||
#define PUSHC 1
|
||||
@ -37,18 +34,5 @@
|
||||
#define CALL 26
|
||||
#define RET 27
|
||||
#define DROP 28
|
||||
#define PUSHR 29
|
||||
#define POPR 30
|
||||
#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 */
|
||||
|
||||
778
matinv.asm
778
matinv.asm
@ -1,778 +0,0 @@
|
||||
//
|
||||
// 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
BIN
matinv.bin
Binary file not shown.
146
matinv.nj
146
matinv.nj
@ -1,146 +0,0 @@
|
||||
//
|
||||
// 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
njvm7 → nja-mac
BIN
njvm7 → nja-mac
Binary file not shown.
Binary file not shown.
11070
njlisp.asm
11070
njlisp.asm
File diff suppressed because it is too large
Load Diff
BIN
njlisp.bin
BIN
njlisp.bin
Binary file not shown.
BIN
njvm?inline=false.2 → njvm-3
Normal file → Executable file
BIN
njvm?inline=false.2 → njvm-3
Normal file → Executable file
Binary file not shown.
503
njvm.c
503
njvm.c
@ -1,340 +1,303 @@
|
||||
#ifndef NJVM
|
||||
#define NJVM
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "consts.c"
|
||||
#include "instruktion.c"
|
||||
#include "code.c"
|
||||
#include "stack.c"
|
||||
#include "program.c"
|
||||
#include "codeReader.c"
|
||||
#include "debugMenu.c"
|
||||
#include "bigint.h"
|
||||
#include "record.c"
|
||||
#include "GC.c"
|
||||
#include "heap.c"
|
||||
|
||||
// Debug
|
||||
int debug = 0;
|
||||
#include "SDA.c"
|
||||
|
||||
// Program
|
||||
struct program program;
|
||||
struct program *program;
|
||||
|
||||
unsigned fp;
|
||||
// SDA
|
||||
int fp;
|
||||
int debug = 0;
|
||||
|
||||
void version(void) {
|
||||
printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", 0, __DATE__, __TIME__);
|
||||
printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", VERSION, __DATE__, __TIME__);
|
||||
}
|
||||
|
||||
void help(void) {
|
||||
printf("Usage: ./njvm [options] <code file>\n\t--debug\tstart virtual machine in debug mode\n\t--version\tshow version and exit\n\t--help\t\tshow this help and exit\n");
|
||||
}
|
||||
|
||||
void execute(struct program program) {
|
||||
int bp = -1;
|
||||
int i;
|
||||
void execute(struct program *program, struct sda *sda) {
|
||||
struct stack stack;
|
||||
stack.size = 1000;
|
||||
stack.currentFrame = 0;
|
||||
struct stack callStack;
|
||||
callStack.size = 1000;
|
||||
callStack.currentFrame = 0;
|
||||
|
||||
for (int i = 0; i < stack.size; ++i) {
|
||||
struct stackFrame *frame = malloc(sizeof(struct stackFrame));
|
||||
frame->fp = malloc(sizeof(int) * stack.size);
|
||||
frame->sp = malloc(sizeof(int) * stack.size);
|
||||
frame->bp = NULL;
|
||||
stack.frames[i] = frame;
|
||||
}
|
||||
|
||||
for (int i = 0; i < callStack.size; ++i) {
|
||||
struct stackFrame *frame = malloc(sizeof(struct stackFrame));
|
||||
frame->fp = malloc(sizeof(int) * stack.size);
|
||||
frame->sp = malloc(sizeof(int) * stack.size);
|
||||
frame->bp = NULL;
|
||||
callStack.frames[i] = frame;
|
||||
}
|
||||
|
||||
struct stackFrame *currentFrame = NULL;
|
||||
//struct stackFrame *currentCallFrame = NULL;
|
||||
unsigned int tmp;
|
||||
int intInput;
|
||||
char charInput;
|
||||
StackSlot tempSlot;
|
||||
ObjRef tempObj;
|
||||
ObjRef tempObj2;
|
||||
int tempInt;
|
||||
for (i = 0; i < *program.size; ++i) {
|
||||
if (debug == 1 || bp == i) debugMenu(fp, stack, &debug, i, &bp);
|
||||
if(debug == 1) printf("(%i)",i);
|
||||
switch (program.program[i] >> 24) {
|
||||
|
||||
for (int i = 0; i < program->size; ++i) {
|
||||
unsigned int instruction = program->program[i];
|
||||
if (i >= program->size) {
|
||||
printf("Error: Jump out of program memory\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch (instruction >> 24) {
|
||||
case HALT:
|
||||
if (debug == 1) printf("halt\n");
|
||||
goto end;
|
||||
case PUSHC:
|
||||
if (debug == 1) printf("pushc: %i\n", IMMEDIATE(program.program[i]));
|
||||
bigFromInt(SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
if (debug == 1) printf("PUSHC %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
|
||||
push(&stack, SIGN_EXTEND(IMMEDIATE(instruction)));
|
||||
break;
|
||||
case ADD:
|
||||
if (debug == 1) printf("add: %i + %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigAdd();
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
if (debug == 1) printf("ADD\n");
|
||||
push(&stack, pop(&stack) + pop(&stack));
|
||||
break;
|
||||
case SUB:
|
||||
if (debug == 1) printf("sub: %i - %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigSub();
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
tmp = pop(&stack);
|
||||
if (debug == 1) printf("SUB\n");
|
||||
if (debug == 1) printf("tmp: %d\n", tmp);
|
||||
push(&stack, pop(&stack) - tmp);
|
||||
break;
|
||||
case MUL:
|
||||
if (debug == 1) printf("mul: %i * %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigMul();
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
if (debug == 1) printf("MUL\n");
|
||||
push(&stack, pop(&stack) * pop(&stack));
|
||||
break;
|
||||
case DIV:
|
||||
if (debug == 1) printf("div: %i / %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigDiv();
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
tmp = pop(&stack);
|
||||
if (debug == 1) printf("DIV\n");
|
||||
if (debug == 1) printf("tmp: %d\n", tmp);
|
||||
push(&stack, pop(&stack) / tmp);
|
||||
break;
|
||||
case MOD:
|
||||
if (debug == 1) printf("mod: %i %% %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigDiv();
|
||||
push(stack, stackSlotWithObjRef(bip.rem));
|
||||
tmp = pop(&stack);
|
||||
if (debug == 1) printf("MOD\n");
|
||||
if (debug == 1) printf("tmp: %d\n", tmp);
|
||||
push(&stack, pop(&stack) % tmp);
|
||||
break;
|
||||
case RDINT:
|
||||
if (debug == 1) printf("rdint\n");
|
||||
bigRead(stdin);
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
if (debug == 1) printf("pushed %i\n", peek(stack, 1));
|
||||
scanf("%i", &intInput);
|
||||
if (debug == 1) printf("RDINT %d\n", intInput);
|
||||
push(&stack, intInput);
|
||||
break;
|
||||
case WRINT:
|
||||
if (debug == 1) printf("wrint: %i\n", peek(stack, 1));
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigPrint(stdout);
|
||||
if (debug == 1) printf("WRINT\n");
|
||||
printf("%i", pop(&stack));
|
||||
break;
|
||||
case RDCHR:
|
||||
if (debug == 1) printf("rdchr\n");
|
||||
scanf("%c", &charInput);
|
||||
bigFromInt(charInput);
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
if (debug == 1) printf("pushed %c\n", charInput);
|
||||
if (debug == 1) printf("RDCHR %c\n", charInput);
|
||||
push(&stack, charInput);
|
||||
break;
|
||||
case WRCHR:
|
||||
if (debug == 1) printf("wrchr: %c\n", peek(stack, 1));
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
printf("%c", bigToInt());
|
||||
if (debug == 1) printf("WRCHR\n");
|
||||
printf("%c", pop(&stack));
|
||||
break;
|
||||
case PUSHG:
|
||||
if (debug == 1) printf("pushg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
push(stack, stackSlotWithObjRef(getSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), sda)));
|
||||
if (debug == 1) printf("PUSHG %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
|
||||
currentFrame = stack.frames[stack.currentFrame];
|
||||
currentFrame->bp = currentFrame->sp;
|
||||
|
||||
*currentFrame->sp++ = getSDA(SIGN_EXTEND(IMMEDIATE(instruction)), sda);
|
||||
break;
|
||||
case POPG:
|
||||
if (debug == 1) printf("popg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
setSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), pop(stack).u.objRef, sda);
|
||||
if (debug == 1) printf("POPG %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
|
||||
currentFrame = stack.frames[stack.currentFrame];
|
||||
currentFrame->bp = currentFrame->sp;
|
||||
|
||||
setSDA(SIGN_EXTEND(IMMEDIATE(instruction)), pop(&stack), sda);
|
||||
break;
|
||||
case ASF:
|
||||
if (debug == 1) printf("asf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
push(stack, stackSlotWitchNumber(fp));
|
||||
fp = *stack.current;
|
||||
*stack.current = *stack.current + SIGN_EXTEND(IMMEDIATE(program.program[i]));
|
||||
if (debug == 1) printf("ASF %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
|
||||
currentFrame = stack.frames[stack.currentFrame];
|
||||
push(&stack, *currentFrame->sp);
|
||||
*currentFrame->sp = stack.currentFrame;
|
||||
currentFrame->bp = currentFrame->sp;
|
||||
|
||||
stack.currentFrame += SIGN_EXTEND(IMMEDIATE(instruction));
|
||||
break;
|
||||
case RSF:
|
||||
if (debug == 1) printf("rsf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
*stack.current = fp;
|
||||
if (debug == 1) printf("pop: %i\n", peek(stack, 1));
|
||||
tempSlot = pop(stack);
|
||||
fp = tempSlot.u.number;
|
||||
break;
|
||||
case POPL:
|
||||
if (debug == 1) printf("popl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
stack.stack[fp + SIGN_EXTEND(IMMEDIATE(program.program[i]))] = pop(stack);
|
||||
if (debug == 1) printf("RSF\n");
|
||||
stack.currentFrame = pop(&stack);
|
||||
currentFrame = stack.frames[stack.currentFrame];
|
||||
currentFrame->bp = NULL;
|
||||
break;
|
||||
case PUSHL:
|
||||
if (debug == 1) printf("pushl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
push(stack, stack.stack[fp + SIGN_EXTEND(IMMEDIATE(program.program[i]))]);
|
||||
printf("PUSHL %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
|
||||
currentFrame = stack.frames[stack.currentFrame];
|
||||
currentFrame->bp = currentFrame->sp;
|
||||
int x = SIGN_EXTEND(IMMEDIATE(instruction));
|
||||
push(&stack, currentFrame->fp[x]);
|
||||
break;
|
||||
case NE:
|
||||
if (debug == 1) printf("ne: %i != %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigFromInt(bigCmp() != 0);
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
case POPL:
|
||||
if (debug == 1) printf("POPL %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
|
||||
currentFrame = stack.frames[stack.currentFrame];
|
||||
currentFrame->fp[SIGN_EXTEND(IMMEDIATE(instruction))] = pop(&stack);
|
||||
break;
|
||||
case EQ:
|
||||
if (debug == 1) printf("eq: %i == %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigFromInt(bigCmp() == 0);
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
break;
|
||||
case LT:
|
||||
if (debug == 1) printf("lt: %i < %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigFromInt(bigCmp() < 0);
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
break;
|
||||
case LE:
|
||||
if (debug == 1) printf("le: %i <= %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigFromInt(bigCmp() <= 0);
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
break;
|
||||
case GT:
|
||||
if (debug == 1) printf("gt: %i > %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigFromInt(bigCmp() > 0);
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
break;
|
||||
case GE:
|
||||
if (debug == 1) printf("ge: %i >= %i\n", peek(stack, 2), peek(stack, 1));
|
||||
bip.op2 = pop(stack).u.objRef;
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
bigFromInt(bigCmp() >= 0);
|
||||
push(stack, stackSlotWithObjRef(bip.res));
|
||||
break;
|
||||
case BRF:
|
||||
if (debug == 1) printf("brf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
if (debug == 1) printf("pop: %i\n", peek(stack, 1));
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
int b = bigToInt();
|
||||
if (b == false) {
|
||||
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
|
||||
if (debug == 1) printf("new i: %i\n", i);
|
||||
} else if (b != true) {
|
||||
printf("Error: brf: %i\n", b);
|
||||
exit(EXIT_FAILURE);
|
||||
if (debug == 1) printf("EQ\n");
|
||||
if (pop(&stack) == pop(&stack)) {
|
||||
push(&stack, 1);
|
||||
} else {
|
||||
push(&stack, 0);
|
||||
}
|
||||
break;
|
||||
case BRT:
|
||||
if (debug == 1) printf("brt: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
if (debug == 1) printf("pop: %i\n", peek(stack, 1));
|
||||
bip.op1 = pop(stack).u.objRef;
|
||||
b = bigToInt();
|
||||
if (b == true) {
|
||||
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
|
||||
if (debug == 1) printf("new i: %i\n", i);
|
||||
} else if (b != false) {
|
||||
printf("Error: brt: %i\n", b);
|
||||
exit(EXIT_FAILURE);
|
||||
case NE:
|
||||
if (debug == 1) printf("NE\n");
|
||||
if (pop(&stack) != pop(&stack)) {
|
||||
push(&stack, 1);
|
||||
} else {
|
||||
push(&stack, 0);
|
||||
}
|
||||
break;
|
||||
case LT:
|
||||
if (debug == 1) printf("LT\n");
|
||||
tmp = pop(&stack);
|
||||
if (pop(&stack) < tmp) {
|
||||
push(&stack, 1);
|
||||
} else {
|
||||
push(&stack, 0);
|
||||
}
|
||||
break;
|
||||
case LE:
|
||||
if (debug == 1) printf("LE\n");
|
||||
tmp = pop(&stack);
|
||||
if (pop(&stack) <= tmp) {
|
||||
push(&stack, 1);
|
||||
} else {
|
||||
push(&stack, 0);
|
||||
}
|
||||
break;
|
||||
case GT:
|
||||
if (debug == 1) printf("GT\n");
|
||||
if (debug == 1) printf("peek(1): %d\n", peek(&stack, 1));
|
||||
if (debug == 1) printf("peek(2): %d\n", peek(&stack, 2));
|
||||
if (debug == 1) printf("peek(1) > peek(2): %d\n", peek(&stack, 2) > peek(&stack, 1));
|
||||
tmp = pop(&stack);
|
||||
if (pop(&stack) > tmp) {
|
||||
push(&stack, 1);
|
||||
} else {
|
||||
push(&stack, 0);
|
||||
}
|
||||
break;
|
||||
case GE:
|
||||
if (debug == 1) printf("GE\n");
|
||||
tmp = pop(&stack);
|
||||
if (pop(&stack) >= tmp) {
|
||||
push(&stack, 1);
|
||||
} else {
|
||||
push(&stack, 0);
|
||||
}
|
||||
break;
|
||||
case JMP:
|
||||
if (debug == 1) printf("jmp: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
|
||||
if (debug == 1) printf("new i: %i\n", i);
|
||||
if (debug == 1) printf("JMP %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
|
||||
int j = SIGN_EXTEND(IMMEDIATE(program->program[i]));
|
||||
if (debug == 1) printf("JMP %d\n", j);
|
||||
if (j-- >= program->size) {
|
||||
printf("Error: Jump out of program memory\n");
|
||||
goto end;
|
||||
}
|
||||
i = j;
|
||||
break;
|
||||
case BRF: // branch on false
|
||||
if (debug == 1) printf("BRF %d\nStack: %d\n", SIGN_EXTEND(IMMEDIATE(instruction)), pop(&stack));
|
||||
if (pop(&stack) == 0) {
|
||||
int j = SIGN_EXTEND(IMMEDIATE(program->program[i]));
|
||||
if (j-- >= program->size) {
|
||||
printf("Error: BRF out of program memory\n");
|
||||
goto end;
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
break;
|
||||
case BRT:
|
||||
if (debug == 1) printf("BRT %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
|
||||
if (pop(&stack) == 1) {
|
||||
int j = SIGN_EXTEND(IMMEDIATE(program->program[i]));
|
||||
if (j-- >= program->size) {
|
||||
printf("Error: BRT out of program memory\n");
|
||||
goto end;
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
break;
|
||||
case CALL:
|
||||
if (debug == 1) printf("call: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||
push(stack, stackSlotWitchNumber(i));
|
||||
if (debug == 1) printf("push: %i\n", i + 1);
|
||||
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
|
||||
if (debug == 1) printf("new i: %i\n", i);
|
||||
tmp = SIGN_EXTEND(IMMEDIATE(program->program[i]));
|
||||
if (j-- >= program->size) {
|
||||
printf("Error: Call out of program memory\n");
|
||||
goto end;
|
||||
}
|
||||
push(&callStack, i + 1);
|
||||
i = tmp;
|
||||
break;
|
||||
case RET:
|
||||
if (debug == 1) printf("ret\n");
|
||||
if (debug == 1) printf("pop: %i\n", peek(stack, 1));
|
||||
i = getIntValfromStackSlot(pop(stack));
|
||||
if (debug == 1) printf("new i: %i\n", i);
|
||||
if (debug == 1) printf("RET\n");
|
||||
tmp = pop(&callStack);
|
||||
if (tmp-- >= program->size) {
|
||||
printf("Error: Return out of program memory\n");
|
||||
goto end;
|
||||
}
|
||||
i = tmp;
|
||||
break;
|
||||
case DROP:
|
||||
if (debug == 1) printf("drop\n");
|
||||
*stack.current = *stack.current - SIGN_EXTEND(IMMEDIATE(program.program[i]));
|
||||
break;
|
||||
case DUP:
|
||||
if (debug == 1) printf("dup\n");
|
||||
tempObj = pop(stack).u.objRef;
|
||||
push(stack, stackSlotWithObjRef(tempObj));
|
||||
push(stack, stackSlotWithObjRef(tempObj));
|
||||
break;
|
||||
case POPR:
|
||||
if (debug == 1) printf("popr\n");
|
||||
push(reg, pop(stack));
|
||||
break;
|
||||
case PUSHR:
|
||||
if (debug == 1) printf("pushr\n");
|
||||
push(stack, pop(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));
|
||||
tmp = SIGN_EXTEND(IMMEDIATE(instruction));
|
||||
if (debug == 1) printf("DROP %d\n", tmp);
|
||||
for (int b = 0; b < tmp; ++b) {
|
||||
pop(&stack);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return;
|
||||
}
|
||||
|
||||
// run prog2.bin
|
||||
void tests(void) {
|
||||
printf("Test started\n");
|
||||
/*struct sda *sda = malloc(sizeof(struct sda));
|
||||
unsigned int s[1000];
|
||||
sda->size = 1000;
|
||||
sda->sda = s;
|
||||
fromFile("prog2.bin", program);
|
||||
execute(program, (struct sda *) &sda);*/
|
||||
printf("Test finished\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Initialize the Stack
|
||||
struct stack stack;
|
||||
int size = SIZE;
|
||||
int current = 0;
|
||||
stack.size = &size;
|
||||
stack.current = ¤t;
|
||||
stack.stack = malloc(size * 1024);
|
||||
if (stack.stack == NULL) {
|
||||
perror("malloc");
|
||||
}
|
||||
|
||||
// Initialize the registery
|
||||
int rSize = 100000;
|
||||
int rCurrent = 0;
|
||||
StackSlot r[100000];
|
||||
reg.size = &rSize;
|
||||
reg.current = &rCurrent;
|
||||
reg.stack = r;
|
||||
stack.size = size;
|
||||
stack.currentFrame = 0;
|
||||
|
||||
// Initialize ProgrammSpeicher
|
||||
int psize = 100000;
|
||||
int saveProgram = 0;
|
||||
unsigned int p[100000];
|
||||
program.size = &psize;
|
||||
program.program = p;
|
||||
program.saveProgram = &saveProgram;
|
||||
int psize = SIZE;
|
||||
unsigned int p[1000];
|
||||
program = malloc(sizeof(struct program));
|
||||
program->size = psize;
|
||||
program->program = p;
|
||||
|
||||
// Initialize runtime variables
|
||||
int run = 0;
|
||||
int sizeSDA;
|
||||
|
||||
@ -348,14 +311,6 @@ int main(int argc, char *argv[]) {
|
||||
} else if (strcmp(argv[i], "--help") == 0) {
|
||||
help();
|
||||
return 0;
|
||||
} else if (strcmp(argv[i], "--stack") == 0) {
|
||||
i++;
|
||||
// TODO: implement stack size
|
||||
} else if (strcmp(argv[i], "--heap") == 0) {
|
||||
i++;
|
||||
initHeap(atoi(argv[i]) * 1024);
|
||||
} else if (strcmp(argv[i], "--gcpurge") == 0) {
|
||||
// TODO: implement gcpurge
|
||||
} else {
|
||||
sizeSDA = fromFile(argv[i], program);
|
||||
run = 1;
|
||||
@ -363,22 +318,28 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Debug mode
|
||||
*/
|
||||
if (debug) {
|
||||
tests();
|
||||
}
|
||||
|
||||
/*
|
||||
* Run program
|
||||
*/
|
||||
if (run) {
|
||||
printf("Ninja Virtual Machine started\n");
|
||||
ObjRef s[sizeSDA];
|
||||
sda.size = &sizeSDA;
|
||||
sda.sda = s;
|
||||
struct sda *sda = malloc(sizeof(struct sda));
|
||||
unsigned int s[sizeSDA];
|
||||
sda->size = sizeSDA;
|
||||
sda->sda = s;
|
||||
if (debug == 1) printProgram(program);
|
||||
execute(program);
|
||||
execute(program, (struct sda *) &sda);
|
||||
printf("Ninja Virtual Machine stopped\n");
|
||||
} else {
|
||||
printf("Error: no code file specified\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ifndef NJVM */
|
||||
12
objref.c
12
objref.c
@ -1,12 +0,0 @@
|
||||
#ifndef OBJREF
|
||||
#define OBJREF
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct ObjRef{
|
||||
unsigned int size;
|
||||
unsigned char data[1];
|
||||
} *ObjRef;
|
||||
|
||||
#endif /* ifndef OBJREF
|
||||
#define OBJREF */
|
||||
50
program.c
50
program.c
@ -9,23 +9,21 @@
|
||||
#include <stdio.h>
|
||||
|
||||
struct program {
|
||||
int *size;
|
||||
unsigned int *program;
|
||||
int *saveProgram;
|
||||
int size;
|
||||
};
|
||||
|
||||
void copyToProgram(const unsigned int codeToCopy[], int size, struct program program) {
|
||||
void copyToProgram(const unsigned int codeToCopy[], int size, struct program *program) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
program.program[i] = codeToCopy[i];
|
||||
program->program[i] = codeToCopy[i];
|
||||
}
|
||||
*program.size = size;
|
||||
*program.saveProgram = 1;
|
||||
program->size = size;
|
||||
}
|
||||
|
||||
void printProgram(struct program program) {
|
||||
void printProgram(struct program *program) {
|
||||
char c[10];
|
||||
for (int i = 0; i < *program.size; i++) {
|
||||
switch (program.program[i] >> 24) {
|
||||
for (int i = 0; i < program->size; i++) {
|
||||
switch (program->program[i] >> 24) {
|
||||
case PUSHC:
|
||||
strcpy(c, "pushc");
|
||||
break;
|
||||
@ -78,55 +76,43 @@ void printProgram(struct program program) {
|
||||
strcpy(c, "popl");
|
||||
break;
|
||||
case EQ:
|
||||
strcpy(c, "eq");
|
||||
strcpy(c,"eq");
|
||||
break;
|
||||
case NE:
|
||||
strcpy(c, "ne");
|
||||
strcpy(c,"ne");
|
||||
break;
|
||||
case LT:
|
||||
strcpy(c, "lt");
|
||||
break;
|
||||
case LE:
|
||||
strcpy(c, "le");
|
||||
strcpy(c,"lt");
|
||||
break;
|
||||
case GT:
|
||||
strcpy(c, "gt");
|
||||
strcpy(c,"gt");
|
||||
break;
|
||||
case GE:
|
||||
strcpy(c, "ge");
|
||||
strcpy(c,"ge");
|
||||
break;
|
||||
case JMP:
|
||||
strcpy(c, "jmp");
|
||||
strcpy(c,"jmp");
|
||||
break;
|
||||
case BRF:
|
||||
strcpy(c, "brf");
|
||||
break;
|
||||
case BRT:
|
||||
strcpy(c, "brt");
|
||||
strcpy(c,"brt");
|
||||
break;
|
||||
case CALL:
|
||||
strcpy(c, "call");
|
||||
strcpy(c,"call");
|
||||
break;
|
||||
case RET:
|
||||
strcpy(c, "ret");
|
||||
strcpy(c,"ret");
|
||||
break;
|
||||
case DROP:
|
||||
strcpy(c, "drop");
|
||||
break;
|
||||
case PUSHR:
|
||||
strcpy(c, "pushr");
|
||||
break;
|
||||
case POPR:
|
||||
strcpy(c, "popr");
|
||||
break;
|
||||
case DUP:
|
||||
strcpy(c, "dup");
|
||||
strcpy(c,"drop");
|
||||
break;
|
||||
default:
|
||||
strcpy(c, "ERROR");
|
||||
break;
|
||||
}
|
||||
IMMEDIATE(program.program[i]) ? printf("%03i:\t%s\t%i\n", i, c, SIGN_EXTEND(IMMEDIATE(program.program[i]))) : printf(
|
||||
IMMEDIATE(program->program[i]) ? printf("%03i:\t%s\t%i\n", i, c, SIGN_EXTEND(IMMEDIATE(program->program[i]))) : printf(
|
||||
"%03i:\t%s\n", i, c);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,778 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
@ -1,146 +0,0 @@
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
_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
|
||||
BIN
programs/nja
BIN
programs/nja
Binary file not shown.
@ -1,15 +1,11 @@
|
||||
pushc 3
|
||||
pushc 4
|
||||
eq
|
||||
wrint
|
||||
add
|
||||
pushc 10
|
||||
wrchr
|
||||
|
||||
pushc 6
|
||||
pushc 6
|
||||
eq
|
||||
sub
|
||||
mul
|
||||
wrint
|
||||
pushc 10
|
||||
wrchr
|
||||
halt
|
||||
|
||||
BIN
programs/prog-test-1.bin
Normal file
BIN
programs/prog-test-1.bin
Normal file
Binary file not shown.
9
programs/prog-test-2.asm
Normal file
9
programs/prog-test-2.asm
Normal file
@ -0,0 +1,9 @@
|
||||
pushc -2
|
||||
rdint
|
||||
mul
|
||||
pushc 3
|
||||
add
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
halt
|
||||
BIN
programs/prog-test-2.bin
Normal file
BIN
programs/prog-test-2.bin
Normal file
Binary file not shown.
5
programs/prog-test-3.asm
Normal file
5
programs/prog-test-3.asm
Normal file
@ -0,0 +1,5 @@
|
||||
rdchr
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
halt
|
||||
BIN
programs/prog-test-3.bin
Normal file
BIN
programs/prog-test-3.bin
Normal file
Binary file not shown.
@ -1,28 +0,0 @@
|
||||
//
|
||||
// prog02.asm -- call/ret with args, but without ret value
|
||||
//
|
||||
|
||||
asf 3
|
||||
pushc 11
|
||||
pushc 33
|
||||
call proc
|
||||
drop 2
|
||||
rsf
|
||||
halt
|
||||
|
||||
proc:
|
||||
asf 2
|
||||
pushl -4
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
pushc 22
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
pushl -3
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
rsf
|
||||
ret
|
||||
@ -1,32 +0,0 @@
|
||||
//
|
||||
// prog04.asm -- call/ret with args, and with ret value
|
||||
//
|
||||
|
||||
asf 3
|
||||
pushc 11
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
pushc 11
|
||||
pushc 33
|
||||
call proc
|
||||
drop 2
|
||||
pushr
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
pushc 33
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
rsf
|
||||
halt
|
||||
|
||||
proc:
|
||||
asf 2
|
||||
pushl -3
|
||||
pushl -4
|
||||
sub
|
||||
popr
|
||||
rsf
|
||||
ret
|
||||
@ -1,31 +0,0 @@
|
||||
//
|
||||
// prog1.asm -- an assembler example with global variables
|
||||
//
|
||||
|
||||
// global Integer x;
|
||||
// global Integer y;
|
||||
// x = 2;
|
||||
// y = x + 3;
|
||||
// x = 7 * y + x;
|
||||
// writeInteger(x + -33);
|
||||
// writeCharacter('\n');
|
||||
|
||||
pushc 2
|
||||
popg 0
|
||||
pushg 0
|
||||
pushc 3
|
||||
add
|
||||
popg 1
|
||||
pushc 7
|
||||
pushg 1
|
||||
mul
|
||||
pushg 0
|
||||
add
|
||||
popg 0
|
||||
pushg 0
|
||||
pushc -33
|
||||
add
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
halt
|
||||
Binary file not shown.
Binary file not shown.
@ -1,9 +1,61 @@
|
||||
pushc 1
|
||||
asf 2
|
||||
asf 4
|
||||
pushc 23
|
||||
asf 3
|
||||
rsf
|
||||
rsf
|
||||
rsf
|
||||
//
|
||||
// prog1.asm -- an assembler example with global variables
|
||||
//
|
||||
|
||||
//
|
||||
// compute the gcd of two positive numbers
|
||||
//
|
||||
// global Integer x;
|
||||
// global Integer y;
|
||||
// x = readInteger();
|
||||
// y = readInteger();
|
||||
// while (x != y) {
|
||||
// if (x > y) {
|
||||
// x = x - y;
|
||||
// } else {
|
||||
// y = y - x;
|
||||
// }
|
||||
// }
|
||||
// writeInteger(x);
|
||||
// writeCharacter('\n');
|
||||
|
||||
// x = readInteger();
|
||||
rdint
|
||||
popg 0
|
||||
// y = readInteger();
|
||||
rdint
|
||||
popg 1
|
||||
// while ...
|
||||
L1:
|
||||
// x != y
|
||||
pushg 0 // 4
|
||||
pushg 1
|
||||
ne
|
||||
brf L2
|
||||
// if ...
|
||||
pushg 0
|
||||
pushg 1
|
||||
gt
|
||||
brf L3
|
||||
// x = x - y
|
||||
pushg 0
|
||||
pushg 1
|
||||
sub
|
||||
popg 0
|
||||
jmp L4
|
||||
L3:
|
||||
// y = y - x
|
||||
pushg 1 // 17
|
||||
pushg 0
|
||||
sub
|
||||
popg 1
|
||||
L4:
|
||||
jmp L1 // 21
|
||||
L2:
|
||||
// writeInteger(x);
|
||||
pushg 0 // 22
|
||||
wrint
|
||||
// writeCharacter('\n');
|
||||
pushc '\n'
|
||||
wrchr
|
||||
halt
|
||||
|
||||
Binary file not shown.
@ -1,12 +1,12 @@
|
||||
//
|
||||
// prog1.asm -- an assembler example with global variables
|
||||
// prog2.asm -- an assembler example with local variables
|
||||
//
|
||||
|
||||
//
|
||||
// compute the gcd of two positive numbers
|
||||
//
|
||||
// global Integer x;
|
||||
// global Integer y;
|
||||
// local Integer x;
|
||||
// local Integer y;
|
||||
// x = readInteger();
|
||||
// y = readInteger();
|
||||
// while (x != y) {
|
||||
@ -19,43 +19,45 @@
|
||||
// writeInteger(x);
|
||||
// writeCharacter('\n');
|
||||
|
||||
asf 2
|
||||
// x = readInteger();
|
||||
rdint
|
||||
popg 0
|
||||
popl 0
|
||||
// y = readInteger();
|
||||
rdint
|
||||
popg 1
|
||||
popl 1
|
||||
// while ...
|
||||
L1:
|
||||
// x != y
|
||||
pushg 0
|
||||
pushg 1
|
||||
pushl 0
|
||||
pushl 1
|
||||
ne
|
||||
brf L2
|
||||
// if ...
|
||||
pushg 0
|
||||
pushg 1
|
||||
pushl 0
|
||||
pushl 1
|
||||
gt
|
||||
brf L3
|
||||
// x = x - y
|
||||
pushg 0
|
||||
pushg 1
|
||||
pushl 0
|
||||
pushl 1
|
||||
sub
|
||||
popg 0
|
||||
popl 0
|
||||
jmp L4
|
||||
L3:
|
||||
// y = y - x
|
||||
pushg 1
|
||||
pushg 0
|
||||
pushl 1
|
||||
pushl 0
|
||||
sub
|
||||
popg 1
|
||||
popl 1
|
||||
L4:
|
||||
jmp L1
|
||||
L2:
|
||||
// writeInteger(x);
|
||||
pushg 0
|
||||
pushl 0
|
||||
wrint
|
||||
// writeCharacter('\n');
|
||||
pushc '\n'
|
||||
wrchr
|
||||
rsf
|
||||
halt
|
||||
|
||||
Binary file not shown.
@ -1,63 +1,35 @@
|
||||
//
|
||||
// prog2.asm -- an assembler example with local variables
|
||||
// prog01.asm -- call/ret without args, and without ret value
|
||||
//
|
||||
|
||||
//
|
||||
// compute the gcd of two positive numbers
|
||||
//
|
||||
// local Integer x;
|
||||
// local Integer y;
|
||||
// x = readInteger();
|
||||
// y = readInteger();
|
||||
// while (x != y) {
|
||||
// if (x > y) {
|
||||
// x = x - y;
|
||||
// } else {
|
||||
// y = y - x;
|
||||
// }
|
||||
// }
|
||||
// writeInteger(x);
|
||||
// writeCharacter('\n');
|
||||
|
||||
asf 2
|
||||
// x = readInteger();
|
||||
rdint
|
||||
popl 0
|
||||
// y = readInteger();
|
||||
rdint
|
||||
popl 1
|
||||
// while ...
|
||||
L1:
|
||||
// x != y
|
||||
pushl 0
|
||||
pushl 1
|
||||
ne
|
||||
brf L2
|
||||
// if ...
|
||||
pushl 0
|
||||
pushl 1
|
||||
gt
|
||||
brf L3
|
||||
// x = x - y
|
||||
pushl 0
|
||||
pushl 1
|
||||
sub
|
||||
popl 0
|
||||
jmp L4
|
||||
L3:
|
||||
// y = y - x
|
||||
pushl 1
|
||||
pushl 0
|
||||
sub
|
||||
popl 1
|
||||
L4:
|
||||
jmp L1
|
||||
L2:
|
||||
// writeInteger(x);
|
||||
pushl 0
|
||||
asf 3
|
||||
pushc 11
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
call proc
|
||||
pushc 44
|
||||
wrint
|
||||
// writeCharacter('\n');
|
||||
pushc '\n'
|
||||
wrchr
|
||||
rsf
|
||||
halt
|
||||
|
||||
proc:
|
||||
asf 2
|
||||
pushc 22
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
call proctwo
|
||||
rsf
|
||||
ret
|
||||
|
||||
proctwo:
|
||||
asf 2
|
||||
pushc 33
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
rsf
|
||||
ret
|
||||
|
||||
Binary file not shown.
@ -1,61 +1,28 @@
|
||||
//
|
||||
// prog1.asm -- an assembler example with global variables
|
||||
// prog02.asm -- call/ret with args, but without ret value
|
||||
//
|
||||
|
||||
//
|
||||
// compute the gcd of two positive numbers
|
||||
//
|
||||
// global Integer x;
|
||||
// global Integer y;
|
||||
// x = readInteger();
|
||||
// y = readInteger();
|
||||
// while (x != y) {
|
||||
// if (x > y) {
|
||||
// x = x - y;
|
||||
// } else {
|
||||
// y = y - x;
|
||||
// }
|
||||
// }
|
||||
// writeInteger(x);
|
||||
// writeCharacter('\n');
|
||||
asf 3
|
||||
pushc 11
|
||||
pushc 33
|
||||
call proc
|
||||
drop 2
|
||||
rsf
|
||||
halt
|
||||
|
||||
// x = readInteger();
|
||||
rdint
|
||||
popg 0
|
||||
// y = readInteger();
|
||||
rdint
|
||||
popg 1
|
||||
// while ...
|
||||
L1:
|
||||
// x != y
|
||||
pushg 0
|
||||
pushg 1
|
||||
ne
|
||||
brf L2
|
||||
// if ...
|
||||
pushg 0
|
||||
pushg 1
|
||||
gt
|
||||
brf L3
|
||||
// x = x - y
|
||||
pushg 0
|
||||
pushg 1
|
||||
sub
|
||||
popg 0
|
||||
jmp L4
|
||||
L3:
|
||||
// y = y - x
|
||||
pushg 1
|
||||
pushg 0
|
||||
sub
|
||||
popg 1
|
||||
L4:
|
||||
jmp L1
|
||||
L2:
|
||||
// writeInteger(x);
|
||||
pushg 0
|
||||
proc:
|
||||
asf 2
|
||||
pushl -4
|
||||
wrint
|
||||
// writeCharacter('\n');
|
||||
pushc '\n'
|
||||
wrchr
|
||||
halt
|
||||
pushc 22
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
pushl -3
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
rsf
|
||||
ret
|
||||
|
||||
@ -1,16 +1,27 @@
|
||||
//
|
||||
// prog04.asm -- call/ret with args, and with ret value
|
||||
// prog02.asm -- call/ret with args, but without ret value
|
||||
//
|
||||
|
||||
pushc 12
|
||||
rdint
|
||||
mul
|
||||
wrint
|
||||
asf 3
|
||||
pushc 11
|
||||
pushc 33
|
||||
call proc
|
||||
drop 2
|
||||
rsf
|
||||
halt
|
||||
|
||||
proc:
|
||||
asf 1
|
||||
asf 2
|
||||
pushl 4
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
pushc 22
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
pushl 3
|
||||
wrint
|
||||
pushc '\n'
|
||||
wrchr
|
||||
rsf
|
||||
|
||||
Binary file not shown.
55
record.c
55
record.c
@ -1,55 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
87
stack.c
87
stack.c
@ -3,79 +3,46 @@
|
||||
//
|
||||
#ifndef STACK
|
||||
#define STACK
|
||||
#define SIZE 1000
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "stackslot.c"
|
||||
|
||||
struct stack {
|
||||
int* size;
|
||||
int* current;
|
||||
StackSlot *stack;
|
||||
struct stackFrame {
|
||||
int *fp; // Frame pointer
|
||||
int *sp; // Stack pointer
|
||||
int *bp; // Base pointer
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned int size;
|
||||
ObjRef *refs;
|
||||
}ObjRefContainer;
|
||||
struct stack {
|
||||
int size;
|
||||
int currentFrame;
|
||||
struct stackFrame *frames[SIZE];
|
||||
};
|
||||
|
||||
void printStack(struct stack stack, int fp) {
|
||||
printf("Stack\nSize:\t\t%i\nCurrent:\t%i\n", *stack.size, *stack.current);
|
||||
for (int i = *stack.current -1; i >= 0; --i) {
|
||||
printf("%i\t",i);
|
||||
if(stack.stack[i].u.objRef == NULL) printf("|NULL|");
|
||||
else
|
||||
if(stack.stack[i].isObjRef){
|
||||
printf("|%p|", (void *)stack.stack[i].u.objRef);
|
||||
if(stack.stack[i].u.objRef->size == sizeof(int))
|
||||
printf("(%i)",*(int *)stack.stack[i].u.objRef->data);
|
||||
}else {
|
||||
printf("|%i|", getIntValfromStackSlot(stack.stack[i]));
|
||||
}
|
||||
if(fp == i) printf("<-\tFP\n");
|
||||
else if(*stack.current == i) printf("<-\tSP\n");
|
||||
else printf("\n");
|
||||
void printStack(struct stack *stack) {
|
||||
printf("Stack:\n");
|
||||
for (int i = 0; i < stack->size; ++i) {
|
||||
printf("[%d] = %d\n", i, stack->frames[stack->currentFrame]->sp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//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) {
|
||||
if (*s.current >= *s.size) {
|
||||
printf("Stack Overflow\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
s.stack[*s.current] = value;
|
||||
*s.current=*s.current + 1;
|
||||
void push(struct stack *stack, unsigned int value) {
|
||||
struct stackFrame *currentFrame = stack->frames[stack->currentFrame];
|
||||
*(currentFrame->sp) = value;
|
||||
currentFrame->sp++;
|
||||
}
|
||||
|
||||
StackSlot pop(struct stack s) {
|
||||
if (*s.current == 0) {
|
||||
printf("Stack Underflow\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
*s.current = *s.current -1;
|
||||
return s.stack[*s.current];
|
||||
int pop(struct stack *stack) {
|
||||
struct stackFrame *currentFrame = stack->frames[stack->currentFrame];
|
||||
currentFrame->sp--;
|
||||
return *(currentFrame->sp);
|
||||
}
|
||||
|
||||
int peek(struct stack s, int steps) {
|
||||
if (*s.current - steps < 0) {
|
||||
printf("Stack Underflow\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return getIntValfromStackSlot(s.stack[*s.current - steps]);
|
||||
int peek(struct stack *stack, int steps) { // peek is pop without removing the value
|
||||
struct stackFrame *currentFrame = stack->frames[stack->currentFrame];
|
||||
return *(currentFrame->sp - steps);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
67
stackslot.c
67
stackslot.c
@ -1,67 +0,0 @@
|
||||
#ifndef STACKSLOT
|
||||
#define STACKSLOT
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "objref.c"
|
||||
#include "heap.h"
|
||||
|
||||
typedef int Object;
|
||||
|
||||
|
||||
typedef struct {
|
||||
bool isObjRef;
|
||||
union {
|
||||
ObjRef objRef;
|
||||
int number;
|
||||
} u;
|
||||
} StackSlot;
|
||||
|
||||
ObjRef getIntObj(int val) {
|
||||
ObjRef intObject;
|
||||
unsigned int objSize = sizeof(ObjRef) + sizeof(int);
|
||||
if ((intObject = my_malloc(objSize)) == NULL) {
|
||||
perror("malloc");
|
||||
}
|
||||
*(int *) intObject->data = val;
|
||||
intObject->size = objSize;
|
||||
return intObject;
|
||||
}
|
||||
|
||||
int getValFromIntObj(ObjRef iref) {
|
||||
if (iref == NULL) perror("ObjRef is null");
|
||||
return *(int *) iref->data;
|
||||
}
|
||||
|
||||
int getIntValfromStackSlot(StackSlot s) {
|
||||
if (s.isObjRef) {
|
||||
return *(int *) s.u.objRef->data;
|
||||
}
|
||||
return s.u.number;
|
||||
}
|
||||
|
||||
void setValIntObj(ObjRef iref, int val) {
|
||||
if (iref == NULL) perror("ObjRef is null");
|
||||
iref->size = sizeof(int)+sizeof(ObjRef);
|
||||
*(int *) iref->data = val;
|
||||
}
|
||||
|
||||
StackSlot stackSlotWithObjRef(ObjRef val) {
|
||||
StackSlot *stackSlot;
|
||||
stackSlot = my_malloc(sizeof(StackSlot));
|
||||
if(stackSlot == NULL) perror("malloc");
|
||||
stackSlot->isObjRef = true;
|
||||
stackSlot->u.objRef = val;
|
||||
return *stackSlot;
|
||||
}
|
||||
|
||||
StackSlot stackSlotWitchNumber(int val) {
|
||||
StackSlot *stackSlot;
|
||||
stackSlot = my_malloc(sizeof(StackSlot));
|
||||
if(stackSlot == NULL) perror("malloc");
|
||||
stackSlot->isObjRef = false;
|
||||
stackSlot->u.number = val;
|
||||
return *stackSlot;
|
||||
}
|
||||
|
||||
#endif
|
||||
28
support.c
28
support.c
@ -1,28 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
155
test.asm
155
test.asm
@ -1,155 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
BIN
test/.DS_Store
vendored
BIN
test/.DS_Store
vendored
Binary file not shown.
BIN
test/tests/1.bin
BIN
test/tests/1.bin
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user