vrtc / pjass (public) (License: BSD) (since 2023-08-03) (hash sha1)
pjass is a free Jass scripting language parser. This repository is a fork of lep/pjass. The goal is to add Debian packaging. As of the time of this writing, it works for current stable, that is Debian 12 (bookworm).
List of commits:
Subject Hash Author Date (UTC)
Missing-return check in elseifs should work now. 4274d6166e2c92a4591c1e46a0d71f1579a57c7d lep 2015-02-03 19:35:39
Missing-return checks also checks elseifs. 889122b0fb788663c728127520d0e7124c2a040c lep 2015-02-03 15:18:12
Fixed some more warnings. a5ae36b5299ac419a91592b60b8fcb1dfd8f4374 lep 2015-02-03 13:24:56
Added early exit to editdistance function. 82e8d024392d357d56c833c6b7f7632ffd6830a8 lep 2015-02-02 16:13:40
Unidentified variables are now marked as initialized. f3ef715b90782bc22fbdd29e1c16d7c917f407a9 lep 2015-02-02 13:56:00
Fixed bug in editdistance. a786775b057fc5795db1b2b106b7b9e3c1df6c4c lep 2015-02-02 13:41:15
Added basic uninitialized variable check for locals. c8222a6f68e44a46624c1f9ee781f590522f45f6 lep 2015-02-02 12:41:25
Added git-versionstring. e13ce6d7d90bccd8e18de6d0b01a18ea4501862b lep 2015-02-01 14:56:01
Removed returnsbool-check for Filter/Condition. e26a973fe1fdc1af999633c8d1f29afcbae76f0b lep 2015-02-01 14:51:47
Fixed some bison warnings. aca6b13e73d95c41787a7a0fdcc33407247be3a8 lep 2015-02-01 14:49:55
Removed multiline comments. e6d3a1bb5099bbf6e3a4ef2501645b15908a1ce8 lep 2015-02-01 14:49:16
Removed unnecessary tokens. 4f37057dfd472c2a400d667a6f7a3762cac01dcd lep 2015-02-01 14:48:14
Comments now work with EOF in addition to newlines at the end. 5363d3ca429da30594f7afb9d351335912b03fbd lep 2015-02-01 14:46:09
pjass 10n 2b2d35bc58dc93bc68014711cda919cecff13b4a lep 2014-10-25 20:38:00
pjass 10m 265bac6343dfeb09e1fc0af5c06571c7dc172455 Deaod 2010-02-15 12:15:00
pjass 10l 0c9161120896904b55b3cdd7b2f7430dd97f82e9 PitzerMike 2009-06-15 21:30:00
pjass 10k 43c1a8a167cdf2982af2c47056beeafcd1840537 Zoxc 2009-04-03 21:23:00
pjass 10j 16bbe625b7670a7affcf495e3370224c30582bca PitzerMike 2007-10-09 09:22:00
pjass 10i 1ecf3d1238619358a0aa9b1b919ed9ba97d36f84 PitzerMike 2007-09-29 11:57:00
pjass 10h dcb319607e8bb35637f86918962610683ada2b08 PitzerMike 2007-09-13 23:49:00
Commit 4274d6166e2c92a4591c1e46a0d71f1579a57c7d - Missing-return check in elseifs should work now.
Author: lep
Author date (UTC): 2015-02-03 19:35
Committer name: lep
Committer date (UTC): 2015-02-03 19:35
Parent(s): 889122b0fb788663c728127520d0e7124c2a040c
Signer:
Signing key:
Signing status: N
Tree: 47e63e7dd853b1022d06307784dcdc8934c18b5c
File Lines added Lines deleted
grammar.y 19 26
misc.c 64 39
misc.h 3 3
File grammar.y changed (mode: 100644) (index ebd5e33..6b3bbeb)
... ... expr: intexpr { $$.ty = gInteger; }
208 208 sprintf(ebuf, "Function %s must not take any arguments when used as code", $2.str); sprintf(ebuf, "Function %s must not take any arguments when used as code", $2.str);
209 209 yyerrorex(3, ebuf); yyerrorex(3, ebuf);
210 210 } }
211 if (fd->ret == gBoolean)
212 $$.ty = gCodeReturnsBoolean;
213 else
214 $$.ty = gCodeReturnsNoBoolean;
211 $$.ty = gCode;
215 212 } }
216 213 } }
217 214 | TNULL { $$.ty = gNull; } | TNULL { $$.ty = gNull; }
 
... ... funcdefn: NEWLINE
391 388
392 389 funcdefncore: funcbegin localblock codeblock funcend { funcdefncore: funcbegin localblock codeblock funcend {
393 390 if(retval != gNothing) { if(retval != gNothing) {
394 if ($3.ty == gAny || $3.ty == gNone)
391 //if ($3.ty == gAny || $3.ty == gNone)
392 if(!getTypeTag($3.ty))
395 393 yyerrorline(1, lineno - 1, "Missing return"); yyerrorline(1, lineno - 1, "Missing return");
396 394 else if (returnbug) else if (returnbug)
397 395 canconvertreturn($3.ty, retval, -1); canconvertreturn($3.ty, retval, -1);
 
... ... funcbegin: FUNCTION rid TAKES optparam_list returnorreturns opttype {
487 485 } }
488 486 ; ;
489 487
490 codeblock: /* empty */ { $$.ty = gNull; }
488 codeblock: /* empty */ { $$.ty = gEmpty; }
491 489 | statement codeblock { | statement codeblock {
492 if($2.ty == gNull)
490 if(typeeq($2.ty, gEmpty))
493 491 $$.ty = $1.ty; $$.ty = $1.ty;
494 492 else else
495 493 $$.ty = $2.ty; $$.ty = $2.ty;
496 494 } }
497 495 ; ;
498 496
499 statement: NEWLINE { $$.ty = gNull; }
497 statement: NEWLINE { $$.ty = gNone; }
500 498 | CALL funccall NEWLINE{ $$.ty = gNone;} | CALL funccall NEWLINE{ $$.ty = gNone;}
501 499 /*1 2 3 4 5 6 7 8 9 */ /*1 2 3 4 5 6 7 8 9 */
502 500 | IF expr THEN NEWLINE codeblock elsifseq elseseq ENDIF NEWLINE { | IF expr THEN NEWLINE codeblock elsifseq elseseq ENDIF NEWLINE {
503 501 canconvert($2.ty, gBoolean, -1); canconvert($2.ty, gBoolean, -1);
504 $5.ty = $5.ty == gNull ? gNone : $5.ty;
505 $6.ty = $6.ty == gNull ? gNull : $6.ty;
506 $7.ty = $7.ty == gNull ? gNone : $7.ty;
507 502 $$.ty = combinetype($5.ty, combinetype($6.ty, $7.ty)); $$.ty = combinetype($5.ty, combinetype($6.ty, $7.ty));
508 503 } }
509 504 | SET rid EQUALS expr NEWLINE { if (getVariable($2.str)->isarray) { | SET rid EQUALS expr NEWLINE { if (getVariable($2.str)->isarray) {
 
... ... statement: NEWLINE { $$.ty = gNull; }
543 538 | loopstart NEWLINE codeblock {$$.ty = $3.ty; yyerrorex(0, "Missing endloop");} | loopstart NEWLINE codeblock {$$.ty = $3.ty; yyerrorex(0, "Missing endloop");}
544 539 | EXITWHEN expr NEWLINE { canconvert($2.ty, gBoolean, -1); if (!inloop) yyerrorline(0, lineno - 1, "Exitwhen outside of loop"); $$.ty = gNone;} | EXITWHEN expr NEWLINE { canconvert($2.ty, gBoolean, -1); if (!inloop) yyerrorline(0, lineno - 1, "Exitwhen outside of loop"); $$.ty = gNone;}
545 540 | RETURN expr NEWLINE { | RETURN expr NEWLINE {
546 $$.ty = $2.ty;
541 $$.ty = mkretty($2.ty, 1);
547 542 if(retval == gNothing) if(retval == gNothing)
548 543 yyerrorline(1, lineno - 1, "Cannot return value from function that returns nothing"); yyerrorline(1, lineno - 1, "Cannot return value from function that returns nothing");
549 544 else if (!returnbug) else if (!returnbug)
 
... ... statement: NEWLINE { $$.ty = gNull; }
552 547 | RETURN NEWLINE { | RETURN NEWLINE {
553 548 if (retval != gNothing) if (retval != gNothing)
554 549 yyerrorline(1, lineno - 1, "Return nothing in function that should return value"); yyerrorline(1, lineno - 1, "Return nothing in function that should return value");
555 $$.ty = gAny;
550 $$.ty = mkretty(gAny, 1);
556 551 } }
557 552 | DEBUG statement {$$.ty = gNone;} | DEBUG statement {$$.ty = gNone;}
558 553 /*1 2 3 4 5 6 7 */ /*1 2 3 4 5 6 7 */
559 554 | IF expr THEN NEWLINE codeblock elsifseq elseseq { | IF expr THEN NEWLINE codeblock elsifseq elseseq {
560 555 canconvert($2.ty, gBoolean, -1); canconvert($2.ty, gBoolean, -1);
561 $5.ty = $5.ty == gNull ? gNone : $5.ty;
562 $6.ty = $6.ty == gNull ? gNull : $6.ty;
563 $7.ty = $7.ty == gNull ? gNone : $7.ty;
564 556 $$.ty = combinetype($5.ty, combinetype($6.ty, $7.ty)); $$.ty = combinetype($5.ty, combinetype($6.ty, $7.ty));
565 557 yyerrorex(0, "Missing endif"); yyerrorex(0, "Missing endif");
566 558 } }
 
... ... loopstart: LOOP {inloop++;}
580 572 loopend: ENDLOOP {inloop--;} loopend: ENDLOOP {inloop--;}
581 573 ; ;
582 574
583 elseseq: /* empty */ { $$.ty = gNull; }
575 elseseq: /* empty */ { $$.ty = gNone; }
584 576 | ELSE NEWLINE codeblock { | ELSE NEWLINE codeblock {
585 if($3.ty == gNull) {
586 $$.ty = gNone;
587 } else {
588 $$.ty = $3.ty;
589 }
577 $$.ty = $3.ty;
590 578 } }
591 579 ; ;
592 580
593 elsifseq: /* empty */ { $$.ty = gNull; }
581 elsifseq: /* empty */ { $$.ty = mkretty(gEmpty, 1); }
594 582 /* 1 2 3 4 5 6 */ /* 1 2 3 4 5 6 */
595 583 | ELSEIF expr THEN NEWLINE codeblock elsifseq { | ELSEIF expr THEN NEWLINE codeblock elsifseq {
596 584 canconvert($2.ty, gBoolean, -1); canconvert($2.ty, gBoolean, -1);
597 if($6.ty == gNull){
598 $$.ty = $5.ty == gNull ? gNone : $5.ty;
585
586 if(typeeq($6.ty, gEmpty)){
587 if(typeeq($5.ty, gEmpty)){
588 $$.ty = mkretty(gNone, 0);
589 }else{
590 $$.ty = $5.ty;
591 }
599 592 }else{ }else{
600 $$.ty = $5.ty == gNull ? gNone : combinetype($5.ty, $6.ty);
593 $$.ty = combinetype($5.ty, $6.ty);
601 594 } }
602 595 } }
603 596 ; ;
File misc.c changed (mode: 100644) (index bb467c3..0dfd52a)
... ... struct hashtable functions, globals, locals, params, types, initialized;
39 39 struct hashtable *curtab; struct hashtable *curtab;
40 40 struct typenode *retval, *retcheck; struct typenode *retval, *retcheck;
41 41 const char *curfile; const char *curfile;
42 struct typenode *gInteger, *gReal, *gBoolean, *gString, *gCode, *gHandle, *gNothing, *gNull, *gAny, *gNone, *gCodeReturnsBoolean, *gCodeReturnsNoBoolean;
42 struct typenode *gInteger, *gReal, *gBoolean, *gString, *gCode, *gHandle, *gNothing, *gNull, *gAny, *gNone, *gEmpty;
43 43 struct typenode *gEmpty; struct typenode *gEmpty;
44 44 struct funcdecl *fCurrent; struct funcdecl *fCurrent;
45 45
 
... ... void init(int argc, char **argv)
61 61 gNull = newtypenode("null", NULL); gNull = newtypenode("null", NULL);
62 62 gAny = newtypenode("any", NULL); gAny = newtypenode("any", NULL);
63 63 gNone = newtypenode("none", NULL); gNone = newtypenode("none", NULL);
64 gCodeReturnsBoolean = newtypenode("codereturnsboolean", gCode);
65 gCodeReturnsNoBoolean = newtypenode("codereturnsnoboolean", gCode);
64 gEmpty = newtypenode("gempty", NULL);
66 65 curtab = &globals; curtab = &globals;
67 66 fno = 0; fno = 0;
68 67 strict = 0; strict = 0;
 
... ... struct typeandname *newtypeandname(const struct typenode *ty, const char *name)
263 262 struct typenode *newtypenode(const char *typename, const struct typenode *superclass) struct typenode *newtypenode(const char *typename, const struct typenode *superclass)
264 263 { {
265 264 struct typenode *result; struct typenode *result;
266 result = calloc(sizeof(struct typenode), 1);
265 result = memalign(8, sizeof(struct typenode));
267 266 result->typename = strdup(typename); result->typename = strdup(typename);
268 267 result->superclass = superclass; result->superclass = superclass;
269 268 return result; return result;
 
... ... const struct typenode *getPrimitiveAncestor(const struct typenode *cur)
302 301 int isDerivedFrom(const struct typenode *cur, const struct typenode *base) int isDerivedFrom(const struct typenode *cur, const struct typenode *base)
303 302 { {
304 303 do { do {
305 if (cur == base) return 1;
304 if (typeeq(cur, base)) return 1;
306 305 cur = cur->superclass; cur = cur->superclass;
307 306 } while (cur); } while (cur);
308 307 return 0; return 0;
 
... ... struct typenode *binop(const struct typenode *a, const struct typenode *b)
405 404 { {
406 405 a = getPrimitiveAncestor(a); a = getPrimitiveAncestor(a);
407 406 b = getPrimitiveAncestor(b); b = getPrimitiveAncestor(b);
408 if (a == gInteger && b == gInteger)
407 if (typeeq(a, gInteger) && typeeq(b, gInteger))
409 408 return gInteger; return gInteger;
410 if (a == gAny)
409 if (typeeq(a, gAny))
411 410 return b; return b;
412 if (b == gAny)
411 if (typeeq(b, gAny))
413 412 return a; return a;
414 if ((a != gInteger && a != gReal) || (b != gInteger && b != gReal)) {
413 if ((!typeeq(a, gInteger) && !typeeq(a, gReal)) || (!typeeq(b, gInteger) && !typeeq(b, gReal))) {
415 414 yyerrorline(3, islinebreak ? lineno - 1 : lineno, "Bad types for binary operator"); yyerrorline(3, islinebreak ? lineno - 1 : lineno, "Bad types for binary operator");
416 415 } }
417 416 return gReal; return gReal;
 
... ... int canconvert(const struct typenode *ufrom, const struct typenode *uto, const i
424 423 char ebuf[1024]; char ebuf[1024];
425 424 if (from == NULL || to == NULL) if (from == NULL || to == NULL)
426 425 return 0; return 0;
427 if (from == gAny || to == gAny)
426 if (typeeq(from, gAny) || typeeq(to, gAny))
428 427 return 1; return 1;
429 428 if (isDerivedFrom(from, to)) if (isDerivedFrom(from, to))
430 429 return 1; return 1;
 
... ... int canconvert(const struct typenode *ufrom, const struct typenode *uto, const i
432 431 // return 1; // blizzard bug allows downcasting erroneously, we don't support this though // return 1; // blizzard bug allows downcasting erroneously, we don't support this though
433 432 if (from->typename == NULL || to->typename == NULL) if (from->typename == NULL || to->typename == NULL)
434 433 return 0; return 0;
435 if (from == gNone || to == gNone)
434 if (typeeq(from, gNone) || typeeq(to, gNone))
436 435 return 0; return 0;
437 436 from = getPrimitiveAncestor(from); from = getPrimitiveAncestor(from);
438 437 to = getPrimitiveAncestor(to); to = getPrimitiveAncestor(to);
439 if ((from == gNull) && (to != gInteger) && (to != gReal) && (to != gBoolean))
438 if (typeeq(from, gNull) && !typeeq(to, gInteger) && !typeeq(to, gReal) && !typeeq(to, gBoolean))
440 439 return 1; return 1;
441 440 if (strict) { if (strict) {
442 if (ufrom == gInteger && (to == gReal || to == gInteger))
441 if (typeeq(ufrom, gInteger) && (typeeq(to, gReal) || typeeq(to, gInteger)))
443 442 return 1; return 1;
444 if (ufrom == to && (ufrom == gBoolean || ufrom == gString || ufrom == gReal || ufrom == gInteger || ufrom == gCode))
443 if (typeeq(ufrom, to) && (typeeq(ufrom, gBoolean) || typeeq(ufrom, gString) || typeeq(ufrom, gReal) || typeeq(ufrom, gInteger) || typeeq(ufrom, gCode)))
445 444 return 1; return 1;
446 445 } else { } else {
447 if (from == gInteger && (to == gReal || to == gInteger))
446 if (typeeq(from, gInteger) && (typeeq(to, gReal) || typeeq(to, gInteger)))
448 447 return 1; return 1;
449 if (from == to && (from == gBoolean || from == gString || from == gReal || from == gInteger || from == gCode))
448 if (typeeq(from, to) && (typeeq(from, gBoolean) || typeeq(from, gString) || typeeq(from, gReal) || typeeq(from, gInteger) || typeeq(from, gCode)))
450 449 return 1; return 1;
451 450 } }
452 451
 
... ... int canconvertreturn(const struct typenode *ufrom, const struct typenode *uto, c
462 461 char ebuf[1024]; char ebuf[1024];
463 462 if (from == NULL || to == NULL) if (from == NULL || to == NULL)
464 463 return 0; // garbage return 0; // garbage
465 if (from == gAny || to == gAny)
464 if (typeeq(from, gAny) || typeeq(to, gAny))
466 465 return 1; // we don't care return 1; // we don't care
467 466 if (isDerivedFrom(from, to)) if (isDerivedFrom(from, to))
468 467 return 1; // eg. from = unit, to = handle return 1; // eg. from = unit, to = handle
 
... ... int canconvertreturn(const struct typenode *ufrom, const struct typenode *uto, c
470 469 // return 1; // blizzard bug allows downcasting erroneously, we don't support this though // return 1; // blizzard bug allows downcasting erroneously, we don't support this though
471 470 if (from->typename == NULL || to->typename == NULL) if (from->typename == NULL || to->typename == NULL)
472 471 return 0; // garbage return 0; // garbage
473 if (from == gNone || to == gNone)
472 if (typeeq(from, gNone) || typeeq(to, gNone))
474 473 return 0; // garbage return 0; // garbage
475 474
476 475 from = getPrimitiveAncestor(from); from = getPrimitiveAncestor(from);
477 476 to = getPrimitiveAncestor(to); to = getPrimitiveAncestor(to);
478 if ((to == gReal) && (from == gInteger)) {
477 if ((typeeq(to, gReal)) && (typeeq(from, gInteger))) {
479 478 // can't return integer when it expects a real (added 9.5.2005) // can't return integer when it expects a real (added 9.5.2005)
480 479 sprintf(ebuf, "Cannot convert returned value from %s to %s", from->typename, to->typename); sprintf(ebuf, "Cannot convert returned value from %s to %s", from->typename, to->typename);
481 480 yyerrorline(1, lineno + linemod, ebuf); yyerrorline(1, lineno + linemod, ebuf);
482 481 return 0; return 0;
483 482 } }
484 if ((from == gNull) && (to != gInteger) && (to != gReal) && (to != gBoolean))
483 if ((typeeq(from, gNull)) && (!typeeq(to, gInteger)) && (!typeeq(to, gReal)) && (!typeeq(to, gBoolean)))
485 484 return 1; // can't return null when it expects integer, real or boolean (added 9.5.2005) return 1; // can't return null when it expects integer, real or boolean (added 9.5.2005)
486 485
487 486 if (strict) { if (strict) {
488 487 if (isDerivedFrom(uto, ufrom)) if (isDerivedFrom(uto, ufrom))
489 488 return 1; return 1;
490 } else if (from == to)
489 } else if (typeeq(from, to))
491 490 return 1; return 1;
492 491
493 492 sprintf(ebuf, "Cannot convert returned value from %s to %s", ufrom->typename, uto->typename); sprintf(ebuf, "Cannot convert returned value from %s to %s", ufrom->typename, uto->typename);
 
... ... int canconvertreturn(const struct typenode *ufrom, const struct typenode *uto, c
495 494 return 0; return 0;
496 495 } }
497 496
498 struct typenode *combinetype(const struct typenode *n1, const struct typenode *n2) {
499 if ((n1 == gNone) || (n2 == gNone)) return gNone;
500 if (n1 == n2) return n1;
501 if (n1 == gNull || n1 == gAny)
502 return n2;
503 if (n2 == gNull || n2 == gAny)
504 return n1;
497 struct typenode* mkretty(struct typenode *ty, int ret){
498 uintptr_t tagMask = (8-1);
499 uintptr_t pointerMask = ~tagMask;
500 uintptr_t ptr = (uintptr_t)ty;
501 ret = ret & tagMask;
502 return (struct typenode*)((ptr & pointerMask) | ret);
503 }
504
505 int getTypeTag(struct typenode *ty){
506 uintptr_t tagMask = (8-1);
507 uintptr_t ptr = (uintptr_t)ty;
508 return (int)(ptr & tagMask);
509 }
510
511 struct typenode* getTypePtr(struct typenode *ty){
512 uintptr_t tagMask = (8-1);
513 uintptr_t pointerMask = ~tagMask;
514 uintptr_t ptr = (uintptr_t)ty;
515 return (struct typenode*)(ptr & pointerMask);
516 }
517
518 int typeeq(struct typenode *a, struct typenode *b){
519 return getTypePtr(a) == getTypePtr(b);
520 }
521
522 struct typenode *combinetype(struct typenode *n1, struct typenode *n2) {
523 int ret = getTypeTag(n1) & getTypeTag(n2);
524 if ((typeeq(n1, gNone)) || (typeeq(n2, gNone))) return mkretty(gNone, ret);
525 if (typeeq(n1, n2)) return mkretty(n1, ret);
526 if (typeeq(n1, gNull))
527 return mkretty(n2, ret);
528 if (typeeq(n2, gNull))
529 return mkretty(n1, ret);
505 530 n1 = getPrimitiveAncestor(n1); n1 = getPrimitiveAncestor(n1);
506 531 n2 = getPrimitiveAncestor(n2); n2 = getPrimitiveAncestor(n2);
507 if (n1 == n2) return n1;
508 if (n1 == gNull || n1 == gAny)
509 return n2;
510 if (n2 == gNull || n2 == gAny)
511 return n1;
512 if ((n1 == gInteger) && (n2 == gReal))
513 return gReal;
514 if ((n1 == gReal) && (n2 == gInteger))
515 return gInteger;
532 if (typeeq(n1, n2)) return mkretty(n1, ret);
533 if (typeeq(n1, gNull))
534 return mkretty(n2, ret);
535 if (typeeq(n2, gNull))
536 return mkretty(n1, ret);
537 if ((typeeq(n1, gInteger)) && (typeeq(n2, gReal)))
538 return mkretty(gReal, ret);
539 if ((typeeq(n1, gReal)) && (typeeq(n2, gInteger)))
540 return mkretty(gInteger, ret);
516 541 // printf("Cannot convert %s to %s", n1->typename, n2->typename); // printf("Cannot convert %s to %s", n1->typename, n2->typename);
517 return gNone;
542 return mkretty(gNone, ret);
518 543 } }
519 544
520 545 void checkParameters(const struct paramlist *func, const struct paramlist *inp) void checkParameters(const struct paramlist *func, const struct paramlist *inp)
 
... ... void checkeqtest(const struct typenode *a, const struct typenode *b)
578 603 return; return;
579 604 if (pa == gNull || pb == gNull) if (pa == gNull || pb == gNull)
580 605 return; return;
581 if (pa != pb) {
606 if (!typeeq(pa, pb)) {
582 607 yyerrorex(3, "Comparing two variables of different primitive types (except real and integer) is not allowed"); yyerrorex(3, "Comparing two variables of different primitive types (except real and integer) is not allowed");
583 608 return; return;
584 609 } }
File misc.h changed (mode: 100644) (index 9fc8f65..9603d7a)
16 16
17 17 struct typenode { struct typenode {
18 18 char *typename; char *typename;
19
20 19 const struct typenode *superclass; const struct typenode *superclass;
21 20 }; };
22 21
 
... ... void showfuncdecl(struct funcdecl *fd);
78 77 struct typenode *binop(const struct typenode *a, const struct typenode *b); struct typenode *binop(const struct typenode *a, const struct typenode *b);
79 78 int canconvert(const struct typenode *from, const struct typenode *to, const int linemod); int canconvert(const struct typenode *from, const struct typenode *to, const int linemod);
80 79 int canconvertreturn(const struct typenode *from, const struct typenode *to, const int linemod); int canconvertreturn(const struct typenode *from, const struct typenode *to, const int linemod);
81 struct typenode *combinetype(const struct typenode *n1, const struct typenode *n2);
80 struct typenode* mkretty(struct typenode *ty, int ret);
81 struct typenode *combinetype(struct typenode *n1, struct typenode *n2);
82 82 void checkParameters(const struct paramlist *func, const struct paramlist *inp); void checkParameters(const struct paramlist *func, const struct paramlist *inp);
83 83 void validateGlobalAssignment(const char *varname); void validateGlobalAssignment(const char *varname);
84 84 void checkcomparisonsimple(const struct typenode *a); void checkcomparisonsimple(const struct typenode *a);
 
... ... extern const char *curfile;
96 96 extern int yydebug; extern int yydebug;
97 97 int *showerrorlevel; int *showerrorlevel;
98 98 extern struct hashtable functions, globals, locals, params, types, initialized, *curtab; extern struct hashtable functions, globals, locals, params, types, initialized, *curtab;
99 extern struct typenode *gInteger, *gReal, *gBoolean, *gString, *gCode, *gHandle, *gNothing, *gNull, *gAny, *gNone, *gCodeReturnsBoolean, *gCodeReturnsNoBoolean;
99 extern struct typenode *gInteger, *gReal, *gBoolean, *gString, *gCode, *gHandle, *gNothing, *gNull, *gAny, *gNone, *gEmpty;
100 100 extern struct funcdecl *fCurrent; extern struct funcdecl *fCurrent;
101 101 extern struct typenode *retval; extern struct typenode *retval;
102 102 const struct typeandname *getVariable(const char *varname); const struct typeandname *getVariable(const char *varname);
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/vrtc/pjass

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/vrtc/pjass

Clone this repository using git:
git clone git://git.rocketgit.com/user/vrtc/pjass

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main