Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/cangjie/Macro/NodeSerialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define CANGJIE_MODULES_NODESERIALIZATION_H

#include <cstdint>
#include <functional>
#include <string>
#include <vector>

Expand Down Expand Up @@ -77,6 +78,10 @@ class NodeWriter {
}
uint8_t* ExportNode(); // uint8_t* -> unsafePtr in CangJie
private:
using ExprSerializer = std::function<NodeFormatExpr(NodeWriter&, AstExpr)>;
static const ExprSerializer* FindPrimaryExprSerializer(AST::ASTKind kind);
static const ExprSerializer* FindSecondaryExprSerializer(AST::ASTKind kind);

std::vector<uint8_t> bufferData;
Ptr<AST::Node> nodePtr = nullptr; // nodePtr is the AST node to be serialized
flatbuffers::Offset<NodeFormat::DeclBase> emptyDeclBase = flatbuffers::Offset<NodeFormat::DeclBase>();
Expand Down Expand Up @@ -119,6 +124,7 @@ class NodeWriter {
flatbuffers::Offset<NodeFormat::Expr> SerializeLitConstExpr(AstExpr expr);
flatbuffers::Offset<NodeFormat::Expr> SerializeUnaryExpr(AstExpr expr);
flatbuffers::Offset<NodeFormat::Expr> SerializeParenExpr(AstExpr expr);
flatbuffers::Offset<NodeFormat::Expr> SerializeAmbiguousForcedCastExpr(AstExpr expr);
flatbuffers::Offset<NodeFormat::Expr> SerializeCallExpr(const AST::Expr* expr);
flatbuffers::Offset<NodeFormat::Expr> SerializeRefExpr(const AST::Expr* expr);
flatbuffers::Offset<NodeFormat::Expr> SerializeReturnExpr(AstExpr expr);
Expand Down
9 changes: 9 additions & 0 deletions schema/NodeFormat.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ union AnyExpr {
ARRAY_EXPR: ArrayExpr,
PERFORM_EXPR: PerformExpr,
RESUME_EXPR: ResumeExpr,
AMBIGUOUS_FORCED_CAST_EXPR: AmbiguousForcedCastExpr,
}

table MatchCase {
Expand Down Expand Up @@ -202,6 +203,14 @@ table ParenExpr {
right_paren_pos: Position;
}

table AmbiguousForcedCastExpr {
base: NodeBase;
type: Type;
left_paren_pos: Position;
expr: Expr;
right_paren_pos: Position;
}

table LitConstExpr {
base: NodeBase;
literal: string;
Expand Down
136 changes: 83 additions & 53 deletions src/Macro/ExprSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,20 @@ flatbuffers::Offset<NodeFormat::Expr> NodeWriter::SerializeParenExpr(AstExpr exp
return NodeFormat::CreateExpr(builder, fbNodeBase, NodeFormat::AnyExpr_PAREN_EXPR, fbParenExpr.Union());
}

flatbuffers::Offset<NodeFormat::Expr> NodeWriter::SerializeAmbiguousForcedCastExpr(AstExpr expr)
{
auto forcedCastExpr = RawStaticCast<const AmbiguousForcedCastExpr*>(expr);
auto fbNodeBase = SerializeNodeBase(forcedCastExpr);
auto type = SerializeType(forcedCastExpr->type.get());
auto leftParenPos = FlatPosCreateHelper(forcedCastExpr->leftParenPos);
auto operand = SerializeExpr(forcedCastExpr->rightExpr.get());
auto rightParenPos = FlatPosCreateHelper(forcedCastExpr->rightParenPos);
auto fbForcedCastExpr = NodeFormat::CreateAmbiguousForcedCastExpr(
builder, fbNodeBase, type, &leftParenPos, operand, &rightParenPos);
return NodeFormat::CreateExpr(builder, fbNodeBase, NodeFormat::AnyExpr_AMBIGUOUS_FORCED_CAST_EXPR,
fbForcedCastExpr.Union());
}

flatbuffers::Offset<NodeFormat::FuncArg> NodeWriter::SerializeFuncArg(AstFuncArg funcArg)
{
if (funcArg == nullptr) {
Expand Down Expand Up @@ -632,65 +646,81 @@ flatbuffers::Offset<NodeFormat::Expr> NodeWriter::SerializeArrayExpr(AstExpr exp
return NodeFormat::CreateExpr(builder, base, NodeFormat::AnyExpr_ARRAY_EXPR, fbArrayExpr.Union());
}

const NodeWriter::ExprSerializer* NodeWriter::FindPrimaryExprSerializer(AST::ASTKind kind)
{
static std::unordered_map<AST::ASTKind, ExprSerializer> serializers = {
{ASTKind::WILDCARD_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeWildcardExpr(expr); }},
{ASTKind::BINARY_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeBinaryExpr(expr); }},
{ASTKind::LIT_CONST_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeLitConstExpr(expr); }},
{ASTKind::UNARY_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeUnaryExpr(expr); }},
{ASTKind::PAREN_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeParenExpr(expr); }},
{ASTKind::AMBIGUOUS_FORCED_CAST_EXPR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializeAmbiguousForcedCastExpr(expr); }},
{ASTKind::CALL_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeCallExpr(expr); }},
{ASTKind::REF_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeRefExpr(expr); }},
{ASTKind::RETURN_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeReturnExpr(expr); }},
{ASTKind::ASSIGN_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeAssignExpr(expr); }},
{ASTKind::MEMBER_ACCESS, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeMemberAccess(expr); }},
{ASTKind::IF_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeIfExpr(expr); }},
{ASTKind::BLOCK, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeBlockExpr(expr); }},
{ASTKind::LAMBDA_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeLambdaExpr(expr); }},
{ASTKind::TYPE_CONV_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeTypeConvExpr(expr); }},
{ASTKind::FOR_IN_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeForInExpr(expr); }},
{ASTKind::ARRAY_LIT, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeArrayLit(expr); }},
{ASTKind::TUPLE_LIT, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeTupleLit(expr); }},
{ASTKind::SUBSCRIPT_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeSubscriptExpr(expr); }},
{ASTKind::RANGE_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeRangeExpr(expr); }},
{ASTKind::MATCH_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeMatchExpr(expr); }},
{ASTKind::TRY_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeTryExpr(expr); }},
};
auto serializer = serializers.find(kind);
return serializer == serializers.end() ? nullptr : &serializer->second;
}

const NodeWriter::ExprSerializer* NodeWriter::FindSecondaryExprSerializer(AST::ASTKind kind)
{
static std::unordered_map<AST::ASTKind, ExprSerializer> serializers = {
{ASTKind::THROW_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeThrowExpr(expr); }},
{ASTKind::PERFORM_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializePerformExpr(expr); }},
{ASTKind::RESUME_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeResumeExpr(expr); }},
{ASTKind::JUMP_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeJumpExpr(expr); }},
{ASTKind::WHILE_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeWhileExpr(expr); }},
{ASTKind::DO_WHILE_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeDoWhileExpr(expr); }},
{ASTKind::INC_OR_DEC_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeIncOrDecExpr(expr); }},
{ASTKind::TOKEN_PART, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeTokenPart(expr); }},
{ASTKind::QUOTE_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeQuoteExpr(expr); }},
{ASTKind::IS_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeIsExpr(expr); }},
{ASTKind::AS_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeAsExpr(expr); }},
{ASTKind::SPAWN_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeSpawnExpr(expr); }},
{ASTKind::SYNCHRONIZED_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeSynchronizedExpr(expr); }},
{ASTKind::OPTIONAL_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeOptionalExpr(expr); }},
{ASTKind::OPTIONAL_CHAIN_EXPR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializeOptionalChainExpr(expr); }},
{ASTKind::TRAIL_CLOSURE_EXPR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializeTrailingClosureExpr(expr); }},
{ASTKind::PRIMITIVE_TYPE_EXPR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializePrimitiveTypeExpr(expr); }},
{ASTKind::LET_PATTERN_DESTRUCTOR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializeLetPatternDestructor(expr); }},
{ASTKind::MACRO_EXPAND_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeMacroExpandExpr(expr); }},
{ASTKind::ARRAY_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeArrayExpr(expr); }},
};
auto serializer = serializers.find(kind);
return serializer == serializers.end() ? nullptr : &serializer->second;
}

flatbuffers::Offset<NodeFormat::Expr> NodeWriter::SerializeExpr(AstExpr expr)
{
if (expr == nullptr) {
return flatbuffers::Offset<NodeFormat::Expr>();
}
static std::unordered_map<AST::ASTKind, std::function<NodeFormatExpr(NodeWriter & nw, AstExpr expr)>>
serializeExprMap = {
{ASTKind::WILDCARD_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeWildcardExpr(expr); }},
{ASTKind::BINARY_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeBinaryExpr(expr); }},
{ASTKind::LIT_CONST_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeLitConstExpr(expr); }},
{ASTKind::UNARY_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeUnaryExpr(expr); }},
{ASTKind::PAREN_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeParenExpr(expr); }},
{ASTKind::CALL_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeCallExpr(expr); }},
{ASTKind::REF_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeRefExpr(expr); }},
{ASTKind::RETURN_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeReturnExpr(expr); }},
{ASTKind::ASSIGN_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeAssignExpr(expr); }},
{ASTKind::MEMBER_ACCESS, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeMemberAccess(expr); }},
{ASTKind::IF_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeIfExpr(expr); }},
{ASTKind::BLOCK, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeBlockExpr(expr); }},
{ASTKind::LAMBDA_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeLambdaExpr(expr); }},
{ASTKind::TYPE_CONV_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeTypeConvExpr(expr); }},
{ASTKind::FOR_IN_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeForInExpr(expr); }},
{ASTKind::ARRAY_LIT, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeArrayLit(expr); }},
{ASTKind::TUPLE_LIT, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeTupleLit(expr); }},
{ASTKind::SUBSCRIPT_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeSubscriptExpr(expr); }},
{ASTKind::RANGE_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeRangeExpr(expr); }},
{ASTKind::MATCH_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeMatchExpr(expr); }},
{ASTKind::TRY_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeTryExpr(expr); }},
{ASTKind::THROW_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeThrowExpr(expr); }},
{ASTKind::PERFORM_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializePerformExpr(expr); }},
{ASTKind::RESUME_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeResumeExpr(expr); }},
{ASTKind::JUMP_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeJumpExpr(expr); }},
{ASTKind::WHILE_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeWhileExpr(expr); }},
{ASTKind::DO_WHILE_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeDoWhileExpr(expr); }},
{ASTKind::INC_OR_DEC_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeIncOrDecExpr(expr); }},
{ASTKind::TOKEN_PART, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeTokenPart(expr); }},
{ASTKind::QUOTE_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeQuoteExpr(expr); }},
{ASTKind::IS_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeIsExpr(expr); }},
{ASTKind::AS_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeAsExpr(expr); }},
{ASTKind::SPAWN_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeSpawnExpr(expr); }},
{ASTKind::SYNCHRONIZED_EXPR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializeSynchronizedExpr(expr); }},
{ASTKind::OPTIONAL_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeOptionalExpr(expr); }},
{ASTKind::OPTIONAL_CHAIN_EXPR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializeOptionalChainExpr(expr); }},
{ASTKind::TRAIL_CLOSURE_EXPR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializeTrailingClosureExpr(expr); }},
{ASTKind::PRIMITIVE_TYPE_EXPR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializePrimitiveTypeExpr(expr); }},
{ASTKind::LET_PATTERN_DESTRUCTOR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializeLetPatternDestructor(expr); }},
{ASTKind::MACRO_EXPAND_EXPR,
[](NodeWriter& nw, AstExpr expr) { return nw.SerializeMacroExpandExpr(expr); }},
{ASTKind::ARRAY_EXPR, [](NodeWriter& nw, AstExpr expr) { return nw.SerializeArrayExpr(expr); }},
};
// Match ReplaceExpr func.
auto serializeFunc = serializeExprMap.find(expr->astKind);
if (serializeFunc != serializeExprMap.end()) {
return serializeFunc->second(*this, expr);
auto serializer = FindPrimaryExprSerializer(expr->astKind);
if (serializer == nullptr) {
serializer = FindSecondaryExprSerializer(expr->astKind);
}
if (serializer != nullptr) {
return (*serializer)(*this, expr);
}
Errorln("Expr Not Supported in Libast Yet\n");
return flatbuffers::Offset<NodeFormat::Expr>();
Expand Down
9 changes: 8 additions & 1 deletion src/Macro/MacroUpdateInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ template <> void UpdateSingleMacroInfo<ASTKind::BINARY_EXPR>(Node& curNode, Macr
UpdateExpr(parent->leftExpr, parent, collector);
}

template <> void UpdateSingleMacroInfo<ASTKind::AMBIGUOUS_FORCED_CAST_EXPR>(Node& curNode, MacroCollector& collector)
{
auto parent = StaticAs<ASTKind::AMBIGUOUS_FORCED_CAST_EXPR>(&curNode);
UpdateExpr(parent->leftExpr, parent, collector);
UpdateExpr(parent->rightExpr, parent, collector);
}

template <> void UpdateSingleMacroInfo<ASTKind::ENUM_DECL>(Node& curNode, MacroCollector& collector)
{
auto parent = StaticAs<ASTKind::ENUM_DECL>(&curNode);
Expand Down Expand Up @@ -174,4 +181,4 @@ void UpdateMacroInfo(const Ptr<AST::Node> node, MacroCollector& collector)

}

#endif
#endif
Loading