Beispiel #1
0
func TestEval(t *testing.T) {
	addTree := ast.New()
	addTree.AddChildren([]ast.Node{
		&ast.Number{
			Value: "2",
		},
		&ast.Operator{
			Class: ast.OpAdd,
		},
		&ast.Number{
			Value: "3",
		},
	})
	subTree := ast.New()
	subTree.AddChildren([]ast.Node{
		&ast.Number{
			Value: "5",
		},
		&ast.Operator{
			Class: ast.OpSubtract,
		},
		&ast.Number{
			Value: "3",
		},
	})
	testCases := []struct {
		tree     ast.Node
		expected *big.Rat
	}{
		{
			tree: &ast.Number{
				Value: "42",
			},
			expected: big.NewRat(42, 1),
		},
		{
			tree:     addTree,
			expected: big.NewRat(5, 1),
		},
		{
			tree:     subTree,
			expected: big.NewRat(2, 1),
		},
	}
	for i, tc := range testCases {
		tcInfo := fmt.Sprintf("test case: %d\ninput:\n%s\n", i, tc.tree.Format(0))
		actual, err := Eval(tc.tree)
		require.NoError(t, err)
		assert.Exactly(t, tc.expected, actual, "\nexpected: %0.3f\ngot:      %0.3f\n%s", ratFloat(tc.expected), ratFloat(actual), tcInfo)
	}
}
Beispiel #2
0
func justNumber(value string) ast.Node {
	base := ast.New()
	base.AddChild(&ast.Number{
		Value: value,
	})
	return base
}
Beispiel #3
0
// E'2 -> "(" E ")"
func ep2(buf *token.Buffer, tree ast.Node) (newTree ast.Node, err error) {
	origPos := buf.Pos()
	defer func() {
		if err != nil {
			buf.MustSeek(origPos)
		}
	}()
	newTree = tree.Copy()
	expr := ast.New()
	newTree.AddChild(expr)
	if err := termOpenParen(buf); err != nil {
		return nil, err
	}
	if buf.Pos() >= buf.Len() {
		return nil, io.EOF
	}
	eTree, err := e(buf, tree.Copy())
	if err != nil {
		return nil, err
	}
	expr.AddChildren(eTree.Children())
	if buf.Pos() >= buf.Len() {
		return nil, io.EOF
	}
	if err := termCloseParen(buf); err != nil {
		return nil, err
	}
	return newTree, nil
}
Beispiel #4
0
func Parse(tokens []token.Token) (ast.Node, error) {
	buf := token.NewBuffer(tokens)
	root := ast.New()
	tree, err := e(buf, root)
	if err != nil {
		if err == io.EOF {
			return nil, errors.New("Unexpected end of input")
		}
		return nil, err
	}
	return tree, nil
}
Beispiel #5
0
func operation(a string, opClass ast.OpClass, b string) ast.Node {
	base := ast.New()
	base.AddChildren([]ast.Node{
		&ast.Number{
			Value: a,
		},
		&ast.Operator{
			Class: opClass,
		},
		&ast.Number{
			Value: b,
		},
	})
	return base
}