ASTNode* parse(MemoryStack* stack, Array<SyntaxError>* errors, char* program) { LexerCarriage mainCarriage = initCarriage(program); ASTNode* result = pushMemory<ASTNode>(stack); result->nodeType = AST_MAIN; result->main.statements = { }; parseStatements(stack, &mainCarriage, errors, &result->main.statements); expectAndEat(&mainCarriage, TOK_EOF, errors); return result; }
static bool parseFunctionCall(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode* result) { LexerCarriage tmpCarriage = *carriage; if (tmpCarriage.topToken.type == TOK_IDENTIFIER) { Token identifier = tmpCarriage.topToken; parseNextToken(&tmpCarriage); if (tmpCarriage.topToken.type == TOK_OPEN_BRACKET) { parseNextToken(&tmpCarriage); result->nodeType = AST_FUNCTION_CALL; result->functionCall.lineNumber = carriage->currentLineNumber; result->functionCall.identifier = identifier.identifierValue; result->functionCall.arguments = { }; if (tmpCarriage.topToken.type != TOK_CLOSE_BRACKET) { ASTNode argument; do { if (parseExpression(stack, &tmpCarriage, errors, &argument)) { *pushElement(&result->functionCall.arguments, stack) = argument; if (tmpCarriage.topToken.type == TOK_COMMA) parseNextToken(&tmpCarriage); else break; } else { pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED }); break; } } while (true); } expectAndEat(&tmpCarriage, TOK_CLOSE_BRACKET, errors); *carriage = tmpCarriage; return true; } } return false; }
bool Parser::ParseProgram(Program* prog) { if (!expectAndEat(spv::MagicNumber)) { return false; } prog->Version = getAndEat(); std::cout << "Version: " << prog->Version << std::endl; prog->GeneratorMagic = getAndEat(); std::cout << "Generator Magic: " << prog->GeneratorMagic << std::endl; prog->IDBound = getAndEat(); std::cout << "ID Bound: " << prog->IDBound << std::endl; prog->InstructionSchema = getAndEat(); std::cout << "Instruction Schema: " << prog->InstructionSchema << std::endl; std::cout << "=================================================" << std::endl; int instructionIndex = 0; prog->NextOp = readInstruction(); do { SOp op = prog->NextOp; std::cout << std::setw(3) << instructionIndex << ": " << writeOp(op); instructionIndex++; if (!end()) { prog->NextOp = readInstruction(); } else { prog->NextOp = SOp{ Op::OpNop, nullptr }; } LUTHandlerMethods[op.Op]((void*)op.Memory, prog); if (prog->InFunction && prog->CurrentFunction->InBlock) { addOp(prog, op); } } while (prog->NextOp.Op != Op::OpNop); return true; }
static bool parseStatement(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode* result) { if (parseVariableDefinition(stack, carriage, errors, result)) return true; if (parseFunctionCall(stack, carriage, errors, result)) return true; if (parseAssignment(stack, carriage, errors, result)) return true; if (carriage->topToken.type == TOK_IDENTIFIER) { Token identifier = carriage->topToken; parseNextToken(carriage); if (carriage->topToken.type == TOK_DOUBLE_DOT) { parseNextToken(carriage); if (carriage->topToken.type == TOK_OPEN_BRACKET) // function definition { parseNextToken(carriage); result->nodeType = AST_STATEMENT_FUNCTION_DEFINITION; result->functionDefinition.lineNumber = carriage->currentLineNumber; result->functionDefinition.identifier = identifier.identifierValue; ASTNode arg; LinkedList<ASTNode> args = {}; if (carriage->topToken.type != TOK_CLOSE_BRACKET) { while (true) { if (parseVariableDefinition(stack, carriage, errors, &arg)) { *pushElement(&args, stack) = arg; if (carriage->topToken.type != TOK_COMMA) break; else parseNextToken(carriage); // pop , } else { pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED }); break; } }; } expectAndEat(carriage, TOK_CLOSE_BRACKET, errors); result->functionDefinition.arguments = args; if (carriage->topToken.type != TOK_VOID) { result->functionDefinition.returnType = pushMemory<ASTNode>(stack); if (!parseTypeIdentifier(stack, carriage, errors, result->functionDefinition.returnType)) { // TODO: change this SyntaxError error = SyntaxError{ SET_UNEXPECTED_TOKEN }; error.unexpectedToken.token = carriage->topToken; error.unexpectedToken.expecting = TOK_IDENTIFIER; pushBack(errors, error); } } else { parseNextToken(carriage); result->functionDefinition.returnType = nullptr; } result->functionDefinition.body = nullptr; if (carriage->topToken.type == TOK_ASSIGN) { parseNextToken(carriage); result->functionDefinition.body = pushMemory<ASTNode>(stack); expectAndEatStatement(stack, carriage, errors, result->functionDefinition.body); } return true; } else if (carriage->topToken.type == TOK_STRUCT) { parseNextToken(carriage); expectAndEat(carriage, TOK_ASSIGN, errors); int bracesOpenedAt = carriage->currentLineNumber; expectAndEat(carriage, TOK_OPEN_BRACES, errors); result->nodeType = AST_STATEMENT_TYPE_DEFINITION; result->typeDefinition.lineNumber = carriage->currentLineNumber; result->typeDefinition.identifier = identifier.identifierValue; result->typeDefinition.definitions = {}; ASTNode definition; do { if (parseVariableDefinition(stack, carriage, errors, &definition)) *pushElement(&result->typeDefinition.definitions, stack) = definition; else break; } while (true); if (carriage->topToken.type == TOK_CLOSE_BRACES) parseNextToken(carriage); else { SyntaxError error = { SET_UNCLOSED_BRACKETS, bracesOpenedAt }; error.unclosedBrackets.closedAt = carriage->currentLineNumber; error.unclosedBrackets.token = carriage->topToken; pushBack(errors, error); } return true; } else { // TODO: error } } else { // TODO: error } } else if (carriage->topToken.type == TOK_OPEN_BRACES) { int openedAt = carriage->currentLineNumber; parseNextToken(carriage); result->nodeType = AST_STATEMENTS_BLOCK; result->statementsBlock.statements = { }; parseStatements(stack, carriage, errors, &result->statementsBlock.statements); if (carriage->topToken.type == TOK_CLOSE_BRACES) parseNextToken(carriage); else { SyntaxError error = SyntaxError{ SET_UNCLOSED_BRACKETS, openedAt }; error.unclosedBrackets.closedAt = carriage->currentLineNumber; error.unclosedBrackets.token = carriage->topToken; pushBack(errors, error); } return true; } else if (carriage->topToken.type == TOK_IF) { parseNextToken(carriage); result->nodeType = AST_STATEMENT_IF; result->ifStatement.condition = pushMemory<ASTNode>(stack); result->ifStatement.ifCase = pushMemory<ASTNode>(stack); expectAndEatExpression(stack, carriage, errors, result->ifStatement.condition); expectAndEatStatement(stack, carriage, errors, result->ifStatement.ifCase); if (carriage->topToken.type == TOK_ELSE) { parseNextToken(carriage); result->ifStatement.elseCase = pushMemory<ASTNode>(stack); expectAndEatStatement(stack, carriage, errors, result->ifStatement.elseCase); } else result->ifStatement.elseCase = nullptr; return true; } else if (carriage->topToken.type == TOK_WHILE) { parseNextToken(carriage); result->nodeType = AST_STATEMENT_WHILE; result->whileStatement.condition = pushMemory<ASTNode>(stack); result->whileStatement.body = pushMemory<ASTNode>(stack); expectAndEatExpression(stack, carriage, errors, result->whileStatement.condition); expectAndEatStatement(stack, carriage, errors, result->whileStatement.body); return true; } return false; }