diff --git a/src/scan.re.c b/src/scan.re.c index 5411200..2c61adb 100644 --- a/src/scan.re.c +++ b/src/scan.re.c @@ -147,8 +147,13 @@ static int scan_day(struct scan *const scan, union date32 date, size_t line = 1; char datestr[12] = {0}; const char *fail = "perhaps a bat?"; - struct pair *input_text = 0; - struct money *input_money = 0; + struct { + enum YYCONDTYPE future; + union { + struct pair *pair; + struct money *money; + }; + } input; struct score *new_score = 0; struct glider *new_glider = 0; struct flight *new_flight = 0; @@ -200,9 +205,10 @@ static int scan_day(struct scan *const scan, union date32 date, for( ; ; ) { /*!re2c /**/ [^\n\x00] { continue; } /* Default ignore. */ + * { fail = "newline expected"; goto catch; } "\x00" { fail = "no newline at end of file"; goto catch; } "\x00" { return 1; } /* End of day. */ - "\n" => line { line++; continue; } + "\n" => line { line++; continue; } * :=> skip "->" :=> place "--" / [^-] :=> source @@ -222,6 +228,7 @@ static int scan_day(struct scan *const scan, union date32 date, "idea: " :=> idea "vaccine: " :=> vaccine "tax: " :=> tax + "in: " :=> income /* Whatsapp messages ignored. [11-03, 04:19] Contact: massage Hopefully they don't have a ':' in their name. */ [0-1][0-9] "-" [0-3][0-9] ", " [0-2][0-9] ":" [0-5][0-9] "] " @@ -240,7 +247,7 @@ static int scan_day(struct scan *const scan, union date32 date, if(!(doc = kvpair_array_new(&scan->documents.array))) goto catch; doc->key.a = s0, doc->key.b = s1; doc->value.a = 0, doc->value.b = 0; - assert(!input_text), input_text = &doc->value; + input.future = yycnewline, input.pair = &doc->value; switch(linemap_tree_bulk_assign(&scan->documents.dates, key, &pi)) { case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch; case TREE_ABSENT: @@ -259,7 +266,7 @@ static int scan_day(struct scan *const scan, union date32 date, if(!(ed = edit_array_new(&scan->edits.array))) goto catch; ed->edit.u32 = 0; ed->desc.a = 0, ed->desc.b = 0; - assert(!input_text), input_text = &ed->desc; + input.future = yycnewline, input.pair = &ed->desc; if(!pair_to_date(s0, &ed->edit)) goto catch; switch(linemap_tree_bulk_assign(&scan->edits.dates, key, &pi)) { case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch; @@ -282,7 +289,7 @@ static int scan_day(struct scan *const scan, union date32 date, } pair->key.a = s0, pair->key.b = s1; pair->value.a = pair->value.b = 0; - assert(!input_text), input_text = &pair->value; + input.future = yycnewline, input.pair = &pair->value; fprintf(stderr, "%s[%zu]: new contact <<%.*s>>.\n", datestr, line, (int)(s1 - s0), s0); continue; @@ -298,7 +305,7 @@ static int scan_day(struct scan *const scan, union date32 date, } pair->key.a = s0, pair->key.b = s1; pair->value.a = pair->value.b = 0; - assert(!input_text), input_text = &pair->value; + input.future = yycnewline, input.pair = &pair->value; fprintf(stderr, "%s[%zu]: new book <<%.*s>>.\n", datestr, line, (int)(s1 - s0), s0); continue; @@ -314,7 +321,7 @@ static int scan_day(struct scan *const scan, union date32 date, } pair->key.a = s0, pair->key.b = s1; pair->value.a = pair->value.b = 0; - assert(!input_text), input_text = &pair->value; + input.future = yycnewline, input.pair = &pair->value; fprintf(stderr, "%s[%zu]: new tv <<%.*s>>.\n", datestr, line, (int)(s1 - s0), s0); continue; @@ -330,7 +337,7 @@ static int scan_day(struct scan *const scan, union date32 date, } pair->key.a = s0, pair->key.b = s1; pair->value.a = pair->value.b = 0; - assert(!input_text), input_text = &pair->value; + input.future = yycnewline, input.pair = &pair->value; fprintf(stderr, "%s[%zu]: new movie <<%.*s>>.\n", datestr, line, (int)(s1 - s0), s0); continue; @@ -346,7 +353,7 @@ static int scan_day(struct scan *const scan, union date32 date, } pair->key.a = s0, pair->key.b = s1; pair->value.a = pair->value.b = 0; - assert(!input_text), input_text = &pair->value; + input.future = yycnewline, input.pair = &pair->value; fprintf(stderr, "%s[%zu]: new idea <<%.*s>>.\n", datestr, line, (int)(s1 - s0), s0); continue; @@ -362,7 +369,7 @@ static int scan_day(struct scan *const scan, union date32 date, } pair->key.a = s0, pair->key.b = s1; pair->value.a = pair->value.b = 0; - assert(!input_text), input_text = &pair->value; + input.future = yycnewline, input.pair = &pair->value; fprintf(stderr, "%s[%zu]: new vaccine <<%.*s>>.\n", datestr, line, (int)(s1 - s0), s0); continue; @@ -378,12 +385,29 @@ static int scan_day(struct scan *const scan, union date32 date, } pair->key.a = s0, pair->key.b = s1; pair->value = (struct money){0, CAD}; - assert(!input_text), input_money = &pair->value; + input.future = yycnewline, input.money = &pair->value; fprintf(stderr, "%s[%zu]: new tax <<%.*s>>.\n", datestr, line, (int)(s1 - s0), s0); continue; } + * { fail = "income unrecognized"; goto catch; } + /* @s0 bralabel @s1 "]" => input_money { + const union line64 key = { { (uint32_t)line, date } }; + struct kvmoney *pair; + switch(linekvmoney_tree_bulk_assign(&scan->taxes, key, &pair)) { + case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch; + case TREE_ABSENT: break; + } + pair->key.a = s0, pair->key.b = s1; + pair->value = (struct money){0, CAD}; + input.future = yycincome_remark, input.pair = &pair->value; + fprintf(stderr, "%s[%zu]: new tax <<%.*s>>.\n", + datestr, line, (int)(s1 - s0), s0); + continue; + } + "]"*/ + * { fail = "place unrecognized"; goto catch; } @s0 parlabel @s1 / "\n" => skip { also_place: { const struct pair keyword = pair(s0, s1); @@ -466,7 +490,7 @@ static int scan_day(struct scan *const scan, union date32 date, *idx = (size_t)(source - scan->sources.array.data); source->key.a = s0, source->key.b = s1; source->value.a = 0, source->value.b = 0; - assert(!input_text), input_text = &source->value; + input.future = yycnewline, input.pair = &source->value; fprintf(stderr, "%s[%zu]: new source <<%.*s>> stored at %zu.\n", datestr, line, (int)(s1 - s0), s0, *idx); goto also_source; @@ -793,40 +817,40 @@ static int scan_day(struct scan *const scan, union date32 date, /* fixme: This is a cool way of doing things. Avoid repetition, make all the things this way. */ + /* Text is only at the end of a line. */ * { fail = "text input"; goto catch; } ws { continue; } - "\n" => line { // empty is okay + /* Hmmm. + "\n" { // empty is okay line++; fprintf(stderr, "text: \n"); assert(input_text); - input_text->a = input_text->b = 0, input_text = 0; + input.pair->a = input.pair->b = 0; + condition = input.future; continue; - } + } */ "<<\n" @s0 => input_text_multi { // multi-line line++; - assert(input_text); - input_text->a = s0; + input.pair->a = s0; continue; } - @s0 anylabel @s1 "\n" => line { // one line + @s0 anylabel @s1 /*future*/ { // one line line++; fprintf(stderr, "text: <<%.*s>>\n", (int)(s1 - s0), s0); - assert(input_text); - input_text->a = s0, input_text->b = s1, input_text = 0; + input.pair->a = s0, input.pair->b = s1; + condition = input.future; continue; } [^\x00\n] { continue; } [\x00] { fail = "missing closing \">>\""; goto catch; } "\n" { line++; continue; } - /* Restricts this to be the last one; you could imagine that it would - be more flexible, "<<\n>>; <<\n>>\n". */ - @s1 ">>\n" => line { + @s1 ">>" { line++; fprintf(stderr, "text: <<\n%.*s>>\n", - (int)(s1 - input_text->a), input_text->a); - assert(input_text && input_text->a); - input_text->b = s1, input_text = 0; + (int)(s1 - input.pair->a), input.pair->a); + input.pair->b = s1; + condition = input.future; continue; } @@ -834,12 +858,15 @@ static int scan_day(struct scan *const scan, union date32 date, { fail = "money input"; goto catch; } ws { continue; } @s0 moneyamount @s1 => input_money_currency { - if(!pair_to_cents(s0, s1, &input_money->cents)) goto catch; - printf("input_money: amount %" PRId64 "\n", input_money->cents); + if(!pair_to_cents(s0, s1, &input.money->cents)) goto catch; + printf("input_money: amount %" PRId64 "\n", input.money->cents); + continue; + } + "$" { + input.money->currency = CAD; + condition = input.future; continue; } - "$\n" => line - { line++; input_money->currency = CAD; continue; } */ } assert(0); /* Never gets here. */