mirror of
https://codeberg.org/scip/rpnc.git
synced 2025-12-17 12:31:04 +01:00
reorganized Eval() return errors and call EvalItem() on each item
This commit is contained in:
200
calc.go
200
calc.go
@@ -222,12 +222,12 @@ func (c *Calc) Prompt() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the actual work horse, evaluate a line of calc command[s]
|
// the actual work horse, evaluate a line of calc command[s]
|
||||||
func (c *Calc) Eval(line string) {
|
func (c *Calc) Eval(line string) error {
|
||||||
// remove surrounding whitespace and comments, if any
|
// remove surrounding whitespace and comments, if any
|
||||||
line = strings.TrimSpace(c.Comment.ReplaceAllString(line, ""))
|
line = strings.TrimSpace(c.Comment.ReplaceAllString(line, ""))
|
||||||
|
|
||||||
if line == "" {
|
if line == "" {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
items := c.Space.Split(line, -1)
|
items := c.Space.Split(line, -1)
|
||||||
@@ -239,98 +239,8 @@ func (c *Calc) Eval(line string) {
|
|||||||
c.notdone = false
|
c.notdone = false
|
||||||
}
|
}
|
||||||
|
|
||||||
num, err := strconv.ParseFloat(item, 64)
|
if err := c.EvalItem(item); err != nil {
|
||||||
|
return err
|
||||||
if err == nil {
|
|
||||||
c.stack.Backup()
|
|
||||||
c.stack.Push(num)
|
|
||||||
} else {
|
|
||||||
// try hex
|
|
||||||
var i int
|
|
||||||
_, err := fmt.Sscanf(item, "0x%x", &i)
|
|
||||||
if err == nil {
|
|
||||||
c.stack.Backup()
|
|
||||||
c.stack.Push(float64(i))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if contains(c.Constants, item) {
|
|
||||||
// put the constant onto the stack
|
|
||||||
c.stack.Backup()
|
|
||||||
c.stack.Push(const2num(item))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if exists(c.Funcalls, item) {
|
|
||||||
if err := c.DoFuncall(item); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
} else {
|
|
||||||
c.Result()
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if exists(c.BatchFuncalls, item) {
|
|
||||||
if !c.batch {
|
|
||||||
fmt.Println("only supported in batch mode")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.DoFuncall(item); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
} else {
|
|
||||||
c.Result()
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if contains(c.LuaFunctions, item) {
|
|
||||||
// user provided custom lua functions
|
|
||||||
c.EvalLuaFunction(item)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
regmatches := c.Register.FindStringSubmatch(item)
|
|
||||||
if len(regmatches) == 3 {
|
|
||||||
switch regmatches[1] {
|
|
||||||
case ">":
|
|
||||||
c.PutVar(regmatches[2])
|
|
||||||
case "<":
|
|
||||||
c.GetVar(regmatches[2])
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// internal commands
|
|
||||||
if exists(c.Commands, item) {
|
|
||||||
c.Commands[item].Func(c)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if exists(c.ShowCommands, item) {
|
|
||||||
c.ShowCommands[item].Func(c)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if exists(c.StackCommands, item) {
|
|
||||||
c.StackCommands[item].Func(c)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if exists(c.SettingsCommands, item) {
|
|
||||||
c.SettingsCommands[item].Func(c)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switch item {
|
|
||||||
case "?":
|
|
||||||
fallthrough
|
|
||||||
case "help":
|
|
||||||
c.PrintHelp()
|
|
||||||
|
|
||||||
default:
|
|
||||||
fmt.Println("unknown command or operator!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,6 +253,106 @@ func (c *Calc) Eval(line string) {
|
|||||||
last := c.stack.Last(5)
|
last := c.stack.Last(5)
|
||||||
fmt.Printf("stack: %s%s\n", dots, list2str(last))
|
fmt.Printf("stack: %s%s\n", dots, list2str(last))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Calc) EvalItem(item string) error {
|
||||||
|
num, err := strconv.ParseFloat(item, 64)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
c.stack.Backup()
|
||||||
|
c.stack.Push(num)
|
||||||
|
} else {
|
||||||
|
// try hex
|
||||||
|
var i int
|
||||||
|
_, err := fmt.Sscanf(item, "0x%x", &i)
|
||||||
|
if err == nil {
|
||||||
|
c.stack.Backup()
|
||||||
|
c.stack.Push(float64(i))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if contains(c.Constants, item) {
|
||||||
|
// put the constant onto the stack
|
||||||
|
c.stack.Backup()
|
||||||
|
c.stack.Push(const2num(item))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists(c.Funcalls, item) {
|
||||||
|
if err := c.DoFuncall(item); err != nil {
|
||||||
|
return Error(err.Error())
|
||||||
|
} else {
|
||||||
|
c.Result()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists(c.BatchFuncalls, item) {
|
||||||
|
if !c.batch {
|
||||||
|
return Error("only supported in batch mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.DoFuncall(item); err != nil {
|
||||||
|
return Error(err.Error())
|
||||||
|
} else {
|
||||||
|
c.Result()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if contains(c.LuaFunctions, item) {
|
||||||
|
// user provided custom lua functions
|
||||||
|
c.EvalLuaFunction(item)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
regmatches := c.Register.FindStringSubmatch(item)
|
||||||
|
if len(regmatches) == 3 {
|
||||||
|
switch regmatches[1] {
|
||||||
|
case ">":
|
||||||
|
c.PutVar(regmatches[2])
|
||||||
|
case "<":
|
||||||
|
c.GetVar(regmatches[2])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal commands
|
||||||
|
// FIXME: propagate errors
|
||||||
|
if exists(c.Commands, item) {
|
||||||
|
c.Commands[item].Func(c)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists(c.ShowCommands, item) {
|
||||||
|
c.ShowCommands[item].Func(c)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists(c.StackCommands, item) {
|
||||||
|
c.StackCommands[item].Func(c)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists(c.SettingsCommands, item) {
|
||||||
|
c.SettingsCommands[item].Func(c)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch item {
|
||||||
|
case "?":
|
||||||
|
fallthrough
|
||||||
|
case "help":
|
||||||
|
c.PrintHelp()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Error("unknown command or operator")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute a math function, check if it is defined just in case
|
// Execute a math function, check if it is defined just in case
|
||||||
@@ -355,7 +365,7 @@ func (c *Calc) DoFuncall(funcname string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if function == nil {
|
if function == nil {
|
||||||
panic("function not defined but in completion list")
|
return Error("function not defined but in completion list")
|
||||||
}
|
}
|
||||||
|
|
||||||
var args Numbers
|
var args Numbers
|
||||||
|
|||||||
18
main.go
18
main.go
@@ -30,7 +30,7 @@ import (
|
|||||||
lua "github.com/yuin/gopher-lua"
|
lua "github.com/yuin/gopher-lua"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VERSION string = "2.0.12"
|
const VERSION string = "2.0.13"
|
||||||
|
|
||||||
const Usage string = `This is rpn, a reverse polish notation calculator cli.
|
const Usage string = `This is rpn, a reverse polish notation calculator cli.
|
||||||
|
|
||||||
@@ -119,7 +119,11 @@ func Main() int {
|
|||||||
// commandline calc operation, no readline etc needed
|
// commandline calc operation, no readline etc needed
|
||||||
// called like rpn 2 2 +
|
// called like rpn 2 2 +
|
||||||
calc.stdin = true
|
calc.stdin = true
|
||||||
calc.Eval(strings.Join(flag.Args(), " "))
|
if err := calc.Eval(strings.Join(flag.Args(), " ")); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +157,10 @@ func Main() int {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
calc.Eval(line)
|
err = calc.Eval(line)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
rl.SetPrompt(calc.Prompt())
|
rl.SetPrompt(calc.Prompt())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +169,10 @@ func Main() int {
|
|||||||
// echo 1 2 3 4 | rpn +
|
// echo 1 2 3 4 | rpn +
|
||||||
// batch mode enabled automatically
|
// batch mode enabled automatically
|
||||||
calc.batch = true
|
calc.batch = true
|
||||||
calc.Eval(flag.Args()[0])
|
if err = calc.Eval(flag.Args()[0]); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
4
util.go
4
util.go
@@ -71,3 +71,7 @@ func const2num(name string) float64 {
|
|||||||
func list2str(list Numbers) string {
|
func list2str(list Numbers) string {
|
||||||
return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(list)), " "), "[]")
|
return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(list)), " "), "[]")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Error(m string) error {
|
||||||
|
return fmt.Errorf("Error: %s!", m)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user