Added optimisation levels

This commit is contained in:
2022-08-06 05:59:29 +01:00
parent 577d1965cb
commit 6b33895f75
6 changed files with 35 additions and 65 deletions

View File

@@ -6,50 +6,3 @@ print 42;
print 3.14; print 3.14;
print -69; print -69;
print -4.20; print -4.20;
print "hello world";
print "hello world";
print "hello world";
print "hello world";
print null;
print true;
print false;
print 42;
print 3.14;
print -69;
print -4.20;
print "hello world";
print "hello world";
print "hello world";
print "hello world";
print null;
print true;
print false;
print 42;
print 3.14;
print -69;
print -4.20;
print "hello world";
print "hello world";
print "hello world";
print "hello world";
print null;
print true;
print false;
print 42;
print 3.14;
print -69;
print -4.20;
print "hello world";
print "hello world";
print "hello world";
print "hello world";
print null;
print true;
print false;
print 42;
print 3.14;
print -69;
print -4.20;
print "hello world";
print "hello world";
print "hello world";

View File

@@ -20,6 +20,7 @@ void initCommand(int argc, const char* argv[]) {
command.filename = NULL; command.filename = NULL;
command.source = NULL; command.source = NULL;
command.verbose = false; command.verbose = false;
command.optimize = 1;
for (int i = 1; i < argc; i++) { //start at 1 to skip the program name for (int i = 1; i < argc; i++) { //start at 1 to skip the program name
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
@@ -49,6 +50,11 @@ void initCommand(int argc, const char* argv[]) {
continue; continue;
} }
if (!strncmp(argv[i], "-O", 2)) {
sscanf(argv[i], "-O%d", &command.optimize);
continue;
}
command.error = true; command.error = true;
} }
@@ -59,7 +65,7 @@ void initCommand(int argc, const char* argv[]) {
} }
void usageCommand(int argc, const char* argv[]) { void usageCommand(int argc, const char* argv[]) {
printf("Usage: %s [-h | -v | [-d][-f filename | -i source]]\n\n", argv[0]); printf("Usage: %s [-h | -v | [-OX][-d][-f filename | -i source]]\n\n", argv[0]);
} }
void helpCommand(int argc, const char* argv[]) { void helpCommand(int argc, const char* argv[]) {
@@ -70,6 +76,7 @@ void helpCommand(int argc, const char* argv[]) {
printf("-f | --file filename\tParse and execute the source file.\n"); printf("-f | --file filename\tParse and execute the source file.\n");
printf("-i | --input source\tParse and execute this given string of source code.\n"); printf("-i | --input source\tParse and execute this given string of source code.\n");
printf("-d | --debug\t\tBe verbose when operating.\n"); printf("-d | --debug\t\tBe verbose when operating.\n");
printf("-OX\t\t\tUse level X optimization (default 1)\n");
} }
void copyrightCommand(int argc, const char* argv[]) { void copyrightCommand(int argc, const char* argv[]) {
@@ -194,7 +201,7 @@ void dissectBytecode(const char* tb, int size) {
switch (opcode) { switch (opcode) {
case OP_PRINT: case OP_PRINT:
printf("print:\n"); printf("print\n");
break; break;
case OP_LITERAL: { case OP_LITERAL: {

View File

@@ -10,6 +10,7 @@ typedef struct {
char* filename; char* filename;
char* source; char* source;
bool verbose; bool verbose;
int optimize;
} Command; } Command;
extern Command command; extern Command command;

View File

@@ -46,7 +46,7 @@ void printNode(Node* node) {
printf("literal:"); printf("literal:");
printLiteral(node->atomic.literal); printLiteral(node->atomic.literal);
break; break;
case NODE_UNARY: case NODE_UNARY:
printf("unary:"); printf("unary:");
printNode(node->unary.child); printNode(node->unary.child);

View File

@@ -7,6 +7,7 @@
typedef union _node Node; typedef union _node Node;
typedef enum NodeType { typedef enum NodeType {
NODE_ERROR,
NODE_LITERAL, //a simple value NODE_LITERAL, //a simple value
NODE_UNARY, //one child NODE_UNARY, //one child
NODE_BINARY, //two children, left and right NODE_BINARY, //two children, left and right

View File

@@ -1,4 +1,6 @@
#include "parser.h" #include "parser.h"
#include "debug.h"
#include "common.h" #include "common.h"
#include "memory.h" #include "memory.h"
@@ -134,29 +136,36 @@ static void unary(Parser* parser, Node** nodeHandle, bool canBeAssigned) {
case TOKEN_MINUS: { case TOKEN_MINUS: {
//temp handle to potentially negate values //temp handle to potentially negate values
Node* tmpNode = NULL; Node* tmpNode = NULL;
parsePrecedence(parser, &tmpNode, PREC_TERNARY); parsePrecedence(parser, &tmpNode, PREC_TERNARY); //can be a literal
//check for literals //check for negative literals (optimisation)
if (tmpNode->type == NODE_LITERAL) { if (command.optimize >= 1 && tmpNode->type == NODE_LITERAL) {
//negate directly, if int or float //negate directly, if int or float
Literal lit = tmpNode->atomic.literal; Literal lit = tmpNode->atomic.literal;
if (IS_INTEGER(lit)) { if (IS_INTEGER(lit)) {
lit = TO_INTEGER_LITERAL( -AS_INTEGER(lit) ); lit = TO_INTEGER_LITERAL(-AS_INTEGER(lit));
} }
if (IS_FLOAT(lit)) { if (IS_FLOAT(lit)) {
lit = TO_FLOAT_LITERAL( -AS_FLOAT(lit) ); lit = TO_FLOAT_LITERAL(-AS_FLOAT(lit));
} }
tmpNode->atomic.literal = lit; tmpNode->atomic.literal = lit;
*nodeHandle = tmpNode; *nodeHandle = tmpNode;
break;
} }
else {
//process normally //process the literal without optimizations
if (tmpNode->type == NODE_LITERAL) {
emitNodeUnary(nodeHandle, OP_NEGATE); emitNodeUnary(nodeHandle, OP_NEGATE);
parsePrecedence(parser, nodeHandle, PREC_TERNARY); nodeHandle = &((*nodeHandle)->unary.child); //re-align after append
(*nodeHandle) = tmpNode; //set negate's child to the literal
break;
} }
error(parser, parser->previous, "Unexpected token passed to unary minus precedence rule");
} }
break; break;
@@ -200,7 +209,7 @@ static void atomic(Parser* parser, Node** nodeHandle, bool canBeAssigned) {
ParseRule parseRules[] = { //must match the token types ParseRule parseRules[] = { //must match the token types
//types //types
{atomic, NULL, PREC_NONE},// TOKEN_NULL, {atomic, NULL, PREC_PRIMARY},// TOKEN_NULL,
{NULL, NULL, PREC_NONE},// TOKEN_BOOLEAN, {NULL, NULL, PREC_NONE},// TOKEN_BOOLEAN,
{NULL, NULL, PREC_NONE},// TOKEN_INTEGER, {NULL, NULL, PREC_NONE},// TOKEN_INTEGER,
{NULL, NULL, PREC_NONE},// TOKEN_FLOAT, {NULL, NULL, PREC_NONE},// TOKEN_FLOAT,
@@ -234,15 +243,15 @@ ParseRule parseRules[] = { //must match the token types
//literal values //literal values
{NULL, NULL, PREC_NONE},// TOKEN_IDENTIFIER, {NULL, NULL, PREC_NONE},// TOKEN_IDENTIFIER,
{atomic, NULL, PREC_NONE},// TOKEN_LITERAL_TRUE, {atomic, NULL, PREC_PRIMARY},// TOKEN_LITERAL_TRUE,
{atomic, NULL, PREC_NONE},// TOKEN_LITERAL_FALSE, {atomic, NULL, PREC_PRIMARY},// TOKEN_LITERAL_FALSE,
{atomic, NULL, PREC_NONE},// TOKEN_LITERAL_INTEGER, {atomic, NULL, PREC_PRIMARY},// TOKEN_LITERAL_INTEGER,
{atomic, NULL, PREC_NONE},// TOKEN_LITERAL_FLOAT, {atomic, NULL, PREC_PRIMARY},// TOKEN_LITERAL_FLOAT,
{string, NULL, PREC_PRIMARY},// TOKEN_LITERAL_STRING, {string, NULL, PREC_PRIMARY},// TOKEN_LITERAL_STRING,
//math operators //math operators
{NULL, NULL, PREC_NONE},// TOKEN_PLUS, {NULL, NULL, PREC_NONE},// TOKEN_PLUS,
{unary, NULL, PREC_NONE},// TOKEN_MINUS, {unary, NULL, PREC_UNARY},// TOKEN_MINUS,
{NULL, NULL, PREC_NONE},// TOKEN_MULTIPLY, {NULL, NULL, PREC_NONE},// TOKEN_MULTIPLY,
{NULL, NULL, PREC_NONE},// TOKEN_DIVIDE, {NULL, NULL, PREC_NONE},// TOKEN_DIVIDE,
{NULL, NULL, PREC_NONE},// TOKEN_MODULO, {NULL, NULL, PREC_NONE},// TOKEN_MODULO,
@@ -334,7 +343,6 @@ static void printStmt(Parser* parser, Node* node) {
//set the node info //set the node info
node->type = NODE_UNARY; node->type = NODE_UNARY;
node->unary.opcode = OP_PRINT; node->unary.opcode = OP_PRINT;
node->unary.child = ALLOCATE(Node, 1);
expression(parser, &(node->unary.child)); expression(parser, &(node->unary.child));
consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of print statement"); consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of print statement");