[Parser] Start parser

This commit is contained in:
jstefanelli 2025-05-02 15:02:20 +02:00
parent e0a8808c31
commit 70e0dd3e01
Signed by: jstefanelli
GPG key ID: 60EDE2437640D2AA

View file

@ -16,13 +16,21 @@ namespace jlx {
Expression,
Block,
FunctionDeclaration,
SimpleIdentifier,
LiteralValue
VariableDeclaration,
LiteralValue,
IfStatement,
};
export enum class literal_value_type {
Boolean,
Numeric,
String,
Character,
};
export template<class T>
concept token_iterator = requires() {
requires std::same_as<decltype(typename T::value_type), jlx::token>;
requires std::same_as<typename T::value_type, jlx::token>;
std::bidirectional_iterator<T>;
};
@ -32,6 +40,8 @@ namespace jlx {
statement(ast_type type) : type(type) {
}
virtual ~statement() = default;
};
struct root_statement : public statement {
@ -39,20 +49,35 @@ namespace jlx {
}
root_statement(std::vector<std::unique_ptr<statement>> statements) : statement(Root), statements(std::move(statements)) {
}
std::vector<std::unique_ptr<statement>> statements;
~root_statement() override = default;
};
struct expression : public statement {
expression() : statement(Expression) {
}
~expression() override = default;
};
struct block : public statement {
block() : statement(Block) {
}
block(std::vector<std::unique_ptr<statement>> statements) : statement(Block), statements(std::move(statements)) {
}
std::vector<std::unique_ptr<statement>> statements;
~block() override = default;
};
struct function_parameter {
@ -65,12 +90,41 @@ namespace jlx {
}
function_declaration(std::string name, std::vector<function_parameter> parameters, std::optional<std::string> return_type, std::unique_ptr<block> body) :
statement(FunctionDeclaration), name(std::move(name)), parameters(std::move(parameters)), return_type(std::move(return_type)), body(std::move(body)) {
}
std::string name;
std::vector<function_parameter> parameters;
std::optional<std::string> return_type;
std::unique_ptr<block> body;
~function_declaration() override = default;
};
struct variable_declaration : public statement {
variable_declaration() : statement(VariableDeclaration) {
}
bool constant;
std::string name;
std::optional<std::string> type;
std::unique_ptr<expression> initial_expression;
~variable_declaration() override = default;
};
struct if_statement : public statement {
if_statement() : statement(IfStatement) {
}
std::unique_ptr<expression> condition;
std::unique_ptr<block> block;
};
export template<token_iterator T, std::sentinel_for<T> E>
class parser {
@ -99,9 +153,101 @@ namespace jlx {
}
next();
while(current->type != Punctuation && current->type != "}") {
while(current->type != Punctuation && current->content != "}") {
}
return nullptr;
}
std::unique_ptr<variable_declaration> parse_variable_declaration() {
if (current->type != Keyword) {
fail_invalid_token(*current);
}
std::string name;
std::optional<std::string> type = std::nullopt;
std::unique_ptr<expression> starting_value = nullptr;
bool constant;
if (current->content == "let") {
constant = true;
} else if (current->content == "var") {
constant = false;
} else {
fail_invalid_token(*current);
return nullptr;
}
next();
if (current->type != Identifier) {
fail_invalid_token(*current);
}
name = current->content;
next();
if (current->type == Punctuation && current->content == ":") {
next();
if (current->type != Identifier) {
fail_invalid_token(*current);
}
type = current->content;
next();
}
if (current->type == Operator && current->content == "=") {
next();
starting_value = parse_expression();
}
auto var = std::make_unique<variable_declaration>();
var->constant = constant;
var->name = std::move(name);
var->type = std::move(type);
var->initial_expression = std::move(starting_value);
return var;
}
std::unique_ptr<if_statement> parse_if_statement() {
if (current->type != Keyword || current->content != "if") {
fail_invalid_token(*current);
}
next();
if (current->type != Punctuation || current->content != "(") {
fail_invalid_token(*current);
}
next();
auto expr = parse_expression();
if (current->type != Punctuation || current->content != ")") {
fail_invalid_token(*current);
}
next();
auto block = parse_block();
auto statement = std::make_unique<if_statement>();
statement->block = std::move(block);
statement->condition = std::move(expr);
return statement;
}
std::unique_ptr<expression> parse_expression() {
return nullptr;
}
std::unique_ptr<function_declaration> parse_function() {
@ -154,8 +300,8 @@ namespace jlx {
next();
auto param_type = parse_type(current, last);
params.push_back(std::move(name), std::move(param_type));
auto param_type = parse_type();
params.emplace_back(std::move(name), std::move(param_type));
next();
first = false;
@ -165,7 +311,7 @@ namespace jlx {
if (current->type == Punctuation && current->content == ":") {
next();
return_type = parse_type(current, last);
return_type = parse_type();
next();
}
@ -188,36 +334,35 @@ namespace jlx {
}
if (current->type == token_type::Keyword) {
switch(current->content) {
case "let":
case "var":
parse_variable_declaration(current, last);
break;
case "if":
parse_if_statement(current, last);
break;
case "fun":
return parse_function(current, last);
if (current->content == "let" || current->content == "var") {
return parse_variable_declaration();
} else if (current->content == "if") {
return parse_if_statement();
} else if (current->content == "fun") {
return parse_function();
}
}
return nullptr;
}
public:
parser(T current, E last) : current(current), last(last) {
}
public:
parser(T current, E last) : current(current), last(last) {
std::unique_ptr<statement> parse() {
}
std::vector<std::unique_ptr<statement>> top_level_statements;
while(current != last) {
auto s = parse_top_level_statement();
if (s == nullptr) {
throw std::runtime_error("No statement parsed...");
}
top_level_statements.push_back(std::move(s));
std::unique_ptr<statement> parse() {
std::vector<std::unique_ptr<statement>> top_level_statements;
while(current != last) {
auto s = parse_top_level_statement();
if (s == nullptr) {
throw std::runtime_error("No statement parsed...");
}
return std::make_unique<root_statement>(top_level_statements);
top_level_statements.push_back(std::move(s));
}
return std::make_unique<root_statement>(std::move(top_level_statements));
}
};
}