WIP Adding for-loop to parser & compiler
This commit is contained in:
@@ -147,6 +147,16 @@ void Toy_private_emitAstWhileThen(Toy_Bucket** bucketHandle, Toy_Ast** astHandle
|
|||||||
(*astHandle) = tmp;
|
(*astHandle) = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Toy_private_emitAstForThen(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* condBranch, Toy_Ast* thenBranch) {
|
||||||
|
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
|
||||||
|
|
||||||
|
tmp->type = TOY_AST_FOR_THEN;
|
||||||
|
tmp->forThen.condBranch = condBranch;
|
||||||
|
tmp->forThen.thenBranch = thenBranch;
|
||||||
|
|
||||||
|
(*astHandle) = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
void Toy_private_emitAstBreak(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
|
void Toy_private_emitAstBreak(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
|
||||||
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
|
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
|
||||||
|
|
||||||
@@ -244,6 +254,16 @@ void Toy_private_emitAstAttribute(Toy_Bucket** bucketHandle, Toy_Ast** astHandle
|
|||||||
(*astHandle) = tmp;
|
(*astHandle) = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Toy_private_emitAstIterable(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* expr) {
|
||||||
|
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
|
||||||
|
|
||||||
|
tmp->type = TOY_AST_ITERABLE;
|
||||||
|
tmp->iterable.left = (*astHandle);
|
||||||
|
tmp->iterable.right = expr;
|
||||||
|
|
||||||
|
(*astHandle) = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
void Toy_private_emitAstStackPop(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
|
void Toy_private_emitAstStackPop(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
|
||||||
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
|
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
|
||||||
|
|
||||||
@@ -293,6 +313,7 @@ const char* Toy_private_getAstTypeAsCString(Toy_AstType type) {
|
|||||||
case TOY_AST_ASSERT: return "ASSERT";
|
case TOY_AST_ASSERT: return "ASSERT";
|
||||||
case TOY_AST_IF_THEN_ELSE: return "IF_THEN_ELSE";
|
case TOY_AST_IF_THEN_ELSE: return "IF_THEN_ELSE";
|
||||||
case TOY_AST_WHILE_THEN: return "WHILE_THEN";
|
case TOY_AST_WHILE_THEN: return "WHILE_THEN";
|
||||||
|
case TOY_AST_FOR_THEN: return "FOR_THEN";
|
||||||
case TOY_AST_BREAK: return "BREAK";
|
case TOY_AST_BREAK: return "BREAK";
|
||||||
case TOY_AST_CONTINUE: return "CONTINUE";
|
case TOY_AST_CONTINUE: return "CONTINUE";
|
||||||
case TOY_AST_RETURN: return "RETURN";
|
case TOY_AST_RETURN: return "RETURN";
|
||||||
@@ -305,6 +326,7 @@ const char* Toy_private_getAstTypeAsCString(Toy_AstType type) {
|
|||||||
case TOY_AST_FN_DECLARE: return "FN_DECLARE";
|
case TOY_AST_FN_DECLARE: return "FN_DECLARE";
|
||||||
case TOY_AST_FN_INVOKE: return "FN_INVOKE";
|
case TOY_AST_FN_INVOKE: return "FN_INVOKE";
|
||||||
case TOY_AST_ATTRIBUTE: return "ATTRIBUTE";
|
case TOY_AST_ATTRIBUTE: return "ATTRIBUTE";
|
||||||
|
case TOY_AST_ITERABLE: return "ITERABLE";
|
||||||
|
|
||||||
case TOY_AST_STACK_POP: return "STACK_POP";
|
case TOY_AST_STACK_POP: return "STACK_POP";
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ typedef enum Toy_AstType {
|
|||||||
TOY_AST_ASSERT,
|
TOY_AST_ASSERT,
|
||||||
TOY_AST_IF_THEN_ELSE,
|
TOY_AST_IF_THEN_ELSE,
|
||||||
TOY_AST_WHILE_THEN,
|
TOY_AST_WHILE_THEN,
|
||||||
|
TOY_AST_FOR_THEN,
|
||||||
TOY_AST_BREAK,
|
TOY_AST_BREAK,
|
||||||
TOY_AST_CONTINUE,
|
TOY_AST_CONTINUE,
|
||||||
TOY_AST_RETURN,
|
TOY_AST_RETURN,
|
||||||
@@ -34,6 +35,7 @@ typedef enum Toy_AstType {
|
|||||||
TOY_AST_FN_DECLARE,
|
TOY_AST_FN_DECLARE,
|
||||||
TOY_AST_FN_INVOKE,
|
TOY_AST_FN_INVOKE,
|
||||||
TOY_AST_ATTRIBUTE,
|
TOY_AST_ATTRIBUTE,
|
||||||
|
TOY_AST_ITERABLE,
|
||||||
|
|
||||||
TOY_AST_STACK_POP, //BUGFIX: force a single stack pop for expression statements
|
TOY_AST_STACK_POP, //BUGFIX: force a single stack pop for expression statements
|
||||||
|
|
||||||
@@ -171,6 +173,12 @@ typedef struct Toy_AstWhileThen {
|
|||||||
Toy_Ast* thenBranch;
|
Toy_Ast* thenBranch;
|
||||||
} Toy_AstWhileThen;
|
} Toy_AstWhileThen;
|
||||||
|
|
||||||
|
typedef struct Toy_AstForThen {
|
||||||
|
Toy_AstType type;
|
||||||
|
Toy_Ast* condBranch;
|
||||||
|
Toy_Ast* thenBranch;
|
||||||
|
} Toy_AstForThen;
|
||||||
|
|
||||||
typedef struct Toy_AstBreak {
|
typedef struct Toy_AstBreak {
|
||||||
Toy_AstType type;
|
Toy_AstType type;
|
||||||
} Toy_AstBreak;
|
} Toy_AstBreak;
|
||||||
@@ -228,6 +236,12 @@ typedef struct Toy_AstAttribute {
|
|||||||
Toy_Ast* right;
|
Toy_Ast* right;
|
||||||
} Toy_AstAttribute;
|
} Toy_AstAttribute;
|
||||||
|
|
||||||
|
typedef struct Toy_AstIterable {
|
||||||
|
Toy_AstType type;
|
||||||
|
Toy_Ast* left;
|
||||||
|
Toy_Ast* right;
|
||||||
|
} Toy_AstIterable;
|
||||||
|
|
||||||
typedef struct Toy_AstStackPop {
|
typedef struct Toy_AstStackPop {
|
||||||
Toy_AstType type;
|
Toy_AstType type;
|
||||||
Toy_Ast* child;
|
Toy_Ast* child;
|
||||||
@@ -259,6 +273,7 @@ union Toy_Ast { //see 'test_ast.c' for bitness tests
|
|||||||
Toy_AstAssert assert;
|
Toy_AstAssert assert;
|
||||||
Toy_AstIfThenElse ifThenElse;
|
Toy_AstIfThenElse ifThenElse;
|
||||||
Toy_AstWhileThen whileThen;
|
Toy_AstWhileThen whileThen;
|
||||||
|
Toy_AstForThen forThen;
|
||||||
Toy_AstBreak breakPoint;
|
Toy_AstBreak breakPoint;
|
||||||
Toy_AstContinue continuePoint;
|
Toy_AstContinue continuePoint;
|
||||||
Toy_AstReturn fnReturn;
|
Toy_AstReturn fnReturn;
|
||||||
@@ -269,6 +284,7 @@ union Toy_Ast { //see 'test_ast.c' for bitness tests
|
|||||||
Toy_AstFnDeclare fnDeclare;
|
Toy_AstFnDeclare fnDeclare;
|
||||||
Toy_AstFnInvoke fnInvoke;
|
Toy_AstFnInvoke fnInvoke;
|
||||||
Toy_AstAttribute attribute;
|
Toy_AstAttribute attribute;
|
||||||
|
Toy_AstIterable iterable;
|
||||||
Toy_AstStackPop stackPop;
|
Toy_AstStackPop stackPop;
|
||||||
Toy_AstPass pass;
|
Toy_AstPass pass;
|
||||||
Toy_AstError error;
|
Toy_AstError error;
|
||||||
@@ -290,6 +306,7 @@ void Toy_private_emitAstAggregate(Toy_Bucket** bucketHandle, Toy_Ast** astHandle
|
|||||||
void Toy_private_emitAstAssert(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* child, Toy_Ast* msg);
|
void Toy_private_emitAstAssert(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* child, Toy_Ast* msg);
|
||||||
void Toy_private_emitAstIfThenElse(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* condBranch, Toy_Ast* thenBranch, Toy_Ast* elseBranch);
|
void Toy_private_emitAstIfThenElse(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* condBranch, Toy_Ast* thenBranch, Toy_Ast* elseBranch);
|
||||||
void Toy_private_emitAstWhileThen(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* condBranch, Toy_Ast* thenBranch);
|
void Toy_private_emitAstWhileThen(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* condBranch, Toy_Ast* thenBranch);
|
||||||
|
void Toy_private_emitAstForThen(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* condBranch, Toy_Ast* thenBranch);
|
||||||
void Toy_private_emitAstBreak(Toy_Bucket** bucketHandle, Toy_Ast** rootHandle);
|
void Toy_private_emitAstBreak(Toy_Bucket** bucketHandle, Toy_Ast** rootHandle);
|
||||||
void Toy_private_emitAstContinue(Toy_Bucket** bucketHandle, Toy_Ast** rootHandle);
|
void Toy_private_emitAstContinue(Toy_Bucket** bucketHandle, Toy_Ast** rootHandle);
|
||||||
void Toy_private_emitAstReturn(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
|
void Toy_private_emitAstReturn(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
|
||||||
@@ -302,6 +319,7 @@ void Toy_private_emitAstVariableAccess(Toy_Bucket** bucketHandle, Toy_Ast** astH
|
|||||||
void Toy_private_emitAstFunctionDeclaration(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_String* name, Toy_Ast* params, Toy_Ast* body);
|
void Toy_private_emitAstFunctionDeclaration(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_String* name, Toy_Ast* params, Toy_Ast* body);
|
||||||
void Toy_private_emitAstFunctionInvokation(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* params);
|
void Toy_private_emitAstFunctionInvokation(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* params);
|
||||||
void Toy_private_emitAstAttribute(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* expr);
|
void Toy_private_emitAstAttribute(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* expr);
|
||||||
|
void Toy_private_emitAstIterable(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* expr);
|
||||||
|
|
||||||
void Toy_private_emitAstStackPop(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
|
void Toy_private_emitAstStackPop(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ static void attr_arrayPopBack(Toy_VM* vm, Toy_FunctionNative* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void attr_arrayForEach(Toy_VM* vm, Toy_FunctionNative* self) {
|
static void attr_arrayForEach(Toy_VM* vm, Toy_FunctionNative* self) {
|
||||||
|
//URGENT: replace with for-loop
|
||||||
(void)self;
|
(void)self;
|
||||||
|
|
||||||
Toy_Value compound = Toy_popStack(&vm->stack);
|
Toy_Value compound = Toy_popStack(&vm->stack);
|
||||||
@@ -241,7 +242,7 @@ static void attr_tableForEach(Toy_VM* vm, Toy_FunctionNative* self) {
|
|||||||
(void)vm;
|
(void)vm;
|
||||||
(void)self;
|
(void)self;
|
||||||
|
|
||||||
//URGENT: attr_tableForEach
|
//URGENT: replace with for-loop
|
||||||
}
|
}
|
||||||
|
|
||||||
Toy_Value Toy_private_handleTableAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
Toy_Value Toy_private_handleTableAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
||||||
|
|||||||
@@ -718,6 +718,15 @@ static unsigned int writeInstructionWhileThen(Toy_Bytecode** mb, Toy_AstWhileThe
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int writeInstructionForThen(Toy_Bytecode** mb, Toy_AstForThen ast) {
|
||||||
|
//URGENT: WIP
|
||||||
|
(void)mb;
|
||||||
|
(void)ast;
|
||||||
|
|
||||||
|
(*mb)->panic = true;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned int writeInstructionBreak(Toy_Bytecode** mb, Toy_AstBreak ast) {
|
static unsigned int writeInstructionBreak(Toy_Bytecode** mb, Toy_AstBreak ast) {
|
||||||
//unused
|
//unused
|
||||||
(void)ast;
|
(void)ast;
|
||||||
@@ -1244,6 +1253,10 @@ static unsigned int writeBytecodeFromAst(Toy_Bytecode** mb, Toy_Ast* ast) {
|
|||||||
result += writeInstructionWhileThen(mb, ast->whileThen);
|
result += writeInstructionWhileThen(mb, ast->whileThen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOY_AST_FOR_THEN:
|
||||||
|
result += writeInstructionForThen(mb, ast->forThen);
|
||||||
|
break;
|
||||||
|
|
||||||
case TOY_AST_BREAK:
|
case TOY_AST_BREAK:
|
||||||
result += writeInstructionBreak(mb, ast->breakPoint);
|
result += writeInstructionBreak(mb, ast->breakPoint);
|
||||||
break;
|
break;
|
||||||
@@ -1284,6 +1297,12 @@ static unsigned int writeBytecodeFromAst(Toy_Bytecode** mb, Toy_Ast* ast) {
|
|||||||
result += writeInstructionAttribute(mb, ast->attribute);
|
result += writeInstructionAttribute(mb, ast->attribute);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOY_AST_ITERABLE:
|
||||||
|
//the 'in' keyword is only valid within a for-loop's condition
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "COMPILER ERROR: the 'in' keyword is only valid within a for-loop's condition\n" TOY_CC_RESET);
|
||||||
|
(*mb)->panic = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case TOY_AST_STACK_POP:
|
case TOY_AST_STACK_POP:
|
||||||
result += writeInstructionStackPop(mb, ast->stackPop);
|
result += writeInstructionStackPop(mb, ast->stackPop);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ typedef enum Toy_OpcodeType {
|
|||||||
TOY_OPCODE_ACCESS,
|
TOY_OPCODE_ACCESS,
|
||||||
TOY_OPCODE_INVOKE, //for calling functions
|
TOY_OPCODE_INVOKE, //for calling functions
|
||||||
TOY_OPCODE_ATTRIBUTE, //for accessing parts of compounds
|
TOY_OPCODE_ATTRIBUTE, //for accessing parts of compounds
|
||||||
|
TOY_OPCODE_ITERABLE, //for operating on all members of a compound
|
||||||
TOY_OPCODE_DUPLICATE, //duplicate the top of the stack
|
TOY_OPCODE_DUPLICATE, //duplicate the top of the stack
|
||||||
TOY_OPCODE_ELIMINATE, //remove the top of the stack
|
TOY_OPCODE_ELIMINATE, //remove the top of the stack
|
||||||
|
|
||||||
|
|||||||
+39
-4
@@ -122,6 +122,7 @@ static Toy_AstFlag aggregate(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_
|
|||||||
static Toy_AstFlag unaryPostfix(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
|
static Toy_AstFlag unaryPostfix(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
|
||||||
static Toy_AstFlag invoke(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
|
static Toy_AstFlag invoke(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
|
||||||
static Toy_AstFlag attribute(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
|
static Toy_AstFlag attribute(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
|
||||||
|
static Toy_AstFlag iterable(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
|
||||||
|
|
||||||
//precedence definitions
|
//precedence definitions
|
||||||
static ParsingTuple parsingRulesetTable[] = {
|
static ParsingTuple parsingRulesetTable[] = {
|
||||||
@@ -156,7 +157,7 @@ static ParsingTuple parsingRulesetTable[] = {
|
|||||||
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_FUNCTION,
|
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_FUNCTION,
|
||||||
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_IF,
|
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_IF,
|
||||||
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_IMPORT,
|
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_IMPORT,
|
||||||
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_IN,
|
{PREC_CALL,NULL,iterable},// TOY_TOKEN_KEYWORD_IN,
|
||||||
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_OF,
|
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_OF,
|
||||||
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_PASS,
|
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_PASS,
|
||||||
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_PRINT,
|
{PREC_NONE,NULL,NULL},// TOY_TOKEN_KEYWORD_PRINT,
|
||||||
@@ -760,6 +761,19 @@ static Toy_AstFlag attribute(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Toy_AstFlag iterable(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
|
||||||
|
//infix must advance
|
||||||
|
advance(parser);
|
||||||
|
|
||||||
|
Toy_Ast* expr = NULL;
|
||||||
|
parsePrecedence(bucketHandle, parser, &expr, PREC_CALL);
|
||||||
|
Toy_private_emitAstIterable(bucketHandle, rootHandle, expr);
|
||||||
|
|
||||||
|
//TODO: check for var declare without assignment
|
||||||
|
|
||||||
|
return TOY_AST_FLAG_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
//grammar rules
|
//grammar rules
|
||||||
static void parsePrecedence(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle, ParsingPrecedence precRule) {
|
static void parsePrecedence(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle, ParsingPrecedence precRule) {
|
||||||
//'step over' the token to parse
|
//'step over' the token to parse
|
||||||
@@ -865,7 +879,7 @@ static void makeIfThenElseStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, To
|
|||||||
makeExpr(bucketHandle, parser, &condBranch);
|
makeExpr(bucketHandle, parser, &condBranch);
|
||||||
consume(parser, TOY_TOKEN_OPERATOR_PAREN_RIGHT, "Expected ')' after 'if' condition");
|
consume(parser, TOY_TOKEN_OPERATOR_PAREN_RIGHT, "Expected ')' after 'if' condition");
|
||||||
|
|
||||||
// { thenBranch }
|
//{ thenBranch }
|
||||||
makeDeclarationStmt(bucketHandle, parser, &thenBranch, true);
|
makeDeclarationStmt(bucketHandle, parser, &thenBranch, true);
|
||||||
|
|
||||||
//else { elseBranch }
|
//else { elseBranch }
|
||||||
@@ -885,12 +899,29 @@ static void makeWhileStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast
|
|||||||
makeExpr(bucketHandle, parser, &condBranch);
|
makeExpr(bucketHandle, parser, &condBranch);
|
||||||
consume(parser, TOY_TOKEN_OPERATOR_PAREN_RIGHT, "Expected ')' after 'while' condition");
|
consume(parser, TOY_TOKEN_OPERATOR_PAREN_RIGHT, "Expected ')' after 'while' condition");
|
||||||
|
|
||||||
// { thenBranch }
|
//{ thenBranch }
|
||||||
makeDeclarationStmt(bucketHandle, parser, &thenBranch, true);
|
makeDeclarationStmt(bucketHandle, parser, &thenBranch, true);
|
||||||
|
|
||||||
Toy_private_emitAstWhileThen(bucketHandle, rootHandle, condBranch, thenBranch);
|
Toy_private_emitAstWhileThen(bucketHandle, rootHandle, condBranch, thenBranch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void makeForStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
|
||||||
|
Toy_Ast* condBranch = NULL;
|
||||||
|
Toy_Ast* thenBranch = NULL;
|
||||||
|
|
||||||
|
//for (condBranch)
|
||||||
|
consume(parser, TOY_TOKEN_OPERATOR_PAREN_LEFT, "Expected '(' after 'for' keyword");
|
||||||
|
makeExpr(bucketHandle, parser, &condBranch);
|
||||||
|
consume(parser, TOY_TOKEN_OPERATOR_PAREN_RIGHT, "Expected ')' after 'for' condition");
|
||||||
|
|
||||||
|
//TODO: check for an iterable node
|
||||||
|
|
||||||
|
//{ thenBranch }
|
||||||
|
makeDeclarationStmt(bucketHandle, parser, &thenBranch, true);
|
||||||
|
|
||||||
|
Toy_private_emitAstForThen(bucketHandle, rootHandle, condBranch, thenBranch);
|
||||||
|
}
|
||||||
|
|
||||||
static void makeBreakStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
|
static void makeBreakStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
|
||||||
Toy_private_emitAstBreak(bucketHandle, rootHandle);
|
Toy_private_emitAstBreak(bucketHandle, rootHandle);
|
||||||
consume(parser, TOY_TOKEN_OPERATOR_SEMICOLON, "Expected ';' at the end of break statement");
|
consume(parser, TOY_TOKEN_OPERATOR_SEMICOLON, "Expected ';' at the end of break statement");
|
||||||
@@ -1070,7 +1101,11 @@ static void makeStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** ro
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//URGENT: for-pre-clause-post-then
|
//for
|
||||||
|
else if (match(parser, TOY_TOKEN_KEYWORD_FOR)) {
|
||||||
|
makeForStmt(bucketHandle, parser, rootHandle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//break
|
//break
|
||||||
else if (match(parser, TOY_TOKEN_KEYWORD_BREAK)) {
|
else if (match(parser, TOY_TOKEN_KEYWORD_BREAK)) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ typedef enum Toy_TokenType {
|
|||||||
TOY_TOKEN_KEYWORD_DO, //unused
|
TOY_TOKEN_KEYWORD_DO, //unused
|
||||||
TOY_TOKEN_KEYWORD_ELSE,
|
TOY_TOKEN_KEYWORD_ELSE,
|
||||||
TOY_TOKEN_KEYWORD_EXPORT, //unused
|
TOY_TOKEN_KEYWORD_EXPORT, //unused
|
||||||
TOY_TOKEN_KEYWORD_FOR, //unused
|
TOY_TOKEN_KEYWORD_FOR,
|
||||||
TOY_TOKEN_KEYWORD_FOREACH, //unused
|
TOY_TOKEN_KEYWORD_FOREACH, //unused
|
||||||
TOY_TOKEN_KEYWORD_FUNCTION, //remapped 'fn'
|
TOY_TOKEN_KEYWORD_FUNCTION, //remapped 'fn'
|
||||||
TOY_TOKEN_KEYWORD_IF,
|
TOY_TOKEN_KEYWORD_IF,
|
||||||
|
|||||||
@@ -1060,6 +1060,7 @@ static unsigned int process(Toy_VM* vm) {
|
|||||||
processIndex(vm);
|
processIndex(vm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOY_OPCODE_ITERABLE: //tmp
|
||||||
case TOY_OPCODE_UNUSED:
|
case TOY_OPCODE_UNUSED:
|
||||||
case TOY_OPCODE_PASS:
|
case TOY_OPCODE_PASS:
|
||||||
case TOY_OPCODE_ERROR:
|
case TOY_OPCODE_ERROR:
|
||||||
|
|||||||
Reference in New Issue
Block a user