Initial Parser Implementation and Feature Completion #1

Merged
me merged 16 commits from parser-dev into main 2025-12-28 11:54:12 -06:00
5 changed files with 88 additions and 16 deletions
Showing only changes of commit 30d64d9b65 - Show all commits

View File

@ -93,7 +93,8 @@ namespace arti::lang::ast {
WhileStmtNode,
DoWhileStmtNode,
InfLoopStmtNode,
ExpressionStmtNode
ExpressionStmtNode,
CodeBlockStmtNode
>;
using ElseBranchNode = Variant<

View File

@ -1002,6 +1002,7 @@ namespace arti::lang::ast {
[&g](const DoWhileStmtNode &n) { return emit(n, g); },
[&g](const InfLoopStmtNode &n) { return emit(n, g); },
[&g](const ExpressionStmtNode &n) { return emit(n, g); },
[&g](const CodeBlockStmtNode &n) { return emit(n, g); },
};
return std::visit(visitor, node);
}

View File

@ -1419,6 +1419,9 @@ namespace arti::lang::ast {
[padding](const ExpressionStmtNode &node) -> std::string {
return toString(node, padding);
},
[padding](const CodeBlockStmtNode &node) -> std::string {
return toString(node, padding);
}
};
return std::visit(visitor, node);

View File

@ -468,6 +468,13 @@ namespace arti::lang {
bool keepParsing = true;
if (auto close = match(TokenV::opRSquirly); ! close) {
return Unexpected{ std::move(close).error() };
}
else if (close.value()) {
keepParsing = false;
}
while (keepParsing) {
if (auto member = parseStructMember(); ! member) {
return Unexpected{ std::move(member).error() };
@ -479,13 +486,22 @@ namespace arti::lang {
if (auto comma = matchAndConsume(TokenV::opComma); ! comma) {
return Unexpected<>{ std::move(comma).error() };
}
if (auto peekToken = tokenizer.peek(); ! peekToken) {
return Unexpected{ std::move(peekToken).error() };
}
else {
if (peekToken->value == TokenV::opRSquirly) {
keepParsing = false;
else if (! comma.value()) {
if (auto peekToken = tokenizer.peek(); ! peekToken) {
return Unexpected{ std::move(peekToken).error() };
}
else {
if (peekToken->value != TokenV::opRSquirly) {
return langException<ExceptCode::ecUnexpectedToken>(
peekToken->line,
peekToken->column,
toString(*peekToken),
"',' or '}'"
);
}
else {
keepParsing = false;
}
}
}
}
@ -533,6 +549,13 @@ namespace arti::lang {
bool keepParsing = true;
if (auto close = match(TokenV::opRSquirly); ! close) {
return Unexpected{ std::move(close).error() };
}
else if (close.value()) {
keepParsing = false;
}
while (keepParsing) {
if (auto member = parseEnumMember(); ! member) {
return Unexpected{ std::move(member).error() };
@ -544,13 +567,22 @@ namespace arti::lang {
if (auto comma = matchAndConsume(TokenV::opComma); ! comma) {
return Unexpected<>{ std::move(comma).error() };
}
if (auto peekToken = tokenizer.peek(); ! peekToken) {
return Unexpected{ std::move(peekToken).error() };
}
else {
if (peekToken->value == TokenV::opRSquirly) {
keepParsing = false;
else if (! comma.value()) {
if (auto peekToken = tokenizer.peek(); ! peekToken) {
return Unexpected{ std::move(peekToken).error() };
}
else {
if (peekToken->value != TokenV::opRSquirly) {
return langException<ExceptCode::ecUnexpectedToken>(
peekToken->line,
peekToken->column,
toString(*peekToken),
"',' or '}'"
);
}
else {
keepParsing = false;
}
}
}
}

View File

@ -36,6 +36,13 @@ namespace arti::lang {
return Unexpected<>{ std::move(lsquirly).error() };
}
if (auto close = match(TokenV::opRSquirly); ! close) {
return Unexpected<>{ std::move(close).error() };
}
else if (close.value()) {
keepParsing = false;
}
while (keepParsing) {
if (auto ok = parseStatement(); ! ok) {
return Unexpected<>{ std::move(ok).error() };
@ -50,6 +57,13 @@ namespace arti::lang {
node->statements.push_back(std::move(stmt).value());
}
}
if (auto close = match(TokenV::opRSquirly); ! close) {
return Unexpected<>{ std::move(close).error() };
}
else if (close.value()) {
keepParsing = false;
}
}
if (auto rsquirly = consume(TokenV::opRSquirly, "'}'"); ! rsquirly) {
@ -300,6 +314,23 @@ namespace arti::lang {
return ast::StatementNode{ std::move(stmt).value() };
}
}
else if (peekToken->value == TokenV::opLSquirly) {
if (label.has_value()) {
return langException<ExceptCode::ecUnexpectedToken>(
peekToken->line,
peekToken->column,
toString(*peekToken),
"loop keyword, i.e. any of ( for, while, do, loop )"
);
}
if (auto stmt = parseCodeBlock(); ! stmt) {
return Unexpected<>{ std::move(stmt).error() };
}
else {
return ast::StatementNode{ std::move(stmt).value() };
}
}
else {
if (label.has_value()) {
return langException<ExceptCode::ecUnexpectedToken>(
@ -981,7 +1012,7 @@ namespace arti::lang {
return Unexpected<>{ std::move(lParen).error() };
}
if (auto skipPre = match(TokenV::opSemicolon); ! skipPre) {
if (auto skipPre = matchAndConsume(TokenV::opSemicolon); ! skipPre) {
return Unexpected<>{ std::move(skipPre).error() };
}
else if (not skipPre.value()) {
@ -1234,6 +1265,10 @@ namespace arti::lang {
return Unexpected<>{ std::move(rParen).error() };
}
if (auto rParen = consume(TokenV::opSemicolon, "';'"); ! rParen) {
return Unexpected<>{ std::move(rParen).error() };
}
return node;
}