Allow for stmt to have empty clauses, resolved #58

This commit is contained in:
2023-02-13 14:42:43 +00:00
parent eb8e522bf2
commit 1ed114b80d
8 changed files with 58 additions and 7 deletions

View File

@@ -135,6 +135,10 @@ static void freeASTNodeCustom(Toy_ASTNode* node, bool freeSelf) {
Toy_freeLiteral(node->import.identifier); Toy_freeLiteral(node->import.identifier);
Toy_freeLiteral(node->import.alias); Toy_freeLiteral(node->import.alias);
break; break;
case TOY_AST_NODE_PASS:
//EMPTY
break;
} }
if (freeSelf) { if (freeSelf) {
@@ -383,3 +387,11 @@ void Toy_emitASTNodeImport(Toy_ASTNode** nodeHandle, Toy_Literal identifier, Toy
*nodeHandle = tmp; *nodeHandle = tmp;
} }
void Toy_emitASTNodePass(Toy_ASTNode** nodeHandle) {
Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1);
tmp->type = TOY_AST_NODE_PASS;
*nodeHandle = tmp;
}

View File

@@ -34,6 +34,7 @@ typedef enum Toy_ASTNodeType {
TOY_AST_NODE_PREFIX_DECREMENT, //decrement a variable TOY_AST_NODE_PREFIX_DECREMENT, //decrement a variable
TOY_AST_NODE_POSTFIX_DECREMENT, //decrement a variable TOY_AST_NODE_POSTFIX_DECREMENT, //decrement a variable
TOY_AST_NODE_IMPORT, //import a library TOY_AST_NODE_IMPORT, //import a library
TOY_AST_NODE_PASS, //for doing nothing
} Toy_ASTNodeType; } Toy_ASTNodeType;
//literals //literals
@@ -238,6 +239,9 @@ typedef struct Toy_NodeImport {
Toy_Literal alias; Toy_Literal alias;
} Toy_NodeImport; } Toy_NodeImport;
//for doing nothing
void Toy_emitASTNodePass(Toy_ASTNode** nodeHandle);
union Toy_private_node { union Toy_private_node {
Toy_ASTNodeType type; Toy_ASTNodeType type;
Toy_NodeLiteral atomic; Toy_NodeLiteral atomic;

View File

@@ -5,8 +5,8 @@
#include <stdint.h> #include <stdint.h>
#define TOY_VERSION_MAJOR 0 #define TOY_VERSION_MAJOR 0
#define TOY_VERSION_MINOR 8 #define TOY_VERSION_MINOR 9
#define TOY_VERSION_PATCH 3 #define TOY_VERSION_PATCH 0
#define TOY_VERSION_BUILD __DATE__ " " __TIME__ #define TOY_VERSION_BUILD __DATE__ " " __TIME__
//platform/compiler-specific instructions //platform/compiler-specific instructions

View File

@@ -965,6 +965,11 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode
return TOY_OP_INDEX_ASSIGN; //override binary's instruction IF it is assign return TOY_OP_INDEX_ASSIGN; //override binary's instruction IF it is assign
} }
break; break;
case TOY_AST_NODE_PASS: {
return TOY_OP_PASS;
}
break;
} }
return TOY_OP_EOF; return TOY_OP_EOF;

View File

@@ -1827,6 +1827,10 @@ static void execInterpreter(Toy_Interpreter* interpreter) {
while(opcode != TOY_OP_EOF && opcode != TOY_OP_SECTION_END && !interpreter->panic) { while(opcode != TOY_OP_EOF && opcode != TOY_OP_SECTION_END && !interpreter->panic) {
switch(opcode) { switch(opcode) {
case TOY_OP_PASS:
//DO NOTHING
break;
case TOY_OP_ASSERT: case TOY_OP_ASSERT:
if (!execAssert(interpreter)) { if (!execAssert(interpreter)) {
return; return;

View File

@@ -3,6 +3,9 @@
typedef enum Toy_Opcode { typedef enum Toy_Opcode {
TOY_OP_EOF, TOY_OP_EOF,
//do nothing
TOY_OP_PASS,
//basic statements //basic statements
TOY_OP_ASSERT, TOY_OP_ASSERT,
TOY_OP_PRINT, TOY_OP_PRINT,

View File

@@ -1350,13 +1350,36 @@ static void forStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) {
//read the clauses //read the clauses
consume(parser, TOY_TOKEN_PAREN_LEFT, "Expected '(' at beginning of for clause"); consume(parser, TOY_TOKEN_PAREN_LEFT, "Expected '(' at beginning of for clause");
declaration(parser, &preClause); //allow defining variables in the pre-clause //check the pre-clause
if (parser->current.type != TOY_TOKEN_SEMICOLON) {
declaration(parser, &preClause); //allow defining variables in the pre-clause
}
else {
consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' after empty declaration of for clause");
Toy_emitASTNodePass(&preClause);
}
parsePrecedence(parser, &condition, PREC_TERNARY); //check the condition clause
consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' after condition of for clause"); if (parser->current.type != TOY_TOKEN_SEMICOLON) {
parsePrecedence(parser, &condition, PREC_TERNARY);
consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' after condition of for clause");
}
else {
consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' after empty condition of for clause");
//empty clause defaults to forever
Toy_Literal f = TOY_TO_BOOLEAN_LITERAL(true);
Toy_emitASTNodeLiteral(&condition, f);
}
parsePrecedence(parser, &postClause, PREC_ASSIGNMENT); //check the postfix clause
consume(parser, TOY_TOKEN_PAREN_RIGHT, "Expected ')' at end of for clause"); if (parser->current.type != TOY_TOKEN_PAREN_RIGHT) {
parsePrecedence(parser, &postClause, PREC_ASSIGNMENT);
consume(parser, TOY_TOKEN_PAREN_RIGHT, "Expected ')' at end of for clause");
}
else {
consume(parser, TOY_TOKEN_PAREN_RIGHT, "Expected ')' after empty increment of for clause");
Toy_emitASTNodePass(&postClause);
}
//read the path //read the path
declaration(parser, &thenPath); declaration(parser, &thenPath);