Updated function signatures
This commit is contained in:
@@ -71,6 +71,10 @@ int main(int argc, char** argv)
|
||||
{
|
||||
Util::Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
Util::PrintContainer("Function AST", functionsAST.Result());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -15,17 +15,22 @@ namespace LXC::Internal
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
||||
}
|
||||
|
||||
bool IsWhitespace(const char c)
|
||||
static constexpr bool IsWhitespace(const char c)
|
||||
{
|
||||
return c == ' ' || c == '\t' || c == '\n' || c == '\r';
|
||||
}
|
||||
|
||||
static constexpr bool IsSymbolOrOperator(const char c)
|
||||
static constexpr bool IsOperator(const char c)
|
||||
{
|
||||
return
|
||||
c == '+' || c == '-' ||
|
||||
c == '*' || c == '/' ||
|
||||
c == '%' || c == '=' ||
|
||||
c == '%' || c == '=';
|
||||
}
|
||||
|
||||
static constexpr bool IsSymbol(const char c)
|
||||
{
|
||||
return
|
||||
c == ',' || c == '[' ||
|
||||
c == ']' || c == '{' ||
|
||||
c == '}' || c == '(' ||
|
||||
@@ -33,7 +38,7 @@ namespace LXC::Internal
|
||||
c == '>';
|
||||
}
|
||||
|
||||
static const std::unordered_map<std::string_view, Lexer::Token::TokenType> symbolAndOpMap =
|
||||
static const std::unordered_map<std::string_view, Lexer::Token::TokenType> operatorMap =
|
||||
{
|
||||
{ "+", Lexer::Token::Add },
|
||||
{ "-", Lexer::Token::Sub },
|
||||
@@ -43,20 +48,24 @@ namespace LXC::Internal
|
||||
|
||||
{ "==", Lexer::Token::Eql },
|
||||
|
||||
{ "=", Lexer::Token::Assign },
|
||||
{ ",", Lexer::Token::Comma },
|
||||
{ "=", Lexer::Token::Assign }
|
||||
};
|
||||
|
||||
{ "[", Lexer::Token::CloseBracket },
|
||||
{ "]", Lexer::Token::OpenBracket },
|
||||
static const std::unordered_map<char, Lexer::Token::TokenType> symbolMap =
|
||||
{
|
||||
{ ',', Lexer::Token::Comma },
|
||||
|
||||
{ "}", Lexer::Token::CloseBrace },
|
||||
{ "{", Lexer::Token::OpenBrace },
|
||||
{ '[', Lexer::Token::CloseBracket },
|
||||
{ ']', Lexer::Token::OpenBracket },
|
||||
|
||||
{ ")", Lexer::Token::CloseParen },
|
||||
{ "(", Lexer::Token::OpenParen },
|
||||
{ '}', Lexer::Token::CloseBrace },
|
||||
{ '{', Lexer::Token::OpenBrace },
|
||||
|
||||
{ ">", Lexer::Token::CloseCrocodile },
|
||||
{ "<", Lexer::Token::OpenCrocodile }
|
||||
{ ')', Lexer::Token::CloseParen },
|
||||
{ '(', Lexer::Token::OpenParen },
|
||||
|
||||
{ '>', Lexer::Token::CloseCrocodile },
|
||||
{ '<', Lexer::Token::OpenCrocodile }
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string_view, Lexer::Token::TokenType> keywords =
|
||||
@@ -87,7 +96,7 @@ namespace LXC::Lexer
|
||||
bool inStrLiteral = false;
|
||||
bool inIdentifier = false;
|
||||
bool inNumLiteral = false;
|
||||
bool inSymbolOrOp = false;
|
||||
bool inOperator = false;
|
||||
|
||||
bool inComment = false;
|
||||
|
||||
@@ -155,22 +164,22 @@ namespace LXC::Lexer
|
||||
}
|
||||
}
|
||||
|
||||
// === Symbols/Operators === //
|
||||
else if (Internal::IsSymbolOrOperator(current))
|
||||
// === Operators === //
|
||||
else if (Internal::IsOperator(current))
|
||||
{
|
||||
// Updates trackers //
|
||||
trackers.sectionStart = trackers.inSymbolOrOp ? trackers.sectionStart : ctx.index;
|
||||
trackers.inSymbolOrOp = true;
|
||||
trackers.sectionStart = trackers.inOperator ? trackers.sectionStart : ctx.index;
|
||||
trackers.inOperator = true;
|
||||
|
||||
// Checks for the end of the symbol or operator //
|
||||
if (!Internal::IsSymbolOrOperator(next)) _LIKELY
|
||||
if (!Internal::IsOperator(next)) _LIKELY
|
||||
{
|
||||
trackers.inSymbolOrOp = false;
|
||||
trackers.inOperator = false;
|
||||
|
||||
// Finds the operator/symbol if it can //
|
||||
std::string_view fullSymbol(ctx.source.data() + trackers.sectionStart, ctx.index - trackers.sectionStart + 1);
|
||||
auto it = Internal::symbolAndOpMap.find(fullSymbol);
|
||||
if (it != Internal::symbolAndOpMap.end())
|
||||
auto it = Internal::operatorMap.find(fullSymbol);
|
||||
if (it != Internal::operatorMap.end())
|
||||
ctx.out.emplace_back(ctx, trackers.sectionStart, (unsigned short)(ctx.index - trackers.sectionStart + 1), it->second);
|
||||
|
||||
else
|
||||
@@ -178,6 +187,12 @@ namespace LXC::Lexer
|
||||
}
|
||||
}
|
||||
|
||||
// === Symbols === //
|
||||
else if (Internal::IsSymbol(current))
|
||||
{
|
||||
ctx.out.emplace_back(ctx, ctx.index, 1, Internal::symbolMap.at(current));
|
||||
}
|
||||
|
||||
// === Whitespace === //
|
||||
else if (Internal::IsWhitespace(current)) _LIKELY {}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ func<int> fib(int num)
|
||||
return fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
|
||||
func<int> main(void)
|
||||
func<int> main()
|
||||
{
|
||||
int res = fib(8)
|
||||
return res == 21
|
||||
|
||||
@@ -3,7 +3,7 @@ func<int> add(int a, int b)
|
||||
return a + b
|
||||
}
|
||||
|
||||
func<int> main(void)
|
||||
func<int> main()
|
||||
{
|
||||
int c = add(3, 4)
|
||||
if (c == 7)
|
||||
|
||||
@@ -12,15 +12,33 @@ namespace LXC::Parser
|
||||
struct FunctionAST
|
||||
{
|
||||
FunctionAST() :
|
||||
name{}, contents{}
|
||||
name{}, contents{}, funcParams{}
|
||||
{}
|
||||
|
||||
FunctionAST(FunctionAST&& other) noexcept :
|
||||
name{}, contents{}
|
||||
name(std::move(other.name)), contents(std::move(other.contents)), funcParams(std::move(other.funcParams))
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
std::vector<std::pair<std::string, std::string>> funcParams;
|
||||
|
||||
AST::SyntaxBranch contents;
|
||||
|
||||
std::string LogStr() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << name << " (";
|
||||
|
||||
for (size_t i = 0; i < funcParams.size(); i++)
|
||||
{
|
||||
os << funcParams[i].first << ' ' << funcParams[i].second;
|
||||
if (i != funcParams.size() - 1)
|
||||
os << ", ";
|
||||
}
|
||||
|
||||
os << ")";
|
||||
return os.str();
|
||||
}
|
||||
};
|
||||
|
||||
Util::ReturnVal<std::vector<FunctionAST>, ParserError> TurnTokensIntoAST(const Lexer::LexerOutput& input);
|
||||
|
||||
@@ -63,39 +63,6 @@ namespace LXC::Parser
|
||||
const size_t length;
|
||||
};
|
||||
|
||||
static void ParseBlock(ParserContext& ctx)
|
||||
{
|
||||
// Local lamdba for working out if at the end (static to avoid double initalisation) //
|
||||
static const std::function<bool(const ParserContext&)> AtEnd = [](const ParserContext& context)
|
||||
{
|
||||
// Peeks the current tokens type //
|
||||
const Lexer::Token* current = context.Peek();
|
||||
if (current != nullptr)
|
||||
{
|
||||
return current->type == Lexer::Token::CloseBrace;
|
||||
}
|
||||
|
||||
// If nullptr means it has overflowed so it is at the end //
|
||||
return true;
|
||||
};
|
||||
|
||||
// Loops over the body until it reaches the end //
|
||||
while (!AtEnd(ctx))
|
||||
{
|
||||
// Force ends if it has gone over the end of the tokens //
|
||||
const Lexer::Token* current = ctx.Advance();
|
||||
if (current != nullptr)
|
||||
{
|
||||
// Recurses if at the start of another block //
|
||||
if (current->type == Lexer::Token::OpenBrace)
|
||||
ParseBlock(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// Advances over the ending close brace //
|
||||
ctx.Advance();
|
||||
}
|
||||
|
||||
static Util::ReturnVal<FunctionAST, ParserError> ParseFunction(ParserContext& ctx)
|
||||
{
|
||||
// Checks for the sequence of: func<T> funcName( //
|
||||
@@ -130,6 +97,8 @@ namespace LXC::Parser
|
||||
const Lexer::Token* paramType = ctx.At();
|
||||
const Lexer::Token* paramName = ctx.Advance();
|
||||
|
||||
currentFunction.funcParams.emplace_back(paramType->Str(), paramName->Str());
|
||||
|
||||
// Expects a comma or close bracket for the next token //
|
||||
const Lexer::Token* end = ctx.Advance();
|
||||
if (end == nullptr)
|
||||
@@ -143,12 +112,23 @@ namespace LXC::Parser
|
||||
}
|
||||
|
||||
// Parses the function body //
|
||||
ParseBlock(ctx);
|
||||
ctx.Advance(); // <- Goes over the closing brace
|
||||
|
||||
const Lexer::Token* current = ctx.At();
|
||||
while (current != nullptr)
|
||||
{
|
||||
if (current->type == Lexer::Token::CloseBrace)
|
||||
{
|
||||
// Advances over closing brace before returning the function //
|
||||
ctx.Advance();
|
||||
return currentFunction;
|
||||
}
|
||||
|
||||
// Advances to the next token //
|
||||
current = ctx.Advance();
|
||||
}
|
||||
|
||||
return Util::FunctionFail<ParserError>(); // <- TODO: Make an actual error
|
||||
}
|
||||
|
||||
Util::ReturnVal<std::vector<FunctionAST>, ParserError> TurnTokensIntoAST(const Lexer::LexerOutput& input)
|
||||
{
|
||||
// Creates the context of the Parser from the tokens and the output of the function //
|
||||
@@ -171,6 +151,8 @@ namespace LXC::Parser
|
||||
if (func.Failed())
|
||||
return Util::FunctionFail<ParserError>(func.Error());
|
||||
|
||||
ctx.output.emplace_back(std::move(func.Result()));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,6 @@ namespace LXC::Lexer
|
||||
Token::CloseCrocodile, // >
|
||||
Token::Identifier, // main
|
||||
Token::OpenParen, // (
|
||||
Token::Identifier, // void
|
||||
Token::CloseParen, // )
|
||||
Token::OpenBrace, // {
|
||||
Token::Identifier, // int
|
||||
@@ -243,7 +242,6 @@ namespace LXC::Lexer
|
||||
Token::CloseCrocodile, // >
|
||||
Token::Identifier, // main
|
||||
Token::OpenParen, // (
|
||||
Token::Identifier, // void
|
||||
Token::CloseParen, // )
|
||||
|
||||
Token::OpenBrace, // {
|
||||
|
||||
Reference in New Issue
Block a user