Added more tests

This commit is contained in:
Eduard Urbach 2024-06-28 23:13:55 +02:00
parent 445556b64d
commit 5f2ff5e74e
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
5 changed files with 73 additions and 30 deletions

View File

@ -109,14 +109,10 @@ func (expr *Expression) write(builder *strings.Builder) {
builder.WriteByte('(') builder.WriteByte('(')
builder.WriteString(expr.Token.Text()) builder.WriteString(expr.Token.Text())
builder.WriteByte(' ')
for i, child := range expr.Children { for _, child := range expr.Children {
builder.WriteByte(' ')
child.write(builder) child.write(builder)
if i != len(expr.Children)-1 {
builder.WriteByte(' ')
}
} }
builder.WriteByte(')') builder.WriteByte(')')

View File

@ -118,6 +118,28 @@ func TestEachLeaf(t *testing.T) {
assert.Equal(t, err.Error(), "error") assert.Equal(t, err.Error(), "error")
} }
func TestEachParameter(t *testing.T) {
src := []byte("1+2,3*4,5*6,7+8")
tokens := token.Tokenize(src)
parameters := []string{}
err := expression.EachParameter(tokens, func(parameter token.List) error {
expr := expression.Parse(parameter)
parameters = append(parameters, expr.String())
return nil
})
assert.Nil(t, err)
assert.DeepEqual(t, parameters, []string{"(+ 1 2)", "(* 3 4)", "(* 5 6)", "(+ 7 8)"})
err = expression.EachParameter(tokens, func(parameter token.List) error {
return fmt.Errorf("error")
})
assert.NotNil(t, err)
assert.Equal(t, err.Error(), "error")
}
func TestRemoveChild(t *testing.T) { func TestRemoveChild(t *testing.T) {
src := []byte("(1+2-3*4)+(5*6-7+8)") src := []byte("(1+2-3*4)+(5*6-7+8)")
tokens := token.Tokenize(src) tokens := token.Tokenize(src)
@ -141,3 +163,17 @@ func TestNilGroup(t *testing.T) {
expr := expression.Parse(tokens) expr := expression.Parse(tokens)
assert.Nil(t, expr) assert.Nil(t, expr)
} }
func TestInvalidOperator(t *testing.T) {
src := []byte("a +++ 2")
tokens := token.Tokenize(src)
expr := expression.Parse(tokens)
assert.Equal(t, expr.String(), "(+++ a 2)")
}
func TestInvalidOperatorCall(t *testing.T) {
src := []byte("+++()")
tokens := token.Tokenize(src)
expr := expression.Parse(tokens)
assert.NotNil(t, expr)
}

View File

@ -16,27 +16,29 @@ type Operator struct {
// Operators defines the operators used in the language. // Operators defines the operators used in the language.
// The number corresponds to the operator priority and can not be zero. // The number corresponds to the operator priority and can not be zero.
var Operators = map[string]*Operator{ var Operators = map[string]*Operator{
".": {".", 13, 2}, ".": {".", 13, 2},
"λ": {"λ", 12, 1}, "λ": {"λ", 12, 1},
"!": {"!", 11, 1}, "!": {"!", 11, 1},
"*": {"*", 10, 2}, "*": {"*", 10, 2},
"/": {"/", 10, 2}, "/": {"/", 10, 2},
"%": {"%", 10, 2}, "%": {"%", 10, 2},
"+": {"+", 9, 2}, "+": {"+", 9, 2},
"-": {"-", 9, 2}, "-": {"-", 9, 2},
">>": {">>", 8, 2}, ">>": {">>", 8, 2},
"<<": {"<<", 8, 2}, "<<": {"<<", 8, 2},
">": {">", 7, 2}, "&": {"&", 7, 2},
"<": {"<", 7, 2}, "^": {"^", 6, 2},
">=": {">=", 7, 2}, "|": {"|", 5, 2},
"<=": {"<=", 7, 2},
"==": {"==", 6, 2}, ">": {">", 4, 2},
"!=": {"!=", 6, 2}, "<": {"<", 4, 2},
"&": {"&", 5, 2}, ">=": {">=", 4, 2},
"^": {"^", 4, 2}, "<=": {"<=", 4, 2},
"|": {"|", 3, 2}, "==": {"==", 3, 2},
"&&": {"&&", 2, 2}, "!=": {"!=", 3, 2},
"||": {"||", 1, 2}, "&&": {"&&", 2, 2},
"||": {"||", 1, 2},
"=": {"=", math.MinInt, 2}, "=": {"=", math.MinInt, 2},
":=": {":=", math.MinInt, 2}, ":=": {":=", math.MinInt, 2},
"+=": {"+=", math.MinInt, 2}, "+=": {"+=", math.MinInt, 2},
@ -56,7 +58,7 @@ func isComplete(expr *Expression) bool {
return true return true
} }
if expr.Token.Kind == token.Operator && len(expr.Children) >= numOperands(expr.Token.Text()) { if expr.Token.Kind == token.Operator && len(expr.Children) == numOperands(expr.Token.Text()) {
return true return true
} }

View File

@ -114,7 +114,7 @@ func scanFile(path string, functions chan<- *Function) error {
break break
} }
if tokens[i].Kind == token.NewLine { if tokens[i].Kind == token.NewLine || tokens[i].Kind == token.Comment {
i++ i++
continue continue
} }

View File

@ -59,15 +59,24 @@ func Tokenize(buffer []byte) List {
// Comment // Comment
case '/': case '/':
if i+1 >= len(buffer) || buffer[i+1] != '/' { if i+1 >= len(buffer) || buffer[i+1] != '/' {
tokens = append(tokens, Token{Operator, i, buffer[i : i+1]}) position := i
i++ i++
for i < len(buffer) && isOperator(buffer[i]) {
i++
}
tokens = append(tokens, Token{Operator, position, buffer[position:i]})
continue continue
} }
position := i
for i < len(buffer) && buffer[i] != '\n' { for i < len(buffer) && buffer[i] != '\n' {
i++ i++
} }
tokens = append(tokens, Token{Comment, position, buffer[position:i]})
continue continue
// String // String