Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func binExpression(ops []string, sub expressionFunc, l []*lexer.Lexer, i *int) (
case "^":
left = expression.Pow(left, right)
default:
return nil, expression.ErrUnknownOperation
return nil, errors.Join(expression.ErrUnknownOperation, fmt.Errorf("unknown operator %s", op))
}
}
return left, nil
Expand Down Expand Up @@ -175,7 +175,10 @@ func literalExpression(l []*lexer.Lexer, i *int) (expression.Expression, error)
}
return expression.Const(f), nil
case lexer.Literal:
return predefinedExpression(l, i, c.Value)
if expression.IsPredefinedFunction(c.Value) {
return predefinedFunction(l, i, c.Value)
}
return expression.LiteralExpression(c.Value)
case lexer.Separator:
if c.Value == "(" {
exp, err := termExpression(l, i)
Expand All @@ -200,25 +203,19 @@ func literalExpression(l []*lexer.Lexer, i *int) (expression.Expression, error)
exp = expression.Neg(exp)
case "+":
default:
return nil, expression.ErrUnknownOperation
return nil, errors.Join(expression.ErrUnknownOperation, fmt.Errorf("unknown unary operator %s", c.Value))
}
return exp, nil
}
return nil, errors.Join(ErrUnknownExpression, fmt.Errorf("unknown type %s: excepting a valid literal expression", c))
}

func predefinedExpression(l []*lexer.Lexer, i *int, id string) (expression.Expression, error) {
if expression.IsPredefinedVariable(id) {
return expression.LiteralVariable(id), nil
}
if expression.IsPredefinedFunction(id) {
exp, err := operatorExpression(l, i)
if err != nil {
return nil, err
}
return expression.LiteralFunction(id, exp), nil
func predefinedFunction(l []*lexer.Lexer, i *int, id string) (expression.Expression, error) {
exp, err := operatorExpression(l, i)
if err != nil {
return nil, err
}
return nil, expression.GenErrUnknownVariable(id)
return expression.LiteralFunction(id, exp), nil
}

func operatorExpression(l []*lexer.Lexer, i *int) (expression.Expression, error) {
Expand Down
2 changes: 1 addition & 1 deletion ast/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ func TestAstErrors(t *testing.T) {
genericTestAstError("1+1)", ErrUnknownExpression)
genericTestAstError("(1+1", ErrInvalidExpression)
genericTestAstError("1+1+", ErrInvalidExpression)
//genericTestAstError("1×1+1", ErrUnknownVariable) // will be valid when omission between number and literal is added
//genericTestAstError("1×1+1", ErrInvalidExpression) // will be valid when omission between number and literal is added
}
2 changes: 1 addition & 1 deletion ast/statements.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ type latexStatement struct {
Expression expression.Expression
}

func (l *latexStatement) Eval(opt *Options) (*StatementResult, error) {
func (l *latexStatement) Eval(_ *Options) (*StatementResult, error) {
s, _, err := l.Expression.RenderLatex()
if err != nil {
return nil, err
Expand Down
18 changes: 18 additions & 0 deletions expression/literal.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ type predefinedVariable variable

type predefinedFunction function

type literalExpression string

func (l *literalExpression) Eval() (*math.Fraction, error) {
return nil, errors.Join(ErrUnknownOperation, fmt.Errorf("literal operations not supported"))
}

func (l *literalExpression) RenderLatex() (string, priority, error) {
return string(*l), literalPriority, nil
}

func (v *predefinedVariable) Eval() (*math.Fraction, error) {
val, ok := predefinedVariables[v.ID]
if !ok {
Expand Down Expand Up @@ -58,6 +68,14 @@ func (f *predefinedFunction) RenderLatex() (string, priority, error) {
return fmt.Sprintf(`\%s\left(%s\right)`, f.ID, val), literalPriority, nil
}

func LiteralExpression(l string) (Literal, error) {
if IsPredefinedVariable(l) {
return LiteralVariable(l), nil
}
exp := literalExpression(l)
return &exp, nil
}

func LiteralVariable(id string) Literal {
v := predefinedVariables[id]
return &predefinedVariable{id, v.OmitSlash}
Expand Down
1 change: 1 addition & 0 deletions expressions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ func TestEvalLatex(t *testing.T) {
genericTestRenderLatex(t, "2!*2!", `2! \times 2!`)
genericTestRenderLatex(t, "3^2!", `3^2!`)
genericTestRenderLatex(t, "(3+2)!", `\left(3 + 2\right)!`)
genericTestRenderLatex(t, "2x", `2 \times x`)
}

func genericTestRenderLatex(t *testing.T, exp string, excepted string) {
Expand Down
Loading