Added the ability for array literals to be undersized

This commit is contained in:
Sasha Koshka 2024-01-28 04:43:01 -05:00
parent 235252b591
commit 3d6142f496
3 changed files with 43 additions and 8 deletions

View File

@ -159,9 +159,9 @@ func (this *Tree) analyzeLiteralArray (
switch base.(type) {
case *entity.TypeArray:
base := base.(*entity.TypeArray)
if base.Length != len(literal.Elements) {
if base.Length < len(literal.Elements) {
return nil, participle.Errorf (
literal.Pos, "expected %v elements",
literal.Pos, "expected %v elements or less",
base.Length)
}
elementType = base.Element

View File

@ -35,7 +35,7 @@ func (this *generator) generateLiteralArrayLoc (literal *entity.LiteralArray, ir
if err != nil { return nil, err }
return this.blockManager.newAllocaFront(irDataType), nil
}
populateData := func (elementType entity.Type, irDestLoc llvm.Value) error {
populateData := func (elementType entity.Type, irDestLoc llvm.Value, max int) error {
irDataType, err := makeDataType(elementType)
if err != nil { return err }
for index, element := range literal.Elements {
@ -49,6 +49,20 @@ func (this *generator) generateLiteralArrayLoc (literal *entity.LiteralArray, ir
elementPointer)
if err != nil { return err }
}
// TODO allow undersized arrays in the analyzer
irElementType, err := this.generateType(elementType)
if err != nil { return err }
for index := len(literal.Elements); index < max; index ++ {
elementPointer := this.blockManager.NewGetElementPtr (
irDataType, irDestLoc,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, int64(index)))
this.blockManager.NewStore (
llvm.NewConstZeroInitializer(irElementType),
elementPointer)
}
return nil
}
@ -61,16 +75,14 @@ func (this *generator) generateLiteralArrayLoc (literal *entity.LiteralArray, ir
base := analyzer.ReduceToBase(literal.Type())
switch base := base.(type) {
case *entity.TypeArray:
// TODO: if there are empty cells left over, set them to the
// zero initializer.
populateData(base.Element, irDestLoc)
populateData(base.Element, irDestLoc, base.Length)
case *entity.TypeSlice:
destDataFieldLoc := this.getSliceDataFieldLoc(irDestLoc, irDestType)
destLengthFieldLoc := this.getSliceLengthFieldLoc(irDestLoc, irDestType)
destData, err := makeData(base.Element)
if err != nil { return nil, err }
err = populateData(base.Element, destData)
err = populateData(base.Element, destData, -1)
if err != nil { return nil, err }
this.blockManager.NewStore(destData, destDataFieldLoc)
this.blockManager.NewStore (
@ -80,7 +92,7 @@ func (this *generator) generateLiteralArrayLoc (literal *entity.LiteralArray, ir
case *entity.TypePointer:
destData, err := makeData(base.Referenced)
if err != nil { return nil, err }
err = populateData(base.Referenced, destData)
err = populateData(base.Referenced, destData, -1)
if err != nil { return nil, err }
this.blockManager.NewStore(destData, irDestLoc)

View File

@ -222,6 +222,29 @@ A: 2:2:Int
`)
}
func TestLiteralArrayUndersized (test *testing.T) {
testString (test,
`define void @main() {
0:
%1 = alloca [4 x i64]
%2 = getelementptr [3 x i64], ptr %1, i32 0, i32 0
store i64 5, ptr %2
%3 = getelementptr [3 x i64], ptr %1, i32 0, i32 1
store i64 9, ptr %3
%4 = getelementptr [3 x i64], ptr %1, i32 0, i32 2
store i64 3, ptr %4
%5 = getelementptr [3 x i64], ptr %1, i32 0, i32 3
store i64 zeroinitializer, ptr %5
ret void
}
`,
`
[main] 'main' = {
a:4:Int = (* 5 9 3)
}
`)
}
func TestTypedStructInstantiation (test *testing.T) {
testString (test,
`%A = type { i64 }