diff --git a/src/types/Function.go b/src/types/Function.go index 855e66b..7e19aac 100644 --- a/src/types/Function.go +++ b/src/types/Function.go @@ -33,7 +33,7 @@ func (f *Function) Name() string { builder.WriteString(output.Name()) if i != len(f.Output)-1 { - builder.WriteString(",") + builder.WriteString(", ") } } diff --git a/src/types/Function_test.go b/src/types/Function_test.go new file mode 100644 index 0000000..dc6db48 --- /dev/null +++ b/src/types/Function_test.go @@ -0,0 +1,26 @@ +package types_test + +import ( + "testing" + + "git.urbach.dev/cli/q/src/types" + "git.urbach.dev/go/assert" +) + +func TestFunction(t *testing.T) { + f := &types.Function{} + assert.Equal(t, f.Name(), "()") + assert.Equal(t, f.Size(), 8) + + f.Input = append(f.Input, types.Int64) + assert.Equal(t, f.Name(), "(int64)") + + f.Input = append(f.Input, types.Int64) + assert.Equal(t, f.Name(), "(int64, int64)") + + f.Output = append(f.Output, types.Int64) + assert.Equal(t, f.Name(), "(int64, int64) -> (int64)") + + f.Output = append(f.Output, types.Int64) + assert.Equal(t, f.Name(), "(int64, int64) -> (int64, int64)") +} \ No newline at end of file diff --git a/src/types/Parse.go b/src/types/Parse.go index 1958c1d..00fd0af 100644 --- a/src/types/Parse.go +++ b/src/types/Parse.go @@ -6,10 +6,18 @@ import ( // Parse returns the type with the given tokens or `nil` if it doesn't exist. func Parse[T ~[]token.Token](tokens T, source []byte) Type { + if len(tokens) == 0 { + return nil + } + if tokens[0].Kind == token.Mul { to := tokens[1:] typ := Parse(to, source) + if typ == nil { + return nil + } + if typ == Any { return AnyPointer } @@ -21,6 +29,10 @@ func Parse[T ~[]token.Token](tokens T, source []byte) Type { to := tokens[2:] typ := Parse(to, source) + if typ == nil { + return nil + } + if typ == Any { return AnyArray } diff --git a/src/types/Parse_test.go b/src/types/Parse_test.go new file mode 100644 index 0000000..59f4943 --- /dev/null +++ b/src/types/Parse_test.go @@ -0,0 +1,56 @@ +package types_test + +import ( + "testing" + + "git.urbach.dev/cli/q/src/token" + "git.urbach.dev/cli/q/src/types" + "git.urbach.dev/go/assert" +) + +func TestParse(t *testing.T) { + tests := []struct { + Source string + ExpectedType types.Type + }{ + {"int", types.Int}, + {"int64", types.Int64}, + {"int32", types.Int32}, + {"int16", types.Int16}, + {"int8", types.Int8}, + {"uint", types.UInt}, + {"uint64", types.UInt64}, + {"uint32", types.UInt32}, + {"uint16", types.UInt16}, + {"uint8", types.UInt8}, + {"byte", types.Byte}, + {"bool", types.Bool}, + {"float", types.Float}, + {"float64", types.Float64}, + {"float32", types.Float32}, + {"any", types.Any}, + {"*any", types.AnyPointer}, + {"*byte", &types.Pointer{To: types.Byte}}, + {"[]any", types.AnyArray}, + {"[]byte", &types.Array{Of: types.Byte}}, + {"123", nil}, + {"*", nil}, + {"[]", nil}, + {"[", nil}, + {"_", nil}, + } + + for _, test := range tests { + t.Run(test.Source, func(t *testing.T) { + src := []byte(test.Source) + tokens := token.Tokenize(src) + typ := types.Parse(tokens, src) + assert.True(t, types.Is(typ, test.ExpectedType)) + }) + } +} + +func TestParseNil(t *testing.T) { + tokens := []token.Token(nil) + assert.Nil(t, types.Parse(tokens, nil)) +} \ No newline at end of file