Skip to content

Commit

Permalink
#234 Merged latest code from master.
Browse files Browse the repository at this point in the history
  • Loading branch information
ericzhang6222 committed May 24, 2020
2 parents a5d4bd4 + 95d8ff8 commit 82837d6
Show file tree
Hide file tree
Showing 29 changed files with 651 additions and 405 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ The ultimate data engine.

## Install

On a Unix-like OS, [install Go](https://golang.org/doc/install), then:
On a Unix-like OS, [install Go](https://golang.org/doc/install) (1.14 or above),
then:

```bash
git clone https://github.com/arr-ai/arrai.git
Expand Down
2 changes: 1 addition & 1 deletion cmd/arrai/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var transformCommand = &cli.Command{
}

func transform(c *cli.Context) error {
panic("unfinished")
panic("transform|x not implemented (https://github.com/arr-ai/arrai/issues/310)")
// source := c.Args().Get(0)

// expr, err := syntax.Parse(parser.NewScanner(source))
Expand Down
12 changes: 11 additions & 1 deletion internal/shell/shell_completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ func (s *shellInstance) Do(line []rune, pos int) (newLine [][]rune, length int)
newLine, length = getScopePredictions(names, lastName, s.scope.MustGet(".").(rel.Tuple))
if l == "//" {
newLine = append(newLine, []rune("{"))
} else if lastName != "" {
if len(newLine) == 0 {
length = 0
}
names, lastName = append(names, lastName), ""
predictions, _ := getScopePredictions(names, lastName, s.scope.MustGet(".").(rel.Tuple))
for i := 0; i < len(predictions); i++ {
predictions[i] = append([]rune("."), predictions[i]...)
}
newLine = append(newLine, predictions...)
}
default:
currentExpr := strings.Join(s.collector.withLine(string(line[:pos])).lines, "\n")
Expand Down Expand Up @@ -158,7 +168,7 @@ func getScopePredictions(tuplePath []string, name string, scope rel.Tuple) ([][]
}

for _, attr := range scope.Names().OrderedNames() {
if strings.HasPrefix(attr, name) {
if strings.HasPrefix(attr, name) && name != attr {
newLine = append(newLine, []rune(attr[length:]))
}
}
Expand Down
4 changes: 4 additions & 0 deletions internal/shell/shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ func TestTabCompletionStdlib(t *testing.T) {
lib := "seq"
strlib := stdlib.MustGet(lib).(rel.Tuple).Names().OrderedNames()
assertTabCompletionWithPrefix(t, prefix, strlib, "//"+lib+".%s\t", nil)
for i := 0; i < len(strlib); i++ {
strlib[i] = "." + strlib[i]
}
assertTabCompletionWithPrefix(t, "", strlib, "//"+lib+"%s\t", nil)
}

func TestTrimExpr(t *testing.T) {
Expand Down
60 changes: 5 additions & 55 deletions rel/expr_binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,7 @@ func NewWhereExpr(scanner parser.Scanner, a, pred Expr) Expr {
if x, ok := a.(Set); ok {
if p, ok := pred.(Closure); ok {
return x.Where(func(v Value) bool {
match, err := p.Call(v, local)
if err != nil {
panic(err)
}
return match.IsTrue()
return SetCall(p, v).IsTrue()
}), nil
}
return nil, errors.Errorf("'where' rhs must be a Fn, not %T", a)
Expand All @@ -175,7 +171,7 @@ func NewOrderByExpr(scanner parser.Scanner, a, key Expr) Expr {
if k, ok := key.(Closure); ok {
values, err := OrderBy(x,
func(value Value) (Value, error) {
return k.Call(value, local)
return SetCall(k, value), nil
},
func(a, b Value) bool {
return a.Less(b)
Expand Down Expand Up @@ -203,15 +199,7 @@ func NewOrderExpr(scanner parser.Scanner, a, key Expr) Expr {
return value, nil
},
func(a, b Value) bool {
f, err := l.Call(a, local)
if err != nil {
panic(err)
}
result, err := f.(Closure).Call(b, local)
if err != nil {
panic(err)
}
return result.IsTrue()
return SetCall(SetCall(l, a).(Closure), b).IsTrue()
})
if err != nil {
return nil, err
Expand All @@ -224,38 +212,9 @@ func NewOrderExpr(scanner parser.Scanner, a, key Expr) Expr {
})
}

type Callable interface {
Call(Expr, Scope) (Value, error)
}

func Call(a, b Value, local Scope) (Value, error) {
switch x := a.(type) {
case Callable:
return x.Call(b, local)
case Set:
var out Value
for e := x.Enumerator(); e.MoveNext(); {
if t, ok := e.Current().(Tuple); ok {
// log.Printf("%v %v %[2]T %v %[3]T", t, t.MustGet("@"), b)
if v, found := t.Get("@"); found && b.Equal(v) {
if out != nil {
return nil, errors.Errorf("Too many items found")
}
if t.Count() != 2 {
return nil, errors.Errorf("Too many outputs")
}
rest := t.Without("@")
for e := rest.Enumerator(); e.MoveNext(); {
_, value := e.Current()
out = value
}
}
}
}
if out == nil {
return nil, errors.Errorf("No items found: %v", b)
}
return out, nil
if x, ok := a.(Set); ok {
return SetCall(x, b), nil
}
return nil, errors.Errorf(
"call lhs must be a function, not %T", a)
Expand Down Expand Up @@ -290,15 +249,6 @@ func (e *BinExpr) String() string {

// Eval returns the subject
func (e *BinExpr) Eval(local Scope) (_ Value, err error) {
defer func() {
switch r := recover().(type) {
case nil:
case error:
panic(wrapContext(r, e))
default:
panic(wrapContext(fmt.Errorf("panic: %v", r), e))
}
}()
a, err := e.a.Eval(local)
if err != nil {
return nil, wrapContext(err, e)
Expand Down
8 changes: 4 additions & 4 deletions rel/expr_dot.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ func (x *DotExpr) Eval(local Scope) (Value, error) {
}
if x.attr[:1] != "&" {
if value, found := t.Get("&" + x.attr); found {
tupleScope := local.With("self", t)
//TODO: add tupleScope self to allow accessing itself
switch f := value.(type) {
case *Function:
return f.Call(nil, tupleScope)
case Closure:
return SetCall(f, nil), nil
case *NativeFunction:
return f.Call(nil, tupleScope)
return SetCall(f, nil), nil
default:
panic(fmt.Errorf("not a function: %v", f))
}
Expand Down
4 changes: 2 additions & 2 deletions rel/expr_reduce.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ func (e *ReduceExpr) Eval(local Scope) (Value, error) {
return nil, wrapContext(err, e)
}
for i := s.Enumerator(); i.MoveNext(); {
b, err := e.f.Call(i.Current(), local)
f, err := e.f.Eval(local)
if err != nil {
return nil, wrapContext(err, e)
}
acc, err = e.reduce(acc, b)
acc, err = e.reduce(acc, SetCall(f.(Closure), i.Current()))
if err != nil {
return nil, wrapContext(err, e)
}
Expand Down
4 changes: 2 additions & 2 deletions rel/expr_unary.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ func NewNotExpr(scanner parser.Scanner, a Expr) Expr {
func NewEvalExpr(scanner parser.Scanner, a Expr) Expr {
return newUnaryExpr(scanner, a, "*", "(*%s)",
func(a Value, local Scope) (Value, error) {
if x, ok := a.(*Function); ok {
return x.Call(None, local)
if x, ok := a.(Closure); ok {
return SetCall(x, None), nil
}
return nil, errors.Errorf("eval arg must be a Function, not %T", a)
})
Expand Down
23 changes: 22 additions & 1 deletion rel/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,32 @@ type Set interface {
Without(Value) Set
Map(func(Value) Value) Set
Where(func(Value) bool) Set
Call(arg Value) Value
CallAll(Value) Set

ArrayEnumerator() (OffsetValueEnumerator, bool)
}

// SetCall does a CallAll to a Set and panics when there's less or more than 1 value.
func SetCall(s Set, arg Value) Value {
result := s.CallAll(arg)
if !result.IsTrue() {
panic(fmt.Sprintf("Call: no return values from set %v", s))
}
for i, e := 1, result.Enumerator(); e.MoveNext(); i++ {
if i > 1 {
panic(fmt.Sprintf("Call: too many return values from set %v: %v", s, result))
}
}
return SetAny(result)
}

func SetAny(s Set) Value {
for e := s.Enumerator(); e.MoveNext(); {
return e.Current()
}
panic("SetAny: set is empty")
}

// NewValue constructs a new value from a Go value.
func NewValue(v interface{}) (Value, error) {
switch x := v.(type) {
Expand Down
4 changes: 3 additions & 1 deletion rel/value_repr.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ func reprArray(a Array, w io.Writer) {
var sep reprCommaSep
for _, v := range a.values {
sep.Sep(w)
reprValue(v, w)
if v != nil {
reprValue(v, w)
}
}
fmt.Fprint(w, "]")
}
Expand Down
Loading

0 comments on commit 82837d6

Please sign in to comment.