implement basic input space position type

codegen template now takes a start and an end parameter
This commit is contained in:
xenia 2020-11-06 00:05:58 -05:00
parent 37a0c76455
commit 16ca6ebe7b
2 changed files with 64 additions and 34 deletions

View File

@ -34,12 +34,15 @@ typedef struct {
int main() { int main() {
char buf [ @(* 20 (vector-length pattern)) ]; char buf [ @(* 20 (vector-length pattern)) ];
@(for/list ([num (in-naturals)] [cset (in-vector pattern)]) @(for/list ([num (in-naturals)] [iset-pos (in-vector pp-start)])
@list{size_t @(format "i~a" num) ; @list{size_t @(format "i~a" num) = @(car iset-pos) ;
vartype @(format "v~a" num) ; vartype @(format "v~a" num) = @(cdr iset-pos) ;
}) })
@(for/list ([num (in-naturals)] [cset (in-vector pattern)])
goto l_inner;
@(for/list ([num (in-naturals)] [iset (in-vector pattern)])
(define iter (format "i~a" num)) (define iter (format "i~a" num))
(define viter (format "v~a" num)) (define viter (format "v~a" num))
(define iset (format "iset~a" num)) (define iset (format "iset~a" num))
@ -55,10 +58,22 @@ int main() {
(string-join (for/list ([i (in-range (vector-length pattern))]) c-type-fmt) " ")) (string-join (for/list ([i (in-range (vector-length pattern))]) c-type-fmt) " "))
l_inner: l_inner:
@(define (end-conditionals)
(add-between
(for/list ([num (in-naturals)] [iset-pos (in-vector pp-end)])
(define iter (format "i~a" num))
(define viter (format "v~a" num))
@list{ @iter >= @(car iset-pos) && @viter >= @(cdr iset-pos) })
" && "))
if ( @end-conditionals[] ) {
goto l_end;
}
ssize_t res = snprintf(buf, sizeof(buf), @(format "\"~a\\n\"" fmt), @vs ); ssize_t res = snprintf(buf, sizeof(buf), @(format "\"~a\\n\"" fmt), @vs );
fwrite(buf, res, 1, stdout); fwrite(buf, res, 1, stdout);
@(for/list ([cset (in-vector pattern)]) "}}") @(for/list ([iset (in-vector pattern)]) "}}")
l_end: l_end:
return 0; return 0;
} }

View File

@ -37,6 +37,9 @@
;; manifest.rkt processing ;; manifest.rkt processing
;; Iset is a listof Interval
;; Interval is a (cons start end) and represents [start, end)
(define (make-iset) '()) (define (make-iset) '())
(define (iset-add iset start end) (define (iset-add iset start end)
@ -71,18 +74,30 @@
(for/sum ([ival (in-list iset)]) (for/sum ([ival (in-list iset)])
(- (cdr ival) (car ival)))) (- (cdr ival) (car ival))))
;; IsetPos is a (cons inum ival)
;; inum - the interval number within the iset
;; ival - the actual input value
;; converts a position of [0, iset-count) to 2 values ;; converts a position of [0, iset-count) to 2 values
;; - iset interval number ;; - iset interval number
;; - actual value within the interval ;; - actual value within the interval
;; allows going up to iset-count to support upper exclusive bounds of intervals
(define (pos->iset-pos iset pos) (define (pos->iset-pos iset pos)
(when (empty? iset) (define (helper iset pos)
(error "iset-pos out of range")) (match-define (cons (cons fs fe) r) iset)
(match-define (cons (cons fs fe) r) iset) (define delta (- fe fs))
(define delta (- fe fs)) (if (< pos delta)
(if (< pos delta) (cons 0 (+ fs pos))
(values 0 (+ fs pos)) (match-let ([(cons inum val) (helper r (- pos delta))])
(let-values ([(inum val) (pos->iset-pos r (- pos delta))]) (cons (add1 inum) val))))
(values (add1 inum) val)))) (define cnt (iset-count iset))
(cond
[(> pos cnt) (error "iset-pos out of range" iset pos)]
[(= pos cnt)
;; support interval exclusive upper bound
(match-define (cons inum ival) (helper iset (sub1 pos)))
(cons inum (add1 ival))]
[else (helper iset pos)]))
(define (char->iset ch) (define (char->iset ch)
(define cp (char->integer ch)) (define cp (char->integer ch))
@ -145,31 +160,32 @@
;; pattern processing ;; pattern processing
;; a PatternPos is a vector of IsetPos
(define (pattern-count pattern) (define (pattern-count pattern)
(for/fold ([sum 1]) ([p (in-vector pattern)]) (for/fold ([sum 1]) ([p (in-vector pattern)])
(* sum (iset-count p)))) (* sum (iset-count p))))
;; design recipe violations follow (define (pattern-start pattern)
;; (sorry) (for/vector ([iset (in-vector pattern)])
;; (i wanted this to be fast so i try to avoid spamming the heap) (pos->iset-pos iset 0)))
; (define (pattern-generate pattern out-port)
; (define len (vector-length pattern)) (define (pattern-end pattern)
; (define gen (make-bytes len)) (for/vector ([iset (in-vector pattern)])
; (define (output gen) (pos->iset-pos iset (iset-count iset))))
; (write-bytes gen out-port)
; (printf "\n")) ;; there used to be a racket implementation of the input generator but it majorly violated the
; (define (permute i gen) ;; design recipe and got obsoleted by the template C version (which is intended to be more portable
; (cond [(= i len) (output gen)] ;; and faster)
; [else
; (for ([chr (in-set (vector-ref pattern i))])
; (bytes-set! gen i chr)
; (permute (add1 i) gen))]))
; (permute 0 gen))
;; ok gamer move time ;; ok gamer move time
(define-runtime-path codegen-template "codegen.template") (define-runtime-path codegen-template "codegen.template")
(define (pattern-codegen pattern) (define (pattern-codegen pattern pp-start pp-end)
(eval-template `(file ,(path->string codegen-template)) (hash 'pattern pattern))) (eval-template
`(file ,(path->string codegen-template))
(hash 'pattern pattern
'pp-start pp-start
'pp-end pp-end)))
(define-values [name mode command pattern] (define-values [name mode command pattern]
(parse-manifest (parse-manifest
@ -178,6 +194,5 @@
(command ("meme")) (command ("meme"))
(pattern "test?d?a?a?s")))) (pattern "test?d?a?a?s"))))
; (pattern-generate pattern (current-output-port)) (pattern-codegen pattern (pattern-start pattern) (pattern-end pattern))
; (displayln (pattern-count pattern)) (printf "// total: ~a\n" (pattern-count pattern))
(pattern-codegen pattern)