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); |