feat(parser): implement object literals to unify struct and slice syntax

Signed-off-by: erick-alcachofa <erick@artichoke.dev>

Implement support for object literals using a unified syntax for both
struct and slice initialization. Since the parser lacks the semantic
context to distinguish between a struct or a slice at this stage, both
are represented by the new `ObjectLiteral` AST node.

initialization within curly braces following a type expression:
* **Named Initializers**: Uses the `.field = value` syntax (e.g.,
  `Point { .x = 10, .y = 20 }`).
* **Positional Initializers**: Uses a comma-separated list of
  expressions (e.g., `[]i32 { 1, 2, 3 }`).

* Renamed `StructLiteral` and `SliceLiteral` nodes to `ObjectLiteral`.
* Refactored initialization helper nodes (e.g.,
  `StructLiteralNamedFieldInit` is now `ObjectLiteralNamedFieldInit`).
* Unified the representation in `Expressions.hpp` and `Literals.hpp` to
  use a single `ObjectLiteral` struct containing a `type` and an
  optional `initializer`.

* Integrated the opening brace `{` (`opLSquirly`) as a high-precedence
  postfix operator (binding power 19).
* Implemented parsing logic in `Expressions.cpp` to handle the
  transition from a type expression to an object initializer.
* Updated `toDot` and `toString` visitors to handle the unified
  `ObjectLiteral` nodes and their respective initializer variants.

* Improved robustness in `Declarations.cpp` by ensuring list parsing
  correctly handles closing braces in specific edge cases.
This commit is contained in:
erick-alcachofa 2025-12-28 00:12:43 -06:00
parent 8dd75e3b8a
commit 3180ca4662
Signed by: me
GPG Key ID: 6FA5F8643444BAFA
9 changed files with 228 additions and 139 deletions

View File

@ -104,6 +104,7 @@ namespace arti::lang::ast {
PtrToSlice, PtrToSlice,
SliceToPtr, SliceToPtr,
Reflect, Reflect,
ObjectLiteral,
}; };
enum class CompoundAssignOperator { enum class CompoundAssignOperator {

View File

@ -76,8 +76,7 @@ namespace arti::lang::ast {
FloatLtrlNode, FloatLtrlNode,
IntegerLtrlNode, IntegerLtrlNode,
BooleanLtrlNode, BooleanLtrlNode,
StructLtrlNode, ObjectLtrlNode,
SliceLtrlNode,
IdentifierExprNode, IdentifierExprNode,
PrefixExprNode, PrefixExprNode,
InfixExprNode, InfixExprNode,
@ -207,30 +206,31 @@ namespace arti::lang::ast {
ExpressionNode object; ExpressionNode object;
}; };
struct nodes::StructLiteralNamedFieldInit { struct nodes::ObjectLiteralNamedFieldInit {
SourceLocation location; SourceLocation location;
String fieldName; String fieldName;
ExpressionNode fieldValue; ExpressionNode fieldValue;
}; };
struct nodes::StructLiteralPositionalInit { struct nodes::ObjectLiteralNamedInitializer {
SourceLocation location; SourceLocation location;
ExpressionNode fieldValue; Vector<ObjectLtrlNamedFieldInitNode> fields;
}; };
struct nodes::StructLiteralNamedInitializer { struct nodes::ObjectLiteralPositionalInitializer {
SourceLocation location; SourceLocation location;
Vector<StructLtrlNamedFieldInitNode> fields; Vector<ExpressionNode> fields;
}; };
struct nodes::StructLiteralPositionalInitializer { struct nodes::ObjectLiteral {
SourceLocation location; SourceLocation location;
Vector<StructLtrlPositionalInitNode> fields; ExpressionNode type;
}; Optional<ObjectLtrlInitializerNode> initializer;
};
} // namespace arti::lang::ast } // namespace arti::lang::ast

View File

@ -37,14 +37,12 @@ namespace arti::lang::ast {
struct FloatLiteral; struct FloatLiteral;
struct IntegerLiteral; struct IntegerLiteral;
struct BooleanLiteral; struct BooleanLiteral;
struct StructLiteral; struct ObjectLiteral;
struct SliceLiteral;
/* Helper declaration node types */ /* Helper declaration node types */
struct StructLiteralNamedFieldInit; struct ObjectLiteralNamedFieldInit;
struct StructLiteralPositionalInit; struct ObjectLiteralNamedInitializer;
struct StructLiteralNamedInitializer; struct ObjectLiteralPositionalInitializer;
struct StructLiteralPositionalInitializer;
} // namespace nodes } // namespace nodes
@ -55,22 +53,19 @@ namespace arti::lang::ast {
using FloatLtrlNode = Ptr<nodes::FloatLiteral>; using FloatLtrlNode = Ptr<nodes::FloatLiteral>;
using IntegerLtrlNode = Ptr<nodes::IntegerLiteral>; using IntegerLtrlNode = Ptr<nodes::IntegerLiteral>;
using BooleanLtrlNode = Ptr<nodes::BooleanLiteral>; using BooleanLtrlNode = Ptr<nodes::BooleanLiteral>;
using StructLtrlNode = Ptr<nodes::StructLiteral>; using ObjectLtrlNode = Ptr<nodes::ObjectLiteral>;
using SliceLtrlNode = Ptr<nodes::SliceLiteral>;
using StructLtrlNamedFieldInitNode = using ObjectLtrlNamedFieldInitNode =
Ptr<nodes::StructLiteralNamedFieldInit>; Ptr<nodes::ObjectLiteralNamedFieldInit>;
using StructLtrlPositionalInitNode = using ObjectLtrlNamedInitializerNode =
Ptr<nodes::StructLiteralPositionalInit>; Ptr<nodes::ObjectLiteralNamedInitializer>;
using StructLtrlNamedInitializerNode = using ObjectLtrlPositionalInitializerNode =
Ptr<nodes::StructLiteralNamedInitializer>; Ptr<nodes::ObjectLiteralPositionalInitializer>;
using StructLtrlPositionalInitializerNode =
Ptr<nodes::StructLiteralPositionalInitializer>;
/* Variant nodes */ /* Variant nodes */
using StructLtrlInitializerNode = Variant< using ObjectLtrlInitializerNode = Variant<
StructLtrlNamedInitializerNode, ObjectLtrlNamedInitializerNode,
StructLtrlPositionalInitializerNode ObjectLtrlPositionalInitializerNode
>; >;
/* Node definitions */ /* Node definitions */
@ -109,20 +104,6 @@ namespace arti::lang::ast {
Boolean value; Boolean value;
}; };
struct nodes::StructLiteral {
SourceLocation location;
TypeNode type;
Optional<StructLtrlInitializerNode> initializer;
};
struct nodes::SliceLiteral {
SourceLocation location;
TypeNode type;
Optional<StructLtrlPositionalInitializerNode> initializer;
};
/* INFO: Helper types definitions are on Expressions.hpp /* INFO: Helper types definitions are on Expressions.hpp
* due to dependency in ExpressionNode variant. */ * due to dependency in ExpressionNode variant. */

View File

@ -178,13 +178,11 @@ namespace arti::lang::ast {
std::string emit(const FloatLtrlNode &, GraphBuilder &); std::string emit(const FloatLtrlNode &, GraphBuilder &);
std::string emit(const IntegerLtrlNode &, GraphBuilder &); std::string emit(const IntegerLtrlNode &, GraphBuilder &);
std::string emit(const BooleanLtrlNode &, GraphBuilder &); std::string emit(const BooleanLtrlNode &, GraphBuilder &);
std::string emit(const StructLtrlNode &, GraphBuilder &); std::string emit(const ObjectLtrlNode &, GraphBuilder &);
std::string emit(const SliceLtrlNode &, GraphBuilder &); std::string emit(const ObjectLtrlNamedFieldInitNode &, GraphBuilder &);
std::string emit(const StructLtrlNamedFieldInitNode &, GraphBuilder &); std::string emit(const ObjectLtrlNamedInitializerNode &, GraphBuilder &);
std::string emit(const StructLtrlPositionalInitNode &, GraphBuilder &); std::string emit(const ObjectLtrlPositionalInitializerNode&, GraphBuilder&);
std::string emit(const StructLtrlNamedInitializerNode &, GraphBuilder &); std::string emit(const ObjectLtrlInitializerNode &, GraphBuilder &);
std::string emit(const StructLtrlPositionalInitializerNode&, GraphBuilder&);
std::string emit(const StructLtrlInitializerNode &, GraphBuilder &);
std::string emit(const IdentifierExprNode &, GraphBuilder &); std::string emit(const IdentifierExprNode &, GraphBuilder &);
std::string emit(const PrefixExprNode &, GraphBuilder &); std::string emit(const PrefixExprNode &, GraphBuilder &);
std::string emit(const InfixExprNode &, GraphBuilder &); std::string emit(const InfixExprNode &, GraphBuilder &);
@ -555,19 +553,8 @@ namespace arti::lang::ast {
} }
// Struct/Slice literals and initializers // Struct/Slice literals and initializers
std::string emit(const StructLtrlNode &node, GraphBuilder &g) { std::string emit(const ObjectLtrlNode &node, GraphBuilder &g) {
auto id = g.makeNode("StructLiteral"); auto id = g.makeNode("ObjectLiteral");
auto t = emit(node->type, g);
g.addEdge(id, t, "Type");
if (node->initializer) {
auto cid = emit(*node->initializer, g);
g.addEdge(id, cid, "Elements");
}
return id;
}
std::string emit(const SliceLtrlNode &node, GraphBuilder &g) {
auto id = g.makeNode("SliceLiteral");
auto t = emit(node->type, g); auto t = emit(node->type, g);
g.addEdge(id, t, "Type"); g.addEdge(id, t, "Type");
if (node->initializer) { if (node->initializer) {
@ -578,7 +565,7 @@ namespace arti::lang::ast {
} }
std::string std::string
emit(const StructLtrlNamedFieldInitNode &node, GraphBuilder &g) { emit(const ObjectLtrlNamedFieldInitNode &node, GraphBuilder &g) {
auto id = g.makeNode("FieldInitializer"); auto id = g.makeNode("FieldInitializer");
auto leaf = makeLeaf(g, node->fieldName); auto leaf = makeLeaf(g, node->fieldName);
g.addEdge(id, leaf, "Field"); g.addEdge(id, leaf, "Field");
@ -588,15 +575,7 @@ namespace arti::lang::ast {
} }
std::string std::string
emit(const StructLtrlPositionalInitNode &node, GraphBuilder &g) { emit(const ObjectLtrlNamedInitializerNode &node, GraphBuilder &g) {
auto id = g.makeNode("PositionalInitializer");
auto val = emit(node->fieldValue, g);
g.addEdge(id, val, "Value");
return id;
}
std::string
emit(const StructLtrlNamedInitializerNode &node, GraphBuilder &g) {
auto id = g.makeNode("InitializerList"); auto id = g.makeNode("InitializerList");
if (! node->fields.empty()) { if (! node->fields.empty()) {
emitGroupVec(g, id, "Elements", node->fields, [&](const auto &f) { emitGroupVec(g, id, "Elements", node->fields, [&](const auto &f) {
@ -607,7 +586,7 @@ namespace arti::lang::ast {
} }
std::string std::string
emit(const StructLtrlPositionalInitializerNode &node, GraphBuilder &g) { emit(const ObjectLtrlPositionalInitializerNode &node, GraphBuilder &g) {
auto id = g.makeNode("InitializerList"); auto id = g.makeNode("InitializerList");
if (! node->fields.empty()) { if (! node->fields.empty()) {
emitGroupVec(g, id, "Elements", node->fields, [&](const auto &f) { emitGroupVec(g, id, "Elements", node->fields, [&](const auto &f) {
@ -617,10 +596,10 @@ namespace arti::lang::ast {
return id; return id;
} }
std::string emit(const StructLtrlInitializerNode &node, GraphBuilder &g) { std::string emit(const ObjectLtrlInitializerNode &node, GraphBuilder &g) {
auto visitor = OverloadSet{ auto visitor = OverloadSet{
[&g](const StructLtrlNamedInitializerNode &n) { return emit(n, g); }, [&g](const ObjectLtrlNamedInitializerNode &n) { return emit(n, g); },
[&g](const StructLtrlPositionalInitializerNode &n) { [&g](const ObjectLtrlPositionalInitializerNode &n) {
return emit(n, g); return emit(n, g);
}, },
}; };
@ -770,8 +749,7 @@ namespace arti::lang::ast {
[&g](const FloatLtrlNode &n) { return emit(n, g); }, [&g](const FloatLtrlNode &n) { return emit(n, g); },
[&g](const IntegerLtrlNode &n) { return emit(n, g); }, [&g](const IntegerLtrlNode &n) { return emit(n, g); },
[&g](const BooleanLtrlNode &n) { return emit(n, g); }, [&g](const BooleanLtrlNode &n) { return emit(n, g); },
[&g](const StructLtrlNode &n) { return emit(n, g); }, [&g](const ObjectLtrlNode &n) { return emit(n, g); },
[&g](const SliceLtrlNode &n) { return emit(n, g); },
[&g](const IdentifierExprNode &n) { return emit(n, g); }, [&g](const IdentifierExprNode &n) { return emit(n, g); },
[&g](const PrefixExprNode &n) { return emit(n, g); }, [&g](const PrefixExprNode &n) { return emit(n, g); },
[&g](const InfixExprNode &n) { return emit(n, g); }, [&g](const InfixExprNode &n) { return emit(n, g); },

View File

@ -53,13 +53,11 @@ namespace arti::lang::ast {
std::string toString(const FloatLtrlNode &, std::string); std::string toString(const FloatLtrlNode &, std::string);
std::string toString(const IntegerLtrlNode &, std::string); std::string toString(const IntegerLtrlNode &, std::string);
std::string toString(const BooleanLtrlNode &, std::string); std::string toString(const BooleanLtrlNode &, std::string);
std::string toString(const StructLtrlNode &, std::string); std::string toString(const ObjectLtrlNode &, std::string);
std::string toString(const SliceLtrlNode &, std::string); std::string toString(const ObjectLtrlNamedFieldInitNode &, std::string);
std::string toString(const StructLtrlNamedFieldInitNode &, std::string); std::string toString(const ObjectLtrlNamedInitializerNode &, std::string);
std::string toString(const StructLtrlPositionalInitNode &, std::string); std::string toString(const ObjectLtrlPositionalInitializerNode&, std::string);
std::string toString(const StructLtrlNamedInitializerNode &, std::string); std::string toString(const ObjectLtrlInitializerNode &, std::string);
std::string toString(const StructLtrlPositionalInitializerNode&, std::string);
std::string toString(const StructLtrlInitializerNode &, std::string);
std::string toString(const IdentifierExprNode &, std::string); std::string toString(const IdentifierExprNode &, std::string);
std::string toString(const PrefixExprNode &, std::string); std::string toString(const PrefixExprNode &, std::string);
std::string toString(const InfixExprNode &, std::string); std::string toString(const InfixExprNode &, std::string);
@ -643,30 +641,9 @@ namespace arti::lang::ast {
return std::format("BooleanLiteral {}", node->value ? "true" : "false"); return std::format("BooleanLiteral {}", node->value ? "true" : "false");
} }
std::string toString(const StructLtrlNode &node, std::string prefix) { std::string toString(const ObjectLtrlNode &node, std::string prefix) {
std::stringstream ss; std::stringstream ss;
ss << "StructLiteral"; ss << "ObjectLiteral";
int total = 1;
if (node->initializer) {
++total;
}
int emitted = 0;
appendGroupOne(ss, prefix, "Type", node->type, ++emitted == total);
if (node->initializer) {
appendGroupOne(
ss,
prefix,
"Elements",
*node->initializer,
++emitted == total
);
}
return ss.str();
}
std::string toString(const SliceLtrlNode &node, std::string prefix) {
std::stringstream ss;
ss << "SliceLiteral";
int total = 1; int total = 1;
if (node->initializer) { if (node->initializer) {
++total; ++total;
@ -686,7 +663,7 @@ namespace arti::lang::ast {
} }
std::string std::string
toString(const StructLtrlNamedFieldInitNode &node, std::string prefix) { toString(const ObjectLtrlNamedFieldInitNode &node, std::string prefix) {
std::stringstream ss; std::stringstream ss;
ss << "FieldInitializer"; ss << "FieldInitializer";
appendGroupLeaf(ss, prefix, "Field", node->fieldName, false); appendGroupLeaf(ss, prefix, "Field", node->fieldName, false);
@ -695,15 +672,7 @@ namespace arti::lang::ast {
} }
std::string std::string
toString(const StructLtrlPositionalInitNode &node, std::string prefix) { toString(const ObjectLtrlNamedInitializerNode &node, std::string prefix) {
std::stringstream ss;
ss << "PositionalInitializer";
appendGroupOne(ss, prefix, "Value", node->fieldValue, true);
return ss.str();
}
std::string
toString(const StructLtrlNamedInitializerNode &node, std::string prefix) {
std::stringstream ss; std::stringstream ss;
ss << "InitializerList"; ss << "InitializerList";
appendGroupVec(ss, prefix, "Elements", node->fields, true); appendGroupVec(ss, prefix, "Elements", node->fields, true);
@ -711,7 +680,7 @@ namespace arti::lang::ast {
} }
std::string toString( std::string toString(
const StructLtrlPositionalInitializerNode &node, const ObjectLtrlPositionalInitializerNode &node,
std::string prefix std::string prefix
) { ) {
std::stringstream ss; std::stringstream ss;
@ -721,12 +690,12 @@ namespace arti::lang::ast {
} }
std::string std::string
toString(const StructLtrlInitializerNode &node, std::string padding) { toString(const ObjectLtrlInitializerNode &node, std::string padding) {
auto visitor = OverloadSet{ auto visitor = OverloadSet{
[padding](const StructLtrlNamedInitializerNode &node) -> std::string { [padding](const ObjectLtrlNamedInitializerNode &node) -> std::string {
return toString(node, padding); return toString(node, padding);
}, },
[padding](const StructLtrlPositionalInitializerNode &node) [padding](const ObjectLtrlPositionalInitializerNode &node)
-> std::string { return toString(node, padding); }, -> std::string { return toString(node, padding); },
}; };
@ -956,10 +925,7 @@ namespace arti::lang::ast {
[padding](const BooleanLtrlNode &node) -> std::string { [padding](const BooleanLtrlNode &node) -> std::string {
return toString(node, padding); return toString(node, padding);
}, },
[padding](const StructLtrlNode &node) -> std::string { [padding](const ObjectLtrlNode &node) -> std::string {
return toString(node, padding);
},
[padding](const SliceLtrlNode &node) -> std::string {
return toString(node, padding); return toString(node, padding);
}, },
[padding](const IdentifierExprNode &node) -> std::string { [padding](const IdentifierExprNode &node) -> std::string {

View File

@ -504,6 +504,13 @@ namespace arti::lang {
} }
} }
} }
if (auto close = match(TokenV::opRSquirly); ! close) {
return Unexpected<>{ std::move(close).error() };
}
else if (close.value()) {
keepParsing = false;
}
} }
return membersList; return membersList;
@ -585,6 +592,13 @@ namespace arti::lang {
} }
} }
} }
if (auto close = match(TokenV::opRSquirly); ! close) {
return Unexpected<>{ std::move(close).error() };
}
else if (close.value()) {
keepParsing = false;
}
} }
return membersList; return membersList;

View File

@ -449,13 +449,6 @@ namespace arti::lang {
} }
} }
} }
if (auto close = match(TokenV::opRParen); ! close) {
return Unexpected<>{ std::move(close).error() };
}
else if (close.value()) {
stillParams = false;
}
} }
if (auto close = consume(TokenV::opRParen, "')'"); ! close) { if (auto close = consume(TokenV::opRParen, "')'"); ! close) {
@ -466,6 +459,155 @@ namespace arti::lang {
node = std::move(newNode); node = std::move(newNode);
} }
else if (op == ast::PostfixOperator::ObjectLiteral) {
auto newNode = ast::MakeNode<ast::ObjectLtrlNode>();
newNode->location = {
.line = peekToken->line,
.column = peekToken->column
};
bool stillParams = true;
if (auto close = match(TokenV::opRSquirly); ! close) {
return Unexpected<>{ std::move(close).error() };
}
else if (close.value()) {
stillParams = false;
}
if (auto isNamed = match(TokenV::opDot); ! isNamed) {
return Unexpected<>{ std::move(isNamed).error() };
}
else if (isNamed.value()) {
auto initializerNode =
ast::MakeNode<ast::ObjectLtrlNamedInitializerNode>();
initializerNode->location = newNode->location;
while (stillParams) {
auto currLocation = ast::SourceLocation{};
if (auto dot = consume(TokenV::opDot, "'.'"); ! dot) {
return Unexpected<>{ std::move(dot).error() };
}
else {
currLocation.line = dot->line;
currLocation.column = dot->column;
}
if (auto ident = consume(TokenV::tkIdentifier, "identifier");
! ident) {
return Unexpected<>{ std::move(ident).error() };
}
else {
if (auto eq = consume(TokenV::opAssign, "'='"); ! eq) {
return Unexpected<>{ std::move(eq).error() };
}
auto value = parseExpression();
if (! value) {
return Unexpected<>{ std::move(value).error() };
}
auto init = ast::MakeNode<ast::ObjectLtrlNamedFieldInitNode>();
init->location = currLocation;
init->fieldName = ident->strValue;
init->fieldValue = std::move(value).value();
initializerNode->fields.push_back(std::move(init));
if (auto comma = matchAndConsume(TokenV::opComma); ! comma) {
return Unexpected{ std::move(comma).error() };
}
else if (! comma.value()) {
if (auto ntok = tokenizer.peek(); ! ntok) {
return Unexpected{ std::move(ntok).error() };
}
else {
if (ntok->value != TokenV::opRSquirly) {
return langException<ExceptCode::ecUnexpectedToken>(
ntok->line,
ntok->column,
toString(*ntok),
"',' or '}'"
);
}
else {
stillParams = false;
}
}
}
}
if (auto close = match(TokenV::opRSquirly); ! close) {
return Unexpected<>{ std::move(close).error() };
}
else if (close.value()) {
stillParams = false;
}
}
newNode->initializer = std::move(initializerNode);
}
else {
auto initializerNode =
ast::MakeNode<ast::ObjectLtrlPositionalInitializerNode>();
initializerNode->location = newNode->location;
while (stillParams) {
auto arg = parseExpression();
if (! arg) {
return Unexpected<>{ std::move(arg).error() };
}
initializerNode->fields.push_back(std::move(arg).value());
if (auto comma = matchAndConsume(TokenV::opComma); ! comma) {
return Unexpected{ std::move(comma).error() };
}
else if (! comma.value()) {
if (auto ntok = tokenizer.peek(); ! ntok) {
return Unexpected{ std::move(ntok).error() };
}
else {
if (ntok->value != TokenV::opRSquirly) {
return langException<ExceptCode::ecUnexpectedToken>(
ntok->line,
ntok->column,
toString(*ntok),
"',' or '}'"
);
}
else {
stillParams = false;
}
}
}
if (auto close = match(TokenV::opRSquirly); ! close) {
return Unexpected<>{ std::move(close).error() };
}
else if (close.value()) {
stillParams = false;
}
}
newNode->initializer = std::move(initializerNode);
}
if (auto close = consume(TokenV::opRSquirly, "'}'"); ! close) {
return Unexpected<>{ std::move(close).error() };
}
newNode->type = std::move(lhs);
node = std::move(newNode);
}
else if (op == ast::PostfixOperator::SliceAccess) { else if (op == ast::PostfixOperator::SliceAccess) {
auto idx = parseExpression(); auto idx = parseExpression();

View File

@ -97,6 +97,7 @@ namespace arti::lang::pratt {
case opPtrSlice: case opPtrSlice:
case opSlicePtr: case opSlicePtr:
case opReflect: case opReflect:
case opLSquirly:
return true; return true;
default: default:
return false; return false;
@ -223,6 +224,8 @@ namespace arti::lang::pratt {
return SliceToPtr; return SliceToPtr;
case opReflect: case opReflect:
return Reflect; return Reflect;
case opLSquirly:
return ObjectLiteral;
default: default:
return Uninitialized; return Uninitialized;
} }

View File

@ -88,9 +88,10 @@ namespace arti::lang::pratt {
case ast::InfixOperator::BoolAndAssignment: case ast::InfixOperator::BoolAndAssignment:
case ast::InfixOperator::BoolOrAssignment: case ast::InfixOperator::BoolOrAssignment:
case ast::InfixOperator::LShiftAssignment: case ast::InfixOperator::LShiftAssignment:
case ast::InfixOperator::RShiftAssignment: return { 2, 1 }; case ast::InfixOperator::RShiftAssignment:
return { 2, 1 };
default: return { 0, 0 }; default:
return { 0, 0 };
} }
} }
@ -103,8 +104,11 @@ namespace arti::lang::pratt {
case ast::PostfixOperator::SliceSize: case ast::PostfixOperator::SliceSize:
case ast::PostfixOperator::PtrToSlice: case ast::PostfixOperator::PtrToSlice:
case ast::PostfixOperator::SliceToPtr: case ast::PostfixOperator::SliceToPtr:
case ast::PostfixOperator::Reflect: return 19; case ast::PostfixOperator::Reflect:
default: return 0; case ast::PostfixOperator::ObjectLiteral:
return 19;
default:
return 0;
} }
} }