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