Skip to content

Commit

Permalink
Merge pull request #13 from fr3fou/tidy
Browse files Browse the repository at this point in the history
Fix tests, Remove useless `handleErr` function
  • Loading branch information
viktordanov authored Oct 8, 2021
2 parents 3b3f78b + f3faebe commit 0f79fdf
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 80 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
.idea/
abacus
definitions.a

.DS_Store
16 changes: 9 additions & 7 deletions abacus_visitor.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package main

import (
"github.com/antlr/antlr4/runtime/Go/antlr"
"github.com/cockroachdb/apd"
"github.com/viktordanov/abacus/parser"
"math"
"strconv"
"strings"

"github.com/antlr/antlr4/runtime/Go/antlr"
"github.com/cockroachdb/apd"
"github.com/viktordanov/abacus/parser"
)

var (
Expand All @@ -17,9 +18,9 @@ var (
E Number
)

func init() {
func initConsts(precision uint32) {
logCache = make(map[string]Number)
decimalCtx = apd.BaseContext.WithPrecision(arguments.Precision)
decimalCtx = apd.BaseContext.WithPrecision(precision)
cachedLog(Number{apd.New(2, 0)})
cachedLog(Number{apd.New(10, 0)})

Expand Down Expand Up @@ -169,13 +170,14 @@ type AbacusVisitor struct {
decimalCtx *apd.Context
}

func NewAbacusVisitor() *AbacusVisitor {
func NewAbacusVisitor(precision uint32) *AbacusVisitor {
initConsts(precision)
return &AbacusVisitor{
ParseTreeVisitor: &parser.BaseAbacusVisitor{},
variables: make(map[string]Number),
lambdaDeclarations: make(map[string]*LambdaDeclaration),
lambdaCallStack: &LambdaCallStack{root: nil, invokes: map[string]uint{}, trace: []*CalledLambda{}, recursion: map[string]*RecursionParameters{}, memoized: map[string]*Result{}},
decimalCtx: apd.BaseContext.WithPrecision(arguments.Precision),
decimalCtx: apd.BaseContext.WithPrecision(precision),
}
}

Expand Down
23 changes: 5 additions & 18 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (

var (
arguments args
precision uint32
homeDir, _ = os.UserHomeDir()
historyFile = filepath.Join(homeDir, ".abacus_history")
funcs = []string{
Expand Down Expand Up @@ -57,7 +56,7 @@ type args struct {
}

func (args) Version() string {
return "v1.2.3\n"
return "v1.2.4\n"
}
func (args) Description() string {
return "abacus - a simple interactive calculator CLI with support for variables, lambdas, comparison checks, and math functions\n"
Expand All @@ -75,9 +74,7 @@ func main() {

func run() error {
arg.MustParse(&arguments)
precision = arguments.Precision

abacusVisitor := NewAbacusVisitor()
abacusVisitor := NewAbacusVisitor(arguments.Precision)
line := liner.NewLiner()

defer line.Close()
Expand Down Expand Up @@ -135,7 +132,6 @@ func run() error {
if err != nil {
return err
}

evaluateExpression(string(dat), abacusVisitor)
}

Expand All @@ -156,9 +152,9 @@ func run() error {
_ = f.Close()
})

// REPL loop
// Read Eval Print Loop
for {
savedPrecision := precision
savedPrecision := arguments.Precision
input, err := line.Prompt(arguments.CustomPromptSymbol)
if err != nil {
if errors.Is(err, liner.ErrPromptAborted) || errors.Is(err, io.EOF) {
Expand All @@ -174,10 +170,9 @@ func run() error {
if input != "" {
line.AppendHistory(input)
handleAndPrintAnswer(evaluateExpression(input, abacusVisitor))
precision = savedPrecision
arguments.Precision = savedPrecision
}
}

}

func evaluateExpression(expr string, visitor *AbacusVisitor) *Result {
Expand Down Expand Up @@ -244,12 +239,10 @@ func updateCompletions(line *liner.State, a *AbacusVisitor) {
continue
}
idx++

break
}
if len(line) == 0 {
c = append(c, n)

continue
}
if idx == -1 {
Expand All @@ -262,9 +255,3 @@ func updateCompletions(line *liner.State, a *AbacusVisitor) {
return
})
}

func handleErr(err error) {
if err != nil {
panic("Abacus crashed: " + err.Error())
}
}
103 changes: 49 additions & 54 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
package main

import (
"math"
"math/big"
"testing"
)

// TODO: Rewrite tests for new return system

func newBigFloat(val float64) *big.Float {
return big.NewFloat(val)
}
"github.com/cockroachdb/apd"
)

type testArgs = []struct {
expr string
Expand All @@ -19,37 +13,38 @@ type testArgs = []struct {
}

func Test_evaluateExpression(t *testing.T) {
visitor := NewAbacusVisitor()
visitor := NewAbacusVisitor(64)
decimalCtx = apd.BaseContext.WithPrecision(64)

additionTests := testArgs{
{expr: "2+2", want: newBigFloat(4), visitor: visitor},
{expr: "2 +2+ 2+2+2+ 2", want: newBigFloat(12), visitor: visitor},
{expr: "0+ 8+( d+4)", want: newBigFloat(12), visitor: visitor},
{expr: "(2+2)", want: newBigFloat(4), visitor: visitor},
{expr: "2-2", want: newBigFloat(0), visitor: visitor},
{expr: "2", want: newBigFloat(2), visitor: visitor},
{expr: "2.139487526 + 9.4777777", want: newBigFloat(11.617265226), visitor: visitor},
{expr: "2+2", want: newNumber(4), visitor: visitor},
{expr: "2 +2+ 2+2+2+ 2", want: newNumber(12), visitor: visitor},
{expr: "0+ 8+( d+4)", want: newNumber(12), visitor: visitor},
{expr: "(2+2)", want: newNumber(4), visitor: visitor},
{expr: "2-2", want: newNumber(0), visitor: visitor},
{expr: "2", want: newNumber(2), visitor: visitor},
{expr: "2.139487526 + 9.4777777", want: newNumber(11.617265226), visitor: visitor},
}
multiplicationTests := testArgs{
{expr: "2*2", want: newBigFloat(4), visitor: visitor},
{expr: "2*2*2", want: newBigFloat(8), visitor: visitor},
{expr: "0.188492164*2.444445187", want: newBigFloat(0.460758763077014668), visitor: visitor},
{expr: "9.00005849491657/0.18849622221346", want: newBigFloat(47.746625312864760550563651153054), visitor: visitor},
{expr: "2*(2+9)", want: newBigFloat(22), visitor: visitor},
{expr: "(2*2)+9", want: newBigFloat(13), visitor: visitor},
{expr: "2*2", want: newNumber(4), visitor: visitor},
{expr: "2*2*2", want: newNumber(8), visitor: visitor},
{expr: "0.188492164*2.444445187", want: newNumFromString(decimalCtx, "0.460758763077014668"), visitor: visitor},
{expr: "9.00005849491657/0.18849622221346", want: newNumFromString(decimalCtx, "47.74662531286476055056365115305431970338920063933451796995514209"), visitor: visitor},
{expr: "2*(2+9)", want: newNumber(22), visitor: visitor},
{expr: "(2*2)+9", want: newNumber(13), visitor: visitor},
}
exponentiationTests := testArgs{
{expr: "2^2", want: newBigFloat(4), visitor: visitor},
{expr: "2^2^2**2", want: newBigFloat(256), visitor: visitor},
{expr: "2^(2**2^2)", want: newBigFloat(65536), visitor: visitor},
{expr: "2**0", want: newBigFloat(1), visitor: visitor},
{expr: "2^2", want: newNumber(4), visitor: visitor},
{expr: "2^2^2**2", want: newNumber(256), visitor: visitor},
{expr: "2^(2**2^2)", want: newNumber(65536), visitor: visitor},
{expr: "2**0", want: newNumber(1), visitor: visitor},
}
variableTests := testArgs{
{expr: "d", want: newBigFloat(0), visitor: visitor},
{expr: "d=1", want: Assignment{[]*big.Float{New(1)}}, visitor: visitor},
{expr: "d", want: newBigFloat(1), visitor: visitor},
{expr: "dd=d", want: Assignment{[]*big.Float{New(1)}}, visitor: visitor},
{expr: "dd", want: newBigFloat(1), visitor: visitor},
{expr: "d", want: newNumber(0), visitor: visitor},
{expr: "d=1", want: Assignment{newNumber(1)}, visitor: visitor},
{expr: "d", want: newNumber(1), visitor: visitor},
{expr: "dd=d", want: Assignment{newNumber(1)}, visitor: visitor},
{expr: "dd", want: newNumber(1), visitor: visitor},
}
comparisonTests := testArgs{
{expr: "0 == 0", want: true, visitor: visitor},
Expand Down Expand Up @@ -77,7 +72,7 @@ func Test_evaluateExpression(t *testing.T) {
}

func BenchmarkEvaluateExpression(b *testing.B) {
visitor := NewAbacusVisitor()
visitor := NewAbacusVisitor(64)
complicatedExpression := "2+2+sin(4**5**((7/(4**(pi/1.45*e*log(97,1.1))))**8))"
for i := 0; i < b.N; i++ {
evaluateExpression(complicatedExpression, visitor)
Expand All @@ -87,46 +82,46 @@ func BenchmarkEvaluateExpression(b *testing.B) {
func runTestSuite(t *testing.T, name string, tests testArgs) {
t.Run(name, func(t *testing.T) {
for _, tt := range tests {
t.Run("", func(t *testing.T) {
t.Run(tt.expr, func(t *testing.T) {
ans := evaluateExpression(tt.expr, tt.visitor)
switch val := ans.(type) {
switch val := ans.Value.(type) {
case Assignment:
expected, ok := tt.want.(Assignment)
if !ok {
t.Errorf("VarAssign %v, unexpected type", ans)
t.Errorf("Assignment %v, unexpected type", ans)
}
for i := 0; i < len(val.Values); i++ {
if !compareBigFloat(val.Values[i], expected.Values[i]) {
t.Errorf("VarAssign %v, want %v", val.Values[i], expected.Values[i])
for i := 0; i < len(val); i++ {
if !compareNum(val[i], expected[i]) {
t.Errorf("Assignment %v, want %v", val[i], expected[i])
}
}

case *big.Float:
expected, ok := tt.want.(*big.Float)
case Number:
expected, ok := tt.want.(Number)
if !ok {
t.Errorf("*big.Float %v, unexpected type", ans)
t.Errorf("Number %v, unexpected type", ans)
}
if !compareBigFloat(val, expected) {
t.Errorf("*big.Float %v, want %v", val, expected)
if !compareNum(val, expected) {
t.Errorf("Number %v, want %v", val, expected)
}
case bool:
case Bool:
expected, ok := tt.want.(bool)
if !ok {
t.Errorf("bool %v, unexpected type", ans)
t.Errorf("Bool %v, unexpected type", ans)
}
if val != expected {
t.Errorf("bool %v, want %v", val, expected)
if bool(val) != expected {
t.Errorf("Bool %v, want %v", val, expected)
}
}

})
}
})
}

func compareBigFloat(left *big.Float, right *big.Float) bool {
a := Zero()
a.Sub(right, left)
floatValue, _ := a.Float64()
return a.Cmp(Zero()) == 0 || (math.Round(floatValue*1e10) == 0)
func newNumFromString(ctx *apd.Context, s string) Number {
n, _, _ := ctx.NewFromString(s)
return Number{n}
}

func compareNum(left, right Number) bool {
return left.Cmp(right.Decimal) == 0
}

0 comments on commit 0f79fdf

Please sign in to comment.