Add support for parsing member expressions

This commit is contained in:
Sam Vervaeck 2023-05-22 11:54:52 +02:00
parent 09fcaccedc
commit bce5bffa85
Signed by: samvv
SSH key fingerprint: SHA256:dIg0ywU1OP+ZYifrYxy8c5esO72cIKB+4/9wkZj1VaY
7 changed files with 77 additions and 6 deletions

View file

@ -75,6 +75,7 @@ namespace bolt {
ReferenceExpression,
MatchCase,
MatchExpression,
MemberExpression,
NestedExpression,
ConstantExpression,
CallExpression,
@ -1117,6 +1118,31 @@ namespace bolt {
};
class MemberExpression : public Expression {
public:
Expression* E;
Dot* Dot;
Token* Name;
inline MemberExpression(
class Expression* E,
class Dot* Dot,
Token* Name
): Expression(NodeKind::MemberExpression),
E(E),
Dot(Dot),
Name(Name) {}
Token* getFirstToken() override;
Token* getLastToken() override;
inline Expression* getExpression() const {
return E;
}
};
class NestedExpression : public Expression {
public:

View file

@ -109,6 +109,8 @@ namespace bolt {
return static_cast<D*>(this)->visitMatchCase(static_cast<MatchCase*>(N));
case NodeKind::MatchExpression:
return static_cast<D*>(this)->visitMatchExpression(static_cast<MatchExpression*>(N));
case NodeKind::MemberExpression:
return static_cast<D*>(this)->visitMemberExpression(static_cast<MemberExpression*>(N));
case NodeKind::NestedExpression:
return static_cast<D*>(this)->visitNestedExpression(static_cast<NestedExpression*>(N));
case NodeKind::ConstantExpression:
@ -372,6 +374,10 @@ namespace bolt {
visitExpression(N);
}
void visitMemberExpression(MemberExpression* N) {
visitExpression(N);
}
void visitNestedExpression(NestedExpression* N) {
visitExpression(N);
}
@ -607,6 +613,9 @@ namespace bolt {
case NodeKind::MatchExpression:
visitEachChild(static_cast<MatchExpression*>(N));
break;
case NodeKind::MemberExpression:
visitEachChild(static_cast<MemberExpression*>(N));
break;
case NodeKind::NestedExpression:
visitEachChild(static_cast<NestedExpression*>(N));
break;
@ -861,6 +870,12 @@ namespace bolt {
}
}
void visitEachChild(MemberExpression* N) {
BOLT_VISIT(N->getExpression());
BOLT_VISIT(N->Dot);
BOLT_VISIT(N->Name);
}
void visitEachChild(NestedExpression* N) {
BOLT_VISIT(N->LParen);
BOLT_VISIT(N->Inner);

View file

@ -1,5 +1,4 @@
#pragma once
#include "zen/config.hpp"

View file

@ -78,6 +78,7 @@ namespace bolt {
Expression* parseInfixOperatorAfterExpression(Expression* LHS, int MinPrecedence);
Expression* parseMemberExpression();
Expression* parsePrimitiveExpression();
ConstraintExpression* parseConstraintExpression();

View file

@ -275,6 +275,14 @@ namespace bolt {
return BlockStart;
}
Token* MemberExpression::getFirstToken() {
return E->getFirstToken();
}
Token* MemberExpression::getLastToken() {
return Name;
}
Token* NestedExpression::getFirstToken() {
return LParen;
}

View file

@ -1,9 +1,7 @@
// TODO Add list of CST variable names to TVar and unify them so that e.g. the typeclass checker may pick one when displaying a diagnostic
// TODO make sure that if we have Eq Int, Eq a ~ Eq Int such that an instance binding eq has the correct type
// TODO make unficiation work like union-find in find()
// TODO (maybe) make unficiation work like union-find in find()
#include <algorithm>
#include <iterator>
@ -1184,7 +1182,8 @@ namespace bolt {
bool Checker::unify(Type* A, Type* B, Node* Source) {
auto find = [&](auto Ty) {
auto find = [&](auto OrigTy) {
auto Ty = OrigTy;
while (Ty->getKind() == TypeKind::Var) {
auto Match = Solution.find(static_cast<TVar*>(Ty));
if (Match == Solution.end()) {

View file

@ -279,8 +279,31 @@ after_constraints:
}
}
Expression* Parser::parseMemberExpression() {
auto E = parsePrimitiveExpression();
for (;;) {
auto T1 = Tokens.peek(0);
auto T2 = Tokens.peek(1);
if (!llvm::isa<Dot>(T1)) {
break;
}
switch (T2->getKind()) {
case NodeKind::IntegerLiteral:
case NodeKind::Identifier:
Tokens.get();
Tokens.get();
E = new MemberExpression { E, static_cast<Dot*>(T1), T2 };
break;
default:
goto finish;
}
}
finish:
return E;
}
Expression* Parser::parseCallExpression() {
auto Operator = parsePrimitiveExpression();
auto Operator = parseMemberExpression();
std::vector<Expression*> Args;
for (;;) {
auto T1 = Tokens.peek();