Skip to content
Merged
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
65 changes: 64 additions & 1 deletion ast/expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,25 @@
PositionalArgs []BLangExpression
// TODO: Add support for NamedArgs
}

BLangMappingKey struct {
BLangNodeBase
Expr BLangExpression
ComputedKey bool
}

BLangMappingKeyValueField struct {
BLangNodeBase
Key *BLangMappingKey
ValueExpr BLangExpression
Readonly bool
}

BLangMappingConstructorExpr struct {
BLangExpressionBase
Fields []model.MappingField
AtomicType semtypes.MappingAtomicType
}
)

var (
Expand All @@ -293,7 +312,7 @@
_ model.LiteralNode = &BLangConstRef{}
_ model.LiteralNode = &BLangLiteral{}
_ BLangExpression = &BLangLiteral{}
_ model.RecordVarNameFieldNode = &BLangConstRef{}
_ model.MappingVarNameFieldNode = &BLangConstRef{}
_ model.DynamicArgNode = &BLangDynamicArgExpr{}
_ model.ElvisExpressionNode = &BLangElvisExpr{}
_ model.MarkdownDocumentationTextAttributeNode = &BLangMarkdownDocumentationLine{}
Expand All @@ -316,6 +335,12 @@
_ BLangExpression = &BLangTypeConversionExpr{}
_ BLangExpression = &BLangErrorConstructorExpr{}
_ BLangNode = &BLangErrorConstructorExpr{}
_ model.MappingConstructor = &BLangMappingConstructorExpr{}
_ model.MappingKeyValueFieldNode = &BLangMappingKeyValueField{}
_ BLangExpression = &BLangMappingConstructorExpr{}
_ BLangNode = &BLangMappingConstructorExpr{}
_ model.Node = &BLangMappingKey{}
_ BLangNode = &BLangMappingKey{}
)

var (
Expand Down Expand Up @@ -348,6 +373,9 @@
_ BLangNode = &BLangIndexBasedAccess{}
_ BLangNode = &BLangListConstructorExpr{}
_ BLangNode = &BLangTypeConversionExpr{}
_ BLangNode = &BLangMappingConstructorExpr{}
_ BLangNode = &BLangMappingKeyValueField{}
_ BLangNode = &BLangMappingKey{}
)

var (
Expand Down Expand Up @@ -954,6 +982,41 @@
panic("not implemented")
}

func (this *BLangMappingKey) GetKind() model.NodeKind {
panic("BLangMappingKey has no NodeKind")

Check warning on line 986 in ast/expressions.go

View check run for this annotation

Codecov / codecov/patch

ast/expressions.go#L985-L986

Added lines #L985 - L986 were not covered by tests
}

func (this *BLangMappingKeyValueField) GetKind() model.NodeKind {
return model.NodeKind_RECORD_LITERAL_KEY_VALUE

Check warning on line 990 in ast/expressions.go

View check run for this annotation

Codecov / codecov/patch

ast/expressions.go#L989-L990

Added lines #L989 - L990 were not covered by tests
}

func (this *BLangMappingKeyValueField) GetKey() model.ExpressionNode {
if this.Key == nil {
return nil

Check warning on line 995 in ast/expressions.go

View check run for this annotation

Codecov / codecov/patch

ast/expressions.go#L993-L995

Added lines #L993 - L995 were not covered by tests
}
return this.Key.Expr

Check warning on line 997 in ast/expressions.go

View check run for this annotation

Codecov / codecov/patch

ast/expressions.go#L997

Added line #L997 was not covered by tests
}

func (this *BLangMappingKeyValueField) GetValue() model.ExpressionNode {
return this.ValueExpr

Check warning on line 1001 in ast/expressions.go

View check run for this annotation

Codecov / codecov/patch

ast/expressions.go#L1000-L1001

Added lines #L1000 - L1001 were not covered by tests
}

func (this *BLangMappingKeyValueField) IsKeyValueField() bool {
return true

Check warning on line 1005 in ast/expressions.go

View check run for this annotation

Codecov / codecov/patch

ast/expressions.go#L1004-L1005

Added lines #L1004 - L1005 were not covered by tests
}

func (this *BLangMappingConstructorExpr) GetKind() model.NodeKind {
return model.NodeKind_RECORD_LITERAL_EXPR

Check warning on line 1009 in ast/expressions.go

View check run for this annotation

Codecov / codecov/patch

ast/expressions.go#L1008-L1009

Added lines #L1008 - L1009 were not covered by tests
}

func (this *BLangMappingConstructorExpr) GetFields() []model.MappingField {
return this.Fields

Check warning on line 1013 in ast/expressions.go

View check run for this annotation

Codecov / codecov/patch

ast/expressions.go#L1012-L1013

Added lines #L1012 - L1013 were not covered by tests
}

func (this *BLangMappingConstructorExpr) SetTypeCheckedType(ty BType) {
this.ExpectedType = ty

Check warning on line 1017 in ast/expressions.go

View check run for this annotation

Codecov / codecov/patch

ast/expressions.go#L1016-L1017

Added lines #L1016 - L1017 were not covered by tests
}

func createBLangUnaryExpr(location Location, operator model.OperatorKind, expr BLangExpression) *BLangUnaryExpr {
exprNode := &BLangUnaryExpr{}
exprNode.pos = location
Expand Down
66 changes: 64 additions & 2 deletions ast/node_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1795,7 +1795,53 @@
}

func (n *NodeBuilder) TransformMappingConstructorExpression(mappingConstructorExpressionNode *tree.MappingConstructorExpressionNode) BLangNode {
panic("TransformMappingConstructorExpression unimplemented")
mappingConstructor := &BLangMappingConstructorExpr{
Fields: make([]model.MappingField, 0),
}
fields := mappingConstructorExpressionNode.FieldNodes()
for i := 0; i < fields.Size(); i += 2 {
field := fields.Get(i)
switch field.Kind() {
case common.SPREAD_FIELD:
panic("mapping constructor spread field not implemented")
case common.COMPUTED_NAME_FIELD:
computedNameField := field.(*tree.ComputedNameFieldNode)
keyExpr := n.createExpression(computedNameField.FieldNameExpr())
key := &BLangMappingKey{
Expr: keyExpr,
ComputedKey: true,

Check warning on line 1812 in ast/node_builder.go

View check run for this annotation

Codecov / codecov/patch

ast/node_builder.go#L1805-L1812

Added lines #L1805 - L1812 were not covered by tests
}
key.SetPosition(getPosition(computedNameField.FieldNameExpr()))
keyValueField := &BLangMappingKeyValueField{
Key: key,
ValueExpr: n.createExpression(computedNameField.ValueExpr()),

Check warning on line 1817 in ast/node_builder.go

View check run for this annotation

Codecov / codecov/patch

ast/node_builder.go#L1814-L1817

Added lines #L1814 - L1817 were not covered by tests
}
keyValueField.SetPosition(getPosition(computedNameField))
mappingConstructor.Fields = append(mappingConstructor.Fields, keyValueField)

Check warning on line 1820 in ast/node_builder.go

View check run for this annotation

Codecov / codecov/patch

ast/node_builder.go#L1819-L1820

Added lines #L1819 - L1820 were not covered by tests
case common.SPECIFIC_FIELD:
specificField := field.(*tree.SpecificFieldNode)
if specificField.ValueExpr() == nil {
panic("mapping constructor var-name field not implemented")

Check warning on line 1824 in ast/node_builder.go

View check run for this annotation

Codecov / codecov/patch

ast/node_builder.go#L1824

Added line #L1824 was not covered by tests
}
keyExpr := n.createExpression(specificField.FieldName())
key := &BLangMappingKey{
Expr: keyExpr,
ComputedKey: false,
}
key.SetPosition(getPosition(specificField.FieldName()))
keyValueField := &BLangMappingKeyValueField{
Key: key,
ValueExpr: n.createExpression(specificField.ValueExpr()),
Readonly: specificField.ReadonlyKeyword() != nil,
}
keyValueField.SetPosition(getPosition(specificField))
mappingConstructor.Fields = append(mappingConstructor.Fields, keyValueField)
default:
panic(fmt.Sprintf("unexpected mapping field kind: %v", field.Kind()))

Check warning on line 1840 in ast/node_builder.go

View check run for this annotation

Codecov / codecov/patch

ast/node_builder.go#L1839-L1840

Added lines #L1839 - L1840 were not covered by tests
}
}
mappingConstructor.SetPosition(getPosition(mappingConstructorExpressionNode))
return mappingConstructor
}

func (n *NodeBuilder) TransformIndexedExpression(indexedExpressionNode *tree.IndexedExpressionNode) BLangNode {
Expand Down Expand Up @@ -2097,7 +2143,23 @@
}

func (n *NodeBuilder) TransformMapTypeDescriptor(mapTypeDescriptorNode *tree.MapTypeDescriptorNode) BLangNode {
panic("TransformMapTypeDescriptor unimplemented")
refType := &BLangBuiltInRefTypeNode{
TypeKind: model.TypeKind_MAP,
}
refType.SetPosition(getPosition(mapTypeDescriptorNode))

mapTypeParamsNode := mapTypeDescriptorNode.MapTypeParamsNode()
if mapTypeParamsNode == nil || mapTypeParamsNode.TypeNode() == nil {
panic("map type requires type parameter")

Check warning on line 2153 in ast/node_builder.go

View check run for this annotation

Codecov / codecov/patch

ast/node_builder.go#L2153

Added line #L2153 was not covered by tests
}
constraint := n.createTypeNode(mapTypeParamsNode.TypeNode())

constrainedType := &BLangConstrainedType{
Type: model.TypeData{TypeDescriptor: refType},
Constraint: model.TypeData{TypeDescriptor: constraint},
}
constrainedType.SetPosition(refType.GetPosition())
return constrainedType
}

func (n *NodeBuilder) TransformNilLiteral(nilLiteralNode *tree.NilLiteralNode) BLangNode {
Expand Down
46 changes: 46 additions & 0 deletions ast/pretty_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ func (p *PrettyPrinter) PrintInner(node BLangNode) {
p.printUnionTypeNode(t)
case *BLangErrorTypeNode:
p.printErrorTypeNode(t)
case *BLangConstrainedType:
p.printConstrainedType(t)
case *BLangTypeDefinition:
p.printTypeDefinition(t)
case *BLangUserDefinedType:
Expand All @@ -112,6 +114,8 @@ func (p *PrettyPrinter) PrintInner(node BLangNode) {
p.printFiniteTypeNode(t)
case *BLangListConstructorExpr:
p.printListConstructorExpr(t)
case *BLangMappingConstructorExpr:
p.printMappingConstructor(t)
case *BLangTypeConversionExpr:
p.printTypeConversionExpr(t)
default:
Expand Down Expand Up @@ -647,6 +651,34 @@ func (p *PrettyPrinter) printListConstructorExpr(node *BLangListConstructorExpr)
p.endNode()
}

func (p *PrettyPrinter) printMappingConstructor(node *BLangMappingConstructorExpr) {
p.startNode()
p.printString("mapping-constructor-expr")
p.indentLevel++
for _, f := range node.Fields {
if kv, ok := f.(*BLangMappingKeyValueField); ok {
p.printMappingKeyValueField(kv)
}
}
p.indentLevel--
p.endNode()
}

// Mapping key-value field printer: prints as (key-value (key) (value))
func (p *PrettyPrinter) printMappingKeyValueField(kv *BLangMappingKeyValueField) {
p.startNode()
p.printString("key-value")
p.indentLevel++
if kv.Key != nil && kv.Key.Expr != nil {
p.PrintInner(kv.Key.Expr.(BLangNode))
}
if kv.ValueExpr != nil {
p.PrintInner(kv.ValueExpr.(BLangNode))
}
p.indentLevel--
p.endNode()
}

// Wildcard binding pattern printer
func (p *PrettyPrinter) printWildCardBindingPattern(node *BLangWildCardBindingPattern) {
p.startNode()
Expand Down Expand Up @@ -689,6 +721,20 @@ func (p *PrettyPrinter) printErrorTypeNode(node *BLangErrorTypeNode) {
p.endNode()
}

func (p *PrettyPrinter) printConstrainedType(node *BLangConstrainedType) {
p.startNode()
p.printString("constrained-type")
p.indentLevel++
if node.Type.TypeDescriptor != nil {
p.PrintInner(node.Type.TypeDescriptor.(BLangNode))
}
if node.Constraint.TypeDescriptor != nil {
p.PrintInner(node.Constraint.TypeDescriptor.(BLangNode))
}
p.indentLevel--
p.endNode()
}

// Type definition printer
func (p *PrettyPrinter) printTypeDefinition(node *BLangTypeDefinition) {
p.startNode()
Expand Down
32 changes: 32 additions & 0 deletions ast/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@
BLangTypeBase
detailType model.TypeData
}

BLangConstrainedType struct {
BLangTypeBase
Type model.TypeData
Constraint model.TypeData
Definition semtypes.Definition
}
)

var (
Expand All @@ -145,6 +152,7 @@
_ BNodeWithSymbol = &BLangUserDefinedType{}
_ model.UnionTypeNode = &BLangUnionTypeNode{}
_ model.ErrorTypeNode = &BLangErrorTypeNode{}
_ model.ConstrainedTypeNode = &BLangConstrainedType{}
)

var (
Expand All @@ -159,7 +167,9 @@
_ BLangNode = &BLangArrayType{}
_ BLangNode = &BLangUserDefinedType{}
_ BLangNode = &BLangValueType{}
_ BLangNode = &BLangConstrainedType{}
_ model.TypeDescriptor = &BLangValueType{}
_ model.TypeDescriptor = &BLangConstrainedType{}
)

func (this *BLangArrayType) GetKind() model.NodeKind {
Expand Down Expand Up @@ -430,3 +440,25 @@
func (this *BLangErrorTypeNode) IsDistinct() bool {
return this.FlagSet.Contains(model.Flag_DISTINCT)
}

func (this *BLangConstrainedType) GetKind() model.NodeKind {
return model.NodeKind_CONSTRAINED_TYPE

Check warning on line 445 in ast/types.go

View check run for this annotation

Codecov / codecov/patch

ast/types.go#L444-L445

Added lines #L444 - L445 were not covered by tests
}

func (this *BLangConstrainedType) GetType() model.TypeData {
return this.Type

Check warning on line 449 in ast/types.go

View check run for this annotation

Codecov / codecov/patch

ast/types.go#L448-L449

Added lines #L448 - L449 were not covered by tests
}

func (this *BLangConstrainedType) GetConstraint() model.TypeData {
return this.Constraint

Check warning on line 453 in ast/types.go

View check run for this annotation

Codecov / codecov/patch

ast/types.go#L452-L453

Added lines #L452 - L453 were not covered by tests
}

func (this *BLangConstrainedType) GetTypeKind() model.TypeKind {
if this.Type.TypeDescriptor == nil {
panic("base type is nil")

Check warning on line 458 in ast/types.go

View check run for this annotation

Codecov / codecov/patch

ast/types.go#L458

Added line #L458 was not covered by tests
}
if builtIn, ok := this.Type.TypeDescriptor.(model.BuiltInReferenceTypeNode); ok {
return builtIn.GetTypeKind()
}
panic("BLangConstrainedType.Type does not implement BuiltInReferenceTypeNode")

Check warning on line 463 in ast/types.go

View check run for this annotation

Codecov / codecov/patch

ast/types.go#L463

Added line #L463 was not covered by tests
}
15 changes: 15 additions & 0 deletions ast/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,17 @@ func Walk(v Visitor, node BLangNode) {
for _, expr := range node.Exprs {
Walk(v, expr.(BLangNode))
}
case *BLangMappingConstructorExpr:
for _, f := range node.Fields {
if kv, ok := f.(*BLangMappingKeyValueField); ok {
if kv.Key != nil && kv.Key.Expr != nil {
Walk(v, kv.Key.Expr.(BLangNode))
}
if kv.ValueExpr != nil {
Walk(v, kv.ValueExpr.(BLangNode))
}
}
}
case *BLangErrorConstructorExpr:
if node.ErrorTypeRef != nil {
Walk(v, node.ErrorTypeRef)
Expand Down Expand Up @@ -545,6 +556,10 @@ func Walk(v Visitor, node BLangNode) {
case *BLangErrorTypeNode:
WalkTypeData(v, &node.detailType)

case *BLangConstrainedType:
WalkTypeData(v, &node.Type)
WalkTypeData(v, &node.Constraint)

// Section 9: Binding Patterns
case *BLangCaptureBindingPattern:
Walk(v, &node.Identifier)
Expand Down
31 changes: 31 additions & 0 deletions bir/bir_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -524,11 +524,42 @@
return listConstructorExpression(ctx, curBB, expr)
case *ast.BLangTypeConversionExpr:
return typeConversionExpression(ctx, curBB, expr)
case *ast.BLangMappingConstructorExpr:
return mappingConstructorExpression(ctx, curBB, expr)
default:
panic("unexpected expression type")
}
}

func mappingConstructorExpression(ctx *stmtContext, curBB *BIRBasicBlock, expr *ast.BLangMappingConstructorExpr) expressionEffect {
var values []MappingConstructorEntry
for _, field := range expr.Fields {
switch f := field.(type) {
case *ast.BLangMappingKeyValueField:
keyEffect := handleExpression(ctx, curBB, f.Key.Expr)
curBB = keyEffect.block
valueEffect := handleExpression(ctx, curBB, f.ValueExpr)
curBB = valueEffect.block
values = append(values, &MappingConstructorKeyValueEntry{
keyOp: keyEffect.result,
valueOp: valueEffect.result,
})
default:
ctx.birCx.CompilerContext.Unimplemented("non-key-value record field not implemented", expr.GetPosition())

Check warning on line 548 in bir/bir_gen.go

View check run for this annotation

Codecov / codecov/patch

bir/bir_gen.go#L547-L548

Added lines #L547 - L548 were not covered by tests
}
}
resultOperand := ctx.addTempVar(expr.GetDeterminedType())
newMap := &NewMap{}
newMap.Type = expr.GetDeterminedType()
newMap.Values = values
newMap.LhsOp = resultOperand
curBB.Instructions = append(curBB.Instructions, newMap)
return expressionEffect{
result: resultOperand,
block: curBB,
}
}

func typeConversionExpression(ctx *stmtContext, curBB *BIRBasicBlock, expr *ast.BLangTypeConversionExpr) expressionEffect {
exprEffect := handleExpression(ctx, curBB, expr.Expression)
curBB = exprEffect.block
Expand Down
Loading