Skip to content

Commit

Permalink
Merge pull request #410 from yumaikas/feature/spreadsheet-from-column…
Browse files Browse the repository at this point in the history
…-data

Clean up tests and expand support for spreadsheet refs
  • Loading branch information
refaktor authored Nov 18, 2024
2 parents 5bffc2f + d1cb2a9 commit e7403f8
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 78 deletions.
9 changes: 9 additions & 0 deletions evaldo/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -6770,6 +6770,11 @@ var builtins = map[string]*env.Builtin{
return MakeBuiltinError(ps, "Spreadsheet is empty.", "first")
}
return s1.GetRow(ps, int(0))
case *env.Spreadsheet:
if s1.NRows() == 0 {
return MakeBuiltinError(ps, "Spreadsheet is empty.", "first")
}
return s1.GetRow(ps, int(0))
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType, env.BlockType, env.StringType, env.ListType}, "first")
}
Expand Down Expand Up @@ -7977,6 +7982,8 @@ var builtins = map[string]*env.Builtin{
return *env.NewBoolean(s1.Series.Len() == 0)
case env.Spreadsheet:
return *env.NewBoolean(len(s1.Rows) == 0)
case *env.Spreadsheet:
return *env.NewBoolean(len(s1.Rows) == 0)
case env.RyeCtx:
return *env.NewBoolean(s1.GetWords(*ps.Idx).Series.Len() == 0)
case env.Vector:
Expand All @@ -8002,6 +8009,8 @@ var builtins = map[string]*env.Builtin{
return *env.NewInteger(int64(s1.Series.Len()))
case env.Spreadsheet:
return *env.NewInteger(int64(len(s1.Rows)))
case *env.Spreadsheet:
return *env.NewInteger(int64(len(s1.Rows)))
case env.RyeCtx:
return *env.NewInteger(int64(s1.GetWords(*ps.Idx).Series.Len()))
case env.Vector:
Expand Down
185 changes: 109 additions & 76 deletions evaldo/builtins_spreadsheet.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,15 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
Doc: "Returns spreadsheet of rows where specific colum is equal to given value.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch spr := arg0.(type) {
case *env.Spreadsheet:
switch col := arg1.(type) {
case env.Word:
return WhereEquals(ps, *spr, ps.Idx.GetWord(col.Index), arg2)
case env.String:
return WhereEquals(ps, *spr, col.Value, arg2)
default:
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-equal")
}
case env.Spreadsheet:
switch col := arg1.(type) {
case env.Word:
Expand All @@ -545,27 +554,31 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
Argsn: 3,
Doc: "Returns spreadsheet of rows where a specific colum matches a regex.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) (res env.Object) {
switch spr := arg0.(type) {
var spr *env.Spreadsheet
switch sheet := arg0.(type) {
case env.Spreadsheet:
switch reNative := arg2.(type) {
case env.Native:
re, ok := reNative.Value.(*regexp.Regexp)
if !ok {
return MakeArgError(ps, 2, []env.Type{env.NativeType}, "where-match")
}
switch col := arg1.(type) {
case env.Word:
return WhereMatch(ps, spr, ps.Idx.GetWord(col.Index), re)
case env.String:
return WhereMatch(ps, spr, col.Value, re)
default:
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-match")
}
spr = &sheet
case *env.Spreadsheet:
spr = sheet
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-match")
}
switch reNative := arg2.(type) {
case env.Native:
re, ok := reNative.Value.(*regexp.Regexp)
if !ok {
return MakeArgError(ps, 2, []env.Type{env.NativeType}, "where-match")
}
switch col := arg1.(type) {
case env.Word:
return WhereMatch(ps, spr, ps.Idx.GetWord(col.Index), re)
case env.String:
return WhereMatch(ps, spr, col.Value, re)
default:
return MakeArgError(ps, 3, []env.Type{env.NativeType}, "where-match")
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-match")
}
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-match")
return MakeArgError(ps, 3, []env.Type{env.NativeType}, "where-match")
}
},
},
Expand All @@ -582,23 +595,27 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
Argsn: 3,
Doc: "Returns spreadsheet of rows where specific colum contains a given string value.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) (res env.Object) {
switch spr := arg0.(type) {
var spr *env.Spreadsheet
switch sheet := arg0.(type) {
case env.Spreadsheet:
switch s := arg2.(type) {
spr = &sheet
case *env.Spreadsheet:
spr = sheet
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-match")
}
switch s := arg2.(type) {
case env.String:
switch col := arg1.(type) {
case env.Word:
return WhereContains(ps, spr, ps.Idx.GetWord(col.Index), s.Value, false)
case env.String:
switch col := arg1.(type) {
case env.Word:
return WhereContains(ps, spr, ps.Idx.GetWord(col.Index), s.Value, false)
case env.String:
return WhereContains(ps, spr, col.Value, s.Value, false)
default:
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-contains")
}
return WhereContains(ps, spr, col.Value, s.Value, false)
default:
return MakeArgError(ps, 3, []env.Type{env.StringType}, "where-contains")
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-contains")
}
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-contains")
return MakeArgError(ps, 3, []env.Type{env.StringType}, "where-contains")
}
},
},
Expand All @@ -615,23 +632,27 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
Argsn: 3,
Doc: "Returns spreadsheet of rows where specific colum contains a given string value.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) (res env.Object) {
switch spr := arg0.(type) {
var spr *env.Spreadsheet
switch sheet := arg0.(type) {
case env.Spreadsheet:
switch s := arg2.(type) {
spr = &sheet
case *env.Spreadsheet:
spr = sheet
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-match")
}
switch s := arg2.(type) {
case env.String:
switch col := arg1.(type) {
case env.Word:
return WhereContains(ps, spr, ps.Idx.GetWord(col.Index), s.Value, true)
case env.String:
switch col := arg1.(type) {
case env.Word:
return WhereContains(ps, spr, ps.Idx.GetWord(col.Index), s.Value, true)
case env.String:
return WhereContains(ps, spr, col.Value, s.Value, true)
default:
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-not-contains")
}
return WhereContains(ps, spr, col.Value, s.Value, true)
default:
return MakeArgError(ps, 3, []env.Type{env.StringType}, "where-not-contains")
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-not-contains")
}
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-not-contains")
return MakeArgError(ps, 3, []env.Type{env.StringType}, "where-not-contains")
}
},
},
Expand All @@ -647,18 +668,22 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
Argsn: 3,
Doc: "Returns spreadsheet of rows where specific colum is greater than given value.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch spr := arg0.(type) {
var spr *env.Spreadsheet
switch sheet := arg0.(type) {
case env.Spreadsheet:
switch col := arg1.(type) {
case env.Word:
return WhereGreater(ps, spr, ps.Idx.GetWord(col.Index), arg2)
case env.String:
return WhereGreater(ps, spr, col.Value, arg2)
default:
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-greater")
}
spr = &sheet
case *env.Spreadsheet:
spr = sheet
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-greater")
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-match")
}
switch col := arg1.(type) {
case env.Word:
return WhereGreater(ps, spr, ps.Idx.GetWord(col.Index), arg2)
case env.String:
return WhereGreater(ps, spr, col.Value, arg2)
default:
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-greater")
}
},
},
Expand All @@ -674,18 +699,22 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
Argsn: 3,
Doc: "Returns spreadsheet of rows where specific colum is lesser than given value.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch spr := arg0.(type) {
var spr *env.Spreadsheet
switch sheet := arg0.(type) {
case env.Spreadsheet:
switch col := arg1.(type) {
case env.Word:
return WhereLesser(ps, spr, ps.Idx.GetWord(col.Index), arg2)
case env.String:
return WhereLesser(ps, spr, col.Value, arg2)
default:
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-lesser")
}
spr = &sheet
case *env.Spreadsheet:
spr = sheet
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-lesser")
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-match")
}
switch col := arg1.(type) {
case env.Word:
return WhereLesser(ps, spr, ps.Idx.GetWord(col.Index), arg2)
case env.String:
return WhereLesser(ps, spr, col.Value, arg2)
default:
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-lesser")
}
},
},
Expand All @@ -704,18 +733,22 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
Argsn: 4,
Doc: "Returns spreadsheet of rows where specific colum is between given values.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) (res env.Object) {
switch spr := arg0.(type) {
var spr *env.Spreadsheet
switch sheet := arg0.(type) {
case env.Spreadsheet:
switch col := arg1.(type) {
case env.Word:
return WhereBetween(ps, spr, ps.Idx.GetWord(col.Index), arg2, arg3)
case env.String:
return WhereBetween(ps, spr, col.Value, arg2, arg3)
default:
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-between")
}
spr = &sheet
case *env.Spreadsheet:
spr = sheet
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-match")
}
switch col := arg1.(type) {
case env.Word:
return WhereBetween(ps, spr, ps.Idx.GetWord(col.Index), arg2, arg3)
case env.String:
return WhereBetween(ps, spr, col.Value, arg2, arg3)
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "where-between")
return MakeArgError(ps, 2, []env.Type{env.WordType, env.StringType}, "where-between")
}
},
},
Expand Down Expand Up @@ -1538,7 +1571,7 @@ func WhereEquals(ps *env.ProgramState, s env.Spreadsheet, name string, val env.O
}
}

func WhereMatch(ps *env.ProgramState, s env.Spreadsheet, name string, r *regexp.Regexp) env.Object {
func WhereMatch(ps *env.ProgramState, s *env.Spreadsheet, name string, r *regexp.Regexp) env.Object {
idx := slices.Index(s.Cols, name)
nspr := env.NewSpreadsheet(s.Cols)
if idx > -1 {
Expand All @@ -1558,7 +1591,7 @@ func WhereMatch(ps *env.ProgramState, s env.Spreadsheet, name string, r *regexp.
}
}

func WhereContains(ps *env.ProgramState, s env.Spreadsheet, name string, val string, not bool) env.Object {
func WhereContains(ps *env.ProgramState, s *env.Spreadsheet, name string, val string, not bool) env.Object {
idx := slices.Index(s.Cols, name)
nspr := env.NewSpreadsheet(s.Cols)
if idx > -1 {
Expand Down Expand Up @@ -1604,7 +1637,7 @@ func WhereIn(ps *env.ProgramState, s env.Spreadsheet, name string, b []env.Objec
}
}

func WhereGreater(ps *env.ProgramState, s env.Spreadsheet, name string, val env.Object) env.Object {
func WhereGreater(ps *env.ProgramState, s *env.Spreadsheet, name string, val env.Object) env.Object {
idx := slices.Index(s.Cols, name)
nspr := env.NewSpreadsheet(s.Cols)
if idx > -1 {
Expand All @@ -1621,7 +1654,7 @@ func WhereGreater(ps *env.ProgramState, s env.Spreadsheet, name string, val env.
}
}

func WhereLesser(ps *env.ProgramState, s env.Spreadsheet, name string, val env.Object) env.Object {
func WhereLesser(ps *env.ProgramState, s *env.Spreadsheet, name string, val env.Object) env.Object {
idx := slices.Index(s.Cols, name)
nspr := env.NewSpreadsheet(s.Cols)
if idx > -1 {
Expand All @@ -1638,7 +1671,7 @@ func WhereLesser(ps *env.ProgramState, s env.Spreadsheet, name string, val env.O
}
}

func WhereBetween(ps *env.ProgramState, s env.Spreadsheet, name string, val1 env.Object, val2 env.Object) env.Object {
func WhereBetween(ps *env.ProgramState, s *env.Spreadsheet, name string, val1 env.Object, val2 env.Object) env.Object {
idx := slices.Index(s.Cols, name)
nspr := env.NewSpreadsheet(s.Cols)
if idx > -1 {
Expand Down
7 changes: 5 additions & 2 deletions tests/structures.rye
Original file line number Diff line number Diff line change
Expand Up @@ -586,8 +586,11 @@ section "Spreadsheet related functions"
mold\nowrap ?spreadsheet
{ }
{
equal { spreadsheet { "name" "rating" "weight" }
{ "Enno" 4.3 120 "Enya" 6 132 "Shizuuchi" 7.2 168 "Kunishima" 2 68 } ::spr |type? } 'spreadsheet
equal { spreadsheet\columns { "name" "rating" "weight" }
{ { "Enno" "Enya" "Shizuuchi" "Kunishima" }
{ 4.3 6 7.2 2 }
{ 120 132 168 68 }
} ::spr |type? } 'spreadsheet
equal { spr |length? } 4
equal { spr |header? |length? } 3
equal\todo { spr -> 2 -> 'name } "Enya"
Expand Down

0 comments on commit e7403f8

Please sign in to comment.