Skip to content

Commit

Permalink
Merge pull request #348 from yumaikas/feature/spreadsheet-thaw
Browse files Browse the repository at this point in the history
Feature/spreadsheet thaw
  • Loading branch information
refaktor authored Sep 22, 2024
2 parents 01ee523 + bfa6dc7 commit 625283f
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 10 deletions.
4 changes: 4 additions & 0 deletions env/spreadsheet.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ func (s *Spreadsheet) AddRow(vals SpreadsheetRow) {
s.Rows = append(s.Rows, vals)
}

func (s *Spreadsheet) RemoveRowByIndex(index int64) {
s.Rows = append(s.Rows[:index], s.Rows[index+1:]...)
}

func (s *Spreadsheet) GetRows() []SpreadsheetRow {
return s.Rows
}
Expand Down
16 changes: 16 additions & 0 deletions evaldo/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,22 @@ var builtins = map[string]*env.Builtin{
},
},

"thaw": {
Argsn: 1,
Doc: "Makes a value (currently only spreadsheets) mutable instead of immutable",
Pure: true,
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch sp := arg0.(type) {
case env.Spreadsheet:
return &sp
case *env.Spreadsheet:
return sp
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "thaw")
}
},
},

"get_": { // *** find a name or decide on order of naming with generic words clashes with
Argsn: 1,
Doc: "Returns value of the word in context",
Expand Down
70 changes: 60 additions & 10 deletions evaldo/builtins_spreadsheet.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,54 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
},
},

"add-rows!": {
Argsn: 2,
Doc: "Add one or more rows to a spreadsheet",
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 data1 := arg1.(type) {
case env.Block:
data := data1.Series
for data.Pos() < data.Len() {
rowd := make([]any, len(spr.Cols))
for ii := 0; ii < len(spr.Cols); ii++ {
k1 := data.Pop()
rowd[ii] = k1
}
spr.AddRow(*env.NewSpreadsheetRow(rowd, spr))
}
return spr
case env.Native:
spr.Rows = append(spr.Rows, data1.Value.([]env.SpreadsheetRow)...)
return spr
default:
return MakeArgError(ps, 2, []env.Type{env.BlockType, env.NativeType}, "add-rows!")
}
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "add-rows!")
}
},
},
"remove-row!": {
Argsn: 2,
Doc: "Remove a row from a spreadsheet by index",
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 data1 := arg1.(type) {
case env.Integer:
spr.RemoveRowByIndex(data1.Value)
return spr
default:
return MakeArgError(ps, 2, []env.Type{env.BlockType, env.NativeType}, "remove-row!")
}
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "remove-row!")
}
},
},

// TODO 2 -- this could move to a go function so it could be called by general load that uses extension to define the loader
"load\\csv": {
Argsn: 1,
Expand Down Expand Up @@ -577,10 +625,12 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
Doc: "Gets the column names (header) as block.",
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:
return spr.GetColumns()
case env.Spreadsheet:
return spr.GetColumns()
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "columns?")
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "headers?")
}
},
},
Expand Down Expand Up @@ -635,42 +685,42 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
case env.Block:
return GenerateColumn(ps, spr, newCol, fromCols, code)
default:
return MakeArgError(ps, 4, []env.Type{env.BlockType}, "add-col!")
return MakeArgError(ps, 4, []env.Type{env.BlockType}, "add-column!")
}
case env.Word:
switch replaceBlock := arg3.(type) {
case env.Block:
if replaceBlock.Series.Len() != 2 {
return MakeBuiltinError(ps, "Replacement block must contain a regex object and replacement string.", "add-col!")
return MakeBuiltinError(ps, "Replacement block must contain a regex object and replacement string.", "add-column!")
}
regexNative, ok := replaceBlock.Series.S[0].(env.Native)
if !ok {
return MakeBuiltinError(ps, "First element of replacement block must be a regex object.", "add-col!")
return MakeBuiltinError(ps, "First element of replacement block must be a regex object.", "add-column!")
}
regex, ok := regexNative.Value.(*regexp.Regexp)
if !ok {
return MakeBuiltinError(ps, "First element of replacement block must be a regex object.", "add-col!")
return MakeBuiltinError(ps, "First element of replacement block must be a regex object.", "add-column!")
}
replaceStr, ok := replaceBlock.Series.S[1].(env.String)
if !ok {
return MakeBuiltinError(ps, "Second element of replacement block must be a string.", "add-col!")
return MakeBuiltinError(ps, "Second element of replacement block must be a string.", "add-column!")
}
err := GenerateColumnRegexReplace(ps, &spr, newCol, fromCols, regex, replaceStr.Value)
if err != nil {
return err
}
return spr
default:
return MakeArgError(ps, 3, []env.Type{env.BlockType}, "add-col!")
return MakeArgError(ps, 3, []env.Type{env.BlockType}, "add-column!")
}
default:
return MakeArgError(ps, 3, []env.Type{env.BlockType}, "add-col!")
return MakeArgError(ps, 3, []env.Type{env.BlockType}, "add-column!")
}
default:
return MakeArgError(ps, 2, []env.Type{env.WordType}, "add-col!")
return MakeArgError(ps, 2, []env.Type{env.WordType}, "add-column!")
}
default:
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "add-col!")
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "add-column!")
}
},
},
Expand Down
18 changes: 18 additions & 0 deletions examples/spreadsheet/in-place-mods.rye
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
; Create a spreadsheet

deliveries: thaw spreadsheet { "street" "city" "zip" "contents" }
[
"Maple" "Onowa" "55555" "A bottle of Maple Syrup"
"Oak" "Springfield" "11111" "A donut-shaped stuffed animal"
"Acorn" "Springfield" "11112" "A handheld fan"
"Birch" "Springfield" "11112" "A laptop"
]

deliveries .to-json |print
print ""
deliveries |add-rows! [ "Vega" "Bayton" "12345" "A Nova" ]
deliveries .to-json |print
print ""
deliveries |remove-row! 1
deliveries .to-json |print
print ""

0 comments on commit 625283f

Please sign in to comment.