Parse function arguments and return type
This commit is contained in:
@@ -23,7 +23,7 @@ string Expression::toString(int indent) {
|
||||
//
|
||||
// ExpressionBinary
|
||||
ExpressionBinary::ExpressionBinary(shared_ptr<Token> token, shared_ptr<Expression> left, shared_ptr<Expression> right):
|
||||
Expression(ExpressionKind::BINARY, ValueType::VOID), left(left), right(right) {
|
||||
Expression(ExpressionKind::BINARY, ValueType::NONE), left(left), right(right) {
|
||||
// Types must match
|
||||
if (left->getValueType() != right->getValueType())
|
||||
exit(1);
|
||||
@@ -124,7 +124,7 @@ string ExpressionBinary::toString(int indent) {
|
||||
//
|
||||
// ExpressionLiteral
|
||||
ExpressionLiteral::ExpressionLiteral(shared_ptr<Token> token):
|
||||
Expression(ExpressionKind::LITERAL, ValueType::VOID) {
|
||||
Expression(ExpressionKind::LITERAL, ValueType::NONE) {
|
||||
switch (token->getKind()) {
|
||||
case TokenKind::BOOL:
|
||||
boolValue = token->getLexme().compare("true") == 0;
|
||||
@@ -157,8 +157,8 @@ float ExpressionLiteral::getReal32Value() {
|
||||
|
||||
string ExpressionLiteral::toString(int indent) {
|
||||
switch (valueType) {
|
||||
case ValueType::VOID:
|
||||
return "VOID";
|
||||
case ValueType::NONE:
|
||||
return "NONE";
|
||||
case ValueType::BOOL:
|
||||
return boolValue ? "true" : "false";
|
||||
case ValueType::SINT32:
|
||||
@@ -185,7 +185,7 @@ string ExpressionGrouping::toString(int indent) {
|
||||
//
|
||||
// ExpressionIfElse
|
||||
ExpressionIfElse::ExpressionIfElse(shared_ptr<Expression> condition, shared_ptr<StatementBlock> thenBlock, shared_ptr<StatementBlock> elseBlock):
|
||||
Expression(ExpressionKind::IF_ELSE, ValueType::VOID), condition(condition), thenBlock(thenBlock), elseBlock(elseBlock) {
|
||||
Expression(ExpressionKind::IF_ELSE, ValueType::NONE), condition(condition), thenBlock(thenBlock), elseBlock(elseBlock) {
|
||||
// Condition must evaluate to bool
|
||||
if (condition->getValueType() != ValueType::BOOL)
|
||||
exit(1);
|
||||
@@ -199,7 +199,7 @@ Expression(ExpressionKind::IF_ELSE, ValueType::VOID), condition(condition), then
|
||||
exit(1);
|
||||
|
||||
// get type or default to void
|
||||
valueType = thenExpression ? thenExpression->getValueType() : ValueType::VOID;
|
||||
valueType = thenExpression ? thenExpression->getValueType() : ValueType::NONE;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> ExpressionIfElse::getCondition() {
|
||||
@@ -235,7 +235,7 @@ string ExpressionIfElse::toString(int indent) {
|
||||
//
|
||||
// ExpressionVar
|
||||
ExpressionVar::ExpressionVar(string name):
|
||||
Expression(ExpressionKind::VAR, ValueType::VOID), name(name) {
|
||||
Expression(ExpressionKind::VAR, ValueType::NONE), name(name) {
|
||||
}
|
||||
|
||||
string ExpressionVar::getName() {
|
||||
@@ -249,7 +249,7 @@ string ExpressionVar::toString(int indent) {
|
||||
//
|
||||
// ExpressionInvalid
|
||||
ExpressionInvalid::ExpressionInvalid(shared_ptr<Token> token):
|
||||
Expression(ExpressionKind::INVALID, ValueType::VOID), token(token) {
|
||||
Expression(ExpressionKind::INVALID, ValueType::NONE), token(token) {
|
||||
}
|
||||
|
||||
shared_ptr<Token> ExpressionInvalid::getToken() {
|
||||
|
||||
@@ -112,6 +112,10 @@ shared_ptr<Token> Lexer::nextToken() {
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(TokenKind::COMMA, ",", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(TokenKind::COLON, ":", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
@@ -191,6 +195,7 @@ shared_ptr<Token> Lexer::nextToken() {
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
// literal
|
||||
token = match(TokenKind::BOOL, "true", true);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
@@ -199,7 +204,6 @@ shared_ptr<Token> Lexer::nextToken() {
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
// literal
|
||||
token = matchReal();
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
@@ -208,11 +212,20 @@ shared_ptr<Token> Lexer::nextToken() {
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
// identifier
|
||||
token = matchType();
|
||||
// type
|
||||
token = match(TokenKind::TYPE, "bool", true);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(TokenKind::TYPE, "sint32", true);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(TokenKind::TYPE, "real32", true);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
// identifier
|
||||
token = matchIdentifier();
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
@@ -280,30 +293,6 @@ shared_ptr<Token> Lexer::matchReal() {
|
||||
return token;
|
||||
}
|
||||
|
||||
shared_ptr<Token> Lexer::matchType() {
|
||||
bool isVarDec = tokens.size() >= 2 &&
|
||||
tokens.at(tokens.size() - 1)->getKind() == TokenKind::COLON &&
|
||||
tokens.at(tokens.size() - 2)->getKind() == TokenKind::IDENTIFIER;
|
||||
|
||||
bool isFunDec = tokens.size() >= 1 &&
|
||||
tokens.at(tokens.size() - 1)->getKind() == TokenKind::RIGHT_ARROW;
|
||||
|
||||
if (!isVarDec && !isFunDec)
|
||||
return nullptr;
|
||||
|
||||
int nextIndex = currentIndex;
|
||||
while (nextIndex < source.length() && isIdentifier(nextIndex))
|
||||
nextIndex++;
|
||||
|
||||
if (nextIndex == currentIndex || !isSeparator(nextIndex))
|
||||
return nullptr;
|
||||
|
||||
string lexme = source.substr(currentIndex, nextIndex - currentIndex);
|
||||
shared_ptr<Token> token = make_shared<Token>(TokenKind::TYPE, lexme, currentLine, currentColumn);
|
||||
advanceWithToken(token);
|
||||
return token;
|
||||
}
|
||||
|
||||
shared_ptr<Token> Lexer::matchIdentifier() {
|
||||
int nextIndex = currentIndex;
|
||||
|
||||
@@ -365,6 +354,7 @@ bool Lexer::isSeparator(int index) {
|
||||
case '>':
|
||||
case '(':
|
||||
case ')':
|
||||
case ',':
|
||||
case ':':
|
||||
case ';':
|
||||
case ' ':
|
||||
|
||||
@@ -20,7 +20,7 @@ private:
|
||||
shared_ptr<Token> match(TokenKind kind, string lexme, bool needsSeparator);
|
||||
shared_ptr<Token> matchInteger();
|
||||
shared_ptr<Token> matchReal();
|
||||
shared_ptr<Token> matchType();
|
||||
//shared_ptr<Token> matchType();
|
||||
shared_ptr<Token> matchIdentifier();
|
||||
shared_ptr<Token> matchEnd();
|
||||
shared_ptr<Token> matchInvalid();
|
||||
|
||||
@@ -97,7 +97,7 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr<ExpressionLiteral> expression) {
|
||||
switch (expression->getValueType()) {
|
||||
case ValueType::VOID:
|
||||
case ValueType::NONE:
|
||||
return llvm::UndefValue::get(typeVoid);
|
||||
case ValueType::BOOL:
|
||||
return llvm::ConstantInt::get(typeBool, expression->getBoolValue(), true);
|
||||
@@ -257,7 +257,7 @@ llvm::Value *ModuleBuilder::valueForVar(shared_ptr<ExpressionVar> expression) {
|
||||
|
||||
llvm::Type *ModuleBuilder::typeForValueType(ValueType valueType) {
|
||||
switch (valueType) {
|
||||
case ValueType::VOID:
|
||||
case ValueType::NONE:
|
||||
return typeVoid;
|
||||
case ValueType::BOOL:
|
||||
return typeBool;
|
||||
|
||||
@@ -45,32 +45,51 @@ shared_ptr<Statement> Parser::nextStatement() {
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementFunctionDeclaration() {
|
||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::COLON, TokenKind::FUNCTION}, true, false))
|
||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::FUNCTION}, true, false))
|
||||
return nullptr;
|
||||
|
||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex);
|
||||
currentIndex++;
|
||||
currentIndex++; // skip colon
|
||||
currentIndex++; // skip fun
|
||||
|
||||
// Return type
|
||||
ValueType returnType = ValueType::VOID;
|
||||
if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) {
|
||||
shared_ptr<Token> valueTypeToken = tokens.at(currentIndex);
|
||||
|
||||
if (valueTypeToken->getLexme().compare("bool") == 0)
|
||||
returnType = ValueType::BOOL;
|
||||
else if (valueTypeToken->getLexme().compare("sint32") == 0)
|
||||
returnType = ValueType::SINT32;
|
||||
else if (valueTypeToken->getLexme().compare("real32") == 0)
|
||||
returnType = ValueType::REAL32;
|
||||
else
|
||||
return matchStatementInvalid("Expected return type");
|
||||
|
||||
currentIndex++; // type
|
||||
// Get arguments
|
||||
vector<pair<string, ValueType>> arguments;
|
||||
if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) {
|
||||
do {
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line
|
||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false))
|
||||
return matchStatementInvalid("Expected function argument");
|
||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex);
|
||||
currentIndex++; // identifier
|
||||
shared_ptr<Token> typeToken = tokens.at(currentIndex);
|
||||
currentIndex++; // type
|
||||
optional<ValueType> argumentType = valueTypeForToken(typeToken);
|
||||
if (!argumentType)
|
||||
return matchStatementInvalid("Invalid argument type");
|
||||
|
||||
arguments.push_back(pair<string, ValueType>(identifierToken->getLexme(), *argumentType));
|
||||
} while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true));
|
||||
}
|
||||
|
||||
// consume optional new line
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
|
||||
|
||||
// Return type
|
||||
ValueType returnType = ValueType::NONE;
|
||||
if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) {
|
||||
shared_ptr<Token> typeToken = tokens.at(currentIndex);
|
||||
optional<ValueType> type = valueTypeForToken(typeToken);
|
||||
if (!type)
|
||||
return matchStatementInvalid("Expected return type");
|
||||
returnType = *type;
|
||||
|
||||
currentIndex++; // type
|
||||
|
||||
// consume new line
|
||||
if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true))
|
||||
return matchStatementInvalid("Expected new line after function declaration");
|
||||
}
|
||||
|
||||
currentIndex++; // new line
|
||||
shared_ptr<Statement> statementBlock = matchStatementBlock({TokenKind::SEMICOLON}, true);
|
||||
if (statementBlock == nullptr)
|
||||
return matchStatementInvalid();
|
||||
@@ -80,7 +99,7 @@ shared_ptr<Statement> Parser::matchStatementFunctionDeclaration() {
|
||||
if(!tryMatchingTokenKinds({TokenKind::NEW_LINE}, false, true))
|
||||
return matchStatementInvalid("Expected a new line after a function declaration");
|
||||
|
||||
return make_shared<StatementFunctionDeclaration>(identifierToken->getLexme(), returnType, dynamic_pointer_cast<StatementBlock>(statementBlock));
|
||||
return make_shared<StatementFunctionDeclaration>(identifierToken->getLexme(), arguments, returnType, dynamic_pointer_cast<StatementBlock>(statementBlock));
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementVarDeclaration() {
|
||||
@@ -94,7 +113,7 @@ shared_ptr<Statement> Parser::matchStatementVarDeclaration() {
|
||||
|
||||
ValueType valueType;
|
||||
if (valueTypeToken->getLexme().compare("bool") == 0)
|
||||
valueType = ValueType::BOOL;
|
||||
valueType = ValueType::BOOL;
|
||||
else if (valueTypeToken->getLexme().compare("sint32") == 0)
|
||||
valueType = ValueType::SINT32;
|
||||
else if (valueTypeToken->getLexme().compare("real32") == 0)
|
||||
@@ -395,3 +414,17 @@ bool Parser::tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
optional<ValueType> Parser::valueTypeForToken(shared_ptr<Token> token) {
|
||||
if (token->getKind() != TokenKind::TYPE)
|
||||
return {};
|
||||
|
||||
if (token->getLexme().compare("bool") == 0)
|
||||
return ValueType::BOOL;
|
||||
else if (token->getLexme().compare("sint32") == 0)
|
||||
return ValueType::SINT32;
|
||||
else if (token->getLexme().compare("real32") == 0)
|
||||
return ValueType::REAL32;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ private:
|
||||
shared_ptr<ExpressionInvalid> matchExpressionInvalid();
|
||||
|
||||
bool tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance);
|
||||
optional<ValueType> valueTypeForToken(shared_ptr<Token> token);
|
||||
|
||||
public:
|
||||
Parser(vector<shared_ptr<Token>> tokens);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
string valueTypeToString(ValueType valueType) {
|
||||
switch (valueType) {
|
||||
case ValueType::VOID:
|
||||
case ValueType::NONE:
|
||||
return "NONE";
|
||||
case ValueType::BOOL:
|
||||
return "BOOL";
|
||||
@@ -32,14 +32,18 @@ string Statement::toString(int indent) {
|
||||
|
||||
//
|
||||
// StatementFunctionDeclaration
|
||||
StatementFunctionDeclaration::StatementFunctionDeclaration(string name, ValueType returnValueType, shared_ptr<StatementBlock> statementBlock):
|
||||
Statement(StatementKind::FUNCTION_DECLARATION), name(name), returnValueType(returnValueType), statementBlock(statementBlock) {
|
||||
StatementFunctionDeclaration::StatementFunctionDeclaration(string name, vector<pair<string, ValueType>> arguments, ValueType returnValueType, shared_ptr<StatementBlock> statementBlock):
|
||||
Statement(StatementKind::FUNCTION_DECLARATION), name(name), arguments(arguments), returnValueType(returnValueType), statementBlock(statementBlock) {
|
||||
}
|
||||
|
||||
string StatementFunctionDeclaration::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
vector<pair<string, ValueType>> StatementFunctionDeclaration::getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
ValueType StatementFunctionDeclaration::getReturnValueType() {
|
||||
return returnValueType;
|
||||
}
|
||||
|
||||
@@ -34,12 +34,14 @@ public:
|
||||
class StatementFunctionDeclaration: public Statement {
|
||||
private:
|
||||
string name;
|
||||
vector<pair<string, ValueType>> arguments;
|
||||
ValueType returnValueType;
|
||||
shared_ptr<StatementBlock> statementBlock;
|
||||
|
||||
public:
|
||||
StatementFunctionDeclaration(string name, ValueType returnValueType, shared_ptr<StatementBlock> statementBlock);
|
||||
StatementFunctionDeclaration(string name, vector<pair<string, ValueType>> arguments, ValueType returnValueType, shared_ptr<StatementBlock> statementBlock);
|
||||
string getName();
|
||||
vector<pair<string, ValueType>> getArguments();
|
||||
ValueType getReturnValueType();
|
||||
shared_ptr<StatementBlock> getStatementBlock();
|
||||
string toString(int indent) override;
|
||||
|
||||
@@ -104,6 +104,8 @@ string Token::toString() {
|
||||
return "(";
|
||||
case TokenKind::RIGHT_PAREN:
|
||||
return ")";
|
||||
case TokenKind::COMMA:
|
||||
return ",";
|
||||
case TokenKind::COLON:
|
||||
return ":";
|
||||
case TokenKind::SEMICOLON:
|
||||
|
||||
@@ -17,6 +17,7 @@ enum class TokenKind {
|
||||
|
||||
LEFT_PAREN,
|
||||
RIGHT_PAREN,
|
||||
COMMA,
|
||||
COLON,
|
||||
SEMICOLON,
|
||||
QUESTION,
|
||||
@@ -58,7 +59,7 @@ enum class StatementKind {
|
||||
};
|
||||
|
||||
enum class ValueType {
|
||||
VOID,
|
||||
NONE,
|
||||
BOOL,
|
||||
SINT32,
|
||||
REAL32
|
||||
|
||||
Reference in New Issue
Block a user