Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Nature concept #665

Merged
merged 1 commit into from
May 31, 2024
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
38 changes: 34 additions & 4 deletions ast/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ package ast
import (
"reflect"

"github.com/expr-lang/expr/checker/nature"
"github.com/expr-lang/expr/file"
)

var (
anyType = reflect.TypeOf(new(any)).Elem()
)

// Node represents items of abstract syntax tree.
type Node interface {
Location() file.Location
SetLocation(file.Location)
Nature() nature.Nature
SetNature(nature.Nature)
Kind() reflect.Kind
Type() reflect.Type
SetType(reflect.Type)
String() string
Expand All @@ -25,8 +33,8 @@ func Patch(node *Node, newNode Node) {

// base is a base struct for all nodes.
type base struct {
loc file.Location
nodeType reflect.Type
loc file.Location
nature nature.Nature
}

// Location returns the location of the node in the source code.
Expand All @@ -39,14 +47,36 @@ func (n *base) SetLocation(loc file.Location) {
n.loc = loc
}

// Nature returns the nature of the node.
func (n *base) Nature() nature.Nature {
return n.nature
}

// SetNature sets the nature of the node.
func (n *base) SetNature(nature nature.Nature) {
n.nature = nature
}

// Kind returns the kind of the node.
// If the type is nil (meaning unknown) then it returns reflect.Interface.
func (n *base) Kind() reflect.Kind {
if n.nature.Type == nil {
return reflect.Interface
}
return n.nature.Type.Kind()
}

// Type returns the type of the node.
func (n *base) Type() reflect.Type {
return n.nodeType
if n.nature.Type == nil {
return anyType
}
return n.nature.Type
}

// SetType sets the type of the node.
func (n *base) SetType(t reflect.Type) {
n.nodeType = t
n.nature.Type = t
}

// NilNode represents nil.
Expand Down
2 changes: 1 addition & 1 deletion builtin/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func TestBuiltin_errors(t *testing.T) {
{`bitushr(-5, -2)`, "invalid operation: negative shift count -2 (type int) (1:1)"},
{`now(nil)`, "invalid number of arguments (expected 0, got 1)"},
{`date(nil)`, "interface {} is nil, not string (1:1)"},
{`timezone(nil)`, "interface {} is nil, not string (1:1)"},
{`timezone(nil)`, "cannot use nil as argument (type string) to call timezone (1:10)"},
}
for _, test := range errorTests {
t.Run(test.input, func(t *testing.T) {
Expand Down
Loading
Loading