expr.scm 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. ; -*- mode: scheme; coding: utf-8 -*-
  2. ; (c) Daniel Llorens - 2019
  3. ; This library is free software; you can redistribute it and/or modify it under
  4. ; the terms of the GNU General Public License as published by the Free
  5. ; Software Foundation; either version 3 of the License, or (at your option) any
  6. ; later version.
  7. ;;; Commentary:
  8. ;; Laziness and composition for newra, WIP.
  9. ;;; Code:
  10. ;; (define-module (newra expr))
  11. (import (newra) (only (srfi :1) fold every) (srfi :71) (srfi :26) (ice-9 match))
  12. ; ----------------
  13. ; 1.a verbs w/o return values
  14. ; ----------------
  15. ; fields are: [0:apply 1:op 2:[ranks ...] 3:[op [ranks ...]] ...]
  16. (define <verb-vtable>
  17. (make-struct/no-tail
  18. <applicable-struct-vtable>
  19. (make-struct-layout (string-append "pwpwpwpw"))))
  20. (define-inlinable (verb? o)
  21. (and (struct? o) (eq? <verb-vtable> (struct-vtable o))))
  22. (define (verb-or-proc? o)
  23. (or (verb? o) (procedure? o)))
  24. (define-syntax %%struct-ref (syntax-rules () ((_ a n) (struct-ref a n))))
  25. (define-inlinable (%%verb-op a) (%%struct-ref a 1))
  26. (define-inlinable (%%verb-ranks a) (%%struct-ref a 2))
  27. (define-inlinable (%%verb-implementation-op-ranks a) (%%struct-ref a 3))
  28. (define-syntax %verbstruct-ref (syntax-rules () ((_ a n) (begin (unless (verb? a) (throw 'not-a-verb a)) (struct-ref a n)))))
  29. (define-inlinable (%verb-op v) (%verbstruct-ref v 1))
  30. (define-inlinable (%verb-ranks v) (%verbstruct-ref v 2))
  31. (define-inlinable (%verb-implementation-op-ranks v) (%verbstruct-ref v 3))
  32. (define (verb-print v port)
  33. (format #t "<verb op: ~a ranks: ~a alt: ~a>" (%verb-op v) (%verb-ranks v) (%verb-implementation-op-ranks v)))
  34. (struct-set! <verb-vtable> vtable-index-printer verb-print)
  35. (define* (ranks? ranks)
  36. (every (lambda (k) (or (integer? k) (eq? '∞ k) (eq? 'infty k))) ranks))
  37. (define* (ranks-final? ranks)
  38. (every (lambda (k) (and (integer? k) (>= k 0))) ranks))
  39. (define (make-verb op . ranks)
  40. (unless (ranks? ranks) (throw 'bad-ranks ranks))
  41. (unless (verb-or-proc? op) (throw 'bad-op op))
  42. (make-struct/no-tail
  43. <verb-vtable>
  44. (lambda i (throw 'you-tried-to-call op ranks i))
  45. op ranks '()))
  46. (define (make-verb-alternates op-ranks0 . op-ranks)
  47. (match (cons op-ranks0 op-ranks)
  48. (((op0 ranks0) (op ranks) ...)
  49. ; alternates doesn't accept argument-dependent rank.
  50. (unless (verb-or-proc? op0) (throw 'bad-op op0))
  51. (unless (ranks-final? ranks0) (throw 'bad-ranks-final ranks0))
  52. (let check ((ranks0 ranks0) (ranks ranks) (op op))
  53. (unless (null? ranks)
  54. (unless (verb-or-proc? (car op))
  55. (throw 'bad-alternate-op (car op)))
  56. ; TODO maybe it's better to select an alternates differently. Like we may have 0 0, then 0 1, then 1 0. So there is no order. So we could pick an alternate by the smallest Σ (verb rank - arg rank) for example.
  57. (unless (and (= (length ranks0) (length (car ranks)))
  58. (every <= ranks0 (car ranks)))
  59. (throw 'bad-alternate-ranks (car ranks)))
  60. (check (car ranks) (cdr ranks) (cdr op))))
  61. ; TODO maybe we want to store the alternates differently? probably want to match them last to first.
  62. (make-struct/no-tail
  63. <verb-vtable>
  64. (lambda i (throw 'you-tried-to-call-alternates op0 ranks0 i))
  65. op0 ranks0 op-ranks))))
  66. (define w/rank )
  67. (define +ᵤ (make-verb (lambda (a b c) (ra-set! c (+ (ra-ref a) (ra-ref b)))) 0 0 0))
  68. (define +ᵘ (make-verb-alternates (list (lambda (a b c) (ra-set! c (+ (ra-ref a) (ra-ref b)))) (list 0 0 0))))
  69. ; ----------------
  70. ; 1.b application (rank extension) of verbs w/o return values.
  71. ; ----------------
  72. ; we'll do this using ra-transpose and dead axes - it's more obvious than the adhoc mechanism in guile-ploy.
  73. ; (verb-with-ranks A ...) -> (ra-slice-for-each naked-op (transpose-appropriately A) ...)
  74. ; ----------------
  75. ; 2.c composition of verbs w/o return values.
  76. ; ----------------
  77. ; ----------------
  78. ; 2.a return values.
  79. ; ----------------
  80. ; ----------------
  81. ; 2.b application with return values
  82. ; ----------------
  83. ; ----------------
  84. ; 2.c composition with return values
  85. ; ----------------