Skip to content

Commit

Permalink
Implemented slice types.
Browse files Browse the repository at this point in the history
  • Loading branch information
markkurossi committed Jul 17, 2024
1 parent 797ee53 commit 255ce5a
Show file tree
Hide file tree
Showing 16 changed files with 317 additions and 63 deletions.
11 changes: 8 additions & 3 deletions circuit/ioarg.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2019-2023 Markku Rossi
// Copyright (c) 2019-2024 Markku Rossi
//
// All rights reserved.
//
Expand Down Expand Up @@ -104,10 +104,11 @@ func (io IOArg) Parse(inputs []string) (*big.Int, error) {
return nil, fmt.Errorf("invalid bool constant: %s", inputs[0])
}

case types.TArray:
case types.TArray, types.TSlice:
count := int(io.Type.ArraySize)
elSize := int(io.Type.ElementType.Bits)
if count == 0 {
if io.Type.Type == types.TArray && count == 0 {
// Handle empty types.TArray arguments.
break
}

Expand All @@ -128,6 +129,10 @@ func (io IOArg) Parse(inputs []string) (*big.Int, error) {
if bitLen%elSize != 0 {
valElCount++
}
if io.Type.Type == types.TSlice {
// Set the count=valElCount for types.TSlice arguments.
count = valElCount
}
if valElCount > count {
return nil, fmt.Errorf("too many values for input: %s",
inputs[0])
Expand Down
6 changes: 5 additions & 1 deletion circuit/stream_evaluator.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2020-2023 Markku Rossi
// Copyright (c) 2020-2024 Markku Rossi
//
// All rights reserved.
//
Expand Down Expand Up @@ -482,6 +482,10 @@ func receiveArgument(conn *p2p.Conn) (arg IOArg, err error) {
}
arg.Type.Bits = types.Size(size)

if arg.Type.Type == types.TSlice {
arg.Type.ArraySize = arg.Type.Bits / arg.Type.ElementType.Bits
}

count, err := conn.ReceiveUint32()
if err != nil {
return arg, err
Expand Down
2 changes: 1 addition & 1 deletion compiler/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ func (ti *TypeInfo) Resolve(env *Env, ctx *Codegen, gen *ssa.Generator) (
// Bits and ArraySize are left uninitialized and they must be
// defined when type is instantiated.
return types.Info{
Type: types.TArray,
Type: types.TSlice,
ElementType: &elInfo,
}, nil

Expand Down
13 changes: 6 additions & 7 deletions compiler/ast/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func copySSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator,
var elementType types.Info

switch dst.Type.Type {
case types.TArray:
case types.TArray, types.TSlice:
baseName = dst.Name
baseType = dst.Type
baseScope = dst.Scope
Expand All @@ -89,9 +89,8 @@ func copySSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator,

case types.TPtr:
elementType = *dst.Type.ElementType
if elementType.Type != types.TArray {
return nil, nil, ctx.Errorf(loc,
"setting elements of non-array %s",
if !elementType.Type.Array() {
return nil, nil, ctx.Errorf(loc, "setting elements of non-array %s",
elementType)
}
baseName = dst.PtrInfo.Name
Expand Down Expand Up @@ -121,7 +120,7 @@ func copySSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator,
srcType = src.Type
}

if srcType.Type != types.TArray {
if !srcType.Type.Array() {
return nil, nil, ctx.Errorf(loc,
"second argument to copy should be slice or array (%v)", src.Type)
}
Expand Down Expand Up @@ -211,7 +210,7 @@ func lenSSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator,
case types.TString:
val = args[0].Type.Bits / types.ByteBits

case types.TArray:
case types.TArray, types.TSlice:
val = args[0].Type.ArraySize

case types.TNil:
Expand Down Expand Up @@ -292,7 +291,7 @@ func lenEval(args []AST, env *Env, ctx *Codegen, gen *ssa.Generator,
return gen.Constant(int64(typeInfo.Bits/types.ByteBits),
types.Undefined), true, nil

case types.TArray:
case types.TArray, types.TSlice:
return gen.Constant(int64(typeInfo.ArraySize), types.Undefined),
true, nil

Expand Down
10 changes: 5 additions & 5 deletions compiler/ast/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func (ast *ArrayCast) Eval(env *Env, ctx *Codegen, gen *ssa.Generator) (
if err != nil {
return ssa.Undefined, false, err
}
if typeInfo.Type != types.TArray {
if !typeInfo.Type.Array() {
return ssa.Undefined, false,
ctx.Errorf(ast.Expr, "array cast to non-array type %v", typeInfo)
}
Expand Down Expand Up @@ -454,7 +454,7 @@ func (ast *Slice) Eval(env *Env, ctx *Codegen, gen *ssa.Generator) (
"invalid slice range %d:%d", from, to)
}
switch expr.Type.Type {
case types.TArray:
case types.TArray, types.TSlice:
arr, err := expr.ConstArray()
if err != nil {
return ssa.Undefined, false, err
Expand Down Expand Up @@ -526,7 +526,7 @@ func (ast *Index) Eval(env *Env, ctx *Codegen, gen *ssa.Generator) (
}

switch expr.Type.Type {
case types.TArray:
case types.TArray, types.TSlice:
if index < 0 || index >= int(expr.Type.ArraySize) {
return ssa.Undefined, false, ctx.Errorf(ast.Index,
"invalid array index %d (out of bounds for %d-element array)",
Expand Down Expand Up @@ -612,7 +612,7 @@ func (ast *CompositeLit) Eval(env *Env, ctx *Codegen, gen *ssa.Generator) (
}
return gen.Constant(values, typeInfo), true, nil

case types.TArray:
case types.TArray, types.TSlice:
// Check if all elements are constants.
var values []interface{}
for _, el := range ast.Value {
Expand Down Expand Up @@ -649,7 +649,7 @@ func (ast *Make) Eval(env *Env, ctx *Codegen, gen *ssa.Generator) (
return ssa.Undefined, false, ctx.Errorf(ast.Type, "%s is not a type",
ast.Type)
}
if typeInfo.Type == types.TArray {
if typeInfo.Type.Array() {
// Arrays are made in Make.SSA.
return ssa.Undefined, false, nil
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/ast/lrvalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func (lrv *LRValue) ConstValue() (ssa.Value, bool, error) {
return lrv.value, false, nil

case types.TBool, types.TInt, types.TUint, types.TFloat, types.TString,
types.TStruct, types.TArray, types.TNil:
types.TStruct, types.TArray, types.TSlice, types.TNil:
return lrv.value, true, nil

default:
Expand Down
36 changes: 20 additions & 16 deletions compiler/ast/ssagen.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ func initValue(typeInfo types.Info) (interface{}, error) {
init = append(init, fieldInit)
}
return init, nil
case types.TArray:
case types.TArray, types.TSlice:
elInit, err := initValue(*typeInfo.ElementType)
if err != nil {
return nil, err
Expand Down Expand Up @@ -323,7 +323,7 @@ func (ast *Assign) SSA(block *ssa.Block, ctx *Codegen,
valueType = *valueType.ElementType
}

if valueType.Type != types.TArray {
if !valueType.Type.Array() {
return nil, nil, ctx.Errorf(ast,
"setting elements of non-array %s (%s)",
arr, lrv.ValueType())
Expand Down Expand Up @@ -778,7 +778,7 @@ castTargetType:
typeInfo.Bits = cv.Type.Bits
typeInfo.SetConcrete(true)

case types.TArray:
case types.TArray, types.TSlice:
switch cv.Type.ElementType.Type {
case types.TUint:
if cv.Type.ElementType.Bits != 8 {
Expand Down Expand Up @@ -898,7 +898,7 @@ func (ast *ArrayCast) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
if err != nil {
return nil, nil, err
}
if typeInfo.Type != types.TArray {
if !typeInfo.Type.Array() {
return nil, nil, ctx.Errorf(ast.Expr, "array cast to non-array type %v",
typeInfo)
}
Expand Down Expand Up @@ -1243,7 +1243,7 @@ func (ast *ForRange) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
}

switch it.Type {
case types.TArray:
case types.TArray, types.TSlice:
count = int(values.Type.ArraySize)
it = *it.ElementType
default:
Expand Down Expand Up @@ -1288,7 +1288,7 @@ func (ast *ForRange) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
r := gen.AnonVal(it)

switch values.Type.Type {
case types.TArray:
case types.TArray, types.TSlice:
from := int64(types.Size(i)*it.Bits + ptrInfo.Offset)
to := int64(types.Size(i+1)*it.Bits + ptrInfo.Offset)

Expand Down Expand Up @@ -1536,9 +1536,13 @@ func (ast *Binary) resultType(ctx *Codegen, l, r ssa.Value) (
if l.Type.Type == types.TString && r.Type.Type == types.TString {
resultType = l.Type
resultType.Bits += r.Type.Bits
} else if l.Type.Type == types.TArray && r.Type.Type == types.TArray &&
} else if l.Type.Type.Array() && r.Type.Type.Array() &&
l.Type.ElementType.Equal(*r.Type.ElementType) {
resultType = l.Type
if r.Type.Type == types.TSlice {
resultType = r.Type
} else {
resultType = l.Type
}
resultType.Bits += r.Type.Bits
resultType.ArraySize += r.Type.ArraySize
} else {
Expand Down Expand Up @@ -1755,7 +1759,7 @@ func (ast *Unary) addrIndex(block *ssa.Block, ctx *Codegen, gen *ssa.Generator,
return
}
vt := lrv.ValueType()
if vt.Type != types.TArray {
if !vt.Type.Array() {
return nil, nil, 0, ctx.Errorf(indexed,
"invalid operation: %s (type %s does not support indexing)",
index, ptrType)
Expand Down Expand Up @@ -1835,7 +1839,7 @@ func (ast *Slice) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
elementSize = 1
elementCount = elementType.Bits

case types.TArray:
case types.TArray, types.TSlice:
elementSize = elementType.ElementType.Bits
elementCount = elementType.ArraySize

Expand Down Expand Up @@ -1888,7 +1892,7 @@ func (ast *Slice) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
var t ssa.Value

if expr.Type.Type == types.TPtr {
if elementType.Type == types.TArray {
if elementType.Type.Array() {

// Take a copy of the PtrInfo and adjust its offset.
ptrInfo := *expr.PtrInfo
Expand Down Expand Up @@ -1918,7 +1922,7 @@ func (ast *Slice) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
Bits: bits,
MinBits: bits,
}
if elementType.Type == types.TArray {
if elementType.Type.Array() {
ti.ElementType = elementType.ElementType
ti.ArraySize = ti.Bits / ti.ElementType.Bits
}
Expand Down Expand Up @@ -2010,7 +2014,7 @@ func (ast *Index) constIndex(block *ssa.Block, ctx *Codegen, gen *ssa.Generator,

return block, []ssa.Value{t}, nil

case types.TArray:
case types.TArray, types.TSlice:
if index < 0 || index >= it.ArraySize {
return nil, nil, ctx.Errorf(ast.Index,
"invalid array index %d (out of bounds for %d-element array)",
Expand Down Expand Up @@ -2054,7 +2058,7 @@ func (ast *Index) index(block *ssa.Block, ctx *Codegen, gen *ssa.Generator,
}

switch it.Type {
case types.TArray:
case types.TArray, types.TSlice:
offset := gen.Constant(int64(ptrInfo.Offset), types.Undefined)
t := gen.AnonVal(*it.ElementType)
block.AddInstr(ssa.NewIndexInstr(expr, offset, index, t))
Expand Down Expand Up @@ -2113,9 +2117,9 @@ func (ast *Make) SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator) (
if err != nil {
return nil, nil, ctx.Errorf(ast.Type, "%s is not a type", ast.Type)
}
if typeInfo.Type != types.TArray {
if !typeInfo.Type.Array() {
return nil, nil, ctx.Errorf(ast.Type,
"cant' make instance of type %s", typeInfo)
"can't make instance of type %s", typeInfo)
}
if typeInfo.Bits != 0 {
return nil, nil, ctx.Errorf(ast.Type,
Expand Down
4 changes: 2 additions & 2 deletions compiler/ssa/generator.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2020-2023 Markku Rossi
// Copyright (c) 2020-2024 Markku Rossi
//
// All rights reserved.
//
Expand Down Expand Up @@ -264,7 +264,7 @@ func (gen *Generator) Constant(value interface{}, ti types.Info) Value {
var elementType types.Info

if len(val) > 0 {
if ti.Type == types.TArray {
if ti.Type.Array() {
elementType = *ti.ElementType
} else {
ev := gen.Constant(val[0], types.Undefined)
Expand Down
4 changes: 2 additions & 2 deletions compiler/ssa/instructions.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2020-2023 Markku Rossi
// Copyright (c) 2020-2024 Markku Rossi
//
// All rights reserved.
//
Expand Down Expand Up @@ -177,7 +177,7 @@ func NewAddInstr(t types.Info, l, r, o Value) (Instr, error) {
op = Uadd
case types.TFloat:
op = Fadd
case types.TString, types.TArray:
case types.TString, types.TArray, types.TSlice:
op = Concat
default:
fmt.Printf("%v + %v (%v)\n", l, r, t)
Expand Down
29 changes: 25 additions & 4 deletions compiler/ssa/value.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2020-2023 Markku Rossi
// Copyright (c) 2020-2024 Markku Rossi
//
// All rights reserved.
//
Expand Down Expand Up @@ -210,7 +210,7 @@ func (v *Value) Bit(bit types.Size) bool {
var elType types.Info

switch v.Type.Type {
case types.TArray:
case types.TArray, types.TSlice:
elType = *v.Type.ElementType
case types.TString:
elType = types.Byte
Expand Down Expand Up @@ -292,7 +292,7 @@ func isSet(v interface{}, vt types.Info, bit types.Size) bool {
case types.TBool, types.TInt, types.TUint, types.TFloat, types.TString:
return isSet(val.ConstValue, val.Type, bit)

case types.TArray:
case types.TArray, types.TSlice:
elType := val.Type.ElementType
idx := bit / elType.Bits
mod := bit % elType.Bits
Expand Down Expand Up @@ -331,7 +331,7 @@ func isSet(v interface{}, vt types.Info, bit types.Size) bool {
}
panic(fmt.Sprintf("ssa.isSet: bit overflow for %v", vt))

case types.TArray:
case types.TArray, types.TSlice:
elType := vt.ElementType
idx := bit / elType.Bits
mod := bit % elType.Bits
Expand All @@ -350,13 +350,34 @@ func isSet(v interface{}, vt types.Info, bit types.Size) bool {
}

// LValueFor checks if the value o can be assigned for lvalue of type l.
// XXX change this to AssignFrom
func LValueFor(l types.Info, o Value) bool {
if o.Const {
return l.CanAssignConst(o.Type)
}
if !l.Concrete() && o.Type.Concrete() {
return l.Specializable(o.Type)
}
if l.Type == types.TArray {
// [N]Type = []Type - check rvalue has corrent amount of elements
ot := o.Type
if ot.Type == types.TPtr {
// Dereference pointer argument.
ot = *ot.ElementType
}
return ot.Type.Array() &&
l.ArraySize == ot.ArraySize &&
l.ElementType.Equal(*ot.ElementType)
}
if l.Type == types.TSlice {
// []Type = [N]Type ok,
ot := o.Type
if ot.Type == types.TPtr {
// Dereference pointer argument.
ot = *ot.ElementType
}
return ot.Type.Array() && l.ElementType.Equal(*ot.ElementType)
}
return l.Equal(o.Type)
}

Expand Down
Loading

0 comments on commit 255ce5a

Please sign in to comment.