{"body":"#lang rhombus\n\n;; =========================================================\n;; AST DEFINITIONS\n;; =========================================================\n\nstruct invoice(id, date, client, items, tax)\nstruct item(desc, hours, rate)\n\n;; =========================================================\n;; DSL SYNTAX CLASSES\n;; =========================================================\n\nsyntax_class invoice_item:\n  pattern [item desc hours h rate r]:\n    #'(item desc h r)\n\nsyntax_class invoice_clause:\n  pattern ~or:\n    [date d]\n    [client c]\n    invoice_item\n    [tax t]\n\n;; =========================================================\n;; MAIN INVOICE DSL FORM\n;; =========================================================\n\nsyntax_class invoice_block:\n  pattern [invoice id clause ...]:\n    #'(build-invoice id (list clause ...))\n\n;; =========================================================\n;; EXPANDER / EVALUATOR\n;; =========================================================\n\n(define (parse-tax t)\n  ;; converts 8% -> 0.08\n  (define s (symbol->string t))\n  (define num (string->number (regexp-replace #px\"%\" s \"\")))\n  (/ num 100.0))\n\n(define (build-invoice id clauses)\n  (define date #f)\n  (define client #f)\n  (define items '())\n  (define tax 0.0)\n\n  (for ([c clauses])\n    (match c\n      [(list 'date d)\n       (set! date d)]\n\n      [(list 'client c)\n       (set! client c)]\n\n      [(item desc h r)\n       (set! items (cons (item desc h r) items))]\n\n      [(list 'tax t)\n       (set! tax (parse-tax t))]))\n\n  (invoice id date client (reverse items) tax))\n\n;; =========================================================\n;; BUSINESS LOGIC\n;; =========================================================\n\n(define (subtotal inv)\n  (for/sum ([i (invoice-items inv)])\n    (* (item-hours i)\n       (item-rate i))))\n\n(define (total inv)\n  (define sub (subtotal inv))\n  (+ sub (* sub (invoice-tax inv))))\n\n;; =========================================================\n;; DSL EXAMPLE\n;; =========================================================\n\ninvoice INV-001:\n  date 2026-04-29\n  client \"Acme Corp\"\n\n  item \"Website redesign\" hours 10 rate 150\n  item \"Hosting setup\" hours 2 rate 100\n\n  tax 8%\n\n;; =========================================================\n;; OPTIONAL TEST EVALUATION\n;; =========================================================\n\n;; If your Rhombus environment supports evaluating last form:\n;; you can bind and compute like this:\n\n(define example-invoice\n  (build-invoice 'INV-001\n    (list\n      '(date \"2026-04-29\")\n      '(client \"Acme Corp\")\n      (item \"Website redesign\" 10 150)\n      (item \"Hosting setup\" 2 100)\n      '(tax 8%))))\n\n(define example-total (total example-invoice))\n\nexample-invoice\nexample-total","name":"","extension":"txt","url":"https://www.irccloud.com/pastebin/QmJXAyuB","modified":1782465510,"id":"QmJXAyuB","size":2718,"lines":110,"own_paste":false,"theme":"","date":1782465510}