diff --git a/README.md b/README.md index 0904e76..1fe6577 100644 --- a/README.md +++ b/README.md @@ -225,10 +225,15 @@ the `register()` function to register your functions to the calculator. This function takes these parameters: - function name -- number of arguments expected (1,2 or -1 allowed), -1 means batch - mode +- number of arguments expected (see below) - help text +Number of expected arguments can be: + +- 0: expect 1 argument but do NOT modify the stack +- 1-n: do a singular calculation +- -1: batch mode work with all numbers on the stack + Please [refer to the lua language reference](https://www.lua.org/manual/5.4/) for more details about LUA. diff --git a/calc.go b/calc.go index dedc461..d9d2275 100644 --- a/calc.go +++ b/calc.go @@ -151,16 +151,16 @@ func NewCalc() *Calc { // pre-calculate mode switching arrays c.Constants = strings.Split(Constants, " ") - for name := range LuaFuncs { - c.LuaFunctions = append(c.LuaFunctions, name) - } - return &c } -// setup the interpreter, called from main() +// setup the interpreter, called from main(), import lua functions func (c *Calc) SetInt(I *Interpreter) { c.interpreter = I + + for name := range LuaFuncs { + c.LuaFunctions = append(c.LuaFunctions, name) + } } func (c *Calc) ToggleDebug() { @@ -448,6 +448,8 @@ func (c *Calc) luafunc(funcname string) { var err error switch c.interpreter.FuncNumArgs(funcname) { + case 0: + fallthrough case 1: x, err = c.interpreter.CallLuaFunc(funcname, c.stack.Last()) case 2: @@ -465,7 +467,15 @@ func (c *Calc) luafunc(funcname string) { c.stack.Backup() + dopush := true + switch c.interpreter.FuncNumArgs(funcname) { + case 0: + a := c.stack.Last() + if len(a) == 1 { + c.History("%s(%f) = %f", funcname, a, x) + } + dopush = false case 1: a := c.stack.Pop() c.History("%s(%f) = %f", funcname, a, x) @@ -478,7 +488,9 @@ func (c *Calc) luafunc(funcname string) { c.History("%s(*) = %f", funcname, x) } - c.stack.Push(x) + if dopush { + c.stack.Push(x) + } c.Result() } diff --git a/example.lua b/example.lua new file mode 100644 index 0000000..fa38af7 --- /dev/null +++ b/example.lua @@ -0,0 +1,38 @@ +-- simple function, return the lower number of the two operands +function lower(a,b) + if a < b then + return a + else + return b + end +end + +-- calculate parallel resistance. Batch function (registered with -1, +-- see below). Takes a table as parameter. +-- +-- Formula: 1/( (1/R1) + (1/R2) + ...) +function parallelresistance(list) + sumres = 0 + + for i, value in ipairs(list) do + sumres = sumres + 1 / value + end + + return 1 / sumres +end + +-- converter example +function inch2centimeter(inches) + return inches * 2.54 +end + +function init() + -- expects 2 args + register("lower", 2, "lower") + + -- expects a list of all numbers on the stack, batch mode + register("parallelresistance", -1, "parallel resistance") + + -- expects 1 arg, but doesn't pop() + register("inch2centimeter", 0) +end diff --git a/interpreter.go b/interpreter.go index 39c0ed8..760a5af 100644 --- a/interpreter.go +++ b/interpreter.go @@ -25,7 +25,8 @@ import ( ) type Interpreter struct { - debug bool + debug bool + script string } // LUA interpreter, instanciated in main() @@ -42,8 +43,12 @@ type LuaFunction struct { // have access to the interpreter instance var LuaFuncs map[string]LuaFunction +func NewInterpreter(script string, debug bool) *Interpreter { + return &Interpreter{debug: debug, script: script} +} + // initialize the lua environment properly -func InitLua(config string, debug bool) *Interpreter { +func (i *Interpreter) InitLua() { // we only load a subset of lua Open modules and don't allow // net, system or io stuff for _, pair := range []struct { @@ -66,7 +71,7 @@ func InitLua(config string, debug bool) *Interpreter { } // load the lua config (which we expect to contain init() and math functions) - if err := L.DoFile(config); err != nil { + if err := L.DoFile(i.script); err != nil { panic(err) } @@ -84,8 +89,6 @@ func InitLua(config string, debug bool) *Interpreter { }); err != nil { panic(err) } - - return &Interpreter{debug: debug} } func (i *Interpreter) Debug(msg string) { @@ -113,6 +116,8 @@ func (i *Interpreter) CallLuaFunc(funcname string, items []float64) (float64, er funcname, LuaFuncs[funcname].numargs)) switch LuaFuncs[funcname].numargs { + case 0: + fallthrough case 1: // 1 arg variant if err := L.CallByParam(lua.P{ diff --git a/main.go b/main.go index 9df9488..d9ad1c8 100644 --- a/main.go +++ b/main.go @@ -30,7 +30,7 @@ import ( lua "github.com/yuin/gopher-lua" ) -const VERSION string = "2.0.5" +const VERSION string = "2.0.6" const Usage string = `This is rpn, a reverse polish notation calculator cli. @@ -98,8 +98,9 @@ func main() { // our config file is interpreted as lua code, only functions can // be defined, init() will be called by InitLua(). if _, err := os.Stat(configfile); err == nil { - I := InitLua(configfile, enabledebug) - calc.SetInt(I) + luarunner := NewInterpreter(configfile, enabledebug) + luarunner.InitLua() + calc.SetInt(luarunner) } if len(flag.Args()) > 1 { diff --git a/rpn.go b/rpn.go index 4b6bee6..2496d37 100644 --- a/rpn.go +++ b/rpn.go @@ -210,7 +210,6 @@ COMMENTS In this case only 123 will be added to the stack. - VARIABLES You can register the last item of the stack into a variable. Variable names must be all caps. Use the ">NAME" command to put a value into @@ -245,8 +244,13 @@ EXTENDING RPN USING LUA * function name - * number of arguments expected (1,2 or -1 allowed), -1 means batch - mode. + * number of arguments expected (see below) + + Number of expected arguments can be: + + - 0: expect 1 argument but do NOT modify the stack + - 1-n: do a singular calculation + - -1: batch mode work with all numbers on the stack * help text diff --git a/rpn.pod b/rpn.pod index 7fce755..899f181 100644 --- a/rpn.pod +++ b/rpn.pod @@ -273,8 +273,13 @@ function name =item * -number of arguments expected (1,2 or -1 allowed), -1 means batch -mode. +number of arguments expected (see below) + +Number of expected arguments can be: + + - 0: expect 1 argument but do NOT modify the stack + - 1-n: do a singular calculation + - -1: batch mode work with all numbers on the stack =item * diff --git a/test.lua b/test.lua deleted file mode 100644 index f71649e..0000000 --- a/test.lua +++ /dev/null @@ -1,17 +0,0 @@ -function add(a,b) - return a + b -end - -function test(a) - return a -end - -function parallelresistance(a,b) - return 1.0 / (a * b) -end - -function init() - register("add", 2, "addition") - register("test", 1, "test") - register("parallelresistance", 2, "parallel resistance") -end