File grammar.y changed (mode: 100644) (index a02117f..f04416a) |
... |
... |
funcdefncore: funcbegin localblock codeblock funcend { |
347 |
347 |
if(retval != gNothing) { |
if(retval != gNothing) { |
348 |
348 |
if(!getTypeTag($3.ty)) |
if(!getTypeTag($3.ty)) |
349 |
349 |
yyerrorline(1, lineno - 1, "Missing return"); |
yyerrorline(1, lineno - 1, "Missing return"); |
350 |
|
else if ((pjass_flags & flag_rb) || (fnannotations & flag_rb)) |
|
|
350 |
|
else if ( flagenabled(flag_rb) ) |
351 |
351 |
canconvertreturn($3.ty, retval, -1); |
canconvertreturn($3.ty, retval, -1); |
352 |
352 |
} |
} |
353 |
353 |
fnannotations = 0; |
fnannotations = 0; |
|
... |
... |
returnorreturns: RETURNS |
363 |
363 |
; |
; |
364 |
364 |
|
|
365 |
365 |
funcbegin: FUNCTION rid TAKES optparam_list returnorreturns opttype { |
funcbegin: FUNCTION rid TAKES optparam_list returnorreturns opttype { |
366 |
|
if (ht_lookup(&locals, $2.str) || ht_lookup(¶ms, $2.str) || ht_lookup(&globals, $2.str)) { |
|
367 |
|
char buf[1024]; |
|
368 |
|
snprintf(buf, 1024, "%s already defined as variable", $2.str); |
|
369 |
|
yyerrorex(3, buf); |
|
370 |
|
} else if (ht_lookup(&types, $2.str)) { |
|
371 |
|
char buf[1024]; |
|
372 |
|
snprintf(buf, 1024, "%s already defined as type", $2.str); |
|
373 |
|
yyerrorex(3, buf); |
|
374 |
|
} |
|
375 |
|
inconstant = 0; |
|
376 |
|
infunction = 1; |
|
377 |
|
curtab = &locals; |
|
378 |
|
$$.fd = newfuncdecl(); |
|
379 |
|
$$.fd->name = strdup($2.str); |
|
380 |
|
$$.fd->p = $4.pl; |
|
381 |
|
$$.fd->ret = $6.ty; |
|
382 |
|
$$.fd->isconst = 0; |
|
383 |
|
put(&functions, $$.fd->name, $$.fd); |
|
384 |
|
fCurrent = ht_lookup(&functions, $2.str); |
|
385 |
|
struct typeandname *tan = $4.pl->head; |
|
386 |
|
for (;tan; tan=tan->next) { |
|
387 |
|
tan->lineno = lineno; |
|
388 |
|
tan->fn = fno; |
|
389 |
|
put(¶ms, strdup(tan->name), newtypeandname(tan->ty, tan->name)); |
|
390 |
|
if (ht_lookup(&functions, tan->name)) { |
|
391 |
|
char buf[1024]; |
|
392 |
|
snprintf(buf, 1024, "%s already defined as function", tan->name); |
|
393 |
|
yyerrorex(3, buf); |
|
394 |
|
} else if (ht_lookup(&types, tan->name)) { |
|
395 |
|
char buf[1024]; |
|
396 |
|
snprintf(buf, 1024, "%s already defined as type", tan->name); |
|
397 |
|
yyerrorex(3, buf); |
|
|
366 |
|
inconstant = 0; |
|
367 |
|
infunction = 1; |
|
368 |
|
$$ = checkfunctionheader($2.str, $4.pl, $6.ty); |
|
369 |
|
$$.fd->isconst = 0; |
398 |
370 |
} |
} |
399 |
|
} |
|
400 |
|
retval = $$.fd->ret; |
|
401 |
|
fnannotations = annotations; |
|
402 |
|
inblock = 1; |
|
403 |
|
inloop = 0; |
|
404 |
|
//showfuncdecl($$.fd); |
|
405 |
|
} |
|
406 |
|
| CONSTANT FUNCTION rid TAKES optparam_list returnorreturns opttype { |
|
407 |
|
if (ht_lookup(&locals, $3.str) || ht_lookup(¶ms, $3.str) || ht_lookup(&globals, $3.str)) { |
|
408 |
|
char buf[1024]; |
|
409 |
|
snprintf(buf, 1024, "%s already defined as variable", $3.str); |
|
410 |
|
yyerrorex(3, buf); |
|
411 |
|
} else if (ht_lookup(&types, $3.str)) { |
|
412 |
|
char buf[1024]; |
|
413 |
|
snprintf(buf, 1024, "%s already defined as type", $3.str); |
|
414 |
|
yyerrorex(3, buf); |
|
415 |
|
} |
|
416 |
|
inconstant = 1; |
|
417 |
|
curtab = &locals; |
|
418 |
|
$$.fd = newfuncdecl(); |
|
419 |
|
$$.fd->name = strdup($3.str); |
|
420 |
|
$$.fd->p = $5.pl; |
|
421 |
|
$$.fd->ret = $7.ty; |
|
422 |
|
$$.fd->isconst = 1; |
|
423 |
|
put(&functions, $$.fd->name, $$.fd); |
|
424 |
|
struct typeandname *tan = $5.pl->head; |
|
425 |
|
for (;tan; tan=tan->next) { |
|
426 |
|
tan->lineno = lineno; |
|
427 |
|
tan->fn = fno; |
|
428 |
|
put(¶ms, strdup(tan->name), newtypeandname(tan->ty, tan->name)); |
|
429 |
|
if (ht_lookup(&functions, tan->name)) { |
|
430 |
|
char buf[1024]; |
|
431 |
|
snprintf(buf, 1024, "%s already defined as function", tan->name); |
|
432 |
|
yyerrorex(3, buf); |
|
433 |
|
} else if (ht_lookup(&types, tan->name)) { |
|
434 |
|
char buf[1024]; |
|
435 |
|
snprintf(buf, 1024, "%s already defined as type", tan->name); |
|
436 |
|
yyerrorex(3, buf); |
|
|
371 |
|
| CONSTANT FUNCTION rid TAKES optparam_list returnorreturns opttype { |
|
372 |
|
inconstant = 1; |
|
373 |
|
infunction = 1; |
|
374 |
|
$$ = checkfunctionheader($3.str, $5.pl, $7.ty); |
|
375 |
|
$$.fd->isconst = 1; |
437 |
376 |
} |
} |
438 |
|
} |
|
439 |
|
retval = $$.fd->ret; |
|
440 |
|
inblock = 1; |
|
441 |
|
inloop = 0; |
|
442 |
|
//showfuncdecl($$.fd); |
|
443 |
|
} |
|
444 |
377 |
; |
; |
445 |
378 |
|
|
446 |
379 |
codeblock: /* empty */ { $$.ty = gEmpty; } |
codeblock: /* empty */ { $$.ty = gEmpty; } |
|
... |
... |
statement: newline { $$.ty = gEmpty; } |
499 |
432 |
$$.ty = mkretty($2.ty, 1); |
$$.ty = mkretty($2.ty, 1); |
500 |
433 |
if(retval == gNothing) |
if(retval == gNothing) |
501 |
434 |
yyerrorline(1, lineno - 1, "Cannot return value from function that returns nothing"); |
yyerrorline(1, lineno - 1, "Cannot return value from function that returns nothing"); |
502 |
|
else if (!(pjass_flags & flag_rb) && !(fnannotations & flag_rb)) |
|
|
435 |
|
else if (! flagenabled(flag_rb) ) |
503 |
436 |
canconvertreturn($2.ty, retval, 0); |
canconvertreturn($2.ty, retval, 0); |
504 |
437 |
} |
} |
505 |
438 |
| RETURN newline { |
| RETURN newline { |
|
... |
... |
vardecl: vartypedecl newline { |
748 |
681 |
if (tan->isconst) { |
if (tan->isconst) { |
749 |
682 |
yyerrorline(3, lineno - 1, "Constants must be initialized"); |
yyerrorline(3, lineno - 1, "Constants must be initialized"); |
750 |
683 |
} |
} |
|
684 |
|
if(infunction && flagenabled(flag_shadowing) ){ |
|
685 |
|
if( ht_lookup(&globals, tan->name)){ |
|
686 |
|
char buf[1024]; |
|
687 |
|
snprintf(buf, 1024, "Local variable %s shadows global variable", tan->name); |
|
688 |
|
yyerrorline(3, lineno -1, buf); |
|
689 |
|
} else if( ht_lookup(¶ms, tan->name)){ |
|
690 |
|
char buf[1024]; |
|
691 |
|
snprintf(buf, 1024, "Local variable %s shadows parameter", tan->name); |
|
692 |
|
yyerrorline(3, lineno -1, buf); |
|
693 |
|
} |
|
694 |
|
} |
751 |
695 |
$$.ty = gNothing; |
$$.ty = gNothing; |
752 |
696 |
} |
} |
753 |
697 |
| vartypedecl EQUALS expr newline { |
| vartypedecl EQUALS expr newline { |
|
... |
... |
vardecl: vartypedecl newline { |
758 |
702 |
if(infunction && !ht_lookup(&initialized, tan->name)){ |
if(infunction && !ht_lookup(&initialized, tan->name)){ |
759 |
703 |
put(&initialized, tan->name, (void*)1); |
put(&initialized, tan->name, (void*)1); |
760 |
704 |
} |
} |
|
705 |
|
if(infunction && flagenabled(flag_shadowing) ){ |
|
706 |
|
if( ht_lookup(&globals, tan->name)){ |
|
707 |
|
char buf[1024]; |
|
708 |
|
snprintf(buf, 1024, "Local variable %s shadows global variable", tan->name); |
|
709 |
|
yyerror(buf); |
|
710 |
|
} else if( ht_lookup(¶ms, tan->name)){ |
|
711 |
|
char buf[1024]; |
|
712 |
|
snprintf(buf, 1024, "Local variable %s shadows parameter", tan->name); |
|
713 |
|
yyerror(buf); |
|
714 |
|
} |
|
715 |
|
} |
761 |
716 |
canconvert($3.ty, tan->ty, -1); |
canconvert($3.ty, tan->ty, -1); |
762 |
717 |
$$.ty = gNothing; |
$$.ty = gNothing; |
763 |
718 |
} |
} |
File misc.c changed (mode: 100644) (index 3a98d99..97ee304) |
... |
... |
void checkParameters(const struct paramlist *func, const struct paramlist *inp, |
278 |
278 |
return; |
return; |
279 |
279 |
} |
} |
280 |
280 |
canconvert(pi->ty, fi->ty, 0); |
canconvert(pi->ty, fi->ty, 0); |
281 |
|
bool has_flag = (pjass_flags & flag_filter) || (fnannotations & flag_filter); |
|
282 |
|
if(has_flag && mustretbool && typeeq(pi->ty, gCodeReturnsNoBoolean)){ |
|
|
281 |
|
if(flagenabled(flag_filter) && mustretbool && typeeq(pi->ty, gCodeReturnsNoBoolean)){ |
283 |
282 |
yyerrorex(semanticerror, "Function passed to Filter or Condition must return a boolean"); |
yyerrorex(semanticerror, "Function passed to Filter or Condition must return a boolean"); |
284 |
283 |
return; |
return; |
285 |
284 |
} |
} |
|
... |
... |
int updateannotation(int cur, char *txt, struct hashtable *flags){ |
477 |
476 |
} |
} |
478 |
477 |
return cur; |
return cur; |
479 |
478 |
} |
} |
|
479 |
|
|
|
480 |
|
bool flagenabled(int flag) |
|
481 |
|
{ |
|
482 |
|
return (pjass_flags & flag) || (fnannotations & flag); |
|
483 |
|
} |
|
484 |
|
|
|
485 |
|
union node checkfunctionheader(char *fnname, struct paramlist *pl, const struct typenode *retty) |
|
486 |
|
{ |
|
487 |
|
union node ret; |
|
488 |
|
|
|
489 |
|
if (ht_lookup(&locals, fnname) || ht_lookup(¶ms, fnname) || ht_lookup(&globals, fnname)) { |
|
490 |
|
char buf[1024]; |
|
491 |
|
snprintf(buf, 1024, "%s already defined as variable", fnname); |
|
492 |
|
yyerrorex(3, buf); |
|
493 |
|
} else if (ht_lookup(&types, fnname)) { |
|
494 |
|
char buf[1024]; |
|
495 |
|
snprintf(buf, 1024, "%s already defined as type", fnname); |
|
496 |
|
yyerrorex(3, buf); |
|
497 |
|
} |
|
498 |
|
|
|
499 |
|
curtab = &locals; |
|
500 |
|
ret.fd = newfuncdecl(); |
|
501 |
|
ret.fd->name = strdup(fnname); |
|
502 |
|
ret.fd->p = pl; |
|
503 |
|
ret.fd->ret = retty; |
|
504 |
|
|
|
505 |
|
put(&functions, ret.fd->name, ret.fd); |
|
506 |
|
|
|
507 |
|
fCurrent = ht_lookup(&functions, fnname); |
|
508 |
|
fnannotations = annotations; |
|
509 |
|
|
|
510 |
|
struct typeandname *tan = pl->head; |
|
511 |
|
for (;tan; tan=tan->next) { |
|
512 |
|
tan->lineno = lineno; |
|
513 |
|
tan->fn = fno; |
|
514 |
|
put(¶ms, strdup(tan->name), newtypeandname(tan->ty, tan->name)); |
|
515 |
|
if (ht_lookup(&functions, tan->name)) { |
|
516 |
|
char buf[1024]; |
|
517 |
|
snprintf(buf, 1024, "%s already defined as function", tan->name); |
|
518 |
|
yyerrorex(3, buf); |
|
519 |
|
} else if (ht_lookup(&types, tan->name)) { |
|
520 |
|
char buf[1024]; |
|
521 |
|
snprintf(buf, 1024, "%s already defined as type", tan->name); |
|
522 |
|
yyerrorex(3, buf); |
|
523 |
|
} |
|
524 |
|
|
|
525 |
|
if( flagenabled(flag_shadowing) ){ |
|
526 |
|
if( ht_lookup(&globals, tan->name) ){ |
|
527 |
|
char buf[1024]; |
|
528 |
|
snprintf(buf, 1024, "Parmeter %s shadows global variable", tan->name); |
|
529 |
|
yyerrorex(3, buf); |
|
530 |
|
} |
|
531 |
|
} |
|
532 |
|
|
|
533 |
|
} |
|
534 |
|
retval = ret.fd->ret; |
|
535 |
|
inblock = 1; |
|
536 |
|
inloop = 0; |
|
537 |
|
|
|
538 |
|
return ret; |
|
539 |
|
} |