fixed some things, broke some others

This commit is contained in:
Zezombye 2017-01-01 10:53:07 +01:00
parent 2b9c390687
commit f77d90b9c2
7 changed files with 443 additions and 274 deletions

View File

@ -33,8 +33,8 @@ BCDvar *B2C_add(BCDvar *buffer, BCDvar *a, BCDvar *b) {
}
//First determine which number has a bigger exponent
expA = ((*a)[0]>>4) * 100 + ((*a)[0]&0x0F) * 10 + ((*a)[1]>>4) - 100;
expB = ((*b)[0]>>4) * 100 + ((*b)[0]&0x0F) * 10 + ((*b)[1]>>4) - 100;
expA = getExp(a);
expB = getExp(b);
if (expA > expB) {
smallerExp = b;
biggerExp = a;
@ -66,7 +66,6 @@ BCDvar *B2C_add(BCDvar *buffer, BCDvar *a, BCDvar *b) {
if (carry == 1) {
biggerExp_int++;
}
biggerExp_int += 100;
//locate(1,6); printChar(biggerExp_int);
//locate(3,6); printChar(expA+'0');
//locate(5,6); printChar(expB+'0');
@ -96,7 +95,7 @@ BCDvar *B2C_sub(BCDvar *buffer, BCDvar *a, BCDvar *b) {
//Substract a positive number B from a positive number A (A-B).
//A must be greater than B for the algorithm to function.
//However this function does the necessary checks so A and B can be any reals.
int expA, expB, expDiff, carry = 0, tempsub;
int expA, expB, expDiff, carry = 0, tempsub, compareResult;
unsigned char tempByte;
int result[15] = {0};
//Check for special cases
@ -104,8 +103,8 @@ BCDvar *B2C_sub(BCDvar *buffer, BCDvar *a, BCDvar *b) {
//Ex: (-4)-(-3) -> 3-4
if ((*a)[0] > 0x30 && (*b)[0] > 0x30) {
BCDvar a2, b2;
memcpy(a2, a, 9);
memcpy(b2, b, 9);
memcpy(a2, *a, 9);
memcpy(b2, *b, 9);
a2[0] -= 0x50;
b2[0] -= 0x50;
return B2C_sub(buffer, &b2, &a2);
@ -114,7 +113,7 @@ BCDvar *B2C_sub(BCDvar *buffer, BCDvar *a, BCDvar *b) {
//Ex: 3-(-4) -> 3+4
if ((*b)[0] > 0x30) {
BCDvar b2;
memcpy(b2, b, 9);
memcpy(b2, *b, 9);
b2[0] -= 0x50;
return B2C_add(buffer, a, &b2);
}
@ -122,21 +121,29 @@ BCDvar *B2C_sub(BCDvar *buffer, BCDvar *a, BCDvar *b) {
//Ex: (-4)-3 -> -(4+3)
if ((*a)[0] > 0x30) {
BCDvar a2;
memcpy(a2, a, 9);
memcpy(a2, *a, 9);
a2[0] -= 0x50;
B2C_add(buffer, &a2, b);
(*buffer)[0] += 0x50;
return buffer;
}
//if a < b sub b-a
if (B2C_greaterThan(b, a)) {
return B2C_sub(buffer, b, a);
compareResult = B2C_compareBCDvars(a, b);
//a < b -> -(a-b)
//Ex : 3-4 -> -(4-3)
if (compareResult == A_LESS_THAN_B) {
B2C_sub(buffer, b, a);
(*buffer)[0] += 0x50;
return buffer;
//if a=b then a-b = 0
} else if (compareResult == A_EQUALS_B) {
return &_0_;
}
//Determine the exponent difference; A is always the biggest number
expA = ((*a)[0]>>4) * 100 + ((*a)[0]&0x0F) * 10 + ((*a)[1]>>4);
expB = ((*b)[0]>>4) * 100 + ((*b)[0]&0x0F) * 10 + ((*b)[1]>>4);
expA = getExp(a);
expB = getExp(b);
expDiff = expA-expB;
//Substract
@ -176,122 +183,221 @@ BCDvar *B2C_sub(BCDvar *buffer, BCDvar *a, BCDvar *b) {
}
int B2C_greaterThan(BCDvar *a, BCDvar *b) {
return FALSE;
BCDvar *B2C_mult(BCDvar *buffer, BCDvar *a, BCDvar *b) {
//TODO: implement algorithm
//Here is my attempt at doing it (warning: yields completely false results)
//Algorithm from wikipedia: https://en.wikipedia.org/wiki/Multiplication_algorithm#Long_multiplication
/*int expA, expB, i, j, carry, tempDigit, expResult, firstDigitInResult = 0;
unsigned char tempByte;
char result[30] = {0};
expA = getExp(a)%500-100;
expB = getExp(b)%500-100;
for (i = 15; i > 0; i--) { //digits of b
carry = 0;
for (j = 15; j > 0; j--) { //digits of a
result[i+j-1] += carry + getDigit(a, j-1) + getDigit(b, i-1);
carry = result[i+j-1]/10;
result[i+j-1] %= 10;
}
result[i+15] += carry;
}
expResult = expA+expB + 100 + carry;
//Put exponent in buffer
(*buffer)[0] = (expResult/100 << 4) + (expResult%100)/10;
tempByte = (expResult%10 << 4);
//Calculate position of first non-zero digit in result
for (i = 0; result[i] == 0 && i < 30; i++) {
firstDigitInResult++;
locate(1,7); Print("test");
}
for (i = 0; i < 15; i++) {
locate(i+1, 4); printChar(result[i]+'0');
locate(i+1, 5); printChar(result[i+15]+'0');
}
//Put result in buffer
for (i = 0; i < 15; i++) {
if (i%2) {
tempByte = result[i+firstDigitInResult] << 4;
} else {
(*buffer)[(i+1)/2+1] = tempByte + result[i+firstDigitInResult];
}
}*/
const char *function = "A\xA9""B";
setAlphaVar('A', a);
setAlphaVar('B', b);
calcExp(&function, dummyOpCode, buffer, 1);
return buffer;
}
BCDvar *B2C_div(BCDvar *buffer, BCDvar *a, BCDvar *b) {
//TODO: make algorithm for division
const char *function = "A\xB9""B";
setAlphaVar('A', a);
setAlphaVar('B', b);
calcExp(&function, dummyOpCode, buffer, 1);
return buffer;
}
BCDvar *B2C_pow(BCDvar *buffer, BCDvar *a, BCDvar *b) {
//TODO: make algorithm for division
const char *function = "A\xA8""B";
setAlphaVar('A', a);
setAlphaVar('B', b);
calcExp(&function, dummyOpCode, buffer, 1);
return buffer;
}
BCDvar *B2C_sqrt(BCDvar *buffer, BCDvar *a, BCDvar *b) {
//TODO: make algorithm for division
const char *function = "A\x86""B";
setAlphaVar('A', a);
setAlphaVar('B', b);
calcExp(&function, dummyOpCode, buffer, 1);
return buffer;
}
BCDvar *B2C_greaterThan(BCDvar *a, BCDvar *b) {
if (B2C_compareBCDvars(a, b) == A_GREATER_THAN_B) return &_1_;
return &_0_;
}
BCDvar *B2C_greaterOrEqualThan(BCDvar *a, BCDvar *b) {
if (B2C_compareBCDvars(a, b) == A_LESS_THAN_B) return &_0_;
return &_1_;
}
BCDvar *B2C_lessThan(BCDvar *a, BCDvar *b) {
if (B2C_compareBCDvars(a, b) == A_LESS_THAN_B) return &_1_;
return &_0_;
}
BCDvar *B2C_lessOrEqualThan(BCDvar *a, BCDvar *b) {
if (B2C_compareBCDvars(a, b) == A_GREATER_THAN_B) return &_0_;
return &_1_;
}
BCDvar *B2C_equalTo(BCDvar *a, BCDvar *b) {
if (B2C_compareBCDvars(a, b) == A_EQUALS_B) return &_1_;
return &_0_;
}
BCDvar *B2C_notEqualTo(BCDvar *a, BCDvar *b) {
if (B2C_compareBCDvars(a, b) == A_EQUALS_B) return &_0_;
return &_1_;
}
int B2C_compareBCDvars(BCDvar *a, BCDvar *b) {
//Return: A_GREATER_THAN_B (1), A_EQUALS_B (0) or A_LESS_THAN_B (-1)
int expA, expB, areBothNegatives = 1, tempDigitA, tempDigitB;
//Compare sign
//If both are negatives we'll compare them then yield the opposite result
if ((*a)[0] > 0x30 && (*b)[0] > 0x30) {
areBothNegatives = -1;
}
//If a > 0 and b < 0 then a > b
if ((*a)[0] < 0x30 && (*b)[0] > 0x30) {
return A_GREATER_THAN_B;
}
//If a < 0 and b > 0 then a < b
if ((*a)[0] > 0x30 && (*b)[0] < 0x30) {
return A_LESS_THAN_B;
}
//Compare exponents
expA = getExp(a);
expB = getExp(b);
if (areBothNegatives) {
expA -= 500;
expB -= 500;
}
if (expA > expB) {
return areBothNegatives * A_GREATER_THAN_B;
} else if (expA < expB) {
return areBothNegatives * A_LESS_THAN_B;
}
//Exponents are equal ; compare digits
for (i = 0; i < 15; i++) {
tempDigitA = getDigit(a, i);
tempDigitB = getDigit(b, i);
if (tempDigitA > tempDigitB) {
return areBothNegatives * A_GREATER_THAN_B;
} else if (tempDigitA < tempDigitB) {
return areBothNegatives * A_LESS_THAN_B;
}
}
//At this point a = b
return A_EQUALS_B;
}
BCDvar *B2C_not(BCDvar *a) {
if ((*a)[1])
return &_0_;
if ((*a)[1]) return &_0_;
return &_1_;
}
BCDvar *B2C_and(BCDvar *a, BCDvar *b) {
if ((*a)[1] && (*b)[1]) return &_1_;
return &_0_;
}
BCDvar *B2C_or(BCDvar *a, BCDvar *b) {
if ((*a)[1] || (*b)[1]) return &_1_;
return &_0_;
}
BCDvar *B2C_xor(BCDvar *a, BCDvar *b) {
//Thanks stackoverflow for optimized xor function
if (!((*a)[1]) != !((*b)[1])) return &_1_;
return &_0_;
}
unsigned char* B2C_convToStr(BCDvar *nb) {
bcdToStr(nb, stringBuffer);
return stringBuffer;
}
void B2C_setListRow(unsigned int nbList, unsigned int row, BCDvar *value) {
//TODO: handle complex numbers
unsigned short nbElements = 0;
char listName[] = "0LIST\0\0";
listName[0] = getSetupEntry(SETUP_LISTFILE) + '0';
if (nbList >= 10) {
listName[5] = nbList/10 + '0';
listName[6] = nbList%10 + '0';
} else {
listName[5] = nbList + '0';
}
//Three possible cases: the list exists and the row isn't a new one, list exists and the row
//has to be added, list doesn't exist and has to be created
//First case: list has to be created
if (getItemData("main", listName, 8, 2, &nbElements)) { //most likely an error "file does not exist" - it can be another error but doing checks is time consuming
unsigned char listContent[28] = {0,0,0,0,0,0,0,0, 0,1, 0,0,0,0,0,0};
memcpy(listContent+16, value, 12);
putInternalItem(DIR_LIST, listName, 28, listContent);
} else {
//Second case: row has to be added
if (row > nbElements) {
//char str[2] = {0};
unsigned short existingListElements;
unsigned int existingListLength;
unsigned char* buffer;
getItemSize("main", listName, &existingListLength);
buffer = calloc(existingListLength+12, 1);
//Copy existing list data
getItemData("main", listName, 0, existingListLength, buffer);
//Increase number of elements
memcpy(buffer+8, &existingListElements, 2);
existingListElements++;
memcpy(&existingListElements, buffer+8, 2);
//Put the new value in the buffer
memcpy(buffer+existingListLength, value, 12);
deleteInternalItem(DIR_LIST, listName);
putInternalItem(DIR_LIST, listName, existingListLength+12, buffer);
free(buffer);
} else if (1) {
overwriteItemData("main", listName, 12, value, 4+12*row);
//DO NOT REMOVE THIS CONDITION OR ANYTHING INSIDE IT; THE DEMON INSIDE THIS FUNCTION WILL NOT APPROVE
} else {
locate(1,6);
Print("test");
locate(23,2);
Print(" ");
}
}
memcpy(list[nbList].data[row], *value, 21);
}
void B2C_setDimList(unsigned int nbList, unsigned short nbElements) {
unsigned char* content = calloc(12*nbElements+LIST_START, 1);
char listName[] = "0LIST\0\0";
listName[0] = getSetupEntry(SETUP_LISTFILE) + '0';
if (nbList >= 10) {
listName[5] = nbList/10 + '0';
listName[6] = nbList%10 + '0';
} else {
listName[5] = nbList + '0';
}
content[8] = nbElements>>8;
content[9] = nbElements&0xFF;
deleteInternalItem(DIR_LIST, listName);
putInternalItem(DIR_LIST, listName, 12*nbElements+LIST_START, content);
free(content);
list[nbList].nbElements = nbElements;
list[nbList].data = calloc(nbElements+1, sizeof(BCDvar));
}
/*
List B2C_newList(int nbElements, ...) {
List list;
va_list vaList;
list.nbElements = nbElements;
list.data = calloc(nbElements+1, sizeof(BCDvar));
va_start(vaList, nbElements);
list.data[0] = _0_;
//memcpy(list.data[0], _0_, sizeof(BCDvar));
for (i = 1; i <= nbElements; i++) {
list.data[i] = va_arg(vaList, BCDvar);
memcpy(list.data[i], va_arg(vaList, BCDvar), 21);
}
va_end(vaList);
return list;
}
*/
void B2C_setDimMat(unsigned char matrix, unsigned short y, unsigned short x) {
unsigned char* content = calloc(12*y*x + MAT_START, 1);
char matName[] = "MAT_ \0\0";
matName[4] = matrix;
memcpy(content+8, &y, 2);
memcpy(content+10, &x, 2);
deleteInternalItem(DIR_MAT, matName);
putInternalItem(DIR_MAT, matName, 12*y*x+MAT_START, content);
free(content);
mat[matrix].width = x;
mat[matrix].height = y;
mat[matrix].data = calloc((y+1)*(x+1), sizeof(BCDvar));
}
void B2C_setMat(unsigned char matrix, unsigned int y, unsigned int x, BCDvar *value) {
char matName[] = "MAT_ \0\0";
unsigned short matWidth;
matName[4] = matrix;
getItemData("main", matName, 10, 2, &matWidth);
overwriteItemData("main", matName, 12, value, MAT_START+12*((y-1)*matWidth+(x-1)));
memcpy(mat[matrix].data[mat[matrix].width*y+x], *value, 21);
}
unsigned int B2C_convToUInt(BCDvar *nb) {
unsigned int result = 0;
//gets the 3rd digit of the exponent - that means it doesn't work for Uints > 10^10
@ -336,15 +442,11 @@ void exitTimerHandler() {
KillTimer(INTERRUPTION_TIMER);
B2C_exit(NO_ERROR);
} else {
SetTimer(INTERRUPTION_TIMER, 50, exitTimerHandler);
SetTimer(INTERRUPTION_TIMER, 50, (void (*)(void))exitTimerHandler);
}
}
#endif
void B2C_exit(int exitCode) {
/*installTimer(6, (void*)&timerHandler, 1);
startTimer(6);
GetKey(&key);
uninstallTimer(6);*/
short menuCode = 0x0308;
PopUpWin(4);
@ -353,10 +455,19 @@ void B2C_exit(int exitCode) {
locate(5,3); Print((unsigned char*)"Interruption");
break;
case MEMORY_ERROR:
locate(4,3); Print((unsigned char*)"Erreur m""\xE6""\x0A""moire");
locate(4,3); Print((unsigned char*)"Erreur m\xE6""\x0A""moire");
break;
}
locate(4,5); Print((unsigned char*)"Appuyer:[EXIT]");
//This syscall could resolve internationalisation problems,
//however it seems quite buggy (for example: interrupt by pressing
//AC/on, repress this key, then try to go back to the addin; the
//popup won't be there and you won't be able to do anything). I also
//managed to crash the main menu using this syscall.
//dispErrorMessage(exitCode);
while (1) {
putMatrixCode(&menuCode);
do {
@ -365,28 +476,26 @@ void B2C_exit(int exitCode) {
}
}
BCDvar *B2C_ranInt(BCDvar *a, BCDvar *b) {
return &_1_;
/*BCDvar result;
BCDvar *B2C_ranInt(BCDvar *buffer, BCDvar *a, BCDvar *b) {
//A + Int (Ran# * (B - A + 1))
const char *function = "A""\x89""\xA6""(""\xC1""\xA9""(B""\x99""A""\x89""1))";
setAlphaVar('A', &a);
setAlphaVar('B', &b);
calcExp(&function, dummyOpCode, &result, 1);
return result;*/
setAlphaVar('A', a);
setAlphaVar('B', b);
calcExp(&function, dummyOpCode, buffer, 1);
return buffer;
}
/*
BCDvar *B2C_getAlphaVar(unsigned char var) {
getAlphaVar(var, alphaVarBuffer);
return &alphaVarBuffer;
}
*/
BCDvar *B2C_calcExp(unsigned char* exp) {
calcExp(&exp, dummyOpCode, &expressionBuffer, 1);
return &expressionBuffer;
}
void B2C_setAlphaVar(unsigned char var, BCDvar *value) {
setAlphaVar(var, *value);
void B2C_setAlphaVar(unsigned char variable, BCDvar *value) {
memcpy(var[variable], *value, 21);
}
void B2C_setStr(Str *value, int isString, int strNum) {
free(strings[strNum].data);
@ -414,7 +523,7 @@ unsigned char* B2C_strToCharArray(Str *str, int isString) {
Str *B2C_charArrayToStr(unsigned char* charArray) {
int strPos = 2;
Str *result = malloc(sizeof(Str));
result->data = calloc(strlen(charArray)+1, 2);
result->data = calloc(strlen((char*)charArray)+1, 2);
result->length = 0;
for (i = 0; charArray[i]; i++) {
if (!(strPos%2) &&

View File

@ -18,14 +18,19 @@ public class B2C {
final static boolean debugMode = true;
static String path = "C:\\Users\\Catherine\\Documents\\CASIO\\fx-9860G SDK\\TestB2C\\";
static String pathToG1M = "C:\\Users\\Catherine\\Desktop\\test.g1m";
static String mainProgramName = "TEST";
static String mainProgramName = "__uiss4_";
static String pathToG1M = "C:\\Users\\Catherine\\Desktop\\puiss4.g1m";
static boolean isRealTimeGame = true;
static boolean assureOS1Compatibility = true;
static boolean usesAcOnTimer = true;
static String main_c;
/**
* Main method of B2C.
* args[0]: path to g1m file
* args[1]: main program name
* args[2]: path to project folder
*/
public static void main(String[] args) {
if (!debugMode) {
Scanner sc = new Scanner(System.in);
@ -65,6 +70,18 @@ public class B2C {
IO.readFromRelativeFile("AddinInfo.txt").replaceAll("%PROG_NAME%", programName), true);
}
if (args.length > 0) {
pathToG1M = args[0];
if (!pathToG1M.matches(".+\\.g[12][mr]")) {
Parser.error("File provided (" + pathToG1M + ") is not of g1m type!");
}
}
if (args.length > 1) {
mainProgramName = args[1];
}
if (args.length > 2) {
path = args[2];
}
long startTime = System.currentTimeMillis();
//Add some constants for functions
@ -88,10 +105,10 @@ public class B2C {
"#include \"main.h\"\n\n" +
"unsigned int key;\n" +
"int i;\n"+
"BCDvar var[28] = {0}; //A-Z, r, theta\n"+
"BCDvar Ans;\n" +
"BCDvar var[29] = {0}; //A-Z, r, theta, Ans\n"+
"Str strings[20];\n" +
"Mat mat[26]; //Important thing: matrixes are (height, width) not (width, height)\n" +
"List list[26];\n" +
"char dummyOpCode[2] = {5, 8};\n" +
"//These are buffers for syscalls that do not return a value.\n" +
"BCDvar alphaVarBuffer;\n" +
@ -109,7 +126,7 @@ public class B2C {
"\t}\n" +
"\t#ifdef USES_INTERRUPTION_TIMER\n" +
"\t//Timer allowing AC/ON to be pressed at any moment\n" +
"\tSetTimer(INTERRUPTION_TIMER, 50, exitTimerHandler);\n" +
"\tSetTimer(INTERRUPTION_TIMER, 50, (void (*)(void))exitTimerHandler);\n" +
"\t#endif\n" +
"\tprog_"+mainProgramName+"();\n\n" +
"\tdo {\n" +
@ -177,16 +194,23 @@ public class B2C {
Syscalls.addSyscall("overwriteItemData", "830");
Syscalls.addSyscall("setSetupEntry", "4DD");
Syscalls.addSyscall("getSetupEntry", "4DC");
Syscalls.addSyscall("dispErrorMessage", "954");
Syscalls.createSyscallFile();
String[] externalLibs = {"MonochromeLib.c", "MonochromeLib.h", "memory.c", "memory.h"};
for (int i = 0; i <= 1; i++) {
IO.writeToFile(new File(path+externalLibs[i]), IO.readFromRelativeFile(externalLibs[i]), true);
}
for (char c = 'A'; c <= 'Z'; c++) {
Header.addDefine(c+" "+(int)c);
}
Header.addDefine("FALSE 0");
Header.addDefine("TRUE 1");
Header.addDefine("NO_ERROR 0");
Header.addDefine("MEMORY_ERROR 1");
Header.addDefine("A_GREATER_THAN_B 1");
Header.addDefine("A_EQUALS_B 0");
Header.addDefine("A_LESS_THAN_B -1");
Header.addDefine("NO_ERROR 1");
Header.addDefine("MEMORY_ERROR 4");
Header.addDefine("INTERRUPTION_TIMER 2");
if (usesAcOnTimer) {
Header.addDefine("USES_INTERRUPTION_TIMER");
@ -200,10 +224,15 @@ public class B2C {
Header.addDefine("LIST_START 0x10");
Header.addDefine("MAT_START 0x10");
Header.addDefine("ANS 28");
Header.addDefine("THETA 27");
Header.addDefine("RADIUS 26");
Header.addDefine("SETUP_LISTFILE 0x2E");
Header.addDefine("free_str(x) if(!isString){free(x->data); free(x);}");
Header.addDefine("getDigit(BCDvar, i) (((i)%2) ? (*(BCDvar))[((i)+1)/2+1]>>4 : (*(BCDvar))[((i)+1)/2+1]&0x0F)");
Header.addDefine("getExp(BCDvar) (((*(a))[0]>>4) * 100 + ((*(a))[0]&0x0F) * 10 + ((*(a))[1]>>4))");
Header.create();
System.out.println("Parsing done in " + (System.currentTimeMillis()-startTime) + " ms.");

View File

@ -13,7 +13,7 @@ public class Constants {
*/
public static void add(String constant) {
constant = constant.replaceAll("\\x99", "-");
System.out.println(constant);
//System.out.println(constant);
if (constant.startsWith(".")) {
constant = "0" + constant;
}
@ -38,13 +38,13 @@ public class Constants {
//Convert integer to scientific notation using StackOverflow magic
//First number apparently means the number of significant digits (including exponent)
//Second number is the number of digits after the decimal point (not including exponent)
System.out.println(constant);
//System.out.println(constant);
String sciNotation = String.format("%18.14e", Double.valueOf(constant.replaceAll("\\.", ""))).replace(",", ".");
String mantissa = sciNotation.substring(0, sciNotation.indexOf("e")).replaceAll("\\.", "");
System.out.println(mantissa);
//System.out.println(mantissa);
exponent += Integer.valueOf(sciNotation.substring(sciNotation.indexOf('e')+1));
//Can't use Integer.valueOf(mantissa) because it might be over 2^32
@ -57,11 +57,11 @@ public class Constants {
if (bcdNotation.contains(".") || bcdNotation.contains("-") || bcdNotation.length() != 18) {
Parser.error("Error in BCD conversion of " + constant + " which gave " + bcdNotation);
}
System.out.println("Result= "+bcdNotation);
//System.out.println("Result= "+bcdNotation);
//Replace groups of 2 digits by "0x##, " and remove the last comma+space
System.out.println(bcdNotation);
//System.out.println(bcdNotation);
bcdNotation = bcdNotation.replaceAll("(.{2})", "0x$1, ").replaceAll(", $", "");
System.out.println(bcdNotation);
//System.out.println(bcdNotation);
Header.addGlobal("const BCDvar " + Constants.getVarNotation(constant) + " = {" + bcdNotation + "};\n");
}

View File

@ -29,12 +29,12 @@ public class Header {
headerDefines + "\n\n" +
"typedef unsigned char BCDvar[24]; //this defines BCDvar as an array of 24 unsigned chars\n" +
"typedef struct {\n" +
"\t//int nbElements;\n" +
"\tint nbElements;\n" +
"\tBCDvar *data;\n" +
"} List;\n\n" +
"typedef struct {\n" +
"\t//int width;\n" +
"\t//int height;\n" +
"\tint width;\n" +
"\tint height;\n" +
"\tBCDvar *data;\n" +
"} Mat;\n\n" +
//"typedef unsigned short Fontchar;\n" +

46
B2C/src/b2c/Operator.java Normal file
View File

@ -0,0 +1,46 @@
package b2c;
public class Operator {
private String casioChar, asciiFunction;
private int precedence, nbOperands;
public Operator(int nbOperands, String casioChar, String asciiFunction, int precedence) {
this.nbOperands = nbOperands;
this.casioChar = casioChar;
this.asciiFunction = asciiFunction;
this.precedence = precedence;
}
public String getCasioChar() {
return casioChar;
}
public void setCasioChar(String casioChar) {
this.casioChar = casioChar;
}
public String getAsciiFunction() {
return asciiFunction;
}
public void setAsciiFunction(String asciiFunction) {
this.asciiFunction = asciiFunction;
}
public int getPrecedence() {
return precedence;
}
public void setPrecedence(int precedence) {
this.precedence = precedence;
}
public int getNbOperands() {
return nbOperands;
}
public void setNbOperands(int nbOperands) {
this.nbOperands = nbOperands;
}
}

View File

@ -0,0 +1,37 @@
package b2c;
import java.util.ArrayList;
public class Operators {
public static int maxPrecedence = 6;
//Not sure if the precedence of xor/or is equal or not
//Pretty sure about all other precedences; feel free to test
//All seem to be left-to-right
public static Operator[][] operators = {{
new Operator(1, new String(new char[]{0x7F, 0xB3}), "B2C_not", 0),
},{
new Operator(2, new String(new char[]{0xA8}), "B2C_pow", 1),
new Operator(2, new String(new char[]{0x86}), "B2C_sqrt", 1),
},{
new Operator(2, new String(new char[]{0xA9}), "B2C_mult", 2),
new Operator(2, new String(new char[]{0xB9}), "B2C_div", 2),
},{
new Operator(2, new String(new char[]{0x89}), "B2C_add", 3),
new Operator(2, new String(new char[]{0x99}), "B2C_sub", 3),
},{
new Operator(2, new String(new char[]{0x10}), "B2C_lessOrEqualThan", 4),
new Operator(2, new String(new char[]{0x12}), "B2C_greaterOrEqualThan", 4),
new Operator(2, "<", "B2C_lessThan", 4),
new Operator(2, ">", "B2C_greaterThan", 4),
new Operator(2, "=", "B2C_equalTo", 4),
new Operator(2, new String(new char[]{0x11}), "B2C_notEqualTo", 4),
},{
new Operator(2, new String(new char[]{0x7F, 0xB0}), "B2C_and", 5),
},{
new Operator(2, new String(new char[]{0x7F, 0xB1}), "B2C_or", 6),
new Operator(2, new String(new char[]{0x7F, 0xB4}), "B2C_xor", 6),
}};
}

View File

@ -86,7 +86,7 @@ public class Parser {
//So List (0x7F51) is above Lbl (0xE2) which is above If (0xF700). (again, exception of => which is after IfEnd)
//RanInt#(
/*if (content.startsWith(new String(new char[]{0x7F,0x87}))) {
if (content.startsWith(new String(new char[]{0x7F,0x87}))) {
if (content.charAt(content.length()-1) == ')') {
content = content.substring(0, content.length()-1);
}
@ -94,10 +94,10 @@ public class Parser {
if (args.length != 1) {
error("RanInt# method doesn't have 2 arguments!");
}
return supportAns("B2C_ranInt(" + parse(content.substring(2, args[0]), CONV_TO_BCD) + ","
return supportAns("B2C_ranInt(" + addBuffer() + ", " + parse(content.substring(2, args[0]), CONV_TO_BCD) + ","
+ parse(content.substring(args[0]+1), CONV_TO_BCD) + ")", option);
}*/
}
//Getkey
if (content.startsWith(new String(new char[]{0x7F,0x8F}))) {
@ -211,7 +211,7 @@ public class Parser {
int assignmentPosition = content.indexOf((char)0x0E);
//Checks for "Step"
int stepPosition = content.indexOf(new String(new char[]{0xF7, 0x06}));
String variable = replaceNonAscii(content.substring(assignmentPosition+1, toPosition));
String variable = content.substring(assignmentPosition+1, toPosition);
System.out.println("Parsing a For instruction. Position of To is "+toPosition+
", position of -> is "+assignmentPosition+", position of Step is "+stepPosition+
", variable is: "+variable);
@ -232,22 +232,22 @@ public class Parser {
incrementTabs();
String result = "for (";
//variable = beginning;
result += parse(content.substring(2, toPosition)) + ";";
result += parse(content.substring(2, toPosition), CONV_TO_BCD) + "; ";
//TODO: parse the step as an integer to know if it is <0 or >0
//also put the break condition in the for
if (stepPosition >= 0) {
//step < 0 && var >= limit || step > 0 && var <= limit; variable = variable + step) {
String step = replaceNonAscii(content.substring(stepPosition+2));
String step = content.substring(stepPosition+2);
System.out.println("Step = " + step);
String limit = replaceNonAscii(content.substring(toPosition+2, stepPosition));
result += " (*B2C_calcExp((unsigned char*)\""+step+"<0\\x7F\"\"\\xB0\"\""+variable+"\\x12\"\""+limit+"\\x7F\"\"\\xB1\"\""+step+">0\\x7F\"\"\\xB0\"\""+variable+"\\x10\"\""+limit+"\"))[1]" + "; "
+ parse(variable+(char)0x89+step+(char)0x0E+variable) + ") {";
String limit = parse(content.substring(toPosition+2, stepPosition), CONV_TO_BCD);
result += "(*" + parse(step+"<0"+(char)0x7F+(char)0xB0+variable+(char)0x12+limit+(char)0x7F+(char)0xB1+step+">0"+(char)0x7F+(char)0xB0+variable+(char)0x10+limit, CONV_TO_BCD)+")[1]" + "; "
+ parse(variable+(char)0x89+step+(char)0x0E+variable, CONV_TO_BCD) + ") {";
//+ "\n" + tabs + "if ((*B2C_calcExp((unsigned char*)\""+step+"<0\\x7F\"\"\\xB0\"\""+variable+"<"+limit+"\\x7F\"\"\\xB1\"\""+step+">0\\x7F\"\"\\xB0\"\""+variable+">"+limit+"\"))[1]) break;";
} else {
//variable <= limit; variable = variable + 1) {"
result += " (*B2C_calcExp((unsigned char*)\"" + variable + "\\x10\"\"" + replaceNonAscii(content.substring(toPosition+2)) + "\"))[1]; "
+ parse(variable + (char)0x89 + "1" + (char)0x0E + variable) + ") {";
result += "(*" + parse(variable + (char)0x10 + content.substring(toPosition+2), CONV_TO_BCD) + ")[1]; "
+ parse(variable + (char)0x89 + "1" + (char)0x0E + variable, CONV_TO_BCD) + ") {";
}
return result;
@ -353,7 +353,7 @@ public class Parser {
System.out.println("Parsing a Dim assignment.");
if (content.substring(matchResult+3).startsWith(new String(new char[]{0x7F, 0x40}))) { //followed by Mat
String result = "B2C_setDimMat('" + content.charAt(matchResult+5) + "', ";
String result = "B2C_setDimMat(" + (content.charAt(matchResult+5)-'A') + ", ";
if (content.startsWith(new String(new char[]{0x7F, 0x51}))) {
result += handleIntConversion(parse(content.substring(0, matchResult) + "[1]")) + ", ";
result += handleIntConversion(parse(content.substring(0, matchResult) + "[2]")) + ");";
@ -385,7 +385,7 @@ public class Parser {
} else if (content.substring(matchResult+1).matches("[A-Z]~[A-Z]")) {
String assignment = parse(content.substring(0, matchResult), CONV_TO_BCD);
incrementTabs();
String result = "for (i = '"+content.charAt(matchResult+1)+"'; i <= '"+content.charAt(matchResult+3)+"'; i++) {\n"+tabs+"B2C_setAlphaVar(i, "+assignment+");\n";
String result = "for (i = "+getAlphaVar(content.charAt(matchResult+1))+"; i <= "+getAlphaVar(content.charAt(matchResult+3))+"; i++) {\n"+tabs+"B2C_setAlphaVar(i, "+assignment+");\n";
decrementTabs();
return result + tabs + "}";
@ -416,7 +416,7 @@ public class Parser {
if (check.length != 1) {
error("Mat instruction does not have one comma!");
}
String result = "B2C_setMat('" + content.charAt(matchResult+3) + "', " +
String result = "B2C_setMat(" + (content.charAt(matchResult+3)-'A') + ", " +
handleIntConversion(content.substring(matchResult+5, matchResult+5+check[0])) + ", " +
handleIntConversion(content.substring(matchResult+5+check[0]+1, content.length()-1)) + ", " +
parse(content.substring(0, matchResult), CONV_TO_BCD) + ");";
@ -436,14 +436,9 @@ public class Parser {
}*/
//Check for variable assignment
} else if (content.substring(matchResult+1).matches("[A-Z\\xCD\\xCE\\xC0]")) {
String result = "B2C_setAlphaVar('";
if (content.charAt(matchResult+1) >= 'A' && content.charAt(matchResult+1) <= 'Z') {
result += content.charAt(matchResult+1);
} else {
result += "\\x" + Integer.toHexString(content.charAt(matchResult+1));
}
result += "', " + parse(content.substring(0, matchResult), CONV_TO_BCD) + ")";
} else if (content.substring(matchResult+1).matches("[A-Z\\xCD\\xCE]")) {
String result = "B2C_setAlphaVar(" + getAlphaVar(content.charAt(matchResult+1))
+ ", " + parse(content.substring(0, matchResult), CONV_TO_BCD) + ")";
if (option == WHOLE_INSTRUCTION) {
result += ";";
}
@ -468,9 +463,11 @@ public class Parser {
if (arg.length != 1) {
error("matrix coordinates are fewer or more than two!");
} else {
return supportAns("mat[" + (content.charAt(2)-'A') + "].data[mat[" + (content.charAt(2)-'A') + "].width*("
+ handleIntConversion(parse(content.substring(check[0]+1, check[0]+1+arg[0]))) + ")+("
+ handleIntConversion(parse(content.substring(check[0]+2+arg[0],content.length()-1))) + ")]", option);
return supportAns("&mat[" + (content.charAt(2)-'A') + "].data[mat[" + (content.charAt(2)-'A') + "].width*("
/*+ handleIntConversion(parse(content.substring(check[0]+1, check[0]+1+arg[0]))) + ")+("
+ handleIntConversion(parse(content.substring(check[0]+2+arg[0],content.length()-1))) + ")]", option);*/
+ handleIntConversion(content.substring(check[0]+1, check[0]+1+arg[0])) + ")+("
+ handleIntConversion(content.substring(check[0]+2+arg[0],content.length()-1)) + ")]", option);
}
}
@ -501,100 +498,45 @@ public class Parser {
}
//searches for an operator
String[] operators = {
new String(new char[]{0x7F, 0xB0}), //And
new String(new char[]{0x7F, 0xB1}), //Or
new String(new char[]{0x7F, 0xB4}), //Xor
new String(new char[]{0x10}), //<=
new String(new char[]{0x11}), //!=
new String(new char[]{0x12}), //>=
"=",
"<",
">",
new String(new char[]{0xA8}), // ^
new String(new char[]{0xA9}), // *
new String(new char[]{0xB9}), // /
new String(new char[]{0x89}), // +
new String(new char[]{0x99}), // -
new String(new char[]{0x7F, 0xB3}) //Not
};
for (int i = 0; i < operators.length; i++) {
for (int j = 0; j < content.length(); j++) {
if (content.startsWith(operators[i], j)) {
//test if the operator is not within parentheses
boolean isInParentheses = false;
for (int k = 0; k < parenthesesPos.length; k+=2) {
if (j >= parenthesesPos[k] && j <= parenthesesPos[k+1]) {
isInParentheses = true;
for (int h = Operators.maxPrecedence; h >= 0; h--) {
for (int j = content.length()-1; j >= 0; j--) {
for (int i = 0; i < Operators.operators[h].length; i++) {
//System.out.println("Checking for operator " + Operators.operators[h][i].getAsciiFunction() + "(i="+i+", j="+j+", h="+h+")");
if (content.substring(0, j).endsWith(Operators.operators[h][i].getCasioChar())) {
//test if the operator is not within parentheses
boolean isInParentheses = false;
for (int k = 0; k < parenthesesPos.length; k+=2) {
if (j >= parenthesesPos[k] && j <= parenthesesPos[k+1]) {
isInParentheses = true;
}
}
System.out.println("Parsing operator: " + Operators.operators[h][i].getAsciiFunction());
//If the operator is at the beginning of the string, it isn't a binary operator
if (!isInParentheses && (j != 0 && Operators.operators[h][i].getNbOperands() != 1)) {
String str = "";
str += Operators.operators[h][i].getAsciiFunction() + "(";
//If it is a mathematical operation (pow, mult, div, add, sub, sqrt)
if (str.startsWith("B2C_pow(") || str.startsWith("B2C_sqrt(") || str.startsWith("B2C_mult(") ||
str.startsWith("B2C_div(") || str.startsWith("B2C_add(") || str.startsWith("B2C_sub(")) {
str += addBuffer() + ", ";
}
if (!str.startsWith("B2C_not(")) {
str += parse(content.substring(0, j-Operators.operators[h][i].getCasioChar().length()), CONV_TO_BCD) + ", " + parse(content.substring(j), CONV_TO_BCD) + ")";
} else {
str += "B2C_not(" + parse(content.substring(2)) + ")";
}
if (option == WHOLE_INSTRUCTION) {
str += ";";
}
return str;
}
}
//If the operator is at the beginning of the string, it isn't a binary operator
if (!isInParentheses && j != 0) {
String str = "";
switch(i) {
case 0:
str = "B2C_and(";
break;
case 1:
str = "B2C_or(";
break;
case 2:
str = "B2C_xor(";
break;
case 3:
str = "B2C_lessOrEqualThan(";
break;
case 4:
str = "B2C_notEqualTo(";
break;
case 5:
str = "B2C_greaterOrEqualThan(";
break;
case 6:
str = "B2C_equalTo(";
break;
case 7:
str = "B2C_lessThan(";
break;
case 8:
str = "B2C_greaterThan(";
break;
case 9: // ^
str = "B2C_pow(";
break;
case 10: // *
str = "B2C_mult(";
break;
case 11: // /
str = "B2C_div(";
break;
case 12: // +
str = "B2C_add(";
break;
case 13: // -
str = "B2C_sub(";
break;
}
str += "&buffer" + nbBuffers + ", ";
nbBuffers++;
if (i <= 2) {
str += parse(content.substring(0, j), CONV_TO_BCD) + ", " + parse(content.substring(j+2), CONV_TO_BCD) + ")";
} else if (i < 14){
str += parse(content.substring(0, j), CONV_TO_BCD) + ", " + parse(content.substring(j+1), CONV_TO_BCD) + ")";
} else {
str += "B2C_not(" + parse(content.substring(2)) + ")";
} if (option == WHOLE_INSTRUCTION) {
str += ";";
}
return str;
}
}
if (isMultibytePrefix(content.charAt(j))) {
j++;
/*if (isMultibytePrefix(content.charAt(j))) {
j++;
}*/
}
}
}
@ -606,20 +548,7 @@ public class Parser {
//replace variables with their position in the var[] array; only do this if the string only contains the variable
if (content.length() == 1 && !content.matches("^\\d")) {
String result = "";
if (content.charAt(0) >= 'A' && content.charAt(0) <= 'Z') {
result += "var[" + (int)(content.charAt(0)-65) + "]";
}
if (content.charAt(0) == (char)0xC0) {
result += "Ans";
}
if (content.charAt(0) == (char)0xCD) { //r
result += "var[26]";
}
if (content.charAt(0) == (char)0xCE) { //theta
result += "var[27]";
}
String result = "&var[" + getAlphaVar(content) + "]";
return supportAns(result, option);
}
@ -991,7 +920,7 @@ public class Parser {
public static String supportAns(String content, int option) {
if (option == WHOLE_INSTRUCTION)
return "B2C_setAlphaVar('\\xC0', " + content + ");";
return "B2C_setAlphaVar("+getAlphaVar((char)0xC0)+", " + content + ");";
return content;
}
@ -1005,14 +934,9 @@ public class Parser {
}
public static String handleAlphaVar(String content, int option) {
//Handle var such that var[char-'A'] gives the correct variable
if (content.matches("[A-Z\\xCD\\xCE\\xC0]")) {
String result = "B2C_getAlphaVar('";
if (content.charAt(0) >= 'A' && content.charAt(0) <= 'Z') {
result += content;
} else {
result += "\\x" + Integer.toHexString(content.charAt(0));
}
result += "')";
String result = "&var[" + getAlphaVar(content) + "]";
return supportAns(result, option);
}
return parse(content, option);
@ -1025,6 +949,30 @@ public class Parser {
tabs = tabs.substring(0, tabs.length()-1);
}
public static String getAlphaVar(char var) {return getAlphaVar(""+var);}
public static String getAlphaVar(String var) {
if (var.length() != 1) {
error("Unknown var!");
} else if (var.charAt(0) >= 'A' && var.charAt(0) <= 'Z') {
return var;
} else if (var.charAt(0) == 0xCD) {
return "RADIUS";
} else if (var.charAt(0) == 0xCE) {
return "THETA";
} else if (var.charAt(0) == 0xC0) {
return "ANS";
}
error("Unknown var!");
return "";
}
public static String addBuffer() {
String result = "&buffer" + nbBuffers;
nbBuffers++;
return result;
}
public static void error(String error) {
System.out.println("\n===ERROR: "+error+"===\n");
System.exit(0);