mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Added optimisation levels
This commit is contained in:
@@ -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";
|
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,10 +136,10 @@ 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;
|
||||||
|
|
||||||
@@ -151,12 +153,19 @@ static void unary(Parser* parser, Node** nodeHandle, bool canBeAssigned) {
|
|||||||
|
|
||||||
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");
|
||||||
|
|||||||
Reference in New Issue
Block a user