While and for loops are working

This commit is contained in:
2022-08-20 13:27:47 +01:00
parent 975ed41d14
commit f5e060051e
4 changed files with 116 additions and 12 deletions

View File

@@ -149,7 +149,7 @@ void writeCompiler(Compiler* compiler, Node* node) {
if (compiler->capacity < compiler->count + 1) { if (compiler->capacity < compiler->count + 1) {
int oldCapacity = compiler->capacity; int oldCapacity = compiler->capacity;
compiler->capacity = GROW_CAPACITY(oldCapacity); compiler->capacity = GROW_CAPACITY_FAST(oldCapacity);
compiler->bytecode = GROW_ARRAY(unsigned char, compiler->bytecode, oldCapacity, compiler->capacity); compiler->bytecode = GROW_ARRAY(unsigned char, compiler->bytecode, oldCapacity, compiler->capacity);
} }
@@ -322,13 +322,63 @@ void writeCompiler(Compiler* compiler, Node* node) {
} }
break; break;
// case NODE_PATH_WHILE: { case NODE_PATH_WHILE: {
// //cache the jump point //cache the jump point
// int jumpToBeginning = compiler->count; unsigned short jumpFromEnd = compiler->count;
// compiler->count += sizeof(unsigned short); //2 bytes
// // //process the condition
// } writeCompiler(compiler, node->path.condition);
//if false, jump to end
compiler->bytecode[compiler->count++] = OP_IF_FALSE_JUMP; //1 byte
unsigned short jumpToEnd = compiler->count;
compiler->count += sizeof(unsigned short); //2 bytes
//write the body
writeCompiler(compiler, node->path.thenPath);
//jump to condition
compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte
compiler->bytecode[compiler->count] = jumpFromEnd;
compiler->count += sizeof(unsigned short); //2 bytes
//jump from condition
compiler->bytecode[jumpToEnd] = compiler->count;
}
break;
case NODE_PATH_FOR: {
compiler->bytecode[compiler->count++] = OP_SCOPE_BEGIN; //1 byte
//initial setup
writeCompiler(compiler, node->path.preClause);
//conditional
unsigned short jumpFromEnd = compiler->count;
writeCompiler(compiler, node->path.condition);
//if false jump to end
compiler->bytecode[compiler->count++] = OP_IF_FALSE_JUMP; //1 byte
unsigned short jumpToEnd = compiler->count;
compiler->count += sizeof(unsigned short); //2 bytes
//write the body
compiler->bytecode[compiler->count++] = OP_SCOPE_BEGIN; //1 byte
writeCompiler(compiler, node->path.thenPath);
compiler->bytecode[compiler->count++] = OP_SCOPE_END; //1 byte
//evaluate third clause, restart
writeCompiler(compiler, node->path.postClause);
compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte
compiler->bytecode[compiler->count] = jumpFromEnd;
compiler->count += sizeof(unsigned short); //2 bytes
compiler->bytecode[jumpToEnd] = compiler->count;
compiler->bytecode[compiler->count++] = OP_SCOPE_END; //1 byte
}
break;
} }
} }

View File

@@ -5,6 +5,7 @@
#define ALLOCATE(type, count) ((type*)reallocate(NULL, 0, sizeof(type) * (count))) #define ALLOCATE(type, count) ((type*)reallocate(NULL, 0, sizeof(type) * (count)))
#define FREE(type, pointer) reallocate(pointer, sizeof(type), 0) #define FREE(type, pointer) reallocate(pointer, sizeof(type), 0)
#define GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2) #define GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2)
#define GROW_CAPACITY_FAST(capacity) ((capacity) < 32 ? 32 : (capacity) * 2)
#define GROW_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) #define GROW_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count))
#define SHRINK_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) #define SHRINK_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count))
#define FREE_ARRAY(type, pointer, oldCount) reallocate((type*)pointer, sizeof(type) * (oldCount), 0) #define FREE_ARRAY(type, pointer, oldCount) reallocate((type*)pointer, sizeof(type) * (oldCount), 0)

View File

@@ -925,11 +925,11 @@ static void ifStmt(Parser* parser, Node** nodeHandle) {
Node* elsePath = NULL; Node* elsePath = NULL;
//read the condition //read the condition
consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at end of if statement"); consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at beginning of if clause");
parsePrecedence(parser, &condition, PREC_TERNARY); parsePrecedence(parser, &condition, PREC_TERNARY);
//read the then path //read the then path
consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of if statement"); consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of if clause");
thenPath = ALLOCATE(Node, 1); thenPath = ALLOCATE(Node, 1);
declaration(parser, &thenPath); declaration(parser, &thenPath);
@@ -944,11 +944,45 @@ static void ifStmt(Parser* parser, Node** nodeHandle) {
} }
static void whileStmt(Parser* parser, Node** nodeHandle) { static void whileStmt(Parser* parser, Node** nodeHandle) {
// Node* condition = NULL;
Node* thenPath = NULL;
//read the condition
consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at beginning of while clause");
parsePrecedence(parser, &condition, PREC_TERNARY);
//read the then path
consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of while clause");
thenPath = ALLOCATE(Node, 1);
declaration(parser, &thenPath);
freeNode(*nodeHandle); //free the initial node
emitNodePath(nodeHandle, NODE_PATH_WHILE, NULL, NULL, condition, thenPath, NULL);
} }
static void forStmt(Parser* parser, Node** nodeHandle) { static void forStmt(Parser* parser, Node** nodeHandle) {
// Node* preClause = ALLOCATE(Node, 1);
Node* postClause = NULL;
Node* condition = NULL;
Node* thenPath = ALLOCATE(Node, 1);
//read the clauses
consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at beginning of for clause");
declaration(parser, &preClause);
parsePrecedence(parser, &condition, PREC_TERNARY);
consume(parser, TOKEN_SEMICOLON, "Expected ';' after condition of for clause");
parsePrecedence(parser, &postClause, PREC_ASSIGNMENT);
consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of for clause");
//read the path
thenPath = ALLOCATE(Node, 1);
declaration(parser, &thenPath);
freeNode(*nodeHandle); //free the initial node
emitNodePath(nodeHandle, NODE_PATH_FOR, preClause, postClause, condition, thenPath, NULL);
} }
//precedence functions //precedence functions

View File

@@ -18,4 +18,23 @@ else {
} }
//test while loop
var whileCounter = 0;
while (whileCounter < 10) {
whileCounter = whileCounter + 1;
}
assert whileCounter == 10, "while-loop failed";
//test for loop
var forCache = 0;
for (var i = 0; i < 20; i = i + 1) {
forCache = i;
}
assert forCache == 19, "for-loop failed";
print "All good"; print "All good";