File misc.c changed (mode: 100644) (index dd7921c..679d3ed) |
... |
... |
void validateGlobalAssignment(const char *varname) |
263 |
263 |
} |
} |
264 |
264 |
|
|
265 |
265 |
|
|
266 |
|
void checkParameters(const struct paramlist *func, const struct paramlist *inp, bool mustretbool) |
|
|
266 |
|
void checkParameters(const struct funcdecl *fd, const struct paramlist *inp, bool mustretbool) |
267 |
267 |
{ |
{ |
|
268 |
|
const struct paramlist *func = fd->p; |
268 |
269 |
const struct typeandname *fi = func->head; |
const struct typeandname *fi = func->head; |
269 |
270 |
const struct typeandname *pi = inp->head; |
const struct typeandname *pi = inp->head; |
270 |
271 |
while(true) { |
while(true) { |
271 |
272 |
if (fi == NULL && pi == NULL) |
if (fi == NULL && pi == NULL) |
272 |
273 |
return; |
return; |
273 |
274 |
if (fi == NULL && pi != NULL) { |
if (fi == NULL && pi != NULL) { |
274 |
|
yyerrorex(semanticerror, "Too many arguments passed to function"); |
|
|
275 |
|
char buf[1024]; |
|
276 |
|
snprintf(buf, 1024, "Too many arguments passed to function %s. ", fd->name); |
|
277 |
|
yyerrorex(semanticerror, buf); |
275 |
278 |
return; |
return; |
276 |
279 |
} |
} |
277 |
280 |
if (fi != NULL && pi == NULL) { |
if (fi != NULL && pi == NULL) { |
278 |
|
yyerrorex(semanticerror, "Not enough arguments passed to function"); |
|
|
281 |
|
char buf[1024]; |
|
282 |
|
snprintf(buf, 1024, "Not enough arguments passed to function %s. ", fd->name); |
|
283 |
|
strncat(buf, "Still missing: ", 1024); |
|
284 |
|
bool addComma = false; |
|
285 |
|
for(; fi; fi = fi->next){ |
|
286 |
|
if(addComma){ |
|
287 |
|
strncat(buf, ", ", 1024); |
|
288 |
|
} |
|
289 |
|
strncat(buf, fi->name, 1024); |
|
290 |
|
addComma = true; |
|
291 |
|
} |
|
292 |
|
yyerrorex(semanticerror, buf); |
279 |
293 |
return; |
return; |
280 |
294 |
} |
} |
281 |
|
canconvert(pi->ty, fi->ty, 0); |
|
|
295 |
|
char buf[1024]; |
|
296 |
|
if(! canconvertbuf(buf, 1024, pi->ty, fi->ty )){ |
|
297 |
|
char pbuf[1024]; |
|
298 |
|
snprintf(pbuf, 1024, " in parameter %s in call to %s", fi->name, fd->name); |
|
299 |
|
strncat(buf, pbuf, 1024); |
|
300 |
|
yyerrorex(semanticerror, buf); |
|
301 |
|
} |
282 |
302 |
if(flagenabled(flag_filter) && mustretbool && typeeq(pi->ty, gCodeReturnsNoBoolean)){ |
if(flagenabled(flag_filter) && mustretbool && typeeq(pi->ty, gCodeReturnsNoBoolean)){ |
283 |
303 |
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 |
304 |
return; |
return; |
|
... |
... |
const struct typenode *combinetype(const struct typenode *n1, const struct typen |
331 |
351 |
return mkretty(gNone, ret); |
return mkretty(gNone, ret); |
332 |
352 |
} |
} |
333 |
353 |
|
|
334 |
|
// this is used for reducing expressions in many places (if/exitwhen conditions, assignments etc.) |
|
335 |
|
void canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod) |
|
|
354 |
|
bool canconvertbuf(char *buf, size_t buflen, const struct typenode *ufrom, const struct typenode *uto) |
336 |
355 |
{ |
{ |
337 |
356 |
const struct typenode *from = ufrom, *to = uto; |
const struct typenode *from = ufrom, *to = uto; |
338 |
|
char ebuf[1024]; |
|
339 |
357 |
if (from == NULL || to == NULL) |
if (from == NULL || to == NULL) |
340 |
|
return; |
|
|
358 |
|
return true; |
341 |
359 |
if (typeeq(from, gAny) || typeeq(to, gAny)) |
if (typeeq(from, gAny) || typeeq(to, gAny)) |
342 |
|
return; |
|
|
360 |
|
return true; |
343 |
361 |
if (isDerivedFrom(from, to)) |
if (isDerivedFrom(from, to)) |
344 |
|
return; |
|
|
362 |
|
return true; |
345 |
363 |
if (getTypePtr(from)->typename == NULL || getTypePtr(to)->typename == NULL) |
if (getTypePtr(from)->typename == NULL || getTypePtr(to)->typename == NULL) |
346 |
|
return; |
|
|
364 |
|
return true; |
347 |
365 |
if (typeeq(from, gNone) || typeeq(to, gNone)) |
if (typeeq(from, gNone) || typeeq(to, gNone)) |
348 |
|
return; |
|
|
366 |
|
return true; |
349 |
367 |
from = getPrimitiveAncestor(from); |
from = getPrimitiveAncestor(from); |
350 |
368 |
to = getPrimitiveAncestor(to); |
to = getPrimitiveAncestor(to); |
351 |
369 |
if (typeeq(from, gNull) && !typeeq(to, gInteger) && !typeeq(to, gReal) && !typeeq(to, gBoolean)) |
if (typeeq(from, gNull) && !typeeq(to, gInteger) && !typeeq(to, gReal) && !typeeq(to, gBoolean)) |
352 |
|
return; |
|
|
370 |
|
return true; |
353 |
371 |
if (typeeq(from, gInteger) && (typeeq(to, gReal) || typeeq(to, gInteger))) |
if (typeeq(from, gInteger) && (typeeq(to, gReal) || typeeq(to, gInteger))) |
354 |
|
return; |
|
|
372 |
|
return true; |
355 |
373 |
if (typeeq(from, to) && (typeeq(from, gBoolean) || typeeq(from, gString) || typeeq(from, gReal) || typeeq(from, gInteger) || typeeq(from, gCode))) |
if (typeeq(from, to) && (typeeq(from, gBoolean) || typeeq(from, gString) || typeeq(from, gReal) || typeeq(from, gInteger) || typeeq(from, gCode))) |
356 |
|
return; |
|
|
374 |
|
return true; |
357 |
375 |
|
|
358 |
|
snprintf(ebuf, 1024, "Cannot convert %s to %s", ufrom->typename, uto->typename); |
|
359 |
|
yyerrorline(semanticerror, lineno + linemod, ebuf); |
|
360 |
|
return; |
|
|
376 |
|
snprintf(buf, buflen, "Cannot convert %s to %s", ufrom->typename, uto->typename); |
|
377 |
|
return false; |
|
378 |
|
} |
|
379 |
|
|
|
380 |
|
// this is used for reducing expressions in many places (if/exitwhen conditions, assignments etc.) |
|
381 |
|
void canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod) |
|
382 |
|
{ |
|
383 |
|
char buf[1024]; |
|
384 |
|
if(! canconvertbuf(buf, 1024, ufrom, uto ) ){ |
|
385 |
|
yyerrorline(semanticerror, lineno + linemod, buf); |
|
386 |
|
} |
361 |
387 |
} |
} |
362 |
388 |
|
|
363 |
389 |
// this is used for return statements only |
// this is used for return statements only |
|
... |
... |
union node checkfunccall(const char *fnname, struct paramlist *pl) |
557 |
583 |
} |
} |
558 |
584 |
if (fd == fCurrent && fCurrent) |
if (fd == fCurrent && fCurrent) |
559 |
585 |
yyerrorex(semanticerror, "Recursive function calls are not permitted in local declarations"); |
yyerrorex(semanticerror, "Recursive function calls are not permitted in local declarations"); |
560 |
|
checkParameters(fd->p, pl, fd == fFilter || fd == fCondition); |
|
|
586 |
|
checkParameters(fd, pl, fd == fFilter || fd == fCondition); |
561 |
587 |
ret.ty = fd->ret; |
ret.ty = fd->ret; |
562 |
588 |
} |
} |
563 |
589 |
return ret; |
return ret; |
File misc.h changed (mode: 100644) (index 83d6ad4..817d16a) |
... |
... |
void getsuggestions(const char*, char*, size_t, int, ...); |
54 |
54 |
|
|
55 |
55 |
const struct typenode *binop(const struct typenode *a, const struct typenode *b); |
const struct typenode *binop(const struct typenode *a, const struct typenode *b); |
56 |
56 |
const struct typenode *combinetype(const struct typenode *n1, const struct typenode *n2); |
const struct typenode *combinetype(const struct typenode *n1, const struct typenode *n2); |
57 |
|
void checkParameters(const struct paramlist *func, const struct paramlist *inp, bool mustretbool); |
|
|
57 |
|
void checkParameters(const struct funcdecl *fd, const struct paramlist *inp, bool mustretbool); |
58 |
58 |
const struct typeandname *getVariable(const char *varname); |
const struct typeandname *getVariable(const char *varname); |
59 |
59 |
|
|
|
60 |
|
bool canconvertbuf(char *buf, size_t buflen, const struct typenode *ufrom, const struct typenode *uto); |
60 |
61 |
void canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod); |
void canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod); |
61 |
62 |
void canconvertreturn(const struct typenode *ufrom, const struct typenode *uto, const int linemod); |
void canconvertreturn(const struct typenode *ufrom, const struct typenode *uto, const int linemod); |
62 |
63 |
|
|