compile.c (23830B)
1 /* 2 bydgoszcz - simple, fast and efficient programming language 3 Copyright (C) 2021 Kacper Kocot <kocotian@kocotian.pl> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software Foundation, 17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 19 */ 20 21 #define _XOPEN_SOURCE 700 22 #define _POSIX_C_SOURCE 200809L 23 24 #include <compile.h> 25 #include <stddef.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <unistd.h> 30 31 #include <errwarn.h> 32 #include <str.h> 33 #include <util.h> 34 35 #define MAX_TYPESIZE 8192 36 #define MAX_EXPRESSIONSIZE 8192 37 38 typedef struct { 39 char ldata[MAX_TYPESIZE], rdata[MAX_TYPESIZE]; 40 size_t llen, rlen; 41 } TypeString; 42 43 typedef struct { 44 char data[MAX_EXPRESSIONSIZE]; 45 size_t len; 46 } ExpressionString; 47 48 static Token *enextToken(File *f, TokenType type); 49 static void g_array(File *f, TypeString *str); 50 static void g_struct(File *f, TypeString *str); 51 static void g_type(File *f, TypeString *str); 52 static void g_expression(File *f, ExpressionString *str); 53 static void g_zadzwon(File *f, ExpressionString *str); 54 static void g_obywatel(File *f); 55 static void g_aglomeracja(File *f); 56 static void g_miasto(File *f); 57 static void initType(TypeString *t, int blank); 58 59 static Token * 60 enextToken(File *f, TokenType type) 61 { 62 Token *r; 63 if ((r = nextToken(f)) == NULL) 64 errwarn(*f, 1, "unexpected end of input"); 65 if (type != TokenNULL && r->type != type) 66 errwarn(*f, 1, "token type mismatch (expected %s, have %s)", 67 stringizeTokenType(type), stringizeTokenType(r->type)); 68 return r; 69 } 70 71 static void 72 g_array(File *f, TypeString *str) 73 { 74 Token *t; 75 ExpressionString count; 76 TypeString type; 77 78 initType(&type, 1); 79 t = enextToken(f, TokenNULL); 80 if (t->type == TokenNumber) { 81 g_expression(f, &count); 82 t = enextToken(f, TokenIdentifier); 83 if (Strccmp(t->c, "elementow")) 84 errwarn(*f, 1, "unexpected identifier (expected elementow)"); 85 t = enextToken(f, TokenNULL); 86 } 87 if (t->type == TokenIdentifier) { 88 if (Strccmp(t->c, "typu")) 89 errwarn(*f, 1, "unexpected identifier (expected typu)"); 90 g_type(f, &type); 91 } else { 92 errwarn(*f, 1, "unexpected token (expected identifier)"); 93 } 94 snprintf((char *)(str->ldata), 95 MAX_TYPESIZE, 96 "%.*s", 97 (int)(type.llen), type.ldata); 98 str->llen = strlen(str->ldata); 99 snprintf((char *)(str->rdata), 100 MAX_TYPESIZE, 101 "[%.*s]", 102 Strevalf(count)); 103 str->rlen = strlen(str->rdata); 104 } 105 106 static void 107 g_struct(File *f, TypeString *str) 108 { 109 Token *t; 110 String name, fname; 111 TypeString type; 112 113 initType(&type, 1); 114 *str->ldata = 0; 115 strncat(str->ldata, "struct", MAX_TYPESIZE); 116 t = enextToken(f, TokenNULL); 117 if (t->type == TokenIdentifier) { 118 name = t->c; 119 strncat(str->ldata, " ", MAX_TYPESIZE); 120 ++(str->llen); 121 str->llen += UMIN(strlen(str->ldata) + name.len, MAX_TYPESIZE); 122 strncat(str->ldata, name.data, 123 UMIN(name.len, MAX_TYPESIZE - str->llen)); 124 str->ldata[UMIN(str->llen, MAX_TYPESIZE)] = 0; 125 t = enextToken(f, TokenNULL); 126 } 127 if (t->type == TokenColon) { 128 strncat(str->ldata, " {\n", MAX_TYPESIZE); 129 while ((t = enextToken(f, TokenIdentifier))) { 130 if (!Strccmp(t->c, "koniec")) { 131 strncat(str->ldata, "}", MAX_TYPESIZE); 132 str->llen = strlen(str->ldata); 133 break; 134 } else { 135 fname = t->c; 136 while ((t = enextToken(f, TokenNULL))) { 137 if (t->type == TokenIdentifier) { 138 if (!Strccmp(t->c, "przechowuje")) { 139 g_type(f, &type); 140 } else { 141 errwarn(*f, 1, "unexpected identifier (expected przechowuje)"); 142 } 143 } else if (t->type == TokenSemicolon) { 144 snprintf((char *)(str->ldata + strlen(str->ldata)), 145 MAX_TYPESIZE - strlen(str->ldata), 146 "%.*s %.*s%.*s;\n", 147 (int)(type.llen), type.ldata, 148 Strevalf(fname), 149 (int)(type.rlen), type.rdata); 150 break; 151 } else { 152 errwarn(*f, 1, "unexpected token (expected identifier or semicolon)"); 153 } 154 } 155 } 156 } 157 } else if (t->type == TokenSemicolon) { 158 } else { 159 errwarn(*f, 1, "unexpected token (expected colon)"); 160 } 161 } 162 163 static void 164 g_type(File *f, TypeString *str) 165 { 166 Token *t; 167 String name, s; 168 TypeString arr; 169 170 int ptrlvl, isptrconst, isvalconst, isunsigned, isshort, islong; 171 ptrlvl = isptrconst = isvalconst = isunsigned = isshort = islong = 0; 172 173 initType(&arr, 1); 174 175 while ((t = enextToken(f, TokenIdentifier))) { 176 s = t->c; 177 if (!Strccmp(s, "wskaznik")) { 178 t = enextToken(f, TokenIdentifier); 179 if (Strccmp(t->c, "na")) 180 errwarn(*f, 1, "expected 'na' after 'wskaznik'"); 181 ++ptrlvl; 182 } 183 else if (!Strccmp(s, "staly")) isptrconst = 1; 184 else if (!Strccmp(s, "stale")) isvalconst = 1; 185 else if (!Strccmp(s, "nieoznakowane")) isunsigned = 1; 186 else if (!Strccmp(s, "oznakowane")) isunsigned = 2; 187 else if (!Strccmp(s, "krotkie")) isshort = 1; 188 else if (!Strccmp(s, "dlugie")) islong = 1; 189 else { 190 /* Basic types */ 191 if (!Strccmp(t->c, "zadupie")) 192 name.len = strlen(name.data = "void"); 193 else if (!Strccmp(t->c, "literki")) 194 name.len = strlen(name.data = "char"); 195 else if (!Strccmp(t->c, "cyferki")) 196 name.len = strlen(name.data = "int"); 197 else if (!Strccmp(t->c, "latajace")) 198 name.len = strlen(name.data = "float"); 199 else if (!Strccmp(t->c, "podwojne")) 200 name.len = strlen(name.data = "double"); 201 else if (!Strccmp(t->c, "cierpienie")) 202 name.len = strlen(name.data = "int"); 203 else if (!Strccmp(t->c, "rodzine")) { 204 TypeString type; 205 initType(&type, 1); 206 g_array(f, &type); 207 name.len = type.llen; 208 name.data = type.ldata; 209 str->rlen = strlen(strncpy(str->rdata, 210 type.rdata, 211 UMIN(MAX_TYPESIZE, type.rlen))); 212 } 213 /* Composite types */ 214 else if (!Strccmp(t->c, "organizacje")) { 215 TypeString type; 216 initType(&type, 1); 217 g_struct(f, &type); 218 name.len = type.llen; 219 name.data = type.ldata; 220 } 221 /* Other types */ 222 else 223 name = t->c; 224 break; 225 } 226 } 227 str->llen = (size_t)(*(str->ldata) = 0); 228 if (isptrconst && ptrlvl) 229 str->llen = strlen(strncat(str->ldata, "const ", MAX_TYPESIZE - str->llen)); 230 if (isunsigned == 1) 231 str->llen = strlen(strncat(str->ldata, "unsigned ", MAX_TYPESIZE - str->llen)); 232 else if (isunsigned == 2) 233 str->llen = strlen(strncat(str->ldata, "signed ", MAX_TYPESIZE - str->llen)); 234 if (isshort) 235 str->llen = strlen(strncat(str->ldata, "short ", MAX_TYPESIZE - str->llen)); 236 else if (islong) 237 str->llen = strlen(strncat(str->ldata, "long ", MAX_TYPESIZE - str->llen)); 238 239 strncat(str->ldata, 240 name.data, 241 UMIN(MAX_TYPESIZE - str->llen, name.len)); 242 243 str->llen += name.len; 244 245 while (ptrlvl > 0 && ptrlvl--) 246 strncat(str->ldata, "*", MAX_TYPESIZE), str->llen++; 247 if (isvalconst) 248 strncat(str->ldata, " const", MAX_TYPESIZE), str->llen += 6; 249 strncat(str->ldata, 250 arr.ldata, 251 UMIN(MAX_TYPESIZE - str->llen, arr.llen)); 252 } 253 254 static void 255 g_expression(File *f, ExpressionString *str) 256 { 257 Token *t; 258 259 t = &(f->curtok); 260 if (t->type == TokenNumber || t->type == TokenString) { 261 strncpy(str->data, t->c.data, UMIN(MAX_EXPRESSIONSIZE, t->c.len)); 262 str->len = t->c.len; 263 } else if (t->type == TokenIdentifier) { 264 if (!Strccmp(t->c, "zadzwon")) { 265 g_zadzwon(f, str); 266 } else if (!Strccmp(t->c, "powieksz") 267 || !Strccmp(t->c, "pomniejsz") 268 || !Strccmp(t->c, "popowieksz") 269 || !Strccmp(t->c, "popomniejsz")) { 270 ExpressionString expr; 271 int v = !Strccmp(t->c, "powieksz") ? 1 : !Strccmp(t->c, "pomniejsz") ? 2 : 272 !Strccmp(t->c, "popowieksz") ? 3 : !Strccmp(t->c, "popomniejsz") ? 4 : 0; 273 t = enextToken(f, TokenNULL); 274 g_expression(f, &expr); 275 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%s%.*s%s", 276 v == 1 ? "++" : v == 2 ? "--" : "", 277 Strevalf(expr), 278 v == 3 ? "++" : v == 4 ? "--" : ""); 279 } else if (!Strccmp(t->c, "prawda")) { 280 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "1"); 281 } else if (!Strccmp(t->c, "nieprawda")) { 282 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "0"); 283 } else if (!Strccmp(t->c, "ustaw")) { 284 ExpressionString what, as; 285 t = enextToken(f, TokenNULL); 286 g_expression(f, &what); 287 t = enextToken(f, TokenIdentifier); 288 if (Strccmp(t->c, "jako")) 289 errwarn(*f, 1, "unexpected identifier (expected jako)"); 290 t = enextToken(f, TokenNULL); 291 g_expression(f, &as); 292 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%.*s = %.*s", 293 Strevalf(what), Strevalf(as)); 294 } else if (!Strccmp(t->c, "dodaj")) { 295 ExpressionString what, where; 296 t = enextToken(f, TokenNULL); 297 g_expression(f, &what); 298 t = enextToken(f, TokenIdentifier); 299 if (Strccmp(t->c, "do")) 300 errwarn(*f, 1, "unexpected identifier (expected do)"); 301 t = enextToken(f, TokenNULL); 302 g_expression(f, &where); 303 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%.*s += %.*s", 304 Strevalf(where), Strevalf(what)); 305 } else if (!Strccmp(t->c, "odejmij")) { 306 ExpressionString what, from; 307 t = enextToken(f, TokenNULL); 308 g_expression(f, &what); 309 t = enextToken(f, TokenIdentifier); 310 if (Strccmp(t->c, "od")) 311 errwarn(*f, 1, "unexpected identifier (expected od)"); 312 t = enextToken(f, TokenNULL); 313 g_expression(f, &from); 314 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%.*s -= %.*s", 315 Strevalf(from), Strevalf(what)); 316 } else if (!Strccmp(t->c, "pomnoz")) { 317 ExpressionString what, bywhat; 318 t = enextToken(f, TokenNULL); 319 g_expression(f, &what); 320 t = enextToken(f, TokenIdentifier); 321 if (Strccmp(t->c, "przez")) 322 errwarn(*f, 1, "unexpected identifier (expected przez)"); 323 t = enextToken(f, TokenNULL); 324 g_expression(f, &bywhat); 325 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%.*s *= %.*s", 326 Strevalf(what), Strevalf(bywhat)); 327 } else if (!Strccmp(t->c, "podziel")) { 328 ExpressionString what, bywhat; 329 t = enextToken(f, TokenNULL); 330 g_expression(f, &what); 331 t = enextToken(f, TokenIdentifier); 332 if (Strccmp(t->c, "przez")) 333 errwarn(*f, 1, "unexpected identifier (expected przez)"); 334 t = enextToken(f, TokenNULL); 335 g_expression(f, &bywhat); 336 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%.*s /= %.*s", 337 Strevalf(what), Strevalf(bywhat)); 338 } else if (!Strccmp(t->c, "suma")) { 339 ExpressionString first, second; 340 t = enextToken(f, TokenNULL); 341 g_expression(f, &first); 342 t = enextToken(f, TokenIdentifier); 343 if (Strccmp(t->c, "oraz")) 344 errwarn(*f, 1, "unexpected identifier (expected oraz)"); 345 t = enextToken(f, TokenNULL); 346 g_expression(f, &second); 347 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%.*s + %.*s", 348 Strevalf(first), Strevalf(second)); 349 } else if (!Strccmp(t->c, "roznica")) { 350 ExpressionString first, second; 351 t = enextToken(f, TokenNULL); 352 g_expression(f, &first); 353 t = enextToken(f, TokenIdentifier); 354 if (Strccmp(t->c, "oraz")) 355 errwarn(*f, 1, "unexpected identifier (expected oraz)"); 356 t = enextToken(f, TokenNULL); 357 g_expression(f, &second); 358 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%.*s - %.*s", 359 Strevalf(first), Strevalf(second)); 360 } else if (!Strccmp(t->c, "iloczyn")) { 361 ExpressionString first, second; 362 t = enextToken(f, TokenNULL); 363 g_expression(f, &first); 364 t = enextToken(f, TokenIdentifier); 365 if (Strccmp(t->c, "oraz")) 366 errwarn(*f, 1, "unexpected identifier (expected oraz)"); 367 t = enextToken(f, TokenNULL); 368 g_expression(f, &second); 369 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%.*s * %.*s", 370 Strevalf(first), Strevalf(second)); 371 } else if (!Strccmp(t->c, "iloraz")) { 372 ExpressionString first, second; 373 t = enextToken(f, TokenNULL); 374 g_expression(f, &first); 375 t = enextToken(f, TokenIdentifier); 376 if (Strccmp(t->c, "oraz")) 377 errwarn(*f, 1, "unexpected identifier (expected oraz)"); 378 t = enextToken(f, TokenNULL); 379 g_expression(f, &second); 380 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%.*s / %.*s", 381 Strevalf(first), Strevalf(second)); 382 } else if (!Strccmp(t->c, "reszta")) { 383 ExpressionString first, second; 384 t = enextToken(f, TokenIdentifier); 385 if (Strccmp(t->c, "z")) 386 errwarn(*f, 1, "unexpected identifier (expected z)"); 387 t = enextToken(f, TokenNULL); 388 g_expression(f, &first); 389 t = enextToken(f, TokenIdentifier); 390 if (Strccmp(t->c, "przez")) 391 errwarn(*f, 1, "unexpected identifier (expected przez)"); 392 t = enextToken(f, TokenNULL); 393 g_expression(f, &second); 394 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%.*s %% %.*s", 395 Strevalf(first), Strevalf(second)); 396 } else if (!Strccmp(t->c, "adres")) { 397 ExpressionString expr; 398 t = enextToken(f, TokenNULL); 399 g_expression(f, &expr); 400 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "&(%.*s)", 401 Strevalf(expr)); 402 } else if (!Strccmp(t->c, "zawartosc")) { 403 ExpressionString expr; 404 t = enextToken(f, TokenNULL); 405 g_expression(f, &expr); 406 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "*(%.*s)", 407 Strevalf(expr)); 408 } else if (!Strccmp(t->c, "przeciwienstwo")) { 409 ExpressionString expr; 410 t = enextToken(f, TokenNULL); 411 g_expression(f, &expr); 412 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "-(%.*s)", 413 Strevalf(expr)); 414 } else if (!Strccmp(t->c, "nie")) { 415 ExpressionString expr; 416 t = enextToken(f, TokenNULL); 417 g_expression(f, &expr); 418 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "!(%.*s)", 419 Strevalf(expr)); 420 } else if (!Strccmp(t->c, "wielkosc")) { 421 ExpressionString expr; 422 t = enextToken(f, TokenNULL); 423 g_expression(f, &expr); 424 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "sizeof (%.*s)", 425 Strevalf(expr)); 426 } else if (!Strccmp(t->c, "naprawde") || !Strccmp(t->c, "czy")) { 427 ExpressionString lexpr, rexpr; 428 int not; int equal; int greater; int lower; 429 not = equal = greater = lower = 0; 430 t = enextToken(f, TokenNULL); 431 g_expression(f, &lexpr); 432 t = enextToken(f, TokenIdentifier); 433 if (!Strccmp(t->c, "nie")) { 434 not = 1; 435 t = enextToken(f, TokenIdentifier); 436 } 437 else if (Strccmp(t->c, "jest")) 438 errwarn(*f, 1, "unexpected identifier (expected jest)"); 439 t = enextToken(f, TokenIdentifier); 440 tester: 441 if (!Strccmp(t->c, "rowne")) { 442 equal = 1; 443 } else { 444 if (!Strccmp(t->c, "wieksze")) { 445 greater = 1; 446 } else if (!Strccmp(t->c, "mniejsze")) { 447 lower = 1; 448 } 449 t = enextToken(f, TokenIdentifier); 450 if (!Strccmp(t->c, "albo")) { 451 t = enextToken(f, TokenIdentifier); 452 goto tester; 453 } else if (Strccmp(t->c, "niz")) 454 errwarn(*f, 1, "unexpected identifier (expected albo or niz)"); 455 } 456 t = enextToken(f, TokenNULL); 457 g_expression(f, &rexpr); 458 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "%s((%.*s) %s%s (%.*s))", 459 not ? "!" : "", 460 Strevalf(lexpr), 461 greater ? ">" : lower ? "<" : equal ? "=" : "", 462 equal ? "=" : "", 463 Strevalf(rexpr)); 464 } else if (!Strccmp(t->c, "czlonek")) { 465 ExpressionString organization; 466 String member; 467 t = enextToken(f, TokenIdentifier); 468 member = t->c; 469 t = enextToken(f, TokenIdentifier); 470 if (Strccmp(t->c, "organizacji")) 471 errwarn(*f, 1, "unexpected identifier (expected organizacji)"); 472 t = enextToken(f, TokenNULL); 473 g_expression(f, &organization); 474 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "(%.*s).%.*s", 475 Strevalf(organization), Strevalf(member)); 476 } else if (!Strccmp(t->c, "element")) { 477 ExpressionString element, family; 478 t = enextToken(f, TokenNULL); 479 g_expression(f, &element); 480 t = enextToken(f, TokenIdentifier); 481 if (Strccmp(t->c, "rodziny")) 482 errwarn(*f, 1, "unexpected identifier (expected rodziny)"); 483 t = enextToken(f, TokenNULL); 484 g_expression(f, &family); 485 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "(%.*s)[%.*s]", 486 Strevalf(family), Strevalf(element)); 487 } else if (!Strccmp(t->c, "rzucaj")) { 488 ExpressionString expr; 489 TypeString type; 490 initType(&type, 1); 491 t = enextToken(f, TokenNULL); 492 g_expression(f, &expr); 493 t = enextToken(f, TokenIdentifier); 494 if (Strccmp(t->c, "w")) 495 errwarn(*f, 1, "unexpected identifier (expected organizacji)"); 496 g_type(f, &type); 497 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "(%.*s)(%.*s)", 498 (int)(type.llen), type.ldata, Strevalf(expr)); 499 } else if (!Strccmp(t->c, "nieoznakowane")) { 500 ExpressionString expr; 501 TypeString type; 502 initType(&type, 1); 503 t = enextToken(f, TokenNULL); 504 g_expression(f, &expr); 505 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "(unsigned)(%.*s)", 506 Strevalf(expr)); 507 } else if (!Strccmp(t->c, "oznakowane")) { 508 ExpressionString expr; 509 TypeString type; 510 initType(&type, 1); 511 t = enextToken(f, TokenNULL); 512 g_expression(f, &expr); 513 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, "(signed)(%.*s)", 514 Strevalf(expr)); 515 } else if (!Strccmp(t->c, "__c")) { 516 t = enextToken(f, TokenString); 517 strncpy(str->data, t->c.data + 1, t->c.len - 2); 518 str->len = t->c.len - 2; 519 } else { 520 strncpy(str->data, t->c.data, UMIN(MAX_EXPRESSIONSIZE, t->c.len)); 521 str->len = t->c.len; 522 } 523 } else { 524 errwarn(*f, 1, "expected expression"); 525 } 526 str->data[UMIN(str->len, MAX_EXPRESSIONSIZE - 1)] = 0; 527 } 528 529 static void 530 g_zadzwon(File *f, ExpressionString *str) 531 { 532 Token *t; 533 String name; 534 ExpressionString expr; 535 536 t = enextToken(f, TokenIdentifier); 537 name = t->c; 538 str->len = (size_t)snprintf(str->data, MAX_EXPRESSIONSIZE, 539 "%.*s(", Strevalf(name)); 540 t = enextToken(f, TokenNULL); 541 if (t->type == TokenIdentifier) { 542 if (!Strccmp(t->c, "daj")) { 543 t = enextToken(f, TokenColon); 544 while ((t = enextToken(f, TokenNULL))) { 545 g_expression(f, &expr); 546 strncat(str->data, expr.data, MAX_EXPRESSIONSIZE); 547 str->len += expr.len; 548 t = enextToken(f, TokenNULL); 549 if (t->type == TokenSemicolon) 550 break; 551 else if (t->type == TokenComma) { 552 strncat(str->data, ", ", MAX_EXPRESSIONSIZE); 553 str->len += 2; 554 } else { 555 errwarn(*f, 1, "unexpected %s (expected comma or semicolon)", 556 stringizeTokenType(t->type)); 557 } 558 } 559 } else { 560 errwarn(*f, 1, "unexpected identifier (expected daj)"); 561 } 562 } 563 strncat(str->data, ")", MAX_EXPRESSIONSIZE); 564 str->len += 1; 565 } 566 567 static void 568 g_obywatel(File *f) 569 { 570 String name; 571 TypeString type; 572 ExpressionString expr; 573 574 Token *t; 575 576 initType(&type, 0); 577 t = enextToken(f, TokenIdentifier); 578 name = t->c; 579 expr.len = strlen(strcpy(expr.data, "")); 580 while ((t = enextToken(f, TokenNULL))) { 581 if (t->type == TokenIdentifier) { 582 if (!Strccmp(t->c, "przechowuje")) { 583 g_type(f, &type); 584 } else if (!Strccmp(t->c, "rowne")) { 585 t = enextToken(f, TokenNULL); 586 g_expression(f, &expr); 587 } else { 588 errwarn(*f, 1, "unexpected identifier (expected przechowuje)"); 589 } 590 } else if (t->type == TokenSemicolon) { 591 dprintf(f->outfd, "%.*s %.*s%.*s%s%.*s;\n", 592 (int)(type.llen), type.ldata, 593 Strevalf(name), 594 (int)(type.rlen), type.rdata, 595 expr.len ? " = " : "", 596 (int)(expr.len), expr.data); 597 return; 598 } else { 599 errwarn(*f, 1, "unexpected token (expected identifier or semicolon)"); 600 } 601 } 602 } 603 604 static void 605 g_aglomeracja(File *f) 606 { 607 Token *t; 608 ExpressionString expr; 609 610 while ((t = enextToken(f, TokenNULL))) { 611 if (t->type == TokenIdentifier) { 612 if (!Strccmp(t->c, "koniec")) { 613 dprintf(f->outfd, "}\n"); 614 return; 615 } else if (!Strccmp(t->c, "obywatel")) { 616 g_obywatel(f); 617 } else if (!Strccmp(t->c, "typ")) { 618 dprintf(f->outfd, "typedef "); 619 g_obywatel(f); 620 } else if (!Strccmp(t->c, "oddaj")) { 621 dprintf(f->outfd, "return "); 622 t = enextToken(f, TokenNULL); 623 goto expr; 624 } else if (!Strccmp(t->c, "jesli") || !Strccmp(t->c, "dopoki")) { 625 int isif; isif = !Strccmp(t->c, "jesli"); 626 dprintf(f->outfd, isif ? "if (" : "while ("); 627 while ((t = enextToken(f, TokenNULL))) { 628 g_expression(f, &expr); 629 t = enextToken(f, TokenIdentifier); 630 dprintf(f->outfd, "(%.*s)", Strevalf(expr)); 631 if ((isif && !Strccmp(t->c, "wtedy")) || (!isif && !Strccmp(t->c, "rob"))) 632 break; 633 else if (!Strccmp(t->c, "albo")) { 634 dprintf(f->outfd, " || "); 635 } else if (!Strccmp(t->c, "oraz")) { 636 dprintf(f->outfd, " && "); 637 } else { 638 errwarn(*f, 1, "unexpected identifier (expected albo, oraz or %s)", 639 isif ? "wtedy" : "rob"); 640 } 641 } 642 dprintf(f->outfd, ") {\n"); 643 t = enextToken(f, TokenColon); 644 g_aglomeracja(f); 645 } else if (!Strccmp(t->c, "inaczej")) { 646 dprintf(f->outfd, "} else {\n"); 647 } else { 648 goto expr; 649 } 650 } else if (t->type == TokenSemicolon) { 651 } else { 652 expr: 653 g_expression(f, &expr); 654 dprintf(f->outfd, "%.*s;\n", Strevalf(expr)); 655 } 656 } 657 658 return; 659 } 660 661 static void 662 g_miasto(File *f) 663 { 664 String name; 665 TypeString type; 666 ExpressionString args; 667 668 Token *t; 669 670 initType(&type, 0); 671 t = enextToken(f, TokenIdentifier); 672 name = t->c; 673 args.len = (unsigned)(*(args.data) = 0); 674 while ((t = enextToken(f, TokenNULL))) { 675 if (t->type == TokenColon) { 676 dprintf(f->outfd, "%.*s %.*s(%.*s) {\n", 677 (int)(type.llen), type.ldata, Strevalf(name), Strevalf(args)); 678 g_aglomeracja(f); 679 return; 680 } else if (t->type == TokenIdentifier) { 681 if (!Strccmp(t->c, "oddaje")) { 682 g_type(f, &type); 683 } else if (!Strccmp(t->c, "przyjmuje")) { 684 t = enextToken(f, TokenColon); 685 while ((t = enextToken(f, TokenIdentifier))) { 686 if (!Strccmp(t->c, "cdn")) { 687 args.len += (size_t)snprintf( 688 (char *)(args.data + strlen(args.data)), 689 MAX_TYPESIZE - strlen(args.data), 690 "..."); 691 t = enextToken(f, TokenSemicolon); 692 break; 693 } else { 694 String argname; 695 TypeString argtype; 696 697 initType(&type, 0); 698 argname = t->c; 699 t = enextToken(f, TokenNULL); 700 if (t->type == TokenIdentifier) { 701 if (!Strccmp(t->c, "przechowuje")) { 702 g_type(f, &argtype); 703 } else { 704 errwarn(*f, 1, "unexpected identifier (expected przechowuje)"); 705 } 706 t = enextToken(f, TokenNULL); 707 } 708 if (t->type == TokenComma || t->type == TokenSemicolon) { 709 args.len += (size_t)snprintf( 710 (char *)(args.data + strlen(args.data)), 711 MAX_TYPESIZE - strlen(args.data), 712 "%.*s %.*s%.*s%s", 713 (int)(argtype.llen), argtype.ldata, 714 Strevalf(argname), 715 (int)(argtype.rlen), argtype.rdata, 716 t->type == TokenComma ? ", " : ""); 717 if (t->type == TokenSemicolon) break; 718 } else { 719 errwarn(*f, 1, "unexpected token (expected identifier or semicolon)"); 720 } 721 } 722 } 723 } else { 724 errwarn(*f, 1, "unexpected identifier (expected przyjmuje or oddaje)"); 725 } 726 } else { 727 errwarn(*f, 1, "unexpected token (expected colon, przyjmuje or oddaje)"); 728 } 729 } 730 } 731 732 static void 733 initType(TypeString *t, int blank) 734 { 735 t->llen = strlen(strcpy(t->ldata, blank ? "" : "int")); 736 t->rlen = strlen(strcpy(t->rdata, "")); 737 } 738 739 void 740 compile(File f) 741 { 742 Token *t; 743 744 while ((t = nextToken(&f)) != NULL) { 745 if (!Strccmp(t->c, "wykorzystaj")) { 746 t = enextToken(&f, TokenString); 747 dprintf(f.outfd, "#include <%.*s.h>\n", 748 (int)t->c.len - 2, t->c.data + 1); 749 } else if (!Strccmp(t->c, "miasto")) { 750 g_miasto(&f); 751 } else if (!Strccmp(t->c, "obywatel")) { 752 g_obywatel(&f); 753 } else if (!Strccmp(t->c, "typ")) { 754 dprintf(f.outfd, "typedef "); 755 g_obywatel(&f); 756 } else { 757 errwarn(f, 1, "unexpected token"); 758 } 759 } 760 }