Skip to content
This repository was archived by the owner on Jan 26, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ script:
- curl -s https://tiplanet.org/scripts/travis/$ROM_FILE_NAME 2>/dev/null > $ROM_FILE_NAME
- export AUTOTESTER_ROM=$(pwd)/$ROM_FILE_NAME
# Test tests
- RESULT=0; for f in tests/*/*.json; do echo "Launching autotester on $f"; autotester "$f"; RESULT=`expr $RESULT + $?`; done; return $RESULT
- RESULT=0; for f in tests/*/*.json; do echo "Launching autotester on $f"; autotester -d "$f"; RESULT=`expr $RESULT + $?`; done; return $RESULT

notifications:
irc:
Expand Down
2 changes: 1 addition & 1 deletion hooks
Submodule hooks updated 2 files
+0 −1 .gitignore
+2 −155 hooks.asm
17 changes: 17 additions & 0 deletions src/asm/randint.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.assume adl = 1
segment data
.def _RandintData

_RandintData:
ex de, hl
push de
or a, a
sbc hl, de
inc hl
push hl
call 0
pop bc
call 0000144h
pop de
add hl, de
ret
22 changes: 22 additions & 0 deletions src/asm/tostring.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.assume adl = 1
segment data
.def _TostringData

_TostringData:
ld de, 0
ld bc, 0
DivideLoop:
ld a, 10
call 0021D90h ; _DivHLByA
dec de
inc bc
add hl, de
add a, '0'
ld (de), a
sbc hl, de
jr nz, DivideLoop
ex de, hl
ret

TempStringData:
.db 0, 0, 0, 0, 0, 0, 0, 0
187 changes: 178 additions & 9 deletions src/ast.c
Original file line number Diff line number Diff line change
@@ -1,48 +1,156 @@
#include "defines.h"
#include "parse.h"
#include "ast.h"

#include "operator.h"
#include "main.h"
#include "functions.h"
#include "errors.h"
#include "stack.h"
#include "output.h"
#include "routines.h"
#include "prescan.h"

NODE *push2(NODE *top, element_t data) {
extern const function_t implementedFunctions[AMOUNT_OF_FUNCTIONS];

#ifndef NDEBUG
void printNodeRecursively(NODE *top, uint8_t depth) {
if (top != NULL) {
uint8_t a;

for (a = 0; a < depth; a++) {
dbg_sprintf(dbgout, " ");
}
dbg_sprintf(dbgout, "Type = %d, operand = $%06X\n", top->data.type, top->data.operand.num);
if (top->child != NULL) {
for (a = 0; a < depth; a++) {
dbg_sprintf(dbgout, " ");
}
dbg_sprintf(dbgout, "Data:\n");
}
printNodeRecursively(top->child, depth + 2);
if (top->sibling != NULL) {
for (a = 0; a < depth; a++) {
dbg_sprintf(dbgout, " ");
}
dbg_sprintf(dbgout, "Sibling:\n");
top = top->sibling;
printNodeRecursively(top, depth);
}
}
}
#endif

NODE *push(NODE *top, element_t data) {
NODE *tempNode = (NODE*)calloc(1, sizeof(NODE));

tempNode->data = data;
tempNode->prev = top;
top->sibling = tempNode;
if (top != NULL) {
top->sibling = tempNode;
}

return tempNode;
}

NODE *pop(NODE *top, element_t *data) {
NODE *tmp = top;

*data = top->data;
top = top->prev;
free(tmp);

return top;
}

NODE *insertData(NODE *top, element_t data, uint8_t index) {
NODE *tempNode = (NODE*)calloc(1, sizeof(NODE));
uint8_t temp;

tempNode->data = data;
for (temp = 1; temp < index; temp++) {
top = top->prev;

if (top == NULL) {
if ((top = top->prev) == NULL) {
return NULL;
}
}
if (top == NULL) {
return NULL;
}
top->prev->sibling = tempNode;
if (top->prev != NULL) {
top->prev->sibling = tempNode;
}
tempNode->child = top;
tempNode->prev = top->prev;

return tempNode;
}

NODE *parseNode(NODE *top) {
return NULL;
NODE *stackToOutput(NODE *outputNode, NODE **stackNode) {
element_t tempElement;

while (*stackNode != NULL) {
uint8_t amountOfArgs = 2;

*stackNode = pop(*stackNode, &tempElement);
if (tempElement.type == TYPE_FUNCTION) {
uint8_t argsShouldHave = implementedFunctions[tempElement.operand.func.index].amountOfArgs;
uint8_t function = tempElement.operand.func.function;

amountOfArgs = tempElement.operand.func.amountOfArgs;
if (argsShouldHave != 255 && argsShouldHave != amountOfArgs) {
return NULL;
}

// Hack for L1(..)
if (function == 0x0F) {
tempElement.operand.func.function = tLBrace;
}

// Ignore parenthesis function
if (function == tLParen) {
continue;
}
}
if ((outputNode = insertData(outputNode, tempElement, amountOfArgs)) == NULL) {
return NULL;
}
}
*stackNode = NULL;

return outputNode;
}

uint8_t parseNode(NODE *top) {
uint8_t type = top->data.type, res = VALID;
uint24_t operand = top->data.operand.num;

if (top == NULL) {
return E_SYNTAX;
}

expr.outputReturnRegister = REGISTER_HL;

if (type <= TYPE_STRING) {
if (type != TYPE_STRING) {
expr.outputIsNumber = true;
expr.outputNumber = operand;
}
LD_HL_IMM(operand, type);
} else if (type == TYPE_VARIABLE) {
expr.outputIsVariable = true;
OutputWriteWord(0x27DD);
OutputWriteByte(operand);
reg.HLIsNumber = false;
reg.HLIsVariable = true;
reg.HLVariable = operand;
} else if (type == TYPE_OPERATOR) {
res = parseOperator(top);
} else if (type == TYPE_FUNCTION) {
res = parseFunction(top);
} else {
res = E_SYNTAX;
}

return res;
}

NODE *reverseNode(NODE *top) {
Expand All @@ -59,4 +167,65 @@ NODE *reverseNode(NODE *top) {
}

return prev;
}

NODE *optimizeNode(NODE *top) {
if (top != NULL) {
// Optimize child and siblings
top->child = optimizeNode(top->child);
top->sibling = optimizeNode(top->sibling);

// Optimize extra parenthesis with a number in it
if (top->data.type == TYPE_FUNCTION && top->data.operand.func.function == tLParen && top->child->data.type == TYPE_NUMBER) {
top->data.operand.num = top->child->data.operand.num;
top->data.type = TYPE_NUMBER;
free(top->child);
top->child = NULL;
}

// Optimize operator with 2 numbers as arguments
if (top->data.type == TYPE_OPERATOR && top->data.operand.op.op != tStore &&
top->child->data.type == TYPE_NUMBER && top->child->sibling->data.type == TYPE_NUMBER &&
!top->child->data.isString && !top->child->sibling->data.isString) {
top->data.operand.num = executeOperator(top);
top->data.type = TYPE_NUMBER;
free(top->child->sibling);
free(top->child);
top->child = NULL;
}

// Optimize function with only numbers as arguments
if (top->data.type == TYPE_FUNCTION && implementedFunctions[top->data.operand.func.index].numbersArgs) {
NODE *child = top->child;
uint8_t loop;
uint8_t function = top->data.operand.func.function;
uint8_t function2 = top->data.operand.func.function2;

for (loop = 0; loop < top->data.operand.func.amountOfArgs; loop++) {
if (child == NULL || child->data.type != TYPE_NUMBER) {
goto doNotDeleteFunction;
}
child = child->sibling;
}
top->data.operand.num = executeFunction(top);
top->data.type = TYPE_NUMBER;
freeNode(top->child);
top->child = NULL;
doNotDeleteFunction:;
}
}

return top;
}

void freeNode(NODE *top) {
if (top->sibling != NULL) {
freeNode(top->sibling);
}
if (top->child != NULL) {
freeNode(top->child);
}
if (top != NULL) {
free(top);
}
}
20 changes: 15 additions & 5 deletions src/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@

typedef uint24_t num_t;
typedef uint8_t vari_t;
typedef uint8_t op_t;

typedef struct {
uint8_t op;
uint8_t precedence;
uint8_t index;
} op_t;

typedef struct {
uint8_t function;
uint8_t amountOfArgs;
uint8_t function2;
uint8_t amountOfArgs;
uint8_t index;
} func_t;

typedef union {
Expand All @@ -21,7 +27,6 @@ typedef union {
typedef struct {
uint8_t isString;
uint8_t type;
uint8_t mask;
operand_t operand;
} element_t;

Expand All @@ -32,9 +37,14 @@ typedef struct node {
struct node *sibling;
} NODE;

NODE *push2(NODE*, element_t);
void printNodeRecursively(NODE*, uint8_t);
NODE *push(NODE*, element_t);
NODE *pop(NODE *top, element_t*);
NODE *insertData(NODE*, element_t, uint8_t);
NODE *parseNode(NODE*);
NODE *stackToOutput(NODE*, NODE**);
uint8_t parseNode(NODE*);
NODE *reverseNode(NODE*);
NODE *optimizeNode(NODE*);
void freeNode(NODE*);

#endif
16 changes: 11 additions & 5 deletions src/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ const uint8_t RandData[] = {
0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01
};
unsigned int rand_bin_len = 118;
const uint8_t RandintData[] = {
0xeb, 0xd5, 0xb7, 0xed, 0x52, 0x23, 0xe5, 0xcd, 0x00, 0x00, 0x00, 0xc1,
0xcd, 0x44, 0x01, 0x00, 0xd1, 0x19, 0xc9
};
unsigned int randint_bin_len = 19;
const uint8_t SincosData[] = {
0x7d, 0xc6, 0x40, 0x6f, 0x7d, 0x47, 0xe6, 0x3f, 0xcb, 0x70, 0x28, 0x03,
0xc6, 0xbf, 0x2f, 0x11, 0x00, 0x00, 0x00, 0xed, 0x62, 0x6f, 0xeb, 0x19,
Expand All @@ -114,16 +119,17 @@ const uint8_t SqrtData[] = {
0x29, 0x17, 0xed, 0x6a, 0x10, 0xe7, 0xc9
};
unsigned int sqrt_bin_len = 43;
const uint8_t SrandData[] = {
0xaf, 0x22, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x77, 0x06, 0x0c,
0x23, 0x70, 0x10, 0xfc, 0xc9
};
unsigned int srand_bin_len = 17;
const uint8_t TimerData[] = {
0x21, 0x31, 0x00, 0xf2, 0xcb, 0xce, 0x2b, 0xcb, 0xce, 0xcb, 0xc6, 0x6c,
0xed, 0x27, 0xc9
};
unsigned int timer_bin_len = 15;
const uint8_t TostringData[] = {
0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x0a, 0xcd, 0x90,
0x1d, 0x02, 0x1b, 0x03, 0x19, 0xc6, 0x30, 0x12, 0xed, 0x52, 0x20, 0xf0,
0xeb, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned int tostring_bin_len = 34;
const uint8_t XorData[] = {
0x01, 0xff, 0xff, 0xff, 0x09, 0x9f, 0xeb, 0x09, 0x99, 0x81, 0xed, 0x62,
0x23
Expand Down
3 changes: 1 addition & 2 deletions src/errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include "errors.h"

#include "ast.h"
#include "stack.h"
#include "parse.h"
#include "main.h"
#include "output.h"
Expand All @@ -20,7 +19,7 @@ static const char *errors[] = {
"This token doesn't have a condition",
"You used 'Else' outside an If-statement",
"You used 'End' outside a condition block",
"You have an invalid \")\", \",\", \"(\", \")\", \"}\" or \"]\"",
"You have an invalid ')' ',' or '}'",
"You have an invalid expression",
"Your icon should start with a quote",
"Invalid hexadecimal",
Expand Down
Loading