Skip to content

Commit

Permalink
support make constructor for slice type
Browse files Browse the repository at this point in the history
  • Loading branch information
douyixuan committed Aug 11, 2024
1 parent 1ca4d82 commit 8c46a93
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 9 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ test/example:
${CELL} -t riscv tests/examples/table.cell && ckb-debugger --bin table
${CELL} -d -t riscv tests/examples/string.cell && ckb-debugger --bin string | grep "eq"
${CELL} -d -t riscv tests/examples/strings.cell && ckb-debugger --bin strings | grep "aa-bb"
${CELL} -d -t riscv tests/examples/make-slice.cell && ckb-debugger --bin make-slice | grep "0422"
${CELL} -d -t riscv tests/examples/func.cell && ckb-debugger --bin func | grep "999"
${CELL} -t riscv tests/examples/cell-data.cell && ckb-debugger --bin cell-data
${CELL} -t riscv tests/examples/inputs.cell && ckb-debugger --bin inputs
Expand Down
7 changes: 5 additions & 2 deletions compiler/compiler/alloc.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ func (c *Compiler) compileAllocNode(v *parser.AllocNode) {
// Set to zero values
// TODO: Make slices less special
if sliceType, ok := treType.(*types.Slice); ok {
sliceType.SliceZero(block, c.osFuncs.Malloc.Value.(llvmValue.Named), 2, val)
sliceType.SliceZero(block, c.osFuncs.Malloc.Value.(llvmValue.Named),
constant.NewInt(irTypes.I32, 0), // len
constant.NewInt(irTypes.I32, 2), // cap
val)

Check failure on line 68 in compiler/compiler/alloc.go

View workflow job for this annotation

GitHub Actions / build

too many arguments in call to sliceType.SliceZero
} else {
treType.Zero(block, val)
}
Expand Down Expand Up @@ -161,7 +164,7 @@ func (c *Compiler) compileAllocConstNode(v *parser.AllocNode) {
cnst := v.Val[i].(*parser.ConstantNode)
c.setVar(varName, value.Value{
Type: &types.UntypedConstantNumber{},
Value: constant.NewInt(i64.LLVM().(*irTypes.IntType), cnst.Value),
Value: constant.NewInt(irTypes.I64, cnst.Value),
})
}
}
Expand Down
5 changes: 4 additions & 1 deletion compiler/compiler/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,10 @@ func (c *Compiler) compileCallNode(v *parser.CallNode) value.Value {
variadicType := fnType.ArgumentTypes[variadicArgIndex].(*types.Slice)

// Convert last argument to a slice.
variadicSlice := c.compileInitializeSliceWithValues(variadicType.Type, args[variadicArgIndex:]...)
variadicSlice := c.compileInitializeSliceWithValues(variadicType.Type,
value.Value{Type: i32, Value: constant.NewInt(llvmTypes.I32, int64(len(args[variadicArgIndex:])))},
value.Value{Type: i32, Value: constant.NewInt(llvmTypes.I32, int64(len(args[variadicArgIndex:])))},
args[variadicArgIndex:]...)

// Remove "pre-sliceified" arguments from the list of arguments
args = args[0:variadicArgIndex]
Expand Down
31 changes: 27 additions & 4 deletions compiler/compiler/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,18 +362,26 @@ func (c *Compiler) compileInitializeSliceNode(v *parser.InitializeSliceNode) val
c.contextAssignDest = c.contextAssignDest[0 : len(c.contextAssignDest)-1]
}

return c.compileInitializeSliceWithValues(itemType, values...)
len := value.Value{Type: i32, Value: constant.NewInt(llvmTypes.I32, 0)}
if v.Len != nil {
len = c.compileValue(v.Len)
}
cap := value.Value{Type: i32, Value: constant.NewInt(llvmTypes.I32, 0)}
if v.Cap != nil {
cap = c.compileValue(v.Cap)
}
return c.compileInitializeSliceWithValues(itemType, len, cap, values...)
}

func (c *Compiler) compileInitializeSliceWithValues(itemType types.Type, values ...value.Value) value.Value {
func (c *Compiler) compileInitializeSliceWithValues(itemType types.Type, initLen, initCap value.Value, values ...value.Value) value.Value {
sliceType := &types.Slice{
Type: itemType,
LlvmType: internal.Slice(itemType.LLVM()),
}

// Create slice with cap set to the requested size
allocSlice := c.contextBlock.NewAlloca(sliceType.LLVM())
sliceType.SliceZero(c.contextBlock, c.osFuncs.Malloc.Value.(llvmValue.Named), len(values), allocSlice)
sliceType.SliceZero(c.contextBlock, c.osFuncs.Malloc.Value.(llvmValue.Named), initLen.Value, initCap.Value, allocSlice)

Check failure on line 384 in compiler/compiler/slice.go

View workflow job for this annotation

GitHub Actions / build

too many arguments in call to sliceType.SliceZero

backingArrayPtr := c.contextBlock.NewGetElementPtr(pointer.ElemType(allocSlice), allocSlice,
constant.NewInt(llvmTypes.I32, 0),
Expand All @@ -399,7 +407,22 @@ func (c *Compiler) compileInitializeSliceWithValues(itemType types.Type, values
constant.NewInt(llvmTypes.I32, 0),
)
lenPtr.SetName(name.Var("len"))
c.contextBlock.NewStore(constant.NewInt(llvmTypes.I32, int64(len(values))), lenPtr)
len32 := initLen.Value
if len32.Type() != llvmTypes.I32 {
len32 = c.contextBlock.NewTrunc(len32, i32.LLVM())
}
c.contextBlock.NewStore(len32, lenPtr)

capPtr := c.contextBlock.NewGetElementPtr(pointer.ElemType(allocSlice), allocSlice,
constant.NewInt(llvmTypes.I32, 0),
constant.NewInt(llvmTypes.I32, 1),
)
capPtr.SetName(name.Var("cap"))
cap32 := initCap.Value
if cap32.Type() != llvmTypes.I32 {
cap32 = c.contextBlock.NewTrunc(cap32, i32.LLVM())
}
c.contextBlock.NewStore(cap32, capPtr)

return value.Value{
Value: allocSlice,
Expand Down
1 change: 1 addition & 0 deletions compiler/lexer/keywords.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ var keywords = map[string]struct{}{
"false": {},
"interface": {},
"range": {},
"make": {},
}
4 changes: 3 additions & 1 deletion compiler/parser/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,11 +397,13 @@ func (sn SubNode) String() string {
type InitializeSliceNode struct {
baseNode
Type TypeNode
Len Node
Cap Node
Items []Node
}

func (i InitializeSliceNode) String() string {
return fmt.Sprintf("InitializeSliceNode-[]%s{%+v}", i.Type, i.Items)
return fmt.Sprintf("InitializeSliceNode-[]%s{%+v}(%d)", i.Type, i.Items, i.Cap)
}

type InitializeArrayNode struct {
Expand Down
44 changes: 43 additions & 1 deletion compiler/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,14 @@ func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentif
items := p.parseUntil(lexer.Item{Type: lexer.OPERATOR, Val: "}"})
p.inAllocRightHand = prevInAlloc

len := &ConstantNode{
Type: NUMBER,
Value: int64(len(items)),
}
res = &InitializeSliceNode{
Type: sliceItemType,
Len: len,
Cap: len,
Items: items,
}
if withAheadParse {
Expand Down Expand Up @@ -329,6 +335,42 @@ func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentif
return outerConditionNode
}

// "make" is a construtor command for composed types
if current.Val == "make" {
p.i++

lParent := p.lookAhead(0)
p.expect(lParent, lexer.Item{Type: lexer.OPERATOR, Val: "("})
p.i++

ty, err := p.parseOneType()
if err != nil {
panic(err)
}
p.i++

items := p.parseUntil(lexer.Item{Type: lexer.OPERATOR, Val: ")"})
switch t := ty.(type) {
case *SliceTypeNode:
if len(items) == 2 {
return &InitializeSliceNode{
Type: t,
Len: items[0],
Cap: items[1],
}
} else if len(items) == 1 {
return &InitializeSliceNode{
Type: t,
Len: items[0],
Cap: items[0],
}
} else {
panic("wrong argument for slice constructor")
}
default:
panic("not supported")
}
}
// "extern" is external function without function body

// single extern: extern func foo() int32
Expand Down Expand Up @@ -385,7 +427,7 @@ func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentif

retVals = append(retVals, p.parseOne(true))
p.i++

checkIfComma := p.lookAhead(0)
if checkIfComma.Type == lexer.OPERATOR && checkIfComma.Val == "," {
p.i++
Expand Down
10 changes: 10 additions & 0 deletions tests/examples/make-slice.cell
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

import "debug"

func main() {
s := make([]int64, 0, 4)
s1 := make([]int64, 2)
debug.Printf("%d%d%d%d", len(s), cap(s), len(s1), cap(s1))
return 0
}

1 comment on commit 8c46a93

@douyixuan
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#14

Please sign in to comment.