Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Smplang Laravel Package

leongrdic/smplang

SMPLang is a small PHP language/parser package for defining and evaluating simple expressions in your app. Useful for lightweight DSLs, rules, filters, or templating-like syntax, with an emphasis on minimal setup and easy integration into Laravel projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require leongrdic/smplang
    

    Requires PHP 8.0+.

  2. First Use Case: Evaluate a simple expression:

    use Leongrdic\Smplang\Smplang;
    
    $smplang = new Smplang();
    $result = $smplang->evaluate('2 + 3 * 4'); // Returns 14
    
  3. Where to Look First:

    • README for basic syntax.
    • Tests for edge cases and examples.
    • Smplang class docs (generated via PHPDoc if available).

Implementation Patterns

Core Workflows

  1. Expression Evaluation:

    $smplang = new Smplang();
    $result = $smplang->evaluate('(5 + 3) * 2'); // 16
    
    • Supports arithmetic (+, -, *, /, %), parentheses, and basic functions.
  2. Variable Binding:

    $smplang = new Smplang();
    $smplang->bind('x', 10);
    $result = $smplang->evaluate('x * 2'); // 20
    
  3. Object/Method Integration:

    class Calculator {
        public function add($a, $b) { return $a + $b; }
    }
    
    $smplang = new Smplang();
    $smplang->bind('calc', new Calculator());
    $result = $smplang->evaluate('calc.add(5, 3)'); // 8
    
  4. Dynamic Contexts:

    $smplang = new Smplang();
    $context = ['user' => ['name' => 'Alice']];
    $result = $smplang->evaluate('user.name', $context); // 'Alice'
    

Integration Tips

  • Laravel Blade Integration: Create a custom directive to embed smplang expressions:

    Blade::directive('eval', function ($expression) {
        return "<?php echo app(Leongrdic\Smplang\Smplang::class)->evaluate($expression); ?>";
    });
    

    Usage in Blade:

    @eval('2 + 3')
    
  • Form Validation: Dynamically validate inputs using smplang expressions:

    $validator = Validator::make($request->all(), [
        'age' => ['required', function ($attribute, $value, $fail) {
            $smplang = new Smplang();
            if (!$smplang->evaluate("{$value} >= 18")) {
                $fail('Must be 18+.');
            }
        }]
    ]);
    
  • API Response Filtering: Filter API responses dynamically:

    $response = collect($users)
        ->filter(function ($user) use ($smplang) {
            return $smplang->evaluate("{$user['role']} === 'admin'");
        });
    

Gotchas and Tips

Pitfalls

  1. No eval() Equivalent:

    • Gotcha: smplang is not a full PHP replacement. Avoid complex logic (loops, conditionals beyond basic arithmetic).
    • Workaround: Use PHP for control flow, smplang for expressions.
      // ❌ Avoid:
      $smplang->evaluate('if (x > 0) { return x; } else { return -x; }');
      
      // ✅ Do:
      $result = $smplang->evaluate('x') > 0 ? $smplang->evaluate('x') : -$smplang->evaluate('x');
      
  2. Object Property Access:

    • Gotcha: Fails silently if an object lacks __get and the property doesn’t exist (pre-1.0.1). Now throws Smplang\Exception.
    • Debug Tip: Wrap evaluations in a try-catch:
      try {
          $result = $smplang->evaluate('user.nonexistent');
      } catch (\Leongrdic\Smplang\Exception $e) {
          report($e); // Log or handle gracefully
      }
      
  3. Method Overloading:

    • Gotcha: __call magic methods are supported, but argument passing is strict (no variadic support).
    • Tip: Test with known object structures:
      $obj = new class {
          public function __call($name, $args) {
              return "Called {$name} with " . implode(', ', $args);
          }
      };
      $smplang->bind('obj', $obj);
      $smplang->evaluate('obj.unknown(1, 2)'); // "Called unknown with 1, 2"
      
  4. Performance:

    • Gotcha: Parsing complex expressions repeatedly can be slow. Cache compiled results if reused.
    • Tip: Use Smplang::compile() for one-time evaluations:
      $compiled = $smplang->compile('2 + 3');
      $result = $compiled(); // Faster than evaluate()
      

Debugging

  • Enable Verbose Errors: Set the debug flag in the constructor:

    $smplang = new Smplang(['debug' => true]);
    

    Throws detailed exceptions for syntax errors.

  • Log Expressions: Use Laravel’s logging to track evaluated expressions:

    $smplang->evaluate('user.score > 100', ['user' => ['score' => 150]]);
    \Log::debug('Evaluated: user.score > 100', ['result' => true]);
    

Extension Points

  1. Custom Functions: Register global functions via Smplang::registerFunction():

    $smplang->registerFunction('max', function ($a, $b) {
        return max($a, $b);
    });
    $smplang->evaluate('max(1, 5)'); // 5
    
  2. Context Overrides: Override default context behavior by extending Smplang:

    class CustomSmplang extends Smplang {
        protected function resolveVariable($name, $context) {
            if ($name === 'default_value') {
                return 'custom_default';
            }
            return parent::resolveVariable($name, $context);
        }
    }
    
  3. Syntax Extensions:

    • Limitation: No built-in way to add custom operators/syntax.
    • Workaround: Pre-process expressions in PHP:
      $expression = str_replace('^', '**', $rawInput); // Replace ^ with ** for exponentiation
      $result = $smplang->evaluate($expression);
      

Config Quirks

  • PHP 8.0+ Only:
    • Uses named arguments and other PHP 8 features. Downgrading will break.
  • No Persistent State:
    • The Smplang instance is stateless between evaluations. Rebind variables as needed:
      $smplang = new Smplang();
      $smplang->bind('x', 1); // Reset x for each evaluation
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views