Example #1
0
static bool parseTypeIdentifier(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode* result)
{
    if (carriage->topToken.type == TOK_REF)
    {
        parseNextToken(carriage);

        result->nodeType = AST_TYPE_IDENTIFIER;
        result->typeIdentifier.isReference = true;
        result->typeIdentifier.name = carriage->topToken.identifierValue;
        // TODO: add error checking

        parseNextToken(carriage);
        return true;
    }
    else if (carriage->topToken.type == TOK_IDENTIFIER)
    {
        result->nodeType = AST_TYPE_IDENTIFIER;
        result->typeIdentifier.isReference = false;
        result->typeIdentifier.name = carriage->topToken.identifierValue;

        parseNextToken(carriage);
        return true;
    }
    else
        return false;
}
Example #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;
}
Example #3
0
static bool parseLValueExpression(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode left, ASTNode* result)
{
    if (carriage->topToken.type == TOK_DOT)
    {
        parseNextToken(carriage);

        ASTNode right;
        if (parseIdentifierExpression(stack, carriage, errors, &right))
        {
            result->nodeType = AST_EXPRESSION_DOT;
            result->binary.left = pushMemory<ASTNode>(stack);
            result->binary.right = pushMemory<ASTNode>(stack);

            *result->binary.left = left;
            *result->binary.right = right;

            parseLValueExpression(stack, carriage, errors, *result, result);
            return true;
        }

        return false;
    }
    else
    {
        *result = left;
        return true;
    }
}
Example #4
0
static bool parseAssignment(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode* result)
{
    LexerCarriage tmpCarriage = *carriage;

    ASTNode lValue;
    if (parseLValueExpression(stack, &tmpCarriage, errors, &lValue))
    {
        if (tmpCarriage.topToken.type == TOK_ASSIGN)
        {
            parseNextToken(&tmpCarriage);
            
            result->nodeType = AST_STATEMENT_ASSIGNMENT;
            result->assignment.lineNumber = tmpCarriage.currentLineNumber;
            result->assignment.lValue = pushMemory<ASTNode>(stack);
            result->assignment.expression = pushMemory<ASTNode>(stack);

            *result->assignment.lValue = lValue;
            expectAndEatExpression(stack, &tmpCarriage, errors, result->assignment.expression);

            *carriage = tmpCarriage;
            return true;
        }
    }

    return false;
}
Example #5
0
static bool parseNotExpression(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode* result)
{
    if (carriage->topToken.type == TOK_NOT)
    {
        parseNextToken(carriage);

        result->nodeType = AST_FUNCTION_CALL;
        result->functionCall.identifier = makeSlice("opNot");
        result->functionCall.arguments = {};

        ASTNode node;
        if (parseAddSubExpression(stack, carriage, errors, &node))
        {
            *pushElement(&result->functionCall.arguments, stack) = node;

            return true;
        }
        else
            return false;
    }
    else
    {
        return parseAddSubExpression(stack, carriage, errors, result);
    }
}
Example #6
0
static bool parseAndOrExpression(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode left, ASTNode* result)
{
    if (carriage->topToken.type == TOK_AND)
    {
        parseNextToken(carriage);

        ASTNode right;
        if (parseCompareExpression(stack, carriage, errors, &right))
        {
            makeFunctionCallNode(result, stack, "opAnd", left, right);
            parseAndOrExpression(stack, carriage, errors, *result, result);

            return true;
        }
        else
        {
            pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED, carriage->currentLineNumber });
            return false;
        }
    }
    else if (carriage->topToken.type == TOK_OR)
    {
        parseNextToken(carriage);

        ASTNode right;
        if (parseCompareExpression(stack, carriage, errors, &right))
        {
            makeFunctionCallNode(result, stack, "opOr", left, right);
            parseAndOrExpression(stack, carriage, errors, *result, result);

            return true;
        }
        else
        {
            pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED, carriage->currentLineNumber });
            return false;
        }
    }
    else
    {
        *result = left;
        return true;
    }
}
Example #7
0
static bool parseVariableDefinition(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_DOUBLE_DOT)
        {
            parseNextToken(&tmpCarriage);
            ASTNode typeIdentifier;

            if (parseTypeIdentifier(stack, &tmpCarriage, errors, &typeIdentifier))
            {
                result->nodeType = AST_STATEMENT_VARIABLE_DECLARATION;

                result->variableDeclaration.lineNumber = carriage->currentLineNumber;
                result->variableDeclaration.identifier = identifier.identifierValue;
                result->variableDeclaration.typeIdentifier = pushMemory<ASTNode>(stack);

                *result->variableDeclaration.typeIdentifier = typeIdentifier;

                if (tmpCarriage.topToken.type == TOK_ASSIGN)
                {
                    parseNextToken(&tmpCarriage);

                    result->variableDeclaration.expression = pushMemory<ASTNode>(stack);
                    expectAndEatExpression(stack, &tmpCarriage, errors, result->variableDeclaration.expression);
                }
                else
                    result->variableDeclaration.expression = nullptr;

                *carriage = tmpCarriage;
                return true;
            }
        }
    }

    return false;
};
Example #8
0
LexerCarriage initCarriage(char* text)
{
    LexerCarriage result;
    result.lexingText = makeSlice(text);
    result.posInText = 0;
    result.currentLineNumber = 1;

    parseNextToken(&result);

    return result;
}
Example #9
0
static bool parseMulDivExpression(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode left, ASTNode* result)
{
    if (carriage->topToken.type == TOK_MULTIPLY)
    {
        parseNextToken(carriage);

        ASTNode right;
        if (parseValueExpression(stack, carriage, errors, &right))
        {
            makeFunctionCallNode(result, stack, "opMul", left, right);
            parseMulDivExpression(stack, carriage, errors, *result, result);

            return true;
        }
        else
            pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED, carriage->currentLineNumber });
    }
    else if (carriage->topToken.type == TOK_DIVIDE)
    {
        parseNextToken(carriage);
        
        ASTNode right;
        if (parseValueExpression(stack, carriage, errors, &right))
        {
            makeFunctionCallNode(result, stack, "opDiv", left, right);
            parseMulDivExpression(stack, carriage, errors, *result, result);

            return true;
        }
        else
            pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED, carriage->currentLineNumber });
    }
    else
    {
        *result = left;
        return true;
    }

    return false;
}
Example #10
0
static void expectAndEat(LexerCarriage* carriage, TokenType expect, Array<SyntaxError>* errors)
{
    if (carriage->topToken.type != expect)
    {
        SyntaxError error = SyntaxError{ SET_UNEXPECTED_TOKEN, carriage->currentLineNumber };
        error.unexpectedToken.token = carriage->topToken;
        error.unexpectedToken.expecting = expect;

        pushBack(errors, error);
    }
    else
        parseNextToken(carriage);
}
Example #11
0
static bool parseIdentifierExpression(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode* result)
{
    if (carriage->topToken.type == TOK_IDENTIFIER)
    {
        result->nodeType = AST_EXPRESSION_IDENTIFIER;
        result->identifier.identifier = carriage->topToken.identifierValue;
        result->identifier.lineNumber = carriage->currentLineNumber;

        parseNextToken(carriage);
        return true;
    }

    return false;
}
Example #12
0
// TODO: this is horrible! (and I think is wrong)
static void skipComment(LexerCarriage* carriage)
{
    if (carriage->topToken.type == TOK_ONE_LINE_COMMENT)
    {
        while (carriage->posInText < carriage->lexingText.length)
        {
            ++carriage->posInText;
            if (carriage->lexingText.pointer[carriage->posInText] == '\n')
            {
                break;
            }
        }

        parseNextToken(carriage);
    }
}
Example #13
0
static bool parseValueExpression(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode* result)
{
    if (parseFunctionCall(stack, carriage, errors, result))
        return true;
    else if (parseLValueExpression(stack, carriage, errors, result))
        return true;
    else if (carriage->topToken.type == TOK_NUMBER_CONSTANT)
    {
        result->nodeType = AST_EXPRESSION_CONSTANT;
        result->constantValue = carriage->topToken.constant.value;

        parseNextToken(carriage);
        return true;
    }
    else
        return false;
}
Example #14
0
uint16 Script::readLineToken(bool errorOnEOF) {
	char buf[200];
	char *line = readLine(buf, 200);
	if (!line) {
		if (errorOnEOF)
			error("unexpected end of file while parsing");
		else
			return 0;
	}

	clearTokens();
	while (*line && _numTokens < MAX_TOKENS) {
		line = parseNextToken(line, _tokens[_numTokens], MAX_TOKEN_LEN, " ");
		line = Common::ltrim(line);
		_numTokens++;
	}
	return _numTokens;
}
Example #15
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;
}
Example #16
0
// TODO: add chaining?
static bool parseCompareExpression(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode left, ASTNode* result)
{
    if (carriage->topToken.type == TOK_EQUALS)
    {
        parseNextToken(carriage);

        ASTNode right;
        if (parseNotExpression(stack, carriage, errors, &right))
        {
            makeFunctionCallNode(result, stack, "opEquals", left, right);
            parseCompareExpression(stack, carriage, errors, *result, result);

            return true;
        }
        else
            pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED, carriage->currentLineNumber });
    }
    else if (carriage->topToken.type == TOK_LESS)
    {
        parseNextToken(carriage);

        ASTNode right;
        if (parseNotExpression(stack, carriage, errors, &right))
        {
            makeFunctionCallNode(result, stack, "opLess", left, right);
            parseCompareExpression(stack, carriage, errors, *result, result);

            return true;
        }
        else
            pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED, carriage->currentLineNumber });
    }
    else if (carriage->topToken.type == TOK_GREATER)
    {
        parseNextToken(carriage);

        ASTNode right;
        if (parseNotExpression(stack, carriage, errors, &right))
        {
            makeFunctionCallNode(result, stack, "opGreater", left, right);
            parseCompareExpression(stack, carriage, errors, *result, result);

            return true;
        }
        else
            pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED, carriage->currentLineNumber });
    }
    else if (carriage->topToken.type == TOK_EQUALS_OR_LESS)
    {
        parseNextToken(carriage);

        ASTNode right;
        if (parseNotExpression(stack, carriage, errors, &right))
        {
            makeFunctionCallNode(result, stack, "opEqualsOrLess", left, right);
            parseCompareExpression(stack, carriage, errors, *result, result);

            return true;
        }
        else
            pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED, carriage->currentLineNumber });
    }
    else if (carriage->topToken.type == TOK_EQUALS_OR_GREATER)
    {
        parseNextToken(carriage);
        
        ASTNode right;
        if (parseNotExpression(stack, carriage, errors, &right))
        {
            makeFunctionCallNode(result, stack, "opEqualsOrGreater", left, right);
            parseCompareExpression(stack, carriage, errors, *result, result);

            return true;
        }
        else
            pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED, carriage->currentLineNumber });
    }
    else
    {
        *result = left;
        return true;
    }

    return false;
}