README
2 files changed
tree: 7345ee44716147a46b39109907161d646afef673
  1. ast/
  2. cmd/
  3. docs/
  4. evaluator/
  5. lexer/
  6. parser/
  7. repl/
  8. sessions/
  9. token/
  10. go.mod
  11. integration_test.go
  12. matheval
  13. README.md
README.md

matheval

A math expression evaluator with user-defined functions and an interactive REPL, written in Go.

Features

  • Arithmetic operators: +, -, *, /
  • Parentheses for grouping
  • Floating point numbers (including .5 syntax)
  • Correct operator precedence (* and / bind tighter than + and -)
  • Left-to-right associativity
  • User-defined functions with f(x) = x + 1 syntax
  • Multi-parameter functions: f(x, y) = x + y
  • Functions can call other user-defined functions (late binding)
  • Clear error messages with position reporting

Build

go build -o matheval ./cmd/matheval

Usage

Run the REPL:

./matheval

Then type expressions and define functions:

>> 2 + 3 * 4
14
>> (2 + 3) * 4
20
>> 7 / 2
3.5
>> 1 / 0
error: division by zero
>> square(x) = x * x
defined square
>> square(5)
25
>> add(x, y) = x + y
defined add
>> add(2, 3)
5
>> hyp(a, b) = square(a) + square(b)
defined hyp
>> hyp(3, 4)
25

Press Ctrl+D (EOF) to exit.

You can also pipe input:

echo "2 + 3" | ./matheval

Architecture

Input string β†’ Lexer β†’ Parser β†’ AST β†’ Evaluator β†’ Result
PackageResponsibility
tokenToken types and data structures
lexerTokenizes input string
astAST node types (NumberLit, BinaryExpr, Ident, FuncCall, FuncDef)
parserRecursive-descent parser (expressions and function definitions)
evaluatorStateful evaluator with function registry
replRead-eval-print loop with persistent state

Grammar

line     β†’ funcdef | expr
funcdef  β†’ IDENT '(' params ')' '=' expr
params   β†’ IDENT (',' IDENT)*
expr     β†’ term (('+' | '-') term)*
term     β†’ factor (('*' | '/') factor)*
factor   β†’ NUMBER | IDENT '(' args ')' | IDENT | '(' expr ')'
args     β†’ expr (',' expr)*

Function Rules

  • Define: name(params) = body β€” body is any expression using the parameters
  • Call: name(args) β€” arguments are arbitrary expressions
  • Redefinition: Not allowed (returns an error)
  • Cross-calling: Functions can call other user-defined functions
  • Late binding: References resolved at call time, not definition time

Tests

go test ./...

This runs unit tests for each package plus integration tests covering the full pipeline.