예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}