diff --git a/parser/parser.go b/parser/parser.go
index c7be53b..15b4cea 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -23,6 +23,125 @@
 	return node, nil
 }
 
+// ParseLine parses a full REPL line, returning either a function definition
+// or an expression statement.
+func ParseLine(tokens []token.Token) (ast.Statement, error) {
+	if len(tokens) == 0 || tokens[0].Type == token.EOF {
+		return nil, fmt.Errorf("empty input")
+	}
+
+	// Detect function definition: look for Equals token.
+	// A function definition has the form: Ident LParen params RParen Equals body
+	if isFuncDef(tokens) {
+		return parseFuncDef(tokens)
+	}
+
+	// Otherwise, parse as expression.
+	node, err := Parse(tokens)
+	if err != nil {
+		return nil, err
+	}
+	return &ast.ExprStmt{Expr: node}, nil
+}
+
+// isFuncDef checks if the token stream looks like a function definition.
+// Pattern: Ident LParen ... RParen Equals ...
+func isFuncDef(tokens []token.Token) bool {
+	if len(tokens) < 5 {
+		return false
+	}
+	if tokens[0].Type != token.Ident {
+		return false
+	}
+	if tokens[1].Type != token.LParen {
+		return false
+	}
+	// Find matching RParen, then check for Equals.
+	depth := 0
+	for i := 1; i < len(tokens); i++ {
+		switch tokens[i].Type {
+		case token.LParen:
+			depth++
+		case token.RParen:
+			depth--
+			if depth == 0 {
+				// Next token must be Equals for this to be a func def.
+				if i+1 < len(tokens) && tokens[i+1].Type == token.Equals {
+					return true
+				}
+				return false
+			}
+		case token.EOF:
+			return false
+		}
+	}
+	return false
+}
+
+// parseFuncDef parses: Ident LParen param1, param2, ... RParen Equals body
+func parseFuncDef(tokens []token.Token) (*ast.FuncDef, error) {
+	p := &parser{tokens: tokens}
+
+	// Function name.
+	nameTok, err := p.expect(token.Ident)
+	if err != nil {
+		return nil, fmt.Errorf("expected function name: %w", err)
+	}
+	name := nameTok.Literal
+
+	// Opening paren.
+	if _, err := p.expect(token.LParen); err != nil {
+		return nil, fmt.Errorf("expected '(' after function name: %w", err)
+	}
+
+	// Parameters: comma-separated identifiers.
+	var params []string
+	if p.current().Type != token.RParen {
+		paramTok, err := p.expect(token.Ident)
+		if err != nil {
+			return nil, fmt.Errorf("expected parameter name: %w", err)
+		}
+		params = append(params, paramTok.Literal)
+
+		for p.current().Type == token.Comma {
+			p.advance() // consume comma
+			paramTok, err := p.expect(token.Ident)
+			if err != nil {
+				return nil, fmt.Errorf("expected parameter name after ',': %w", err)
+			}
+			params = append(params, paramTok.Literal)
+		}
+	}
+
+	// Closing paren.
+	if _, err := p.expect(token.RParen); err != nil {
+		return nil, fmt.Errorf("expected ')' after parameters: %w", err)
+	}
+
+	// Equals sign.
+	if _, err := p.expect(token.Equals); err != nil {
+		return nil, fmt.Errorf("expected '=' in function definition: %w", err)
+	}
+
+	// Body expression.
+	body, err := p.expr()
+	if err != nil {
+		return nil, fmt.Errorf("error in function body: %w", err)
+	}
+
+	// Ensure all tokens consumed.
+	if p.current().Type != token.EOF {
+		tok := p.current()
+		return nil, fmt.Errorf("unexpected token %v at position %d after function body", tok.Type, tok.Pos)
+	}
+
+	return &ast.FuncDef{
+		Name:   name,
+		Params: params,
+		Body:   body,
+	}, nil
+}
+
 // parser holds the state for a single parse operation.
 type parser struct {
 	tokens []token.Token
@@ -96,7 +215,7 @@
 	return left, nil
 }
 
-// factor → NUMBER | '(' expr ')'
+// factor → NUMBER | IDENT | IDENT '(' args ')' | '(' expr ')'
 func (p *parser) factor() (ast.Node, error) {
 	tok := p.current()
 	switch tok.Type {
@@ -108,6 +227,35 @@
 		}
 		return &ast.NumberLit{Value: val}, nil
 
+	case token.Ident:
+		p.advance()
+		// If followed by '(', this is a function call.
+		if p.current().Type == token.LParen {
+			p.advance() // consume '('
+			var args []ast.Node
+			if p.current().Type != token.RParen {
+				arg, err := p.expr()
+				if err != nil {
+					return nil, err
+				}
+				args = append(args, arg)
+				for p.current().Type == token.Comma {
+					p.advance() // consume ','
+					arg, err := p.expr()
+					if err != nil {
+						return nil, err
+					}
+					args = append(args, arg)
+				}
+			}
+			if _, err := p.expect(token.RParen); err != nil {
+				return nil, fmt.Errorf("expected ')' after function arguments at position %d", p.current().Pos)
+			}
+			return &ast.FuncCall{Name: tok.Literal, Args: args}, nil
+		}
+		// Otherwise, it's a variable reference.
+		return &ast.Ident{Name: tok.Literal}, nil
+
 	case token.LParen:
 		p.advance() // consume '('
 		node, err := p.expr()
diff --git a/parser/parser_test.go b/parser/parser_test.go
index 521455b..99b0e32 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -6,23 +6,14 @@
 	"testing"
 )
 
-// helper: tokenize inline for concise tests
-func tokens(toks ...token.Token) []token.Token {
-	return toks
-}
+// --- Parse (backward compatibility) ---
 
-func tok(typ token.Type, lit string, pos int) token.Token {
-	return token.Token{Type: typ, Literal: lit, Pos: pos}
-}
-
-// --- Success cases ---
-
-func TestParseSingleNumber(t *testing.T) {
-	toks := tokens(
-		tok(token.Number, "42", 0),
-		tok(token.EOF, "", 2),
-	)
-	node, err := Parse(toks)
+func TestParse_SingleNumber(t *testing.T) {
+	tokens := []token.Token{
+		{Type: token.Number, Literal: "42", Pos: 0},
+		{Type: token.EOF, Literal: "", Pos: 2},
+	}
+	node, err := Parse(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
@@ -31,443 +22,433 @@
 		t.Fatalf("expected *ast.NumberLit, got %T", node)
 	}
 	if num.Value != 42 {
-		t.Fatalf("expected 42, got %f", num.Value)
+		t.Fatalf("expected 42, got %v", num.Value)
 	}
 }
 
-func TestParseDecimalNumber(t *testing.T) {
-	toks := tokens(
-		tok(token.Number, "3.14", 0),
-		tok(token.EOF, "", 4),
-	)
-	node, err := Parse(toks)
+func TestParse_BinaryExpr(t *testing.T) {
+	tokens := []token.Token{
+		{Type: token.Number, Literal: "1", Pos: 0},
+		{Type: token.Plus, Literal: "+", Pos: 2},
+		{Type: token.Number, Literal: "2", Pos: 4},
+		{Type: token.EOF, Literal: "", Pos: 5},
+	}
+	node, err := Parse(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	num, ok := node.(*ast.NumberLit)
-	if !ok {
-		t.Fatalf("expected *ast.NumberLit, got %T", node)
-	}
-	if num.Value != 3.14 {
-		t.Fatalf("expected 3.14, got %f", num.Value)
-	}
-}
-
-func TestParseAddition(t *testing.T) {
-	// 1 + 2
-	toks := tokens(
-		tok(token.Number, "1", 0),
-		tok(token.Plus, "+", 2),
-		tok(token.Number, "2", 4),
-		tok(token.EOF, "", 5),
-	)
-	node, err := Parse(toks)
-	if err != nil {
-		t.Fatalf("unexpected error: %v", err)
-	}
-	expr, ok := node.(*ast.BinaryExpr)
+	bin, ok := node.(*ast.BinaryExpr)
 	if !ok {
 		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
 	}
-	if expr.Op != token.Plus {
-		t.Fatalf("expected Plus, got %v", expr.Op)
+	if bin.Op != token.Plus {
+		t.Fatalf("expected Plus, got %v", bin.Op)
 	}
-	assertNumber(t, expr.Left, 1)
-	assertNumber(t, expr.Right, 2)
 }
 
-func TestParseSubtraction(t *testing.T) {
-	// 5 - 3
-	toks := tokens(
-		tok(token.Number, "5", 0),
-		tok(token.Minus, "-", 2),
-		tok(token.Number, "3", 4),
-		tok(token.EOF, "", 5),
-	)
-	node, err := Parse(toks)
+// --- factor: Ident ---
+
+func TestParse_Ident(t *testing.T) {
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "x", Pos: 0},
+		{Type: token.EOF, Literal: "", Pos: 1},
+	}
+	node, err := Parse(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	expr, ok := node.(*ast.BinaryExpr)
+	ident, ok := node.(*ast.Ident)
 	if !ok {
-		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+		t.Fatalf("expected *ast.Ident, got %T", node)
 	}
-	if expr.Op != token.Minus {
-		t.Fatalf("expected Minus, got %v", expr.Op)
+	if ident.Name != "x" {
+		t.Fatalf("expected 'x', got %q", ident.Name)
 	}
-	assertNumber(t, expr.Left, 5)
-	assertNumber(t, expr.Right, 3)
 }
 
-func TestParseMultiplication(t *testing.T) {
-	// 2 * 3
-	toks := tokens(
-		tok(token.Number, "2", 0),
-		tok(token.Star, "*", 2),
-		tok(token.Number, "3", 4),
-		tok(token.EOF, "", 5),
-	)
-	node, err := Parse(toks)
+func TestParse_IdentInExpr(t *testing.T) {
+	// x + 1
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "x", Pos: 0},
+		{Type: token.Plus, Literal: "+", Pos: 2},
+		{Type: token.Number, Literal: "1", Pos: 4},
+		{Type: token.EOF, Literal: "", Pos: 5},
+	}
+	node, err := Parse(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	expr, ok := node.(*ast.BinaryExpr)
+	bin, ok := node.(*ast.BinaryExpr)
 	if !ok {
 		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
 	}
-	if expr.Op != token.Star {
-		t.Fatalf("expected Star, got %v", expr.Op)
+	left, ok := bin.Left.(*ast.Ident)
+	if !ok {
+		t.Fatalf("expected left to be *ast.Ident, got %T", bin.Left)
 	}
-	assertNumber(t, expr.Left, 2)
-	assertNumber(t, expr.Right, 3)
+	if left.Name != "x" {
+		t.Fatalf("expected 'x', got %q", left.Name)
+	}
 }
 
-func TestParseDivision(t *testing.T) {
-	// 6 / 2
-	toks := tokens(
-		tok(token.Number, "6", 0),
-		tok(token.Slash, "/", 2),
-		tok(token.Number, "2", 4),
-		tok(token.EOF, "", 5),
-	)
-	node, err := Parse(toks)
+// --- factor: FuncCall ---
+
+func TestParse_FuncCallNoArgs(t *testing.T) {
+	// f()
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.RParen, Literal: ")", Pos: 2},
+		{Type: token.EOF, Literal: "", Pos: 3},
+	}
+	node, err := Parse(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	expr, ok := node.(*ast.BinaryExpr)
+	fc, ok := node.(*ast.FuncCall)
 	if !ok {
-		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+		t.Fatalf("expected *ast.FuncCall, got %T", node)
 	}
-	if expr.Op != token.Slash {
-		t.Fatalf("expected Slash, got %v", expr.Op)
+	if fc.Name != "f" {
+		t.Fatalf("expected 'f', got %q", fc.Name)
 	}
-	assertNumber(t, expr.Left, 6)
-	assertNumber(t, expr.Right, 2)
+	if len(fc.Args) != 0 {
+		t.Fatalf("expected 0 args, got %d", len(fc.Args))
+	}
 }
 
-func TestParsePrecedence(t *testing.T) {
-	// 1 + 2 * 3  →  1 + (2 * 3)
-	toks := tokens(
-		tok(token.Number, "1", 0),
-		tok(token.Plus, "+", 2),
-		tok(token.Number, "2", 4),
-		tok(token.Star, "*", 6),
-		tok(token.Number, "3", 8),
-		tok(token.EOF, "", 9),
-	)
-	node, err := Parse(toks)
+func TestParse_FuncCallOneArg(t *testing.T) {
+	// f(42)
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.Number, Literal: "42", Pos: 2},
+		{Type: token.RParen, Literal: ")", Pos: 4},
+		{Type: token.EOF, Literal: "", Pos: 5},
+	}
+	node, err := Parse(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	// Root should be Plus
-	expr, ok := node.(*ast.BinaryExpr)
+	fc, ok := node.(*ast.FuncCall)
 	if !ok {
-		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+		t.Fatalf("expected *ast.FuncCall, got %T", node)
 	}
-	if expr.Op != token.Plus {
-		t.Fatalf("expected Plus at root, got %v", expr.Op)
+	if fc.Name != "f" {
+		t.Fatalf("expected 'f', got %q", fc.Name)
 	}
-	assertNumber(t, expr.Left, 1)
-	// Right should be Star
-	right, ok := expr.Right.(*ast.BinaryExpr)
+	if len(fc.Args) != 1 {
+		t.Fatalf("expected 1 arg, got %d", len(fc.Args))
+	}
+	arg, ok := fc.Args[0].(*ast.NumberLit)
 	if !ok {
-		t.Fatalf("expected right to be *ast.BinaryExpr, got %T", expr.Right)
+		t.Fatalf("expected arg to be *ast.NumberLit, got %T", fc.Args[0])
 	}
-	if right.Op != token.Star {
-		t.Fatalf("expected Star, got %v", right.Op)
+	if arg.Value != 42 {
+		t.Fatalf("expected 42, got %v", arg.Value)
 	}
-	assertNumber(t, right.Left, 2)
-	assertNumber(t, right.Right, 3)
 }
 
-func TestParsePrecedenceMulFirst(t *testing.T) {
-	// 2 * 3 + 1  →  (2 * 3) + 1
-	toks := tokens(
-		tok(token.Number, "2", 0),
-		tok(token.Star, "*", 2),
-		tok(token.Number, "3", 4),
-		tok(token.Plus, "+", 6),
-		tok(token.Number, "1", 8),
-		tok(token.EOF, "", 9),
-	)
-	node, err := Parse(toks)
+func TestParse_FuncCallMultiArgs(t *testing.T) {
+	// f(1, 2, 3)
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.Number, Literal: "1", Pos: 2},
+		{Type: token.Comma, Literal: ",", Pos: 3},
+		{Type: token.Number, Literal: "2", Pos: 5},
+		{Type: token.Comma, Literal: ",", Pos: 6},
+		{Type: token.Number, Literal: "3", Pos: 8},
+		{Type: token.RParen, Literal: ")", Pos: 9},
+		{Type: token.EOF, Literal: "", Pos: 10},
+	}
+	node, err := Parse(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	expr, ok := node.(*ast.BinaryExpr)
+	fc, ok := node.(*ast.FuncCall)
 	if !ok {
-		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+		t.Fatalf("expected *ast.FuncCall, got %T", node)
 	}
-	if expr.Op != token.Plus {
-		t.Fatalf("expected Plus at root, got %v", expr.Op)
+	if len(fc.Args) != 3 {
+		t.Fatalf("expected 3 args, got %d", len(fc.Args))
 	}
-	left, ok := expr.Left.(*ast.BinaryExpr)
-	if !ok {
-		t.Fatalf("expected left to be *ast.BinaryExpr, got %T", expr.Left)
-	}
-	if left.Op != token.Star {
-		t.Fatalf("expected Star, got %v", left.Op)
-	}
-	assertNumber(t, left.Left, 2)
-	assertNumber(t, left.Right, 3)
-	assertNumber(t, expr.Right, 1)
 }
 
-func TestParseLeftAssociativity(t *testing.T) {
-	// 1 - 2 - 3  →  (1 - 2) - 3
-	toks := tokens(
-		tok(token.Number, "1", 0),
-		tok(token.Minus, "-", 2),
-		tok(token.Number, "2", 4),
-		tok(token.Minus, "-", 6),
-		tok(token.Number, "3", 8),
-		tok(token.EOF, "", 9),
-	)
-	node, err := Parse(toks)
+func TestParse_FuncCallExprArgs(t *testing.T) {
+	// f(1+2, 3*4)
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.Number, Literal: "1", Pos: 2},
+		{Type: token.Plus, Literal: "+", Pos: 3},
+		{Type: token.Number, Literal: "2", Pos: 4},
+		{Type: token.Comma, Literal: ",", Pos: 5},
+		{Type: token.Number, Literal: "3", Pos: 7},
+		{Type: token.Star, Literal: "*", Pos: 8},
+		{Type: token.Number, Literal: "4", Pos: 9},
+		{Type: token.RParen, Literal: ")", Pos: 10},
+		{Type: token.EOF, Literal: "", Pos: 11},
+	}
+	node, err := Parse(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	// Root: (1 - 2) - 3
-	expr, ok := node.(*ast.BinaryExpr)
+	fc, ok := node.(*ast.FuncCall)
 	if !ok {
-		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+		t.Fatalf("expected *ast.FuncCall, got %T", node)
 	}
-	if expr.Op != token.Minus {
-		t.Fatalf("expected Minus at root, got %v", expr.Op)
+	if len(fc.Args) != 2 {
+		t.Fatalf("expected 2 args, got %d", len(fc.Args))
 	}
-	assertNumber(t, expr.Right, 3)
-	left, ok := expr.Left.(*ast.BinaryExpr)
+	// First arg: 1+2
+	_, ok = fc.Args[0].(*ast.BinaryExpr)
 	if !ok {
-		t.Fatalf("expected left to be *ast.BinaryExpr, got %T", expr.Left)
+		t.Fatalf("expected first arg to be *ast.BinaryExpr, got %T", fc.Args[0])
 	}
-	if left.Op != token.Minus {
-		t.Fatalf("expected Minus, got %v", left.Op)
-	}
-	assertNumber(t, left.Left, 1)
-	assertNumber(t, left.Right, 2)
 }
 
-func TestParseParentheses(t *testing.T) {
-	// (1 + 2) * 3
-	toks := tokens(
-		tok(token.LParen, "(", 0),
-		tok(token.Number, "1", 1),
-		tok(token.Plus, "+", 3),
-		tok(token.Number, "2", 5),
-		tok(token.RParen, ")", 6),
-		tok(token.Star, "*", 8),
-		tok(token.Number, "3", 10),
-		tok(token.EOF, "", 11),
-	)
-	node, err := Parse(toks)
+func TestParse_FuncCallInExpr(t *testing.T) {
+	// f(1) + 2
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.Number, Literal: "1", Pos: 2},
+		{Type: token.RParen, Literal: ")", Pos: 3},
+		{Type: token.Plus, Literal: "+", Pos: 5},
+		{Type: token.Number, Literal: "2", Pos: 7},
+		{Type: token.EOF, Literal: "", Pos: 8},
+	}
+	node, err := Parse(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	expr, ok := node.(*ast.BinaryExpr)
+	bin, ok := node.(*ast.BinaryExpr)
 	if !ok {
 		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
 	}
-	if expr.Op != token.Star {
-		t.Fatalf("expected Star at root, got %v", expr.Op)
-	}
-	assertNumber(t, expr.Right, 3)
-	left, ok := expr.Left.(*ast.BinaryExpr)
+	_, ok = bin.Left.(*ast.FuncCall)
 	if !ok {
-		t.Fatalf("expected left to be *ast.BinaryExpr, got %T", expr.Left)
+		t.Fatalf("expected left to be *ast.FuncCall, got %T", bin.Left)
 	}
-	if left.Op != token.Plus {
-		t.Fatalf("expected Plus, got %v", left.Op)
-	}
-	assertNumber(t, left.Left, 1)
-	assertNumber(t, left.Right, 2)
 }
 
-func TestParseNestedParentheses(t *testing.T) {
-	// ((1 + 2))
-	toks := tokens(
-		tok(token.LParen, "(", 0),
-		tok(token.LParen, "(", 1),
-		tok(token.Number, "1", 2),
-		tok(token.Plus, "+", 4),
-		tok(token.Number, "2", 6),
-		tok(token.RParen, ")", 7),
-		tok(token.RParen, ")", 8),
-		tok(token.EOF, "", 9),
-	)
-	node, err := Parse(toks)
+func TestParse_FuncCallMissingRParen(t *testing.T) {
+	// f(1
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.Number, Literal: "1", Pos: 2},
+		{Type: token.EOF, Literal: "", Pos: 3},
+	}
+	_, err := Parse(tokens)
+	if err == nil {
+		t.Fatal("expected error for missing closing paren in func call")
+	}
+}
+
+// --- ParseLine: expression statement ---
+
+func TestParseLine_ExprStmt(t *testing.T) {
+	// "1 + 2"
+	tokens := []token.Token{
+		{Type: token.Number, Literal: "1", Pos: 0},
+		{Type: token.Plus, Literal: "+", Pos: 2},
+		{Type: token.Number, Literal: "2", Pos: 4},
+		{Type: token.EOF, Literal: "", Pos: 5},
+	}
+	stmt, err := ParseLine(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	expr, ok := node.(*ast.BinaryExpr)
+	es, ok := stmt.(*ast.ExprStmt)
 	if !ok {
-		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+		t.Fatalf("expected *ast.ExprStmt, got %T", stmt)
 	}
-	if expr.Op != token.Plus {
-		t.Fatalf("expected Plus, got %v", expr.Op)
+	_, ok = es.Expr.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected expr to be *ast.BinaryExpr, got %T", es.Expr)
 	}
-	assertNumber(t, expr.Left, 1)
-	assertNumber(t, expr.Right, 2)
 }
 
-func TestParseComplexExpression(t *testing.T) {
-	// 1 + 2 * 3 - 4 / 2  →  (1 + (2*3)) - (4/2)
-	toks := tokens(
-		tok(token.Number, "1", 0),
-		tok(token.Plus, "+", 2),
-		tok(token.Number, "2", 4),
-		tok(token.Star, "*", 5),
-		tok(token.Number, "3", 6),
-		tok(token.Minus, "-", 8),
-		tok(token.Number, "4", 10),
-		tok(token.Slash, "/", 11),
-		tok(token.Number, "2", 12),
-		tok(token.EOF, "", 13),
-	)
-	node, err := Parse(toks)
+func TestParseLine_ExprStmtFuncCall(t *testing.T) {
+	// "f(1)"
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.Number, Literal: "1", Pos: 2},
+		{Type: token.RParen, Literal: ")", Pos: 3},
+		{Type: token.EOF, Literal: "", Pos: 4},
+	}
+	stmt, err := ParseLine(tokens)
 	if err != nil {
 		t.Fatalf("unexpected error: %v", err)
 	}
-	// Root: (1 + (2*3)) - (4/2)
-	root, ok := node.(*ast.BinaryExpr)
+	es, ok := stmt.(*ast.ExprStmt)
 	if !ok {
-		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+		t.Fatalf("expected *ast.ExprStmt, got %T", stmt)
 	}
-	if root.Op != token.Minus {
-		t.Fatalf("expected Minus at root, got %v", root.Op)
-	}
-	// Left: 1 + (2*3)
-	left, ok := root.Left.(*ast.BinaryExpr)
+	_, ok = es.Expr.(*ast.FuncCall)
 	if !ok {
-		t.Fatalf("expected left to be *ast.BinaryExpr, got %T", root.Left)
+		t.Fatalf("expected expr to be *ast.FuncCall, got %T", es.Expr)
 	}
-	if left.Op != token.Plus {
-		t.Fatalf("expected Plus, got %v", left.Op)
-	}
-	assertNumber(t, left.Left, 1)
-	mul, ok := left.Right.(*ast.BinaryExpr)
-	if !ok {
-		t.Fatalf("expected *ast.BinaryExpr, got %T", left.Right)
-	}
-	if mul.Op != token.Star {
-		t.Fatalf("expected Star, got %v", mul.Op)
-	}
-	assertNumber(t, mul.Left, 2)
-	assertNumber(t, mul.Right, 3)
-	// Right: 4/2
-	div, ok := root.Right.(*ast.BinaryExpr)
-	if !ok {
-		t.Fatalf("expected right to be *ast.BinaryExpr, got %T", root.Right)
-	}
-	if div.Op != token.Slash {
-		t.Fatalf("expected Slash, got %v", div.Op)
-	}
-	assertNumber(t, div.Left, 4)
-	assertNumber(t, div.Right, 2)
 }
 
-// --- Error cases ---
+// --- ParseLine: function definition ---
 
-func TestParseEmptyInput(t *testing.T) {
-	toks := tokens(
-		tok(token.EOF, "", 0),
-	)
-	_, err := Parse(toks)
+func TestParseLine_FuncDefSingleParam(t *testing.T) {
+	// "f(x) = x + 1"
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.Ident, Literal: "x", Pos: 2},
+		{Type: token.RParen, Literal: ")", Pos: 3},
+		{Type: token.Equals, Literal: "=", Pos: 5},
+		{Type: token.Ident, Literal: "x", Pos: 7},
+		{Type: token.Plus, Literal: "+", Pos: 9},
+		{Type: token.Number, Literal: "1", Pos: 11},
+		{Type: token.EOF, Literal: "", Pos: 12},
+	}
+	stmt, err := ParseLine(tokens)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	fd, ok := stmt.(*ast.FuncDef)
+	if !ok {
+		t.Fatalf("expected *ast.FuncDef, got %T", stmt)
+	}
+	if fd.Name != "f" {
+		t.Fatalf("expected name 'f', got %q", fd.Name)
+	}
+	if len(fd.Params) != 1 || fd.Params[0] != "x" {
+		t.Fatalf("expected params [x], got %v", fd.Params)
+	}
+	// Body should be x + 1
+	bin, ok := fd.Body.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected body to be *ast.BinaryExpr, got %T", fd.Body)
+	}
+	if bin.Op != token.Plus {
+		t.Fatalf("expected Plus in body, got %v", bin.Op)
+	}
+}
+
+func TestParseLine_FuncDefMultiParam(t *testing.T) {
+	// "add(x, y) = x + y"
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "add", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 3},
+		{Type: token.Ident, Literal: "x", Pos: 4},
+		{Type: token.Comma, Literal: ",", Pos: 5},
+		{Type: token.Ident, Literal: "y", Pos: 7},
+		{Type: token.RParen, Literal: ")", Pos: 8},
+		{Type: token.Equals, Literal: "=", Pos: 10},
+		{Type: token.Ident, Literal: "x", Pos: 12},
+		{Type: token.Plus, Literal: "+", Pos: 14},
+		{Type: token.Ident, Literal: "y", Pos: 16},
+		{Type: token.EOF, Literal: "", Pos: 17},
+	}
+	stmt, err := ParseLine(tokens)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	fd, ok := stmt.(*ast.FuncDef)
+	if !ok {
+		t.Fatalf("expected *ast.FuncDef, got %T", stmt)
+	}
+	if fd.Name != "add" {
+		t.Fatalf("expected name 'add', got %q", fd.Name)
+	}
+	if len(fd.Params) != 2 || fd.Params[0] != "x" || fd.Params[1] != "y" {
+		t.Fatalf("expected params [x y], got %v", fd.Params)
+	}
+}
+
+func TestParseLine_FuncDefNoParams(t *testing.T) {
+	// "c() = 42"
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "c", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.RParen, Literal: ")", Pos: 2},
+		{Type: token.Equals, Literal: "=", Pos: 4},
+		{Type: token.Number, Literal: "42", Pos: 6},
+		{Type: token.EOF, Literal: "", Pos: 8},
+	}
+	stmt, err := ParseLine(tokens)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	fd, ok := stmt.(*ast.FuncDef)
+	if !ok {
+		t.Fatalf("expected *ast.FuncDef, got %T", stmt)
+	}
+	if fd.Name != "c" {
+		t.Fatalf("expected name 'c', got %q", fd.Name)
+	}
+	if len(fd.Params) != 0 {
+		t.Fatalf("expected 0 params, got %d", len(fd.Params))
+	}
+}
+
+// --- ParseLine: error cases ---
+
+func TestParseLine_Empty(t *testing.T) {
+	tokens := []token.Token{
+		{Type: token.EOF, Literal: "", Pos: 0},
+	}
+	_, err := ParseLine(tokens)
 	if err == nil {
 		t.Fatal("expected error for empty input")
 	}
 }
 
-func TestParseMissingRParen(t *testing.T) {
-	// (1 + 2
-	toks := tokens(
-		tok(token.LParen, "(", 0),
-		tok(token.Number, "1", 1),
-		tok(token.Plus, "+", 3),
-		tok(token.Number, "2", 5),
-		tok(token.EOF, "", 6),
-	)
-	_, err := Parse(toks)
+func TestParseLine_FuncDefMissingBody(t *testing.T) {
+	// "f(x) ="
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.Ident, Literal: "x", Pos: 2},
+		{Type: token.RParen, Literal: ")", Pos: 3},
+		{Type: token.Equals, Literal: "=", Pos: 5},
+		{Type: token.EOF, Literal: "", Pos: 6},
+	}
+	_, err := ParseLine(tokens)
 	if err == nil {
-		t.Fatal("expected error for missing right paren")
+		t.Fatal("expected error for missing function body")
 	}
 }
 
-func TestParseUnexpectedRParen(t *testing.T) {
-	// ) 1
-	toks := tokens(
-		tok(token.RParen, ")", 0),
-		tok(token.Number, "1", 2),
-		tok(token.EOF, "", 3),
-	)
-	_, err := Parse(toks)
+func TestParseLine_FuncDefBadParams(t *testing.T) {
+	// "f(1) = 2" — params must be identifiers
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.Number, Literal: "1", Pos: 2},
+		{Type: token.RParen, Literal: ")", Pos: 3},
+		{Type: token.Equals, Literal: "=", Pos: 5},
+		{Type: token.Number, Literal: "2", Pos: 7},
+		{Type: token.EOF, Literal: "", Pos: 8},
+	}
+	_, err := ParseLine(tokens)
 	if err == nil {
-		t.Fatal("expected error for unexpected right paren")
+		t.Fatal("expected error for numeric parameter in func def")
 	}
 }
 
-func TestParseTrailingOperator(t *testing.T) {
-	// 1 +
-	toks := tokens(
-		tok(token.Number, "1", 0),
-		tok(token.Plus, "+", 2),
-		tok(token.EOF, "", 3),
-	)
-	_, err := Parse(toks)
+func TestParseLine_FuncDefTrailingTokens(t *testing.T) {
+	// "f(x) = x 1" — extra token after body
+	tokens := []token.Token{
+		{Type: token.Ident, Literal: "f", Pos: 0},
+		{Type: token.LParen, Literal: "(", Pos: 1},
+		{Type: token.Ident, Literal: "x", Pos: 2},
+		{Type: token.RParen, Literal: ")", Pos: 3},
+		{Type: token.Equals, Literal: "=", Pos: 5},
+		{Type: token.Ident, Literal: "x", Pos: 7},
+		{Type: token.Number, Literal: "1", Pos: 9},
+		{Type: token.EOF, Literal: "", Pos: 10},
+	}
+	_, err := ParseLine(tokens)
 	if err == nil {
-		t.Fatal("expected error for trailing operator")
-	}
-}
-
-func TestParseTrailingTokens(t *testing.T) {
-	// 1 2
-	toks := tokens(
-		tok(token.Number, "1", 0),
-		tok(token.Number, "2", 2),
-		tok(token.EOF, "", 3),
-	)
-	_, err := Parse(toks)
-	if err == nil {
-		t.Fatal("expected error for trailing tokens")
-	}
-}
-
-func TestParseConsecutiveOperators(t *testing.T) {
-	// 1 + * 2
-	toks := tokens(
-		tok(token.Number, "1", 0),
-		tok(token.Plus, "+", 2),
-		tok(token.Star, "*", 4),
-		tok(token.Number, "2", 6),
-		tok(token.EOF, "", 7),
-	)
-	_, err := Parse(toks)
-	if err == nil {
-		t.Fatal("expected error for consecutive operators")
-	}
-}
-
-func TestParseEmptyParens(t *testing.T) {
-	// ()
-	toks := tokens(
-		tok(token.LParen, "(", 0),
-		tok(token.RParen, ")", 1),
-		tok(token.EOF, "", 2),
-	)
-	_, err := Parse(toks)
-	if err == nil {
-		t.Fatal("expected error for empty parentheses")
-	}
-}
-
-// --- Helper ---
-
-func assertNumber(t *testing.T, node ast.Node, expected float64) {
-	t.Helper()
-	num, ok := node.(*ast.NumberLit)
-	if !ok {
-		t.Fatalf("expected *ast.NumberLit, got %T", node)
-	}
-	if num.Value != expected {
-		t.Fatalf("expected %f, got %f", expected, num.Value)
+		t.Fatal("expected error for trailing tokens after function body")
 	}
 }
