From 0aef2810c879f03a379e66aab43e52ec9ec1f9bf Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 10 Sep 2021 19:27:42 +0200 Subject: [PATCH] Added fasta example. --- resources/examples/fasta.c3 | 105 ++++++++++++++++++++++++++++++++++++ src/compiler/llvm_codegen.c | 4 ++ src/compiler/sema_expr.c | 6 +-- 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 resources/examples/fasta.c3 diff --git a/resources/examples/fasta.c3 b/resources/examples/fasta.c3 new file mode 100644 index 000000000..7cc25de49 --- /dev/null +++ b/resources/examples/fasta.c3 @@ -0,0 +1,105 @@ +module fasta; + +const IM = 139968; +const IA = 3877; +const IC = 29573; +const SEED = 42; + +uint seed = SEED; + +func float fasta_rand(float max) +{ + seed = (seed * IA + IC) % IM; + return max * seed / IM; +} + +private char[] alu = + "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" + "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" + "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" + "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" + "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" + "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" + "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"; + +extern func int atoi(char *s); +extern func int printf(char *s, ...); +extern func void putchar(int c); + +char[] iub = "acgtBDHKMNRSVWY"; +double[*] iub_p = { + 0.27, + 0.12, + 0.12, + 0.27, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02, + 0.02 }; + +char[] homosapiens = "acgt"; +double[*] homosapiens_p = { + 0.3029549426680, + 0.1979883004921, + 0.1975473066391, + 0.3015094502008 +}; + +const LINELEN = 60; + +// slowest character-at-a-time output +func void repeat_fasta(char[] seq, int n) +{ + usize len = seq.len(); + int i = void; + for (i = 0; i < n; i++) + { + putchar(seq[i % len]); + if (i % LINELEN == LINELEN - 1) putchar('\n'); + } + if (i % LINELEN != 0) putchar('\n'); +} + +func void random_fasta(char[] symb, double[] probability, int n) +{ + assert(symb.len() == probability.len()); + int len = (int)(probability.len()); + int i = void; + for (i = 0; i < n; i++) + { + double v = fasta_rand(1.0); + /* slowest idiomatic linear lookup. Fast if len is short though. */ + int j = void; + for (j = 0; j < len - 1; j++) + { + v -= probability[j]; + if (v < 0) break; + } + putchar(symb[j]); + if (i % LINELEN == LINELEN - 1) putchar('\n'); + } + if (i % LINELEN != 0) putchar('\n'); +} + +func void main(int argc, char **argv) +{ + int n=1000; + if (argc > 1) n = atoi(argv[1]); + + printf(">ONE Homo sapiens alu\n"); + repeat_fasta(alu, n * 2); + + printf(">TWO IUB ambiguity codes\n"); + random_fasta(iub, &iub_p, n * 3); + + printf(">THREE Homo sapiens frequency\n"); + random_fasta(homosapiens, &homosapiens_p, n * 5); + +} diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index f4de9f089..30fabbe9e 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -94,6 +94,10 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_ LLVMTypeRef element_type_llvm = llvm_get_type(c, element_type); ConstInitializer **elements = const_init->init_array_full; ArrayIndex size = array_type->array.len; + if (array_type->type_kind == TYPE_SUBARRAY) + { + size = vec_size(elements); + } assert(size > 0); LLVMValueRef *parts = VECNEW(LLVMValueRef, size); for (ArrayIndex i = 0; i < size; i++) diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 2a4d137ba..4b1ba57e4 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -3096,18 +3096,18 @@ static inline bool sema_expr_analyse_array_plain_initializer(Context *context, T ConstInitializer *const_init = CALLOCS(ConstInitializer); const_init->kind = CONST_INIT_ARRAY_FULL; const_init->type = type_flatten(initializer->type); - ConstInitializer **inits = MALLOC(sizeof(ConstInitializer *) * vec_size(elements)); + ConstInitializer **inits = VECNEW(ConstInitializer*, vec_size(elements)); VECEACH(elements, i) { Expr *expr = elements[i]; if (expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_LIST) { - inits[i] = expr->const_expr.list; + vec_add(inits, expr->const_expr.list); continue; } ConstInitializer *element_init = MALLOC(sizeof(ConstInitializer)); sema_create_const_initializer_value(element_init, expr); - inits[i] = element_init; + vec_add(inits, element_init); } const_init->init_array_full = inits; expr_set_as_const_list(initializer, const_init);