crossfire/crossfire/codegen.rktc

119 lines
3.3 KiB
Plaintext

@;; crossfire: distributed brute force infrastructure
@;;
@;; Copyright (C) 2020 haskal
@;;
@;; This program is free software: you can redistribute it and/or modify
@;; it under the terms of the GNU Affero General Public License as published by
@;; the Free Software Foundation, either version 3 of the License, or
@;; (at your option) any later version.
@;;
@;; This program is distributed in the hope that it will be useful,
@;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@;; GNU Affero General Public License for more details.
@;;
@;; You should have received a copy of the GNU Affero General Public License
@;; along with this program. If not, see <https://www.gnu.org/licenses/>.
@;; vim: ft=c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
@(define c-type "uint64_t")
@(define c-type-fmt "%lx")
typedef @c-type vartype;
typedef bool (*callback)( @(add-between (for/list ([_ (in-vector pattern)]) "vartype") ",") );
typedef struct {
vartype start;
vartype end;
} interval;
typedef struct {
size_t length;
interval values[];
} iset;
@(define (output-iset num iset)
(define name (format "iset~a" num))
(define len (length iset))
@list{iset @name = @"{" @len @"," @"{" @(add-between
(for/list ([ival (in-list iset)])
@list{@"{" @car[ival] @"," @cdr[ival] @"}"})
",") @"}}" ;
})
@(for/list ([i (in-naturals)] [iset (in-vector pattern)])
(output-iset i iset))
int crossfire_main(callback cb) {
char buf [ @(* 20 (vector-length pattern)) ];
@(for/list ([num (in-naturals)] [iset-pos (in-vector pp-start)])
@list{size_t @(format "i~a" num) = @(car iset-pos) ;
vartype @(format "v~a" num) = @(cdr iset-pos) ;
})
goto l_inner;
@(for/list ([num (in-naturals)] [iset (in-vector pattern)])
(define iter (format "i~a" num))
(define viter (format "v~a" num))
(define iset (format "iset~a" num))
@list{
for (@iter = 0; @iter < @iset @".length" ; @iter ++) @"{"
for (@viter = @iset .values[ @iter ].start; @viter < @iset .values[ @iter ].end; @viter ++) @"{"
})
@(define vs
(string-join (for/list ([i (in-range (vector-length pattern))]) (format "v~a" i)) ","))
@(define arg-vs
(string-join (for/list ([i (in-range (vector-length pattern))]) (format "vartype v~a" i)) ","))
@(define fmt
(string-join (for/list ([i (in-range (vector-length pattern))]) c-type-fmt) " "))
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;
}
@(match mode
['stdout
@list{ssize_t res = snprintf(buf, sizeof(buf), @(format "\"~a\\n\"" fmt), @vs );
fwrite(buf, res, 1, stdout);}]
['callback
@list{ if (cb( @vs )) { cf_report_success( @vs ); return 0; } }])
@(for/list ([iset (in-vector pattern)]) "}}")
l_end:
return 0;
}
@(if (equal? mode 'stdout)
@list{
int main() {
return crossfire_main(NULL);
}
}
@list{
void cf_report_success( @arg-vs ) {
// TODO
}
})